Play Sentence Made of Segments (PIC16F877)

This example, written by Ron Hayes, plays a sentence made up of a sequence of segments. By utilizing the Hardware Busy indicator on the uMP3, the code knows when the last segment has completed playing, then plays the next segment.

In this example, Ron demonstrates how this code can be used to verbalize the distance to an object.

You can find the full download here, including the MP3 audio samples and source code.

;FILES OBJECT.MP3, 10.MP3 AND CHANG.MP3 SHOULD BE IN THE ROOT DIRECTORY OF THE SD CARD.
;MAKE SURE THAT THE uMP3 MODULE HAS THE HARDWARE BUSY SETTING IS TURNED ON (ST H 1).
;BAUD RATE IS SET TO 19,200.
;HARDWARE BUSY SIGNAL IS ON PORTB,0
;OSC IS 4Mhz


	list      p=16F877A             ; list directive to define processor
	#include          ; processor specific variable definitions

	__CONFIG    _CP_OFF & _WDT_OFF & _HS_OSC & _LVP_OFF & _BODEN_OFF & _PWRTE_ON
	ERRORLEVEL	-302
; '__CONFIG' directive is used to embed configuration data within .asm file.
; The lables following the directive are located in the respective .inc file.
; See respective data sheet for additional information on configuration word.


;***** VARIABLE DEFINITIONS
	CBLOCK	0X20
	FILENAME
	STRING
	TEMP
	PL
	PH
	ENDC
	
;***** DEFINES

	#DEFINE	PLAYCMD	F1-F1	;FILENAME OFFSET DEFINES
	#DEFINE	SENDEND	F2-F1	;F#-F1 CALCULATES FILENAME OFFSET
	#DEFINE PLAYMP3	F3-F1
	#DEFINE OBJECT	F4-F1
	#DEFINE CHANG	F5-F1
	#DEFINE N10	F6-F1
	#DEFINE BUSYPIN	PORTB,0	;HARDWARE BUSY FLAG
	#DEFINE VIN	PORTB,1
	#DEFINE	VOUT	PORTB,2
	
	CONSTANT     BAUD=D'12'	;19200 @ 4.608MHZ 	= '14'
				;19200 @ 20MHZ		= '64'
				;9600  @ 4MHZ		= '25'
				;19200  @ 4MHZ		= '12'
	
	NOP
	BSF	STATUS,RP0
	MOVLW	B'00000101'
	MOVWF	TRISB
	MOVLW	B'11000000'
	MOVWF	TRISC		;SET PORTE AS ALL OUTPUT
	MOVLW	B'00000111'
	MOVWF	ADCON1		;SET PORT A AS OUTPUTS
	MOVLW	BAUD
	MOVWF	SPBRG		;LOAD BAUD RATE GENERATOR
	MOVLW	B'00100100'
	MOVWF	TXSTA		;ENABLE TX AND HIGH BAUD
	BCF	STATUS,RP0
	MOVLW 	B'10010000'
	MOVWF	RCSTA  		;ENABLE SERIAL PORT ENABLE AND CONT RX ENABLE
	CLRF	PORTB
	
START	MOVLW	OBJECT		;LOAD OBJECT DETECTED MP3
	CALL	PLAY
	MOVLW	N10		;LOAD DISTANCE MP3
	CALL	PLAY		
	MOVLW	CHANG		;LOAD CHANGE COURSE MP3
	CALL	PLAY
	GOTO	$		;END HERE, LOOP FOREVER

PLAY	MOVWF	FILENAME	;PASS FILENAME IN W TO THIS SUB TO PLAY THEM
	MOVLW	PLAYCMD
	CALL	SENDMP3		;ADD PLAY COMMAND PREFIX (PC )
	MOVLW	PLAYMP3
	CALL	SENDMP3		;ADD PLAY FILE PREFIX (F /)
	MOVF	FILENAME,W	;INSERT FILENAME
	CALL	SENDMP3
	MOVLW	SENDEND
	CALL	SENDMP3		;ADD SUFFIX (.MP3)
	CALL	BUSY		;WAIT FOR MP3 TO FINISH PLAYING
	RETURN

BUSY	CALL	DELAY
	BTFSC	BUSYPIN		;WAIT FOR HARDWARE BUSY PIN TO TURN OFF
	GOTO	BUSY
	RETURN
	
SENDMP3	MOVWF	STRING		;GET FILENAME FROM LOOKUP TABLE
	CALL	TBLREAD
	MOVWF	TEMP
	MOVF	TEMP,F		;TEST IF CHARACTER IS 0
	BTFSC	STATUS,Z
	RETURN
	CALL	TX		;SEND STRING OUT USART
	INCF	STRING,F
	MOVF	STRING,W
	GOTO	SENDMP3
	
	
TX 
	BTFSS   PIR1,TXIF        ;WAIT FOR TX BUFFER TO EMPTY 
	GOTO    $-1 
	MOVWF   TXREG            ;MOVE W TO TX 
	RETURN 
	
DELAY	MOVLW	0XFF		;DELAY OF ~50mS REQUIRED BETWEEN COMMAND SENT
	MOVWF	PH		;AND HARDWARE BUSY SIGNAL TURNS ON.
PLR	MOVLW	0X40
	MOVWF	PL
	DECFSZ	PL,F
	GOTO	$-1
	DECFSZ	PH,F
	GOTO	PLR
	RETURN
	
	
TBLREAD	ADDWF	PCL,F		;FILENAME LOOKUP TABLE
F1	DT "PC ",0		;PLAY COMMAND
F2	DT ".MP3",0X0D,0
F3	DT "F /",0
F4	DT "OBJECT",0
F5	DT "CHANG",0
F6	DT "10",0

	END