Hetal said:well but its funny tht was a simple code and all this while i was trying al the hard stuff..
aneways i guess this way i learnt how to .. do a/d conversion and timer interrupts.. soo a quick question though .. when is the actual need for an interrupt can u give me a good example..
thnks a lot for the time and effort u took to help me for the code.... really appreciated..now i feel from a person who knew nothing about the assembly language seems to .. understand
Main
call Delay255
call Delay255
call Delay255
call Delay255
incf ones, f
movf ones, w ;test first digit
sublw 0x0A
btfss STATUS, Z
goto Main
clrf ones
incf tens, f
movf tens, w ;test second digit
sublw 0x0A
btfss STATUS, Z
goto Main
clrf tens
goto Main ;loop for ever
#include<P16f877.inc>
LIST p=16F877
errorlevel 1,-302 ;to disable MPLAB bank warnings.
;**** Declare registers
STATUS equ 03h
PIE1 equ 8Ch
PIR1 equ 0Ch
DATA1 equ 2fh
;***Port Initilisation
bsf STATUS,5 ;change to bank 1
movlw b'00001001' ; RA0 and RA3 are inputs
movwf TRISA
movwf 00h
movwf TRISB
bcf STATUS,5
;*** A/D converter initialization
movlw b'10000001' ;ADCS=10 CHS=AN0 ADON=ON
movwf ADCON0
bsf STATUS,RP0 ;move to bank 1
movlw b'00000101' ;ADFM=0 PCFG=0101
movwf ADCON1 ;set adcon1 register
bcf STATUS, RP0 ;return to bank 0
call ADC
;*** PWM initialization
clrf CCPR1L
clrf TMR2
bsf STATUS,5
movlw 3Fh ; value of pr2 calculated came upto be 63
movwf PR2
call GETDATA;get the output of adc conversion as input to pwm duty cycle
movf DATA1,0;get data1 into w
clrf INTCON ;disable interrupts
bcf STATUS,5
movlw H'99' ; 60 percent duty cycle as the output
movwf CCPR1L
bsf CCP1CON,CCP1Y ;
bcf CCP1CON,CCP1X
bsf STATUS,5
bcf TRISC,2
clrf PIE1
bcf STATUS,5
movlw b'0000100' ; the prescaler is 1:1 and setting the tm2on
movwf T2CON
;*** enable pwm mode
movf CCP1CON, W
andlw 0x30 ;mask all but prev. set duty cycle bits
iorlw 0x0f ;and enable PWM mode
movwf CCP1CON
return
GETDATA
bsf STATUS,5
movf ADRESL,0 ; get the lsb byte of the output of adc
bcf STATUS,5
movwf DATA1
btfsc DATA1,0;check bit d0 from ADC output
bsf CCP1CON,4 ; if D0=1 set D4 in CCP1CON(bit D0 in PWM input)
btfsc DATA1,1 ;check bit D1 from ADC output
bsf CCP1CON,5 ; if D1=1 set D5 in CCP1CON(bit D1 in PWM input)
rrf DATA1,1;rotate D0 into the carry bit
rrf DATA1,1;rotate D1 into the carry bit
bcf DATA1,6;clear bit D8 into the carry bit
bcf DATA1,7;clear bit D9 into the carry bit
btfsc ADRESH,0
bsf DATA1,6
btfsc ADRESH,1
bsf DATA1,7
return
ADC bsf ADCON0,GO ;start the A/D conversion
Wait btfsc ADCON0,GO ;wait until conversion is done
goto Wait
return ;no then keep checking
end
Hetal said:thnks for the informations ..i have that program working. however since i have written this code, i hope u could review this code. i am not using any interrupts here... and this prgramm will basically place the output of the a/d conversion in the pwm duty cycle and hence the output....
however when i simulated this programe i got one error, which i dont understand
CORE-E0002: Stack under flow error occurred from instruction at 0x000024
if you could pls help me out
Nigel Goodwin said:You're still not writing the program correctly, where does it loop round? - it doesn't, it just runs until it reaches a spurious 'return' and crashes.
Well where shoutld i include the loop? I Thought the program runs on its own and then loops bak to the initial position. could u help me as to where i should include the loop. and the reason i wrote .. return was when callign a subroutine i thot i must write a return to get bak to the prog.
It's also written very confusingly, with a strange mixture of using the include file names and not, so it's hard to try and understand.
You're also declaring register names that are already declared in the include file, a further cause of confusion and possible mistakes.
i have deleted the register names and only included the data1 register .
The code itself seems rather long winded and complicated?, I would also like to see an ORG to set the program start address
i guess the reason its long is cos of adding the analogue inputs into the
CCPR1L register.. here i dont have a fixed duty cycle .. so it reads the inuts and places it accordingly ... instead of writing the code
Code:movf ADRESH,W movwf CCPR1L
i wrote this
Code:GETDATA bsf STATUS,5 movf ADRESL,0 ; get the lsb byte of the output of adc bcf STATUS,5 movwf DATA1 btfsc DATA1,0;check bit d0 from ADC output bsf CCP1CON,4 ; if D0=1 set D4 in CCP1CON(bit D0 in PWM input) btfsc DATA1,1 ;check bit D1 from ADC output bsf CCP1CON,5 ; if D1=1 set D5 in CCP1CON(bit D1 in PWM input) rrf DATA1,1;rotate D0 into the carry bit rrf DATA1,1;rotate D1 into the carry bit bcf DATA1,6;clear bit D8 into the carry bit bcf DATA1,7;clear bit D9 into the carry bit btfsc ADRESH,0 bsf DATA1,6 btfsc ADRESH,1 bsf DATA1,7 return
so is it enuff if i had used the previous code ??/
this is my code with some modifications. however i would want to know where all i need to make further changes...should i include a loop at the end of pwm... ??
Code:#include<P16f877.inc> LIST p=16F877 errorlevel 1,-302 ;to disable MPLAB bank warnings. ;**************** Program Start *********************** org 0x00 ;Reset Vector goto init ;**** Declare registers DATA1 equ 2fh ;***Port Initilisation init bsf STATUS,5 ;change to bank 1 movlw b'00001001' ; RA0 and RA3 are inputs movwf TRISA movwf 00h movwf TRISB bcf STATUS,5 ;*** A/D converter initialization movlw b'10000001' ;ADCS=10 CHS=AN0 ADON=ON movwf ADCON0 bsf STATUS,RP0 ;move to bank 1 movlw b'00000101' ;ADFM=0 PCFG=0101 movwf ADCON1 ;set adcon1 register bcf STATUS, RP0 ;return to bank 0 call ADC ;*** PWM initialization clrf CCPR1L clrf TMR2 bsf STATUS,5 movlw 3Fh movwf PR2 call GETDATA; movf DATA1,0;get data1 into w clrf INTCON ;disable interrupts bcf STATUS,5 movlw H'99' movwf CCPR1L bsf CCP1CON,CCP1Y bcf CCP1CON,CCP1X bsf STATUS,5 bcf TRISC,2 clrf PIE1 bcf STATUS,5 movlw b'0000100' ; the prescaler is 1:1 and tm2on movwf T2CON ;*** enable pwm mode movf CCP1CON, W andlw 0x30 ;mask all but prev. set duty cycle bits iorlw 0x0f ;and enable PWM mode movwf CCP1CON GETDATA bsf STATUS,5 movf ADRESL,0 ; get the lsb byte of the output of adc bcf STATUS,5 movwf DATA1 btfsc DATA1,0;check bit d0 from ADC output bsf CCP1CON,4 ; if D0=1 set D4 in CCP1CON(bit D0 in PWM input) btfsc DATA1,1 ;check bit D1 from ADC output bsf CCP1CON,5 ; if D1=1 set D5 in CCP1CON(bit D1 in PWM input) rrf DATA1,1;rotate D0 into the carry bit rrf DATA1,1;rotate D1 into the carry bit bcf DATA1,6;clear bit D8 into the carry bit bcf DATA1,7;clear bit D9 into the carry bit btfsc ADRESH,0 bsf DATA1,6 btfsc ADRESH,1 bsf DATA1,7 return ADC bsf ADCON0,GO ;start the A/D conversion Wait btfsc ADCON0,GO ;wait until conversion is done goto Wait end
#include <P16f877.inc>
__CONFIG _RC_OSC & _CP_OFF & _WDT_OFF & _PWRTE_ON &_LVP_OFF
errorlevel 1,-302 ;to disable MPLAB bank warnings.
org 0
;set A/D Conversion
movlw b'10000001' ;ADCS=10 CHS=AN0 ADON=ON
movwf ADCON0
bsf STATUS,RP0 ;move to bank 1
movlw b'00000101' ;ADFM=0 PCFG=0101
movwf ADCON1 ;set adcon1 register
bcf STATUS, RP0 ;return to bank 0
;Set the PWM period (976Hz = 1.025ms) by writing to the PR2 register
movlw 3Fh ;255-dec = 0xff-hex
bsf STATUS,RP0 ;use bank 1
movwf PR2 ;setting the period of PWM
bcf STATUS,RP0 ;return to bank 0
;Set the PWM Duty Cycle by writing to the CCPR1L register and CCP1CON<5:4> bits.
movlw H'99' ;10000000-bin = 0x80-hex
movwf CCPR1L ;load 0x80 in W to CCPR1L
bcf CCP1CON,CCP1X; ;set bit 1 of the duty cycle
bcf CCP1CON,CCP1Y; ;set bit 0 of the duty cycle
;Make the CCP1 pin an output by clearing the TRISC<2> bit
bsf STATUS,RP0 ;move to bank 1
movlw 0xfb ;11111011-bin = 0xfb-hex
andwf TRISC ;clear TRISC<2>
bcf STATUS,RP0 ;return to bank 0
;Set the TMR2 prescale value and enable TMR2 by writing to T2CON.
movlw b'0000100' ;TMR2 on, prescale = 4
movwf T2CON ;load 0x05 into T2CON reg
;Start the A/D conversion by setting ADCON0<2>
start: nop
nop
nop
nop
nop
nop
nop
nop
nop
bsf ADCON0,GO ;start the A/D conversion
Wait: btfsc ADCON0,GO ;wait until conversion is done
goto Wait
;Write the 8 most significant bits located in ADRESH (since we setup the registers to be left justified) to Value
movf ADRESH,W
movwf CCPR1L ;write value into PWM
bcf CCP1CON,CCP1X
bcf CCP1CON,CCP2Y
;Configure the CCP1 module for PWM
movf CCP1CON, W
andlw 0x30 ;mask all but prev. set duty cycle bits
iorlw 0x0f ;and enable PWM mode
movwf CCP1CON
goto start
END
Initialise PIC
Initialise PWM
Initialise A2D
Loop
Read A2D
Modify PWM
Delay (may be required to give time for PWM change to settle)
Goto Loop
org 0
[COLOR="Sienna"];Initialise PIC [/COLOR]
bsf STATUS,5 ;change to bank 1
movlw b'00001001' ; RA0 and RA3 (Vref+) are inputs
movwf TRISA
movwf 00h
movwf TRISB
bcf STATUS,5
[COLOR="sienna"];Initialise PWM[/COLOR]
;Set the PWM period (976Hz = 1.025ms) by writing to the PR2 register
movlw 3Fh ;255-dec = 0xff-hex
bsf STATUS,RP0 ;use bank 1
movwf PR2 ;setting the period of PWM
bcf STATUS,RP0 ;return to bank 0
;Set the PWM Duty Cycle by writing to the CCPR1L register and CCP1CON<5:4> bits.
movlw H'99' ;10000000-bin = 0x80-hex
movwf CCPR1L ;load 0x80 in W to CCPR1L
bcf CCP1CON,CCP1X; ;set bit 1 of the duty cycle
bcf CCP1CON,CCP1Y; ;set bit 0 of the duty cycle
;Make the CCP1 pin an output by clearing the TRISC<2> bit
bsf STATUS,RP0 ;move to bank 1
movlw 0xfb ;11111011-bin = 0xfb-hex
andwf TRISC ;clear TRISC<2>
bcf STATUS,RP0 ;return to bank 0
;Set the TMR2 prescale value and enable TMR2 by writing to T2CON.
movlw b'0000100' ;TMR2 on, prescale = 4
movwf T2CON ;load 0x05 into T2CON reg
; Configure the CCP1 module for PWM
movf CCP1CON, W
andlw 0x30 ;mask all but prev. set duty cycle bits
iorlw 0x0f ;and enable PWM mode
movwf CCP1CON
[COLOR="sienna"];Initialise A/D Conversion[/COLOR]
movlw b'10000001' ;ADCS=10 CHS=AN0 ADON=ON
movwf ADCON0
bsf STATUS,RP0 ;move to bank 1
movlw b'00000101' ;ADFM=0 PCFG=0101
movwf ADCON1 ;set adcon1 register
bcf STATUS, RP0 ;return to bank 0
;Start the A/D conversion by setting ADCON0<2>
[COLOR="sienna"]Loop [/COLOR] : nop
nop
nop
nop
nop
nop
nop
nop
nop
bsf ADCON0,GO ;start the A/D conversion
Wait: btfsc ADCON0,GO ;wait until conversion is done
goto Wait
movf ADRESH,W
movwf CCPR1L ;write value into PWM
bcf CCP1CON,CCP1X
bcf CCP1CON,CCP2Y
[COLOR="sienna"]goto Loop[/COLOR]
END
Hetal said:welll ihave modified it accordingly .. so is it right now ????
Pommie said:Nigel,
You should have been a teacher. You get my vote for the most tolerant contributer.
Hetal said:do u have a code on how i can... do the maths...
pls help me programmin this part..
say if my analogue input is ..10 volts .. my output will always remain 6 volts
so basically my new duty cycle will be .. 6/10 ..
if input is .. 8 volts then 6/8
its a buck converter operation
sorry for the trouble
[i thought that by just puttng the value from a2d in the pwm register.. the duty cycle will vary accdgly.. ]
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?