View previous topic :: View next topic |
Author |
Message |
[terminate]
Joined: 08 Jan 2006 Posts: 26
|
PWM 18F452 question |
Posted: Mon Jan 09, 2006 10:11 pm |
|
|
I have the following code right here:
Code: |
#include <18F452.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use fast_io(b)
#use fast_io(c)
void main(void)
{
INT VALUE;
output_high(PIN_A0);
SET_TRIS_B(0b11111101); // set the b ports for input
set_tris_c(0b11111011);
SETUP_CCP1(CCP_PWM); // PUT THE CCP1 PORT INTO PWM MODE
SETUP_TIMER_2(T2_DIV_BY_1,255,1);
VALUE = 0;
delay_ms(2000); // two second initialization
WHILE (TRUE)
{
SET_PWM1_DUTY(VALUE);
output_high(PIN_B1);
delay_ms(100);
output_low(PIN_B1);
delay_ms(100);
value--;
if (input(PIN_B0)==1)
{
VALUE = 0;
}
}
}
|
I set the value of the duty cycle to zero, but the motor still turns, ie the CCP1 port is still outputting. Is there a reason why? |
|
|
[terminate]
Joined: 08 Jan 2006 Posts: 26
|
|
Posted: Mon Jan 09, 2006 10:28 pm |
|
|
well, i think i've figured it out. I have to set the pwm duty to zero before initializing the PWM mode using setup_ccp |
|
|
[terminate]
Joined: 08 Jan 2006 Posts: 26
|
|
Posted: Mon Jan 09, 2006 11:52 pm |
|
|
Just one more question.
I have this loop here:
Code: |
...
SETUP_CCP1(CCP_PWM); // PUT THE CCP1 PORT INTO PWM MODE
SETUP_TIMER_2(T2_DIV_BY_1,127,1);
delay_ms(3000); // three second initialization
WHILE (TRUE)
{
set_pwm1_duty(120);
}
}
|
I expect it to turn the motor continuously, however, it doesn't. It turns for a random amount of time and then turns off, and then repeats.
I'm using 3.203
Thanks! Much appreciated! |
|
|
Ttelmah Guest
|
|
Posted: Tue Jan 10, 2006 4:22 am |
|
|
Why would you expect it to be continuous?. It should be on for 120/127th of the time.
However the big problem is that you are continuously writing to the registers, while the PWM runs. The value only gets transferred at the end of the PWM cycle, but what happens if the data transfer is 'half done' at this point?. When updating a PWM, I always synchronise to the PWM itself to do this. So:
Code: |
#bit TMR2IF=0xF9E.1
TMR2IF=0;
while (TRUE) {
while (TMR2IF==0) ;
TMR2IF==0;
set_pwm1_duty(120);
}
|
This waits for the PWM cycle to occur (by looking for the interrupt flag that is set at the end of the timer2 count), and then writes the new value. I have found this to be 100% reliable, even when updating PWM values at a very high rate.
Best Wishes |
|
|
does'nt_wish_to_disclose Guest
|
HOW ?? |
Posted: Tue Jan 10, 2006 4:35 am |
|
|
I was just wondering how Mr. RJ can answer all the questions that are being asked on this forum. I am following almost all of RJ's posts for quiet some time(I'm a registered user-. Looks like he has a lot of experience in all topics. My salute to the GURU.... |
|
|
Ttelmah Guest
|
|
Posted: Tue Jan 10, 2006 8:03 am |
|
|
Thanks for the 'vote of confidence'. There are several other people here, who do 'sterling service', as well though. PCM Programmer, Neutone, and Humberto in particular come to mind.
In common with anybody, I can make some real 'errors' at times, and you can learn a lot from these (and sometimes some really 'beautiful' algorithms and techniques get posted, which can be useful to everyone).
I have used PICs for a _long_ time. When MicroChip first launched their 'site', I actually had to email them and point out that the 'launch date' for one of their earliest chips, had to be wrong, since I had a product 'on the market', using it, a year before the date they claimed...
I use this site, as a way of avoiding going into 'brain freeze', when working on stuff here. Changing, and looking at another problem, even if it is one that is basic, helps to stop me becoming fixated on what I am doing...
Best Wishes |
|
|
[terminate]
Joined: 08 Jan 2006 Posts: 26
|
|
Posted: Tue Jan 10, 2006 10:01 am |
|
|
thank you very much! your help is very much appreciated! |
|
|
[terminate]
Joined: 08 Jan 2006 Posts: 26
|
|
Posted: Tue Jan 10, 2006 10:26 am |
|
|
I changed that little bit and it still does the same thing, but then i hooked an LED onto that pin and it's constantly on, so the problem (i think) is the transistor im using to switch the motor on and off has too high of a gate voltage so the PWM doesn't work, or the frequency of the switching is too low? Thanks for your help! |
|
|
Ttelmah Guest
|
|
Posted: Tue Jan 10, 2006 1:34 pm |
|
|
Er. If the 'gate voltage' required is too high, for a normal layout, the FET should not switch on. How have you got this wired?.
To drive from a processor directly, a 'logic level' N channel MOSFET, should be no problem. Your frequency, should be just under 4KHz, with the code as given. This will buzz annoyingly, but should work.
Best Wishes |
|
|
[terminate]
Joined: 08 Jan 2006 Posts: 26
|
|
Posted: Tue Jan 10, 2006 7:50 pm |
|
|
I'm using a TIP31 NPN transistor
I'll try a mosfet |
|
|
[terminate]
Joined: 08 Jan 2006 Posts: 26
|
|
Posted: Wed Jan 11, 2006 7:01 pm |
|
|
I hope this is not asking too much, but how would you implement an interrupt to your above code?
Thank you so mucH!!! |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1636 Location: Perth, Australia
|
|
Posted: Wed Jan 11, 2006 7:30 pm |
|
|
[terminate] wrote: | I'm using a TIP31 NPN transistor
I'll try a mosfet |
Hmmm. Sounds like a possible problem with your implementation. Can you post your schematic. _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
Ttelmah Guest
|
|
Posted: Thu Jan 12, 2006 4:50 am |
|
|
It depends what you want the interrupt to do?.....
On the driver, a TIP31, should be fine, with the following 'caveats'. PIC output pin, to the base (no 'gate' on a transistor...), via a 270R resistor (limits the current flow to about 15mA - remember that a conventional transistor isa _current controlled_ device, not a 'voltage controlled' device). Then from the base to ground, perhaps a 10K resistor (this ensures the transistor is 'off', when the PIC wakes up, and the pin is an input etc.). Emitter to gnd, collector to the motor. Put a fast recovery diode, reverse biased across the motor. This latter is essential, if you are not going to blow up the transistor when the drive switches off. When you release the drive from the motor, the energy in the magnetic field, has to go somewhere, and the voltage on the coil, will rise, till it finds a path to go through. Without a trap diode like this, the voltage will rise to the point where it destroys the transistor...
Best Wishes |
|
|
[terminate]
Joined: 08 Jan 2006 Posts: 26
|
|
Posted: Thu Jan 12, 2006 9:57 am |
|
|
hey! thanks for the tips. I'll try them out.
My goal for the interrupt is to satisfy this:
When the motor is running, a sensor senses a pylon, and then the sensor interrupt will switch the motor is only one side (differential format) to turn away from a pylon.
I tried your caveats and they work great. The motor still stops at random times (maybe due to the pwm value being 120 instead of the full 128), but it turns "more" continuously now. I'm going to have to get a diode first
I've tried setting it up with 256 bits of PWM resolution with the full set_pwm1_duty(256); but the motor still runs inconsistently. Any ideas? I have not yet to include the diode, perhaps that is the problem. I'll try getting one today
Thanks so much! |
|
|
[terminate]
Joined: 08 Jan 2006 Posts: 26
|
|
Posted: Sun Jan 15, 2006 6:33 pm |
|
|
Code: |
#bit TMR2IF=0xF9E.1
TMR2IF=0;
while (TRUE) {
while (TMR2IF==0) ;
TMR2IF==0;
set_pwm1_duty(120);
}
|
Just wondering, should that be TMR2IF=0; in the second tmr2if statement? |
|
|
|