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