⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 audio.asm

📁 CCP1模块使用的有关PIC应用程序Trabicom On Board Engine Controller
💻 ASM
字号:
; audio.asm

; Program to demonstrate the use of PWM using the CCP modules on the PIC 
; by driving the audio output on the Raven board.
;
; PWM output is a square wave with the following characteristics
;
;                Period
;          |<----------------->|
;
;          |-------|           |-------|
;          |       |           |       |
;   -------|       |-----------|       |-------
;          
;          :<----->:           :
;          : Duty  :           :
;          : Cycle :       TMR2 = PR2
;          :       :         
;      TMR2=PR2   TMR2 = Duty Cycle
;
; You begin with PR2 set to some value.  Timer2 is started and when the 
; Timer2 count register is equal to PR2, the PWM output goes high. It 
; then resets Timer2 and counts until the Timer2 count equals the duty 
; cycle counter (CCPRxL:CCP1CON) and then the signal goes low again.  
; Then the process starts again.  So the period consists of a high part
; and a low part, defined by the period and the duty cycle.  Note that 
; the duty cycle need not be one-half of the period.  Normally the duty 
; cycle is reported as a percentage, such as 65%, meaning that 65% of the 
; period the signal is high.
;
; In this instance, we want to generate signals that can be used to drive 
; a speaker, so we will have a duty cycle of 50% and we will want to vary 
; the frequency (by varying the period) to get different tones.

        LIST P=16F877, R=DEC

        INCLUDE "P16F877.inc"

; Definitions

;  __CONFIG _CP_OFF & _DEBUG_OFF & _WRT_ENABLE_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _PWRTE_ON & _WDT_OFF & _HS_OSC20

; Define start of vars

RAM        EQU   0x20

; Variables

Temp       EQU   RAM+0
DTemp1     EQU   RAM+1
DTemp2     EQU   RAM+2
Counter    EQU   RAM+3

; Start of the Program

        ORG       3
        goto      Start

        ORG       4
Timer1ISR
; Since PWM won't give us the low end frequencies we want, we will generate our own.
; Timer1 will be set up to interrupt every 1/4000 seconds to give us the desired
; resolution.  Then, we will set our own version of T2CON to determine the period.
; In this case, the duty cycle is always 50%, so its not a problem.
;

; 
        ORG       0x20

; The frequencies are numbered 0 through 15 and represent an uniformly spaced
; group from 1225 Hz to 9470 Hz in steps of about 550Hz.

GetFreq 
        addwf     PCL,F
        retlw     33
        retlw     48
        retlw     63
        retlw     77
        retlw     92
        retlw     107
        retlw     122
        retlw     137
        retlw     151
        retlw     166
        retlw     181
        retlw     196
        retlw     211
        retlw     225
        retlw     240
        retlw     255

SongNote
        addwf     PCL,F
        retlw     0x0F
        retlw     0x0E
        retlw     0x1B
        retlw     0x0C
        retlw     0x0B
        retlw     0x09
        retlw     0x0A
        retlw     0x0B
        retlw     0x0C
        retlw     0x0D
        retlw     0x1A
        retlw     0x1C

Start

        bsf       STATUS, RP0
        bcf       TRISC,2                    ; PWM output port
        bcf       STATUS, RP0

        call      PWMConfig

; Go through a cycle of creating some special sounds.  We aren't far from music
; here.  Everybody sing along!!

        movlw     11
        movwf     Counter
main_loop
        movf      Counter,W
        call      SongNote
        call      PlayNote
        decfsz    Counter,F
        goto      main_loop
        movlw     11
        movwf     Counter
        goto      main_loop

; Sound support

PlayNote
        movwf     Temp
        andlw     0x0F
        call      GetFreq
        call      PWMSetPeriod
        movlw     250
        btfss     Temp,7
        movlw     100
        call      Delay_ms
        return

            
; -------------------------------------------------------------------
; PWM routines

; We want to have frequencies in the range of 100 Hz to about 10,000 Hz, so
; we need periods of 0.01 to 0.0001.  Given the formula:
;    PWM period = [PR2 + 1] * 4 / Fosc * Timer2 Prescale Value
; 
; and an oscillator frequency of 20Mhz (Fosc),
; For a 20 MHz clock, the frequency table is:
;
;  Prescaler         Pr2=1      Pr2=255
;     1              5 MHz       1.9608 kHz
;     4              1.25 MHz    4.902  kHz
;    16              0.3125 MHz  1.225  kHz
;
; So we will have to use two different prescalers.  One for use a prescaler of 4 for Timer2 and let Pr2 vary from 208 down 
; to about 0.

PWMConfig
; Initialize CCP1

        movlw       255
        call        PWMSetPeriod

        movlw       b'00100000'         ; duty cycle is 50% = 128
        movwf       CCPR1L

        movlw       b'00000110'         ; Timer 2 is on and prescaler is 16
        movwf       T2CON

        movlw       b'00001100'         ; PWM mode with two LSB's = 00
        movwf       CCP1CON

        return
        

PWMSetPeriod
        bsf         STATUS,RP0      
        movwf       PR2          ; set period

        bcf         STATUS,C
        rrl         PR2,W        ; and duty cycle = period/2
        movwf       CCPR1L
        bcf         STATUS,RP0
        return

; -----------------------------------------------
; Output a value to the LED bar

DispLedBar

; Enable the led bar and put the value in W there.

        movwf     Temp             ; save W
        movlw     0x12
        movwf     PORTA

        comf      Temp,W
        movwf     PORTD

        return

; -------------------------
; Delay milliseconds

Delay_ms
        bsf     STATUS,RP0
        bsf     STATUS,RP1

        movwf  	DTemp1
dloop_0	                ; number of ms to delay
        movlw  	250
        movwf  	DTemp2
dloop_1	                ; 1 ms delay (approximately)
        fill (nop), 17
        decfsz 	DTemp2,F
        goto    dloop_1
        decfsz 	DTemp1,F
        goto   	dloop_0

        bcf     STATUS,RP1
        bcf     STATUS,RP0
        return

        END



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -