; ; *************************************************************************** ; *** Bubble Software Parallax to PIC Source Converter. Copyright 1999. *** ; *** http://www.picnpoke.com email: sales@picnpoke.com *** ; *************************************************************************** ; ; SOUND port, pin, frequency, duration ; Generates squarewave tones (notes) of the specified frequency and ; duration. This demonstration program shows how to use lookup tables to ; play tunes or effects from data stored in program memory. ; Device data and reset vector P = pic16c55 #include <16c55.inc> ; processor assembler definitions _CONFIG _xt_osc & _wdt_off & _protect_off reset start org 8 pin Res d'1' ; Pin number to use as output (0-7). freq Res d'1' ; Frequency of note. duratn Res d'1' ; Duration of note. f_copy Res d'1' ; Copy of freq variable. temp Res d'1' ; Variable to stretch duratn to 16 bits. index Res d'1' ; Index to tables of notes, lengths. org 0 ; Table to convert pin number (0-7) into bit mask (00000001b to 10000000b). Pinz ADDWF pcl RETLW d'1' RETLW d'2' RETLW d'4' RETLW d'8' RETLW d'16' RETLW d'32' RETLW d'64' RETLW d'128' ; Table of notes for the demonstration tune "Charge." Notes ADDWF pcl RETLW d'166' RETLW d'189' RETLW d'204' RETLW d'212' RETLW d'204' RETLW d'212' ; Table of note durations for the demonstration tune "Charge." Lengths ADDWF pcl RETLW d'52' RETLW d'52' RETLW d'52' RETLW d'82' RETLW d'45' RETLW d'190' start MOVLW d'0' ; Output for speaker. TRIS 5h CLRF temp ; Clear LSB of duratn counter. CLRF index ; Clear the note counter. start_loop MOVF index,w ; Look up note in table. CALL Notes MOVWF freq ; Store note in freq. MOVF index,w ; Look up length in table. CALL Lengths MOVWF duratn ; Store in duratn. MOVLW d'3' ; Select pin 3 of port MOVWF pin MOVLW d'0' ; RA for speaker output CALL Sound ; Play the sound. INCF index ; Advance to next sound in tables. MOVLW ~d'5' ; IF index <= 5, play note ADDWF index,w BTFSS status,c GOTO start_loop GOTO $ ; ELSE end. ; Upon entry, the desired speaker pin must already be set up as an output. ; The w register contains a number representing the output port (0-2) for ; RA through RC. Variable "pin" contains the pin number (0-7). The variables ; freq and duratn are the frequency and duration of the note. ; Upon exit, duratn will be cleared to 0, but freq will be intact. If you require the ; value of duratn for some other purpose, copy it before calling Sound. The ; variable pin and the file-select register (fsr) will also have be altered. Sound COMF duratn ; Convert to two's complement. INCF duratn MOVWF fsr ; Point to the port number. MOVLW 5h ; Add offset for port RA. ADDWF fsr MOVF pin,w ; Now look up pin number in CALL Pinz ; table and get bit mask. MOVWF pin ; Put the mask into pin. MOVF freq,w ; Use copy so freq value is saved. MOVWF f_copy BTFSC status,z ; If freq is 0, clear pin to CLRF pin ; produce a silent delay. Sound_loop MOVF pin,w ; f_copy=f_copy+1: IF f_copy<=255 INCFSZ f_copy ; THEN w=pin ELSE w=0 CLRW ; (makes a silent delay if freq = 0) XORWF indirect ; indirect=indirect XOR w MOVF f_copy,w ; If f_copy has rolled over to 0, BTFSC status,z ; reload it with the value of freq. MOVF freq,w MOVWF f_copy INCF temp ; Increment LSB of duratn counter. BTFSC status,z ; Overflow? Yes: Increment duratn and INCFSZ duratn ; if it overflows, return. Else loop. GOTO Sound_loop RETLW 0h end end