EXAMPLE 14
Sound generating, using macros
The generation of sound is a task commonly assigned to the microcontroller. Basically, it all comes to generating a pulse sequence on one output pin. While doing so, the proportion of logic zero (0) to logic one (1) duration determines the tone pitch and by changing different tones, different melodies arise.In this example, any press on push-buttons T1 and T2 generates a sound. The appropriate instructions are stored in macro "beep" containing two arguments.


Source Code
;*********************** Header ***************************************
;******************* Defining variables in program ********************
cblock 0x20
HIcnt ; Auxiliary variables for macro pausems
LOcnt
LOOPcnt
PRESCwait
Beep_TEMP1 ; Belongs to macro "BEEP"
Beep_TEMP2
Beep_TEMP3
endc
#define BEEPport PORTD, 2 ; Speaker pin
#define BEEPtris TRISD, 2
expand
;**********************************************************************
ORG 0x0000 ; RESET vector address
goto main ; Jump to program start (label - main)
;**********************************************************************
; remaining code goes here
include "pause.inc"
include "button.inc"
include "beep.inc"
main
banksel ANSEL ; Selects bank containing ANSEL
clrf ANSEL ; All outputs are digital
clrf ANSELH
banksel TRISD
movlw b'11111011' ; PORTA D initialization
movwf TRISD
banksel PORTD
BEEPinit ; Macro "Beep"
Loop
button PORTD,0,0,Play1 ; Push-button 1
button PORTD,1,0,Play2 ; Push-button 2
goto Loop
Play1 ; First tone
BEEP 0xFF, 0x02
BEEP 0x90, 0x05
BEEP 0xC0, 0x03
BEEP 0xFF, 0x03
goto Loop
Play2 ; Second tone
BEEP 0xBB, 0x02
BEEP 0x87, 0x05
BEEP 0xA2, 0x03
BEEP 0x98, 0x03
goto Loop
;**********************************************************************
END ; End of program
Macro "beep":
BEEPinit MACRO
bcf STATUS, RP0
bcf STATUS, RP1
bcf BEEPport
bsf STATUS, RP0
bcf STATUS, RP1
bcf BEEPtris
movlw b'00000111' ; TMR0 prescaler rate 1:256
movwf OPTION_REG ; OPTION <- W
bcf STATUS, RP0
bcf STATUS, RP1
ENDM
BEEP MACRO freq, duration
bcf STATUS, RP0
bcf STATUS, RP1
movlw freq
movwf Beep_TEMP1
movlw duration
movwf Beep_TEMP2
call BEEPsub
ENDM
;**********************************************************************
; Subroutines
BEEPsub
clrf TMR0 ; Counter initialization
bcf INTCON, T0IF
bcf BEEPport
BEEPa
bcf INTCON, T0IF ; Clears TMR0 Overflow Flag
BEEPb
bsf BEEPport
call B_Wait ; Logic one "1" duration
bcf BEEPport
call B_Wait ; Logic zero "0" duration
btfss INTCON, T0IF ; Check TMR0 Overflow Flag,
goto BEEPb ; skip next if set
decfsz Beep_TEMP2, f ; Is Beep_TEMP2 = 0 ?
goto BEEPa ; Go to BEEPa again
return
B_Wait
movf Beep_TEMP1, w
movwf Beep_TEMP3
B_Waita
decfsz Beep_TEMP3, f
goto B_Waita
return