How everyone I am working on a project for school a audio amplifier to be exact. I have to use the Pic16F887 in the build, the PGA2310 while i have already brought that part. Anyways the project most be coded in Assembly Language
[Name: PicLab9.asm
; By James Harris
__config _CONFIG1, 0x03F4 ; internal oscillator, WDT off
__config _CONFIG2, 0x3FFF
#include p16f887.inc ; included with MPLab
#include lowercase_887sfr.inc ; in the Files folder (see note)
;define variables
cblock 0x20
direction,
w_save,
status_save,
pclath_save,
m_index,
volume_data,
volume,
userflags,
volume_Right,
Right_Channel,
volume_Left,
Left_Channel
endc
;define constants
#define DRE_0 portd,3
#define DRE_1 portb,1
#define Left userflags,0
#define Right userflags,1
#define Unbalance userflags,2
#define CW_Rotate userflags,3
#define Gain_on_Left userflags,4
#define Gain_on_Right userflags,5
org 0x00
call Init
goto Main
org 0x04 ; interrupt vector
movwf w_save ; save registers
swapf status,W
movwf status_save
movf pclath,W
movwf pclath_save
clrf pclath
call Isr
movf pclath_save,W ; restore registers
movwf pclath
swapf status_save,W
movwf status
swapf w_save,F
swapf w_save,W
retfie
Volume_table
movf volume, W ; add index to pcl
andlw b'00011111' ; mask numbers larger then 31
addwf pcl, F
dt .0,.1,.63,.73,.83,.93,.103,.113,.123,.133,.143,.153,.163,.173,.183,.192,.193,.194,.195,.196,.197,.198,.199,.200,.201,.202,.203,.204,.205,.206,.207,.208
Init
bsf status,RP0 ;switch to Bank1
bsf pie1,SSPIE
clrf SSPSTAT
bsf sspstat,CKE
bsf trisb,1
bcf trisc,3
bcf trisc,5
bcf trisd,2
bsf trisd,3
bsf trisd,4
banksel anselh
bcf anselh,ANS10 ;enable digital input on RB1
banksel option_reg
bcf option_reg,NOT_RBPU ;enable pull-ups
banksel wpub
bsf wpub,WPUB1 ;enable RB1 pull-up
banksel iocb
bsf iocb,IOCB1 ;enable RB1 on-change interrupt
bcf status,RP0
movlw b'01110010' ;8MHz internal oscillator???
movwf osccon ;osccon is in bank1
bcf status,RP0 ;switch to Bank0
movlw b'00100010'
movwf sspcon
bcf portc,5
bcf portc,3
bsf portd,2
clrf volume
clrf direction
clrf sspbuf
clrf userflags
clrf volume_Right
clrf volume_Left
clrf Right_Channel
clrf Left_Channel
bsf intcon,RBIE ;enable interrupts
bsf intcon,PEIE
bsf intcon, GIE
return
Main
goto Main
Isr
btfss intcon,RBIF
return
call Dre_isr
return
Dre_isr
movf portb,W ;ends the mismatch on change
bcf intcon,RBIF ; clear portb interrupt flag
btfss DRE_0 ; detect direction
return ; negative edge only
movlw 1 ; CW
btfss DRE_1
movlw -1 ; CCW
movwf direction
btfss portd,4 ; Test if Balance Button Pressed
call Volume_isr
btfsc portd,4 ; Test if in Balance mode
call Unbalance_isr
clrf direction ; Clear direction data for next cycle
return
Volume_isr
movf direction,W ; place direction value in working register to add to volume total
addwf volume,F
call Volume_table ; fetch PGA2310 binary volume equivalent
movwf volume_data ; store the volume information
movf volume_data,W ; move volume information into the Working Register
call Transmit
movf volume_data,W ; Move volume_data into Left,Right Volume register used as reference
movwf volume_Left
movwf volume_Right
clrf Right_Channel ; Clear Channels for balance change reference point
clrf Left_Channel
return
Unbalance_isr
comf direction,W ; If the Z flag is set then the direction was CCW
btfss status,Z
call Right_CW
btfss CW_Rotate ; Set CW_Rotate when enter Right_CW to skip Left_CCW on return
call Left_CCW
bcf CW_Rotate
return
Right_CW
movf Left_Channel ; Move Left_Channel so no increment occurs on Right_Channel if Left had Gain added
btfsc status,Z
incf Right_Channel ; Increment Right_Channel if no gain was on Left_Channel
bcf status,Z
movf Left_Channel,W ; Test if Left Channel has Gain
btfss status,Z
bsf Gain_on_Left ; Set bit if Gain was added to Left_Channel
call Gain_NoGain_Right
bsf CW_Rotate
return
Left_CCW
movf Right_Channel ; Move Right_Channel so no increment occur on Left_Channel if Right had Gain added
btfsc status,Z
incf Left_Channel ; Increment Left_Channel if no gain was on Right_Channel
bcf status,Z
movf Right_Channel,W ; Test if Right Channel has Gain
btfss status,Z
bsf Gain_on_Right ; Set bit if Gain was added to Right_Channel
call Gain_NoGain_Left
return
Gain_NoGain_Right
movf volume_data,W ; Move volume_data into working for transmit if no gain is on the Left
btfss Gain_on_Left
goto CW_Left
movlw 2 ; If gain is on the Left substract 1db as the rotate was CW
subwf volume_Left
movf volume_Left,W
CW_Left
bcf portd,2 ; Transmits
movwf sspbuf
Wait_Right
btfss pir1,SSPIF ; Wait for transmit complete
goto Wait_Right
CW_Right
movf volume_data,W ; Move volume_data into working for transmit if no Gain was on Left
btfsc Gain_on_Left
goto CW
movlw 2 ; If no gain was substracted from Left_Channel add 1db to Right_Channel
addwf volume_Right
movf volume_Right,W
CW
bcf pir1,SSPIF ; Wait for transmit complete
movwf sspbuf
Wait2_Right
btfss pir1,SSPIF
goto Wait2_Right
bsf portd,2 ; Disable CS PGA2310
bcf intcon,RBIF ; Clear interrupts
bcf pir1,SSPIF
btfsc Gain_on_Left ; Test if gain was on Left to decrement count because 1db was substracted
decfsz Left_Channel
return
bcf Gain_on_Left ; If the Left_Channel is zero then no gain is on Left clear the Gain bit
return
Gain_NoGain_Left
movf volume_data,W ; Move volume_data into working for transmit if gain is on the Right
btfsc Gain_on_Right
goto CCW_Left
movlw 2 ; If no gain on Right_Channel then add 1db as rotate was CCW
addwf volume_Left
CCW_Left
movf volume_Left,W ; Transmit
bcf portd,2
movwf sspbuf
Wait3_Left
btfss pir1,SSPIF ; Wait for transmit complete
goto Wait3_Left
movf volume_data,W ; Move volume_data into working for transmit if gain is on the Right
btfss Gain_on_Right
goto CCW_Right
movlw 2 ; If gain is on the Right substract 1db as the rotate was CCW
subwf volume_Right
movf volume_Right,W
CCW_Right
bcf pir1,SSPIF ; Transmit
movwf sspbuf
Wait4_Left
btfss pir1,SSPIF ; Wait for transmit complete
goto Wait4_Left
bsf portd,2 ; Disable PGA2310
bcf intcon,RBIF ; Clear inerrupts
bcf pir1,SSPIF
btfsc Gain_on_Right
decfsz Right_Channel ; Test if gain was on Right to decrement count because 1db was substracted
return
bcf Gain_on_Right ; If the Left_Channel is zero then no gain is on Left clear the Gain bit
return
Transmit
bcf portd,2 ; enable PGA2310
movwf SSPBUF ; Transmit Volume data
Spi_wait
btfss pir1,SSPIF ; wait until data is sent
goto Spi_wait
bcf pir1,SSPIF ; clear interrupt flag
movwf SSPBUF
Spi_wait2
btfss pir1,SSPIF ; wait until data is sent
goto Spi_wait2
bsf portd,2 ; disable PGA2310
bcf intcon,RBIF ; clear interrupts
bcf pir1,SSPIF
return
end