![]() | ![]() | ![]() |
| |||||||
| Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc. |
![]() |
| | Tools |
| | #1 |
|
i have a problem with the 877A Below i've recycled a Pwm pgm which worked on a F88 , but needed some changes on the 877A specifically the 877 has no ANSEL register , it took me a few hours to essentially remove two lines and correct the bits put into ADCON1 i was able to load the program into the F877 and run it ,which may not sound like much , but for me it was alot. no joy on the either ccp/pwm pin ![]() is there anything in the factory config settings , that would prevent this from working? because i havnt changed them pwm is not my strong suit, which is why i checked both outputs ![]() if someone could check the pwm for me i would be very greatfull the Fosc is 5 Mhz but i can divide it down with counters if needed , i'm looking to get 20 - 25 khz varible pwm out thanks for reading ![]() Code: LIST P=16F877A
include "P16F877A.inc"
errorlevel -302 ;Eliminate bank warning
TEMP EQU 0x20
ADON EQU 0X00
ADIF EQU 0X06
GO_DONE EQU 0X02
TMR2ON EQU 0X02
TMR2IF EQU 0X01
RP0 EQU 0x05
RP1 EQU 0x06
W EQU H'0000'
F EQU H'0001'
;----- Register Files------------------------------------------------------
INDF EQU H'0000'
TMR0 EQU H'0001'
PCL EQU H'0002'
STATUS EQU H'0003'
FSR EQU H'0004'
PORTA EQU H'0005'
PORTB EQU H'0006'
PCLATH EQU H'000A'
INTCON EQU H'000B'
PIR1 EQU H'000C'
PIR2 EQU H'000D'
TMR1L EQU H'000E'
TMR1H EQU H'000F'
T1CON EQU H'0010'
TMR2 EQU H'0011'
T2CON EQU H'0012'
CCPR1L EQU H'0015'
CCPR1H EQU H'0016'
CCP1CON EQU H'0017'
RCSTA EQU H'0018'
TXREG EQU H'0019'
RCREG EQU H'001A'
ADRESH EQU H'001E'
ADCON0 EQU H'001F'
OPTION_REG EQU H'0081'
TRISA EQU H'0085'
TRISB EQU H'0086'
PIE1 EQU H'008C'
PCON EQU H'008E'
PR2 EQU H'0092'
TXSTA EQU H'0098'
SPBRG EQU H'0099'
EEDATA EQU H'010C'
CMCON EQU H'009C'
EECON2 EQU H'018D'
ADRESL EQU H'009E'
ADCON1 EQU H'009F'
org 0x00 ; Reset Vector
clrf PORTA ;B0
clrf PORTB ;B0
CLRF STATUS ;B0
;B0
Banksel TRISA ;B1
CLRF TRISA ;B1
CLRF TRISB ;B1
;B1
BCF STATUS ,RP0 ;B0
;B0
CLRF T2CON ;B0
MOVLW D'000' ;B0
MOVWF CCPR1L ;B0
BSF STATUS,RP0 ;B1
MOVLW d'255'-1 ;B1
MOVWF PR2 ;B1
BCF STATUS,RP0 ;B0
MOVLW b'00001100' ;B0
MOVWF CCP1CON ;B0
BSF T2CON,TMR2ON ;B0
;B0
BSF STATUS,RP0 ;B1
MOVLW b'00000001' ;B1
MOVWF TRISA ;B1
;B1
;B1
MOVLW b'10001111' ;B1 AN0 as input: AN2 as Vref-
MOVWF ADCON1 ;B1 : AN3 as Vref+
BCF STATUS,RP0 ;B0
MOVLW b'01000000' ;B0
MOVWF ADCON0 ;B0
BSF ADCON0,ADON ;B0 turn on A2D
CLRF PIR1 ;B0
;B0
LOOP CALL ADC ;B0
MOVWF CCPR1L ;B0
GOTO LOOP ;B0
;B0
ADC BTFSS PIR1,TMR2IF ;B0
GOTO ADC ;B0
BCF PIR1,TMR2IF ;B0
;B0
MOVF ADRESH,W ;B0
BSF ADCON0,GO_DONE ;B0
RETURN
END
| |
| |
| | #2 |
|
ok Programming these little beasties is not my strong suit , at all. something just isnt clicking , if ya'll could consider me a noob programmer that would be fine constructing and interfacing sensors i'm not too bad at designing digital and analog circuits also not to bad at i was once a little better at programming PICs but after a year of not trying to program them , alot escapes me ![]() i understand the interactions of the various components on earlier uProcessors , but the PICs have you jumping all over the place to get ANYTHING done. for example on the F877a , to set the analog input pin to RA0 , and Vref+ and Vref- pins required setting bits on both the ADCON1 and ADCON2 registers , not too bad ,but the pwm i dont think i understand at all !! and timers forget it. ![]() i dont expect anyone to try and explain it , but if it was presented from a different point of view in the data sheets that might help , i'm not sure i've used Mikekl8h's method for keeping track of the banks , that helps . again thanks for reading and any help with the program would be greatly appreciated | |
| |
| | #3 |
|
You might try checking my PWM 'tutorial', which demonstrates how to set the 16F876/7 for two channel PWM.
| |
| |
| | #4 |
|
ok lets analyze your program if you dont mind? why are you bank selecting PORTA , fourth instruction down. for those as little unsure , Banksel is an assembler directive for setting the current bank http://www.interq.or.jp/japan/se-inoue/e_pic4_8.htm this is a good source of info on assembler directives there may very well be an explaination in MPLab , but i couldnt find it. i understand banksel ADCON1 , and then using it , but i dont understand why you would select bank 0 ,Banksel PORTA ,and do nothing once you get there? Code:
Initialise:
BANKSEL ADCON1 ;turn off A2D
MOVLW 0x06
MOVWF ADCON1
BANKSEL PORTA
BANKSEL TRISC
MOVLW 0 ;set PORTC as all outputs
MOVWF TRISC
BANKSEL PORTC
MOVF CCP1CON,W ;set CCP1 as PWM
ANDLW 0xF0
IORLW 0x0C
MOVWF CCP1CON
MOVF CCP2CON,W ;set CCP2 as PWM
ANDLW 0xF0
IORLW 0x0C
MOVWF CCP2CON
MOVLW 126 ;set highest PWM value
BANKSEL PR2 ;over this (127) is permanently on
MOVWF PR2
BANKSEL TMR2
MOVF T2CON,W ;set prescaler to 16
ANDLW 0xF8 ;PWM at 2500HZ
IORLW 0x02
MOVWF T2CON
MOVF T2CON,W ;set postscaler to 1
ANDLW 0x07
IORLW 0x00
MOVWF T2CON
CLRF CCPR1L ;set PWM to zero
CLRF CCPR2L
BSF T2CON, TMR2ON ;and start the timer running
RETURN
| |
| |
| | #5 | ||
| Quote:
Quote:
Code: BANKSEL PORTA
BANKSEL TRISC
| |||
| |
| | #6 |
|
Fair enough ![]() I also see why you are ANDing & ORing the the CCP1CON & CCP2CON , because whatever is in there the lower four bits will allways end up as b'xxxx1100', when ANDed and ORed with those values after this it starts getting fuzzy i'll go back and study what you have written about the next section thanks! | |
| |
| | #7 | |
| Quote:
EDIT: now i see , i think. the pwm period = (pr2+1) (4)(Tosc)(Prescale value) Last edited by williB; 10th September 2006 at 03:50 AM. | ||
| |
| | #8 |
|
so with a PR2 value of 0x7F and a Fosc of 10Mhz & a prescale of one should give me a 19.53Khz pwm frequency . right? ok i'm getting some wierd numbers for the duty cycle or what to load into ccpr1L & the two bits of ccp1CON <5>& <4>..?? 10 bits is 1024 resolution , but when i calculated the resolution i got 8.97 bits , what does that mean? | |
| |
| | #9 | |
| Quote:
Check page 212 of the mid-range reference manual, at 20MHz you can get 10 bit resolution upto 19.53KHz. | ||
| |
| | #10 |
|
Thanks Nigel , i got it working horray for me!! | |
| |
| | #11 |
|
Well done!.
| |
| |
| | #12 |
|
It was actually Mike, K8LH who did the work , with helping me out , with the origional PWM code for the F88. all i did was realize the F877A didnt have an analog register that the F88 did ,the ANSEL register i believe is not on the F877A in fact the code segment below , which i changed myself , is not right , because with the MSB as a ONE , only gave me two bits of resolution ,four possible states or values, because it changed the justification ,which was interresting to see one scope BTW Code: MOVLW b'10001111' ;B1 AN0 as input: AN2 as Vref- MOVWF ADCON1 ;B1 : AN3 as Vref+ I guess what i want to say is Thank you Mike, K8LH !! | |
| |
| | #13 |
|
I thought i would share the joy of having a program run below ive included the assembly code and the hex code for pwm on a 16F877A . the PWM is varible by connecting a 10K varible resistor (pot) between ground and +5V and using the wiper output as the analog input to pin 2. Pin 17 is the PWM output Pin 2 is the analog input pin Pin 4 is the Vref- (can be connected to ground) Pin 5 is the Vref+ ( can be connected to 5V ) or lower if need be. one more thing i havnt changed the config bits yet so it runs on a 'stock' chip if you notice there are no config bit settings at the beginning of the assembly listing the electrotech online wouldnt let me list the whole .lst file , sorry . but if you copy and paste the source , and save it as a .asm file then run MPASM it will create one. the assembly code Code: LIST P=16F877A
include "P16F877A.inc"
errorlevel -302 ;Eliminate bank warning
TEMP EQU 0x20
ADON EQU 0X00
ADIF EQU 0X06
GO_DONE EQU 0X02
TMR2ON EQU 0X02
TMR2IF EQU 0X01
RP0 EQU 0x05
RP1 EQU 0x06
W EQU H'0000'
F EQU H'0001'
;----- Register Files------------------------------------------------------
INDF EQU H'0000'
TMR0 EQU H'0001'
PCL EQU H'0002'
STATUS EQU H'0003'
FSR EQU H'0004'
PORTA EQU H'0005'
PORTB EQU H'0006'
PCLATH EQU H'000A'
INTCON EQU H'000B'
PIR1 EQU H'000C'
PIR2 EQU H'000D'
TMR1L EQU H'000E'
TMR1H EQU H'000F'
T1CON EQU H'0010'
TMR2 EQU H'0011'
T2CON EQU H'0012'
CCPR1L EQU H'0015'
CCPR1H EQU H'0016'
CCP1CON EQU H'0017'
RCSTA EQU H'0018'
TXREG EQU H'0019'
RCREG EQU H'001A'
ADRESH EQU H'001E'
ADCON0 EQU H'001F'
OPTION_REG EQU H'0081'
TRISA EQU H'0085'
TRISB EQU H'0086'
PIE1 EQU H'008C'
PCON EQU H'008E'
PR2 EQU H'0092'
TXSTA EQU H'0098'
SPBRG EQU H'0099'
EEDATA EQU H'010C'
ANSEL EQU H'009B'
CMCON EQU H'009C'
EECON2 EQU H'018D'
ADRESL EQU H'009E'
ADCON1 EQU H'009F'
org 0x00 ; Reset Vector
clrf PORTA ;B0
clrf PORTC ;B0
CLRF STATUS ;B0
;B0
Banksel TRISA ;B1
CLRF TRISA ;B1
CLRF TRISC ;B1
;B1
BCF STATUS ,RP0 ;B0
;B0
CLRF T2CON ;B0
MOVLW D'000' ;B0
MOVWF CCPR1L ;B0
BSF STATUS,RP0 ;B1
MOVLW d'254' ;B1
MOVWF PR2 ;B1
BCF STATUS,RP0 ;B0
MOVLW b'00001100' ;B0
MOVWF CCP1CON ;B0
BSF T2CON,TMR2ON ;B0
;B0
BSF STATUS,RP0 ;B1
MOVLW b'00000001' ;B1
MOVWF TRISA ;B1
;B1
;B1
MOVLW b'00001111' ;B1 AN0 as input: AN2 as Vref-
MOVWF ADCON1 ;B1 : AN3 as Vref+
BCF STATUS,RP0 ;B0
MOVLW b'01000000' ;B0
MOVWF ADCON0 ;B0
BSF ADCON0,ADON ;B0 turn on A2D
CLRF PIR1 ;B0
;B0
LOOP CALL ADC ;B0
MOVWF CCPR1L ;B0
GOTO LOOP ;B0
;B0
ADC BTFSS PIR1,TMR2IF ;B0
GOTO ADC ;B0
BCF PIR1,TMR2IF ;B0
;B0
MOVF ADRESH,W ;B0
BSF ADCON0,GO_DONE ;B0
RETURN
END
Code: Code: :020000040000FA :10000000850187018301831603138501870183120C :100010009201003095008316FE30920083120C305E :10002000970012158316013085000F309F00831250 :1000300040309F001F148C011F2095001C288C1C31 :0A0040001F288C101E081F15080071 :00000001FF | |
| |
| | #14 | |
| Quote:
Watchdog Timer On So, I think your code is reseting every so often due to the WDT (and lack of CLRWDT). It obviously makes no difference at the moment as your code simply resets and continues doing the same thing. However, if you add more functionality, then this could cause a problem. Anyway, well done on getting it working. Have you a particular use for this code now it is working? Mike. | ||
| |
| | #15 |
|
Yes , i use pwm all the time to cut foam , when i'm makeng foam windmill blades. it makes a really nice way to adjust/ Control the current through a stainless wire when cutting foam. it starts cutting at about .5A , and i usually run it at .75A , also since i got it going at 20kHZ i may try to use it in a boost converter . | |
| |
|
| Tags |
| pwm |
| Thread Tools | |
| Display Modes | |
| |