| Home | Products | Prices | Directory | Order | Contact | New | Books | Files | Links | FAQ |
| Bottom of Page |
The Sound routine generates squarewave tones with frequencies of 280 Hz to 71 kHz and durations of 3.6 ms to 0.92 seconds at 4 MHz. It differs from its PBASIC counterpart in that all frequency values from 1 to 255 produce squarewave tones. PBASIC's Sound instruction generates tones when the frequency is in the range of 1 to 127, and hissing white-noise effects from 128 to 255. Both PBASIC and assembly versions of Sound produce a silent pause with a frequency value of 0.
To use the routine, store a frequency value from 0 to 255 in freq, and a duration from 0 to 255 in duratn. Put the output pin number (0 to 7) into pin and the port number (0 to 2 for RA through RC) into the w register, and call Sound.
The following formula determines the frequency output by Sound (assuming a PIC clock speed of 4 MHz):

The formula shows that freq sets the period of the tone in 14-µs units. As a result, the frequency isn't a linear function of freq. For example, a freq of 1 produces a 280.1-Hz tone, while 2 produces 281.2 Hz. At the higher end of the scale, a freq of 250 produces an 11.9-kHz tone, while 251 produces 14.29 kHz.
PBASIC's Sound command has the same characteristic, but starts slightly below 100 Hz. It has a period resolution of approximately 83µs. If you want to more closely emulate PBASIC, just pad the :loop of this Sound routine to take a total of 83µs.
The PBASIC command permits you to specify a list of frequencies and durations to be played. The demonstration program shows how to do this in assembly by using a pair of lookup tables. If you need white-noise effects in your program, use the Random routine. Call Random from within a tight program loop, and copy one bit of its shift register to the speaker output. The random bit stream will produce a hissing sound.
One hint on using Sound: always assign the port number to w immediately before calling the routine. If you don't, some other instruction that uses w may change its contents, causing an error.

; ; *************************************************************************** ; *** 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 endSee also:
; 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. org 8 pin ds 1 ; Pin number to use as output (0-7). freq ds 1 ; Frequency of note. duratn ds 1 ; Duration of note. f_copy ds 1 ; Copy of freq variable. temp ds 1 ; Variable to stretch duratn to 16 bits. index ds 1 ; Index to tables of notes, lengths. ; Device data and reset vector device pic16c55,xt_osc,wdt_off,protect_off reset start org 0 ; Table to convert pin number (0-7) into bit mask (00000001b to 10000000b). Pinz jmp pc+w retw 1,2,4,8,16,32,64,128 ; Table of notes for the demonstration tune "Charge." Notes jmp pc+w retw 166,189,204,212,204,212 ; Table of note durations for the demonstration tune "Charge." Lengths jmp pc+w retw 52,52,52,82,45,190 start mov !ra, #0 ; Output for speaker. clr temp ; Clear LSB of duratn counter. clr index ; Clear the note counter. :loop mov w,index ; Look up note in table. call Notes mov freq,w ; Store note in freq. mov w,index ; Look up length in table. call Lengths mov duratn,w ; Store in duratn. mov pin,#3 ; Select pin 3 of port mov w,#0 ; RA for speaker output call Sound ; Play the sound. inc index ; Advance to next sound in tables. cjbe index,#5,:loop ; IF index <= 5, play note jmp $ ; 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 NEG duratn ; Convert to two's complement. mov fsr,w ; Point to the port number. add fsr,#RA ; Add offset for port RA. mov w,pin ; Now look up pin number in call Pinz ; table and get bit mask. mov pin,w ; Put the mask into pin. mov f_copy,freq ; Use copy so freq value is saved. snz ; If freq is 0, clear pin to clr pin ; produce a silent delay. :loop mov w,pin ; f_copy=f_copy+1: IF f_copy<=255 incsz f_copy ; THEN w=pin ELSE w=0 clr w ; (makes a silent delay if freq = 0) XOR indirect,w ; indirect=indirect XOR w mov w,f_copy ; If f_copy has rolled over to 0, snz ; reload it with the value of freq. mov w,freq mov f_copy,w inc temp ; Increment LSB of duratn counter. snz ; Overflow? Yes: Increment duratn and incsz duratn ; if it overflows, return. Else loop. jmp :loop ret
| Home | Products | Prices | Directory | Order | Contact | New | Books | Files | Links | FAQ |
Send us a message
Copyright © 1996-2001 DonTronics
| Top of Page |