| Author |
Message |
|
|
Posted: Jan 17, 2010 - 11:47 PM |
|

Joined: Jan 14, 2010
Posts: 11
|
|
|
new2atmel wrote:
Hi all,
Firstly I have to say the Dean is a gentleman and a scholar for providing such an educational tutorial.
Secondly, if anyone is interested here is some PWM code I wrote in AVR Studio. It uses UART commands from the PC for triggering the PWM on or off. It uses the Mega32 @10MHz and sets up the PWM for motor control with the frequency set at ~20kHz @ 75% duty cycle using Timer 0
Code:
void PWM_Init()
{
TCCR0 = (0<<WGM01)|(1<<WGM00)|(1<<CS00);//setup PMW, no prescaler
OCR0 = 0xC0; //set 75% duty cycle
DDRB |= (1<<DDB3);
}
void main()
{
unsigned char PWM_on;
unsigned char PWMON[]="PWM on Pin 4";
unsigned char PWMOFF[]="PWM off Pin 4";
PWM_on = 0;
PWM_Init();
while (1)
{
switch (Received_Command)
{
case '3':
if (PWM_on == 1)
{
TCCR0 ^=(1<<COM01); //disable OC0
PWM_on = 0;
UART_putstring(PWMOFF);
USART_Transmit(LF);
Received_Command = '0';
}
else
{
TCCR0 ^=(1<<COM01);
//Clear OC0 on compare match when up-counting. Set OC0 on compare match when downcounting.
PWM_on = 1;
UART_putstring(PWMON);
USART_Transmit(LF);
Received_Command = '0';
}
}//end while(1)
}
I won't bother with the UART code as there is a tute for this.
Enjoy
Thank you very much for this help. I am writing a program to control my servo using the PWM on the ATmega1280 (Arduino Mega).
I tried to understand the code and write a similar program but I failed. Here is the code I am using:
Code:
void pwm_r()
{
OCR1A = 2000;
}
void pwm_l()
{
OCR1A = 1000;
}
void pwm_c()
{
OCR1A = 1500;
}
void init_pwm()
{
DDRB |= (1<<DDB3);
//initialization of timer 1 and the frequency (50Hz)
ICR1 = 20000;
TCCR1A = ((1 << COM1A1) | (1 << COM1B1) | (1 << WGM11) | (0 << WGM10));
TCCR1A = ((1 << COM1A1) | (1 << COM1B1));
TCCR1B = ((1 << CS10) | (1 << CS11) | (1 << WGM13));
ICR1 = 0xFF;
TCCR1B = ((1 << CS10) | (1 << CS11) | (1 << WGM13) | (1 << WGM12));
}
I then call pwm_l, pwm_c, and pwm_r in main. The purposes of the functions are to turn the servo counter-clockwise, position it to center, and clockwise respectively. When I download the program, it only turns the servo clockwise.
What can I do to actually have the servo turn clockwise, counter-clockwise, and position it in the middle position??
Thanks a lot for the help. |
|
|
| |
|
|
|
|
|
Posted: Jan 18, 2010 - 09:36 AM |
|


Joined: Jul 18, 2005
Posts: 62354
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
|
Quote:
When I download the program, it only turns the servo clockwise.
Why are you seting TCCR1B and ICR1 twice? Only the second setting of each will work yet the OCR1=1000,1500,2000 with ICR1=20000 values sound like they are the ones you probably want to use (assuming F_CPU with the CS?? combination give th right tick rate) |
_________________
|
| |
|
|
|
|
|
Posted: Jan 23, 2010 - 08:37 PM |
|

Joined: Mar 23, 2008
Posts: 85
|
|
| Any Plans to Finish this tutorial ? |
|
|
| |
|
|
|
|
|
Posted: Feb 23, 2010 - 07:04 AM |
|

Joined: Feb 23, 2010
Posts: 1
|
|
Hi
I am trying to use Atmega16 to turn on/off a MOSFET. I don't really want to generate a PWM. My goal is that when the voltage at a specific point of the circuit is equal or greater than 5V, the MOSFET will turn on, otherwise the MOSFET will turn off.
I appreciate any hints or tutorial from all of you.
Thank you very much. |
|
|
| |
|
|
|
|
|
Posted: Feb 23, 2010 - 09:35 AM |
|


Joined: Jul 18, 2005
Posts: 62354
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
|
Quote:
I appreciate any hints or tutorial from all of you.
You hijacked thew wrong tutorial. You wanted the one about Analog to Digital Conversion. Your program would basically be:
Code:
while(1) {
take_AC_reading()
if (reading >= threshold) {
set IO to turn MOSFET on
}
else {
clear IO to turn MOSFET off
}
}
}
|
_________________
|
| |
|
|
|
|
|
Posted: Mar 24, 2010 - 08:25 AM |
|

Joined: Mar 12, 2010
Posts: 11
|
|
What i ahve understood so far from this tutorial is as follows please let me know if i am correct
TOP=OCRxx BOTTOM=TCNTx
for a PWM wave set the timer in the PWM mode first
then for say 75% duty cycle i.e. we need a count of 192/255 means OCRxx=0xC0 and TCNTx=0xFF.
now since TOP is set at 255 count and if the frequency of the CPU is say 16 Mhz then then total Time period of the wave will be 255/16Mhz=16Microsecs of which 12 microsecs is the ON period.Now this time period can be easily modified by using prescalar values.
Am i correct ?? please let me know.
but i will get the 25% off period only if i use the Toggle mode isnt it ? |
|
|
| |
|
|
|
|
|
Posted: Mar 24, 2010 - 05:09 PM |
|

Joined: Nov 17, 2004
Posts: 13851
Location: Vancouver, BC
|
|
|
Quote:
i am correct
TOP=OCRxx - this depends on what mode you are in, but in the example you gave, OCRxx is the duty cycle, not TOP
BOTTOM=TCNTx - No, never. TCNTx is the current value of the timer. BOTTOM is always 0.
then for say 75% duty cycle i.e. we need a count of 192/255 means OCRxx=0xC0 and TCNTx=0xFF. - OCRxx is correct, assuming that you have selected a mode where TOP is 255. Again, no need to set TCNTx.
255/16Mhz=16Microsecs of which 12 microsecs is the ON period. - Yes, except that it is really 256/16MHz.
Now this time period can be easily modified by using prescalar values. - Yes, but you can also vary this by changing what TOP is set to.
but i will get the 25% off period only if i use the Toggle mode isnt it ? - Incorrect. You need the "clear on compare, set on TOP" mode. |
_________________ Regards,
Steve A.
The Board helps those that help themselves.
|
| |
|
|
|
|
|
Posted: Mar 24, 2010 - 05:40 PM |
|

Joined: Mar 12, 2010
Posts: 11
|
|
How to change the TOP value ???
is there a clear on compare and set on top mode..??? |
|
|
| |
|
|
|
|
|
Posted: Mar 24, 2010 - 05:45 PM |
|

Joined: Mar 12, 2010
Posts: 11
|
|
ohh yea i got the Clear and Set modes but how to change the TOP value ??
for example if i am using a 16 bit Timer.. i will have to give a huge count for a duty cycle of 75% as my top value will be oxffff |
|
|
| |
|
|
|
|
|
Posted: Mar 24, 2010 - 05:46 PM |
|


Joined: Jul 18, 2005
Posts: 62354
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
|
Quote:
How to change the TOP value ???
Pick a PWM mode from the WGM table in which the TOP column includes the name of a register rather than a fixed value. |
_________________
|
| |
|
|
|
|
|
Posted: Mar 26, 2010 - 04:20 AM |
|

Joined: Mar 12, 2010
Posts: 11
|
|
|
|
|
|
|
Posted: Jul 19, 2010 - 01:32 AM |
|

Joined: Jul 13, 2010
Posts: 10
|
|
Such a shame that this tutorial is incomplete! When I search for tutorials, I specifically look to see if you have written one first.
Still, what you have posted so far is very helpful. Thanks! |
|
|
| |
|
|
|
|
|
Posted: Jul 19, 2010 - 10:28 AM |
|


Joined: Jul 18, 2005
Posts: 62354
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
|
|
|
|
|
Posted: Jul 19, 2010 - 11:25 AM |
|

Joined: Jul 13, 2010
Posts: 10
|
|
Yes I did, those tutorials were helpful. Thanks clawson.
And while they are good tutorials, for some reason, I just prefer abcminiuser's style. |
|
|
| |
|
|
|
|
|
Posted: Jul 21, 2010 - 04:28 AM |
|

Joined: Jun 30, 2010
Posts: 13
|
|
hi Dean, This is very useful material, espcially for beginners. THANKZ,
I hope you can make a PDF for it, I would like to save it for further use.
thankz again, |
|
|
| |
|
|
|
|
|
Posted: Aug 01, 2010 - 05:42 AM |
|

Joined: May 25, 2008
Posts: 1
|
|
A very useful material indeed.
Thanks for sharing. |
|
|
| |
|
|
|
|
|
Posted: Aug 15, 2010 - 10:09 PM |
|

Joined: Nov 07, 2008
Posts: 22
Location: E. Europe > Romania > Bucharest
|
|
I can't grasp the difference between phase correct PWM and fast PWM.
I see that you consider the time periods to start at different moments, but that is not relevant to the circuit, is it? In both cases it sees some evenly spaced duty cicles.
And second: why 8-9-10 bit PWM and not 16bit PWM? Timer1 is 2 bytes long, it can count on 16 bits, but the PWM will be 10 bits because ......................
? |
|
|
| |
|
|
|
|
|
Posted: Aug 15, 2010 - 10:29 PM |
|


Joined: Mar 27, 2002
Posts: 18585
Location: Lund, Sweden
|
|
|
Quote:
In both cases it sees some evenly spaced duty cicles.
Depends on what you mean by "evenly". Lets consider a simplified case where the counter counts to 4 (ie 5 steps before it wraps. Lets look at 20% and 60% duty cycle they would be like below for fast PWM
Code:
20%: 10000100001000010000...
60%: 11100111001110011100...
but for phase correct PWM they would be
Code:
20%: 00100001000010000100...
60%: 01110011100111001110...
Now, finally, to hopefully make the difference obvious lets look at two syscles of 20% and two cycles of 60% for both fast PWM and phase correct PWM
Code:
fast PM 10000100001110011100
phase correct PWM 00100001000111001110
Now, lets align the 20% on-parts with each other
Code:
fast PM ..10000100001110011100
phase correct PWM 00100001000111001110..
^ ^ ^ ^
and notice how the 60% on-parts are not matching.
Phase correct PWM is about centring the on-part around a specific, iterating, point in time (which I have marked above with ^). (Fast PWM starts its on-parts at those points). |
|
|
| |
|
|
|
|
|
Posted: Aug 16, 2010 - 09:50 AM |
|


Joined: Jul 18, 2005
Posts: 62354
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
Here's a tip. If you want to know how something looks different then type "phase correct PWM" into Google's image search. You'll get a number of results including this one:
(rather ironically that URL says that is hosted on fourwalledcubicle.com (Dean's site) and appears on Freaks in a Timer tutorial)
EDIT irony upon irony, that picture is in the first post of this very thread - so exactly what don't you understand about it now? Surely that shows exactly how fast/phase-correct differ - with phase correct having the pulse centred in the time frame. |
_________________
|
| |
|
|
|
|
|
Posted: Aug 16, 2010 - 10:58 AM |
|


Joined: Mar 27, 2002
Posts: 18585
Location: Lund, Sweden
|
|
| I guess the question 'chooglin' might ask now is: Why do you need it? |
|
|
| |
|
|
|
|
|