Created
May 17, 2020 18:53
-
-
Save archmangler/e49788be745c332ef081e1e8bc86f021 to your computer and use it in GitHub Desktop.
PIC Assembly Buzzer Example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; Connect switch header to PORTB (RB) | |
; Uses RETLW instruction to return a value from subroutine which | |
; sets buzzer frequency. Which value is returned depends on number in index. | |
; Buzzer starts when switch 0 is pressed and | |
; stops when switch 0 is released. | |
Title "buzzer using RETLW" | |
#include "p16F1789.inc" | |
; CONFIG1 | |
; __config 0x3FE2 | |
__CONFIG _CONFIG1, _FOSC_HS & _WDTE_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_ON & _FCMEN_ON | |
; CONFIG2 | |
; __config 0x3EFF | |
__CONFIG _CONFIG2, _WRT_OFF & _VCAPEN_OFF & _PLLEN_OFF & _STVREN_ON & _BORV_LO & _LPBOR_OFF & _LVP_OFF | |
;RAM DEFINITIONS | |
CBLOCK 0x20 ; create first variable | |
tone | |
index | |
TableLength | |
ENDC | |
ORG 0x0000 ; assembler directive to place code at this address | |
GOTO setup ; jump to main code (over interrupt vector) | |
ORG 0x04 ; place code at address 0x004 Interrupt Vector address | |
Interrupt retfie | |
setup | |
; setup switches on PORTB | |
banksel ANSELB ; bank 3 | |
clrf ANSELB ; Turn off analog inputs. | |
banksel WPUB ; bank 4 | |
movlw 0xFF | |
movwf WPUB ;Turn on weak pullups. | |
banksel TRISD | |
movlw 0xFF ; port B as input for switches | |
movwf TRISD | |
banksel PORTB ; change to bank 0 for switch read | |
clrf PORTB | |
clrf index ; Clear table pointer | |
movlw 0x07 ; number of enties - 1 | |
movwf TableLength ; number of retlw instructions in frequency subroutine-1 | |
loop | |
;read switches | |
switch | |
; loop until switch 0 pressed | |
btfsc PORTB,0 ; skip goto if PORTB.0 is 0 (pressed) | |
goto switch | |
; get value needed for frequency | |
movf index, W | |
call frequency ; Call table to get tone needed | |
movwf tone ; frequency subroutine returns value in | |
; W depending on value of index | |
call pwm_start ; start pwm with pwm value in tone register | |
; check that index is not bigger than table length | |
incf index, F ; Increase table pointer | |
movf TableLength,w ; copy tablelength to W | |
subwf index, W ; subtract index from W | |
btfsc STATUS, Z ; if they are equal, Z flag is set | |
clrf index ; reset table index to 0 if index = tableIndex | |
switchlow | |
; loop until switch released | |
movf PORTB, w ; copy switches to W | |
sublw 0xFF ; if no switch pressed, PORTB = 0xFF, FF-FF=0 | |
btfss STATUS,Z ; Z flag set if PORTB was 0xFF ie no switch | |
goto switchlow ; loop until switch released | |
call pwm_stop ; stop buzzer | |
goto loop ; repeat | |
pwm_start | |
banksel TRISC | |
movlw 0xFF ; disable output pin | |
movwf TRISC | |
banksel PR2 | |
;Set PWM period - see formula in datasheet | |
movf tone, w | |
movwf PR2 ; bank 0 | |
bcf STATUS, C | |
rrf tone, w ; tone/2 | |
;set duty cycle to - 10 bit value - changes with PWM frequency | |
;This approximates 50% | |
banksel CCPR1L | |
movwf CCPR1L ; = tone/2 ;bank 5 | |
bcf CCP1CON,DC1B0 ; bank 5 | |
bcf CCP1CON,DC1B1 ; | |
banksel TRISC | |
movlw b'11111011' ; enable output pin | |
movwf TRISC | |
banksel PORTD | |
;Set pre-scale to 64 | |
bsf T2CON,T2CKPS0 ; // bank0 set pre-scale bits | |
bsf T2CON,T2CKPS1 ; //set pre-scale bits | |
banksel CCP1CON | |
;SET CCP1 to PWM - (note, CCP1M1/CCP1M0 are don't care for PWM) | |
bsf CCP1CON,CCP1M3 ;bank5 | |
bsf CCP1CON,CCP1M2 ; | |
bcf CCP1CON,CCP1M1 ; | |
bcf CCP1CON,CCP1M0 ; | |
banksel PORTD | |
;start timer | |
bsf T2CON,TMR2ON ; //bank 0 | |
return ; with bank0 | |
;pwm stop | |
pwm_stop | |
;stop timer | |
bcf T2CON,TMR2ON ; | |
banksel TRISC | |
movlw 0xFF | |
movwf TRISC; //disable output pin | |
banksel CCP1CON | |
;RESET CCP1 | |
movlw 0xF0 ; to clear bit 3:0, CCP1M [ 3:0] | |
andwf CCP1CON | |
;CCP1CON,CCP1M3 = 0; | |
;CCP1CON,CCP1M2 = 0; | |
;CCP1CON,CCP1M1 = 0; | |
;CCP1CON,CCP1M0 = 0; | |
banksel PORTD | |
return | |
; frequency table | |
; execution jumps by index and returns value in W using RETLW | |
; value returned depends on value of index | |
frequency ; index in W register | |
addwf PCL, F ; add W reg to Program Counter (PCL) | |
retlw d'255' | |
retlw d'127' | |
retlw d'63' | |
retlw d'42' | |
retlw d'31' | |
retlw d'15' | |
retlw d'9' ; value returned depends on index | |
retlw d'7' | |
; change these values to change tones | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment