|
|
View previous topic :: View next topic |
Author |
Message |
djpark
Joined: 02 Mar 2004 Posts: 49
|
Seeking HELP for PIC12F683 PWM output |
Posted: Mon Mar 21, 2005 10:25 pm |
|
|
I thought this is going to be a simple practice, but turned out to be a mistery to me. Can someone point out what is wrong and advice to correct to get the PWM output using PIC12F683? I am using PIN_A2 (CCP1) as led output.
TIA,
-- dj
Code: |
#include <12F683.h>
#fuses NOWDT, INTRC_IO, NOCPD, NOPROTECT, NOMCLR, NOPUT, BROWNOUT
#use delay (clock=8000000)
void main()
{
int8 duty;
setup_oscillator(OSC_8MHZ);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_comparator(NC_NC);
setup_vref(FALSE);
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DIV_BY_1, 0x3f, 1);
setup_ccp1(CCP_PWM);
set_tris_a(0b11111011);
while (1)
{
for (duty=1; duty<255; duty++)
{
set_pwm1_duty(duty);
delay_ms(100);
}
for (duty=255; duty>0; duty--)
{
set_pwm1_duty(duty);
delay_ms(1000);
}
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Mar 22, 2005 12:24 am |
|
|
One problem I can see immediately is that you're trying to set
the PWM duty cycle to be longer than the period.
The 12F683, in section 11.3.2, says:
"Note: If the PWM duty cycle value is longer than
the PWM period, the CCP1 pin will not be cleared".
This means the output stays at a high level.
You've set the PWM period to 0x3F here:
setup_timer_2(T2_DIV_BY_1, 0x3f, 1);
But then here, you're setting the PWM duty cycle
to a value greater than 0x3F.
for (duty=1; duty<255; duty++)
{
set_pwm1_duty(duty);
See this post for more info:
http://www.ccsinfo.com/forum/viewtopic.php?t=17729 |
|
|
djpark
Joined: 02 Mar 2004 Posts: 49
|
|
Posted: Tue Apr 05, 2005 3:25 am |
|
|
Thanks for the info. But I think I am missing something very basic.
When I tried the following code, it doesn't turn on the led connected to PIN_A2 at all.
Is there anything else I need to setup to use the PWM?
-- dj
Code: |
#include <12F683.h>
#fuses NOWDT, INTRC_IO, NOCPD, NOPROTECT, NOMCLR, NOPUT, NOBROWNOUT, NOIESO, NOFCMEN
#use delay (clock=8000000)
void main()
{
setup_oscillator(OSC_8MHZ);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_comparator(NC_NC);
setup_vref(FALSE);
set_tris_a(0b11111011);
setup_timer_2(T2_DIV_BY_16, 124, 1);
setup_ccp1(CCP_PWM);
set_pwm1_duty(100);
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Apr 05, 2005 8:36 am |
|
|
In the link that I posted, there is sample code at the end of the thread.
Look at the last line in that sample program.
Look at the comment on that last line. |
|
|
djpark
Joined: 02 Mar 2004 Posts: 49
|
|
Posted: Tue Apr 05, 2005 9:05 am |
|
|
Sorry, it was my mistake to omit from the source posted. But it is actually there in my test program as below.
Even then, there is no light coming out of the led from PIN_A2.
I am wodnering if there is something else I need such as enabling timer interrupt or anything else.
-- dj |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Apr 05, 2005 11:09 am |
|
|
Post your version of the compiler.
I'll compile the program with that version and look at the ASM code. |
|
|
djpark
Joined: 02 Mar 2004 Posts: 49
|
|
Posted: Wed Apr 06, 2005 10:46 am |
|
|
Thanks for help.
I use PCM 3.187 and it generated the following LST.
Code: |
#include <12F683.h>
#fuses NOWDT, INTRC_IO, NOCPD, NOPROTECT, NOMCLR, NOPUT, NOBROWNOUT, NOIESO, NOFCMEN
#use delay (clock=8000000)
void main()
{
setup_oscillator(OSC_8MHZ);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_comparator(NC_NC);
setup_vref(FALSE);
set_tris_a(0b11111011);
setup_timer_2(T2_DIV_BY_1, 124, 1);
setup_ccp1(CCP_PWM);
set_pwm1_duty(100);
while (1)
;
}
CCS PCM C Compiler, Version 3.187, 22755
Filename: 683-pwm.LST
ROM used: 74 (4%)
Largest free fragment is 1974
RAM used: 5 (4%) at main() level
5 (4%) worst case
Stack: 0 locations
*
0000: MOVLW 00
0001: MOVWF 0A
0002: GOTO 004
0003: NOP
0004: MOVLW 07
0005: MOVWF 0A
0006: CALL 7FF
0007: BSF 03.5
0008: MOVWF 10
0009: MOVLW 00
000A: MOVWF 0A
000B: GOTO 00C
.................... #include <12F683.h>
.................... //////// Standard Header file for the PIC12F683 device ////////////////
.................... #device PIC12F683
.................... #list
....................
.................... #fuses NOWDT, INTRC_IO, NOCPD, NOPROTECT, NOMCLR, NOPUT, NOBROWNOUT, NOIESO, NOFCMEN
.................... #use delay (clock=8000000)
....................
.................... void main()
.................... {
000C: CLRF 04
000D: MOVLW 1F
000E: ANDWF 03,F
000F: BSF 03.5
0010: MOVF 1F,W
0011: ANDLW F0
0012: MOVWF 1F
0013: BCF 03.5
0014: BCF 1F.6
0015: MOVLW 07
0016: MOVWF 1F
0017: MOVLW 70
0018: BSF 03.5
0019: MOVWF 0F
.................... setup_oscillator(OSC_8MHZ);
001A: MOVLW 70
001B: MOVWF 0F
....................
.................... setup_adc_ports(NO_ANALOGS);
001C: MOVF 1F,W
001D: ANDLW F0
001E: MOVWF 1F
001F: BCF 03.5
0020: BCF 1F.6
.................... setup_adc(ADC_OFF);
0021: BSF 03.5
0022: MOVF 1F,W
0023: ANDLW 0F
0024: MOVWF 1F
0025: BCF 03.5
0026: MOVF 1F,W
0027: ANDLW 0C
0028: MOVWF 1F
.................... setup_comparator(NC_NC);
0029: MOVLW 07
002A: MOVWF 19
002B: BSF 03.5
002C: MOVF 05,W
002D: MOVLW 06
002E: BCF 03.5
002F: MOVWF 20
0030: DECFSZ 20,F
0031: GOTO 030
0032: NOP
0033: MOVF 19,W
0034: BCF 0C.3
.................... setup_vref(FALSE);
0035: BSF 03.5
0036: CLRF 19
....................
.................... set_tris_a(0b11111011);
0037: MOVLW FB
0038: TRIS 5
....................
.................... setup_timer_2(T2_DIV_BY_1, 124, 1);
0039: MOVLW 00
003A: BCF 03.5
003B: MOVWF 21
003C: IORLW 04
003D: MOVWF 12
003E: MOVLW 7C
003F: BSF 03.5
0040: MOVWF 12
....................
.................... setup_ccp1(CCP_PWM);
0041: BCF 06.3
0042: BCF 03.5
0043: BCF 06.3
0044: MOVLW 0C
0045: MOVWF 17
.................... set_pwm1_duty(100);
0046: MOVLW 64
0047: MOVWF 15
....................
.................... while (1)
.................... ;
0048: GOTO 048
.................... }
....................
0049: SLEEP
Configuration Fuses:
Word 1: 30D4 NOWDT NOCPD NOPROTECT NOMCLR NOPUT INTRC_IO NOBROWNOUT NOIESO NOFCMEN
|
-- dj |
|
|
DragonPIC
Joined: 11 Nov 2003 Posts: 118
|
|
Posted: Wed Apr 06, 2005 11:32 am |
|
|
Did you check your hardware? _________________ -Matt |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Apr 06, 2005 12:36 pm |
|
|
Your version of the compiler is buggy with the 12F683.
You will need to make the changes shown in bold below.
Reasons:
Problems with the start-up code:
The compiler is calling address 0x7FF, as if this PIC has an OSCCAL
value at that address. However, it does not, so this is a bug.
Also, the value is being put into the OSCTUNE register, since this
PIC has no OSCCAL register.
The work-around is to use a #rom statement to place a RETLW 0
opcode there. This will cause your version of the compiler to load 0
into the OSCTUNE register, which is the power-up default value.
Doing this will fix the bug.
Problems with setup_ccp1(CCP_PWM):
The compiler is setting up the wrong port and the wrong pin for
the PWM output. By doing output_low(PIN_A2) in standard i/o mode,
we can fix this. The compiler is also using the wrong address for
the CCP1CON register. We can fix this by defining the register address
with a #byte statement, and then writing to it directly with a line of code.
Problems with set_pwm1_duty(100):
The compiler is using the wrong address for the CCPR1L register.
We can fix this by defining the CCPR1L address with a #byte statement
and writing directly to the register with a line of code.
My comment: Your version of the compiler is buggy with this PIC.
Assume that there may be other bugs that you may discover in the
future.
#include <12F683.h>
#fuses NOWDT, INTRC_IO, NOCPD, NOPROTECT, NOMCLR, NOPUT,
NOBROWNOUT, NOIESO, NOFCMEN
#use delay (clock=8000000)
#ROM 0x7FF = {0x3400} // Add this line
#byte CCPR1L = 0x13
#byte CCP1CON = 0x15
void main()
{
setup_oscillator(OSC_8MHZ);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_comparator(NC_NC);
setup_vref(FALSE);
set_tris_a(0b11111011);
setup_timer_2(T2_DIV_BY_1, 124, 1);
// setup_ccp1(CCP_PWM); // Comment out this line
output_low(PIN_A2); // Add this line
CCP1CON = CCP_PWM; // Add this line
// set_pwm1_duty(100); // Comment out this line
CCPR1L = 100; // Add this line
while(1);
} |
|
|
djpark
Joined: 02 Mar 2004 Posts: 49
|
|
Posted: Wed Apr 06, 2005 12:45 pm |
|
|
DragonPIC wrote: | Did you check your hardware? |
As I read your post, something struck my mind.
I was using a breadboard to test and decided to give a check on the all the pins. Then I found that a few of the holes in the middle where the PIC chip is going doesn't provide the contact. It is surprising to see such wear and tare.
Thanks, PCM for great help for fixing the code.
After replacing with a new breadboard, it works like a magic.
Thanks a lot for everyone's help.
-- dj |
|
|
|
|
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
|