|
|
View previous topic :: View next topic |
Author |
Message |
dezso
Joined: 04 Mar 2010 Posts: 102
|
PWM OMG |
Posted: Sat Mar 24, 2012 1:52 am |
|
|
PIC16F877A
4.128 no IDE
20Mhz Clock
Turned to CCS again since my ASM code went sideways, after days of coding and close to 1000 line realized my approach is somewhat incorrect, just to blow some steam fired up CCS to play with it.
Now I been playing with C and C# for a few years but isn't my strongest tool, so don't byte my head off.
Below a simple code to Blink a LED on PortD and run PWM on CCP1 at 78.125Khz 25% duty.
Its not working ! LED blink about 2,3x than stops, PWM continue to run, went back to MC asm and create sample project with same values, I'm not including here the full asm just my timer and CCP setup, technically the rest of the asm is plain port setup and delay routine.
Why is this C code will stop executing the while(true) part after 1-2sec later !?
Maybe I'm just to stressed out and can't see the tree from the forest.
Code: | #include <main.h>
#define LED PIN_D0
void main()
{
setup_ccp1(CCP_PWM);
set_pwm1_duty((int16)63);
setup_timer_2(T2_DIV_BY_1,63,1); //12.8 us overflow, 12.8 us interrupt
while(true)
{
output_toggle(LED);
delay_ms(250);
}
}
//INIT_PWM
// BANKSEL PR2
// MOVLW 0X3F // PWM period 78.125khz
// MOVWF PR2
// MOVLW B'00000100' // Setup Timer2
// //0 // Unimplemented
// //-0000 // 1:1 postscale
// //-----1 // TMR2ON
// //------00 // Prescaler is 1
// MOVWF T2CON
// BANKSEL CCPR1L
// MOVLW B'00000111' // Load 25% Duty 255/100*25=63.xx
// MOVWF CCPR1L // MSB loaded to CCPR1L
// BANKSEL CCP1CON // LSB loaded to CCP1CON 5:4 bit
// MOVLW B'00111100'
// //00 // Unimplemented
// //--11 // LSB of Duty
// //----11xx // PWM mode
// MOVWF CCP1CON
// BSF T2CON, TMR2ON // Timer2 ON
// RETURN | _________________ I'm could be wrong many time's, at least I know what I'm doing |
|
|
gpsmikey
Joined: 16 Nov 2010 Posts: 588 Location: Kirkland, WA
|
|
Posted: Sat Mar 24, 2012 9:27 am |
|
|
The first thing that comes to mind when you say it works a few times then quits is are there any interrupts running etc (you indicate this is only part of the code) ? When I have run into something like this in the past it was due to "clever" use of the stack where I was pushing something on it then forgetting to get it back and managing to crash the stack. Maybe after I have my coffee something will become more obvious to me, but that was the first thing that came to mind. (This does have the feel of one of those "duh" moments when you solve it though -- I have them on a regular basis myself ) _________________ mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3 |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Mar 24, 2012 4:45 pm |
|
|
Quote: | Why is this C code will stop executing the while(true) part after 1-2sec later !? |
Always post the complete test program. Post the code in main.h.
You could have the LVP fuse set. Then that pin might float to a high level
and the PIC would go into LVP programming mode and lock up.
Or maybe you're missing the MCLR pull-up resistor, so that pin floats low
and locks up the PIC.
Or maybe you left off the series resistor on the LED and then the PIC's
pin driver circuit (or the whole PIC) has a problem.
I don't know. You didn't give enough information. |
|
|
dezso
Joined: 04 Mar 2010 Posts: 102
|
|
Posted: Sat Mar 24, 2012 5:31 pm |
|
|
this is beyond me...
This is the generated asm from the c code, it will compile and has the same result, led will stop flashing after 2,3 flash later.
It does not use any call so the stock stays at 0 level.
In the debugger if found that the line XORWF 0x8, F will not toggle the portd pin0, the W have value of 1 and bank switched back to 0, but it will toggle other registers if I change it to
Quote: | Or maybe you're missing the MCLR pull-up resistor, so that pin floats low
and locks up the PIC. |
MCLR is pulled up with 6.8k "thats what I pulled out from the box first !, It works with the ASM code just fine.
Code: | ;--- C:\Documents and Settings\DevXP\My Documents\MPLAB8Project\10WattLEDC\main.c ---------------
;1: #include <main.h>
org 0x00
MOVLW 0
MOVWF 0xa
GOTO 0x1a
NOP
;2: #define LED PIN_D0
;3:
;4: void main()
;5: {
org 0x1a
CLRF 0x4
BCF 0x3, 0x7
MOVLW 0x1f
ANDWF 0x3, F
MOVLW 0x40
BSF 0x3, 0x5
MOVWF 0x19
MOVLW 0xa6
MOVWF 0x18
MOVLW 0x90
BCF 0x3, 0x5
MOVWF 0x18
MOVLW 0xff
MOVWF 0x20
BSF 0x3, 0x5
BSF 0x1f, 0
BSF 0x1f, 0x1
BSF 0x1f, 0x2
BCF 0x1f, 0x3
MOVLW 0x7
MOVWF 0x1c
;6: setup_ccp1(CCP_PWM);
BCF 0x3, 0x5
BCF 0x20, 0x2
MOVF 0x20, W
BSF 0x3, 0x5
MOVWF 0x7
BCF 0x3, 0x5
BCF 0x7, 0x2
MOVLW 0xc
MOVWF 0x17
;7: set_pwm1_duty((int16)63);
MOVLW 0xf
MOVWF 0x15
MOVF 0x17, W
ANDLW 0xcf
IORLW 0x30
MOVWF 0x17
;8: setup_timer_2(T2_DIV_BY_1,63,1); //12.8 us overflow, 12.8 us interrupt
MOVLW 0
MOVWF 0x78
IORLW 0x4
MOVWF 0x12
MOVLW 0x3f
BSF 0x3, 0x5
MOVWF 0x12
;9: while(true)
;10: {
;11: output_toggle(LED);
BCF 0x8, 0
MOVLW 0x1
BCF 0x3, 0x5 ;0x3
XORWF 0x8, F
;12: delay_ms(250);
MOVLW 0xfa
MOVWF 0x21
GOTO 0x4
;13: }
BSF 0x3, 0x5
GOTO 0x45
SLEEP
;--- C:\Documents and Settings\DevXP\My Documents\MPLAB8Project;;\10WattLEDC\main.h ---------------
;1: #include <16F877A.h>
;2: #device adc=8
;3: #FUSES NOWDT //No Watch Dog Timer
;4: #FUSES HS //High speed Osc (> 4mhz ;for PCM/PCH) (>10mhz for PCD)
;5: #FUSES NOPUT //No Power Up Timer
;6: #FUSES NOBROWNOUT //No brownout reset
;7: #FUSES NOLVP //No low voltage prgming, ;B3(PIC16) or B5(PIC18) used for I/O
;8:
;9: #use delay(clock=20000000)
org 0x04
MOVLW 0x21
MOVWF 0x4
BCF 0x3, 0x7
MOVF 0, W
BTFSC 0x3, 0x2
GOTO 0x17
MOVLW 0x6
MOVWF 0x78
CLRF 0x77
DECFSZ 0x77, F
GOTO 0xd
DECFSZ 0x78, F
GOTO 0xc
MOVLW 0x7b
MOVWF 0x77
DECFSZ 0x77, F
GOTO 0x13
DECFSZ 0, F
GOTO 0xa
BCF 0xa, 0x3
BCF 0xa, 0x4
GOTO 0x4c
end
|
_________________ I'm could be wrong many time's, at least I know what I'm doing |
|
|
dezso
Joined: 04 Mar 2010 Posts: 102
|
|
Posted: Sat Mar 24, 2012 8:35 pm |
|
|
ok found the problem and now it is working, wasn't a compile or code problem, it was working as it should be.
The problem was that I connected the led to the PORTD pin0 wo any resistor, the code simply was trying to XOR the state of the pin, doing this by reading the pin and could not read as high since was loaded by the LED.
Adding a 470ohm fixed the problem, on port B or C it wouldn't be a problem, that was a interesting experiment tho.. _________________ I'm could be wrong many time's, at least I know what I'm doing |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Mar 24, 2012 9:14 pm |
|
|
You should always use a series resistor with an LED. It's standard
engineering design practice. It limits the current to be within the
specified range, so as not to exceed the limits for the LED or the
pin driver on the PIC. |
|
|
dezso
Joined: 04 Mar 2010 Posts: 102
|
|
Posted: Sun Mar 25, 2012 12:13 am |
|
|
There was no design in place, this has nothing to do with the project I'm working on, LED was added for debugging purpose only and wasn't thinking on the portD architecture. When I noticed that the port not toggling than I start a new project to investigate why.
Thanks anyway.
_________________ I'm could be wrong many time's, at least I know what I'm doing |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|