Dave's ****










; RA4------------------+
;                      |
; RA3----R1---+---R2---+---R3---C2---+----+---> TO AMPLIFIER
;             |                      |    |
;             |                      |    |
;            C1                     C3   R4
;             |                      |    |
;             |                      |    |
;            GND                    GND  GND

;Some component values, for the sake of an example:

; R1 = 470 ohms
; C1 = 10uF
; R2 = R3 = R4 = 10K ohms
; C2 = C3 = 10nF

; 1. Before initiating a "dong" procedure, RA3 and RA4 are both 
; configured as outputs and both have been outputting a LOW.

; 2. To start the "dong", output a HIGH on both RA3 and RA4, and
; wait a period of time at least 5 * R1 * C1 to give C1 time to 
; charge up (in this example, that would be about 25 milliseconds).

; 3. At the end of this period, change RA3 from an output to an input.

; 4. Then start outputting alternating 1's and 0's on RA4 at 
; whatever frequency you want the tone to be, with roughly a 50% 
; duty cycle. This generates the tone by "chopping" the DC voltage 
; that's on the top end of C1, and it also causes C1 to start 
; discharging through R2 during the half-cycles when port pin 
; RA4 is low.  Since the voltage on C1 decays exponentially, 
; and since it's being chopped, you end up with a tone that decays 
; in amplitude very realistically.

; 5. Once C1 is discharged, which takes about 10 * R2 * C1 seconds 
; (about a second, in this example), stop toggling RA4 and leave 
; it LOW; also make RA3 an output again and bring it LOW, too, 
; until you want to emit another "dong".
;
; Dave Dilatush

;dong.asm - sound from 2 PIC pins
;           13th February 2002
;
         list p=16F628
         include "P16F628.inc"

bank0    macro
         bcf    status,rp0
         bcf    status,rp1
         bcf    status,irp
         endm

bank1    macro
         bsf    status,rp0
         bcf    status,rp1
         bcf    status,irp
         endm

#define button  porta,0
#define audio1  porta,3
#define audio2  porta,4

         cblock 0x20

         count1       ;IRQ counter
         limit        ;number of IRQs @ 256us
         stage        ;progress flags byte
         timelo       ;1 second counter
         timehi
         shadow

         endc

begin  equ 0x00       ;progress flags bits
tone   equ 0x01
finish equ 0x02
done   equ 0x03

       __config _intrc_osc_noclkout & _wdt_off & _pwrte_on & _lvp_off & _boden_off

         org  0x00
         goto init

         org  0x04
         goto isr

init     clrf   porta
         movlw  0x07
         movwf  cmcon

         bank1
         movlw  b'00000001'   ;oooo oooi all o/p except button
         movwf  trisa
         movlw  b'00000000'   ;oooo oooo, unused, set as o/p
         movwf  trisb
         movlw  b'10000000'   ;pull-ups off, no timer pre-scaler
         movwf  option_reg
         bank0         

         clrf   porta
         clrf   portb
         clrf   count1
         clrf   stage
         clrf   timelo
         movlw  0x0f          ;set 1 second time limit
         movwf  timehi        ;15 x 256 x 256 = 983,040 us

waitl    btfsc  button        ;wait for button push-release to start
         goto   waitl
waith    btfss  button
         goto   waith

         movlw  0x64          ;charge for ~25ms (100 x 256us)
         movwf  limit

         bsf    audio1
         nop
         bsf    audio2

         movlw  b'00000001'   ;set "begin" flag
         movwf  stage

         bsf    intcon,t0ie   ;enable TMR0 IRQs
         bsf    intcon,gie

;==============================

loop1    nop                  ;loop here during "begin" IRQs
         btfss  stage,tone    ;jump out if ready for stage2
         goto   loop1

;==============================

stage2   bank1
         movlw  b'00001000'   ;set RA3 to i/p
         movwf  trisa
         bank0                ;and tone freq on RA4

loop2    nop                  ;loop here during "tone" IRQs
         btfss  stage,finish  ;jump out if ready for stage3
         goto   loop2

;==============================

loop3    nop                  ;loop here during "decay" IRQs
         btfss  stage,done    ;jump out if at main timer limit
         goto   loop3

;==============================

stop     bank1
         movlw  b'00000000'   ;RA3 as o/p again
         movwf  trisa
         bank0

         bcf    audio1
         nop
         bcf    audio2

         bcf    intcon,t0ie
         bcf    intcon,gie

         goto   init          ;restart

;==============================

isr      bcf    intcon,t0if

         incfsz timelo        ;1 second main timer
         goto   cont
         decfsz timehi
         goto   cont          ;if not 1 second, continue
         rlf    stage         ;1 second, set "done" flag, end sound
         retfie               ;return to loop3

cont     btfss  stage,tone    ;do not use "limit" for tone
         goto   inccnt

toggle   movfw  porta         ;copy porta to RAM
         movwf  shadow
         movlw  b'00010000'   ;toggle RA4 output
         xorwf  shadow,w
         movwf  porta
         retfie               ;return to loop2
         
inccnt   incf   count1        ;compare counter to limit (100)
         movfw  limit
         xorwf  count1,w
         skpz                 ;if 25ms limit, set "tone" flag
         retfie

         clrc
         rlf    stage         ;move flag through byte
         retfie 

  end