Tuesday, March 28, 2006

PIC: EXAMPLE 14

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.
Macro Beep
Example 14 - Sound generating, using macros

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