|
|
View previous topic :: View next topic |
Author |
Message |
deenadayalan
Joined: 19 Oct 2013 Posts: 19 Location: salam
|
pwm problem |
Posted: Wed Mar 25, 2015 10:49 pm |
|
|
HI, i am driving dc motor through mosfet with pwm, motor will rotate 1sec forward and 1 sec reverse with various speed. my code giving pwm single time only then maintaining zero
Code: |
#include "I:\VEN\timertv\timertv.h" //20 mhz
#include <lcd.c>
int16 rotcount=0;
#int_EXT
void EXT_isr(void)
{
rotcount=rotcount+1;
}
void main()
{
port_b_pullups (TRUE);
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
ext_int_edge( L_TO_H );
setup_timer_1(T1_INTERNAL|T1_DIV_BY_4);
setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_16,255, 1);
set_tris_c(0x00);
output_c(0x00);
lcd_init();
delay_ms(1000);
set_pwm1_duty(10);//duty 1
while(true)
{
output_low(pin_c3);
output_high(pin_c0);
set_timer1(0);
while(count<19) //for 1 sec
{
while((get_timer1())<65525);
count++;
}
output_low(pin_c0);
output_low(pin_c3);
set_pwm1_duty(31);//duty 2
count=0;
lcd_gotoxy(1,1);
printf(lcd_putc,"EN.PULSE.D:%lu ",rotcount);
rotcount=0;
delay_ms(2000);
output_low(pin_c0);
output_high(pin_c3);
set_timer1(0);
while(count<19)
{
while((get_timer1())<65525);
count++;
}
output_low(pin_c3);
output_low(pin_c0);
count=0;
lcd_gotoxy(1,1);
printf(lcd_putc,"EN.PULSE.U:%lu ",rotcount);
rotcount=0;
set_pwm1_duty(10);
delay_ms(2000);
}
}
|
please help me,thanks in advance |
|
|
deenadayalan
Joined: 19 Oct 2013 Posts: 19 Location: salam
|
|
Posted: Thu Mar 26, 2015 4:45 am |
|
|
please tell me,is this correct formate for pwm wave generation |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Thu Mar 26, 2015 5:44 am |
|
|
The code is untidy, and impossible to actually work out what is meant to happen.
You need to _document_. Either in comments in the source, or in separate text:
1) What clock rate are you running?.
2) What chip?.
3) What compiler version?.
4) What pins do what?. How are things wired?.
5) What feeds INT_EXT?. How ius this connected.
6) What are the peripheral chips?. Some form of rotation detector?. How is this wired?. How is the PWM wired?.
These should be part of the basic documentation of your code, before you even start one line. Look at the headers on the CCS examples. Note how they give this type of data.
Then your code is awful. First, again _document_. We had a rule at a company I used to work for that any source code delivered without at least 50% comments (though this was variable when things like variable names, could themselves be comments), would instantly be rejected, without even bothering to read/test. Your documentation is near zero.
Then things like your method of timing. This could very easily give massive problems (will....). While potentially 'nice' to use a timer, rather than the simple delay, the approach is fundamentally flawed. With your timer settings, the timer will be incrementing every fourth instruction. You test if it is <65525, which takes a few instructions, the value being used to avoid 'missing' a count >=65525, since the test takes time. However sometimes if the test just happens to see this value exactly 'on' this count, you risk the value being seen again straight away. Result (if this happens), count will increment very quickly, and your time will go wrong.....
If you want to use the timer approach, then do something like:
Code: |
void delay_1sec(void)
{
//routine to delay for approximately 1 second independant
//of timing errors from interrupts etc..
int8 count;
set_timer1(0); //ensure start at zero
clear_interrupts(INT_TIMER1);
for (count=0;count<19;count++) //for 19*4*4*65536 clock cycles
{
while(!interrupt_active(INT_TIMER1))
; //wait for interrupt flag to set.
clear_interrupts(INT_TIMER1); //clear
} //and loop
}
|
For a 20MHz master clock this will give 0.996 seconds.
This uses the interrupt _flag_, but not the interrupt. Since this triggers, whenever the timer wraps from 65535 to 0, it'll set every 65536 counts, and the count can't be missed.
Now then give your pins names, so they help tell you what you are doing. So:
Code: |
//Guessing here
#define LOW_MOTOR_ON PIN_C3
#define DIRECTION PIN_C0
//Which then makes your initial motor start code:
output_low(LOW_MOTOR_ON);
output_high(DIRECTION);
//and helps document what you are actually doing.....
|
Then what happens if you receive an INT_EXT, _while you are printing rotcount_?.
The value displayed _will_ be garbage.
What sort of actual pulse width, do you expect?. 10 as a duty cycle, is less than 4% 'on time' a tiny pulse.
Why, if you are using the timer for one delay, do you then use the delay_ms function. |
|
|
deenadayalan
Joined: 19 Oct 2013 Posts: 19 Location: salam
|
|
Posted: Thu Mar 26, 2015 10:29 pm |
|
|
Dear Ttelmah sir, thanks for your reply.
I am using
clock rate 20mhz
chip pic16f877a
compiler version ccs_pcwhd 4.07
ccp1(c2)- connected with transistor base(bc547)
header file
Code: |
#include <16F877A.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //High speed Osc (> 4mhz)
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES WRT_50% //Lower half of Program Memory is Write Protected
#use delay(clock=20000000)
|
main coding
Code: |
#include "C:\Users\Localadmin\Desktop\pwm\pwm1.h"
void main()
{
set_tris_c(0x00);
output_c(0x00);
setup_timer_2(T2_DIV_BY_16,255,1); // 1khz pwm
setup_ccp1(CCP_PWM);
set_pwm1_duty(102); // 10% duty cycle
while(true);
}
|
This code also didn't give pwm. I am doing major mistake but i couldn't find out, help me sir.
Once again thank you sir |
|
|
|
|
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
|