View previous topic :: View next topic |
Author |
Message |
Neo
Joined: 06 May 2010 Posts: 5
|
16f877 pwm code problem |
Posted: Thu May 06, 2010 4:08 pm |
|
|
Hi, I am trying to make 100khz pwm signal with 20 MHz oscillator, and I'll change duty with buttons...
I use this calculation : Tpwm=Tosc*4*(PR2+1)*1 => PR2=49
Code: |
#include <16f877.h>
#fuses HS,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay (clock=20MHz)
#use fast_io(a)
#use fast_io(c)
int i=49; //duty
void main ( )
{
setup_psp(PSP_DISABLED);
setup_timer_1(T1_DISABLED);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
set_tris_a(0x03);
set_tris_c(0x00);
setup_ccp1(CCP_PWM);
setup_ccp2(CCP_PWM);
setup_timer_2(T2_DIV_BY_1,49,1);
set_pwm1_duty(i);
set_pwm2_duty(i);
while(1) // in this loop making duty
{
if (input(pin_a0))
{
delay_ms(20);
while(input(pin_a0)); //increase duty
i+=3;
if (i>49)
i=49;
set_pwm1_duty(i);
set_pwm2_duty(i);
}
if (input(pin_a1))
{
delay_ms(20);
while(input(pin_a1));
i-=3; //decrease duty
if (i<10)
i=10;
set_pwm1_duty(i);
set_pwm2_duty(i);
}
}
}
|
Using this code in Proteus, but I can't reach 100khz frequency.
http://i41.tinypic.com/oj32ft.png (proteus)
Where is problem? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19562
|
|
Posted: Fri May 07, 2010 3:21 am |
|
|
Have you told Proteus that your master oscillator is 20MHz?. I'd suspect this has not imported from the crystal properly. If I remember, setting the 'freq' value, does not automatically tell the simulator that this is the frequency in use....
Though I have Proteus, I don't use it's simulation. More trouble than it is worth.
Best Wishes |
|
|
Neo
Joined: 06 May 2010 Posts: 5
|
|
Posted: Fri May 07, 2010 4:44 am |
|
|
In Proteus, if I change processors clock time to 20 MHz it works fine (Proteus gives 1mhz), but in reality where I can change processors clock time ?
I think I should tell this processor in program code.
I found something for pic18f2320 changing oscillator time with this code:
Code: |
setup_oscillator(OSC_8MHZ)
|
I know 16f877 don't have internal oscillator, but what does it mean in Proteus "processors clock time"? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19562
|
|
Posted: Fri May 07, 2010 8:46 am |
|
|
The way you change the processors frequency, is with the crystal....
Some processors, have _internal_ calibrated RC oscillators (not accurate enough for many applications), and these can then be controlled with the setup_oscillator instruction, _if selected in the fuses first_.
Your chip does not have this.
You cannot tell Proteus what the clock rate is, from Program code.
Your program code has to be told what the real oscillator is, just as Proteus does. This is what the clock statement does in CCS.
Best Wishes |
|
|
sshahryiar
Joined: 05 May 2010 Posts: 94 Location: Dhaka, Bangladesh
|
PWM Problem Reply. |
Posted: Sat May 08, 2010 3:29 am |
|
|
Firstly your code has got some problems. I will tell u later......Secondly, Proteus does not show PWM operations in a "should be" way......It made me remember I had a problem like u.... _________________ https://www.facebook.com/MicroArena
SShahryiar |
|
|
sshahryiar
Joined: 05 May 2010 Posts: 94 Location: Dhaka, Bangladesh
|
|
Posted: Sat May 08, 2010 3:34 am |
|
|
Code: | #include <16f877.h>
#fuses HS,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay (clock=20MHz)
int i=49; //duty
void main ( )
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_timer_2(T2_DIV_BY_1,49,1);
set_tris_a(0x03);
set_tris_c(0x00);
setup_ccp1(CCP_PWM);
setup_ccp2(CCP_PWM);
while(1) // in this loop making duty
{
if (input(pin_a0))
{
delay_ms(20);
while(input(pin_a0)); //increase duty
i+=3;
if (i>49)
{
i=49;
}
}
else if (input(pin_a1))
{
delay_ms(20);
while(input(pin_a1));
i-=3; //decrease duty
if (i<10)
{
i=10;
}
}
else
{
set_pwm1_duty(i);
set_pwm2_duty(i);
}
}
}
|
Try this code Neo. Hopefully it will do good. _________________ https://www.facebook.com/MicroArena
SShahryiar |
|
|
Neo
Joined: 06 May 2010 Posts: 5
|
|
Posted: Sun May 09, 2010 1:26 pm |
|
|
Thank you sshahryiar but your code gived same result...
I'll try my code tomorrow in laboratory. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun May 09, 2010 2:17 pm |
|
|
Try this program. It will go from 0 to 100% duty cycle. It starts at 50%.
When you press 'F', it increases the duty cycle. When you press 'R' it
decreases the duty cycle. When you press 'S', it goes to 50%.
I tested this program in hardware with compiler vs. 4.107.
Code: |
#include <16F877.h>
#fuses HS, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
//===========================
void main()
{
char c;
int8 pwm_duty;
setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_1, 49, 1);
pwm_duty = 25; // Initially set pwm duty cycle to 50%
set_pwm1_duty(pwm_duty);
while(1)
{
c = toupper(getc()); // Wait for input
if(c == 'F')
{
if(pwm_duty < 50)
{
pwm_duty++;
set_pwm1_duty(pwm_duty);
}
}
if(c == 'R')
{
if(pwm_duty > 0)
{
pwm_duty--;
set_pwm1_duty(pwm_duty);
}
}
if(c == 'S')
{
pwm_duty = 25;
set_pwm1_duty(pwm_duty);
}
}
} |
|
|
|
Neo
Joined: 06 May 2010 Posts: 5
|
|
Posted: Mon May 10, 2010 12:28 pm |
|
|
Thank you PCM programmer, but i tried my code today and it worked fine ;)
But i have new question, i want to get complemented pulse on other pwm out port. How can i turn first pulse to inverse? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon May 10, 2010 1:07 pm |
|
|
The 16F877 doesn't have the ability to do that. You need to use another
type of PIC.
It would help if you tell us what is the purpose of your project. |
|
|
Neo
Joined: 06 May 2010 Posts: 5
|
|
Posted: Mon May 10, 2010 1:40 pm |
|
|
I'm trying to make boost converter with Mosfet, and this control circuit dirves mosfet at 100kHz.
I asked that inverted pulse for my friend, he tries static compensation and need to drive 2 mosfets with complemented pwm. |
|
|
|