Offline
Newbie
Karma: 0
Posts: 30
|
 |
« on: December 30, 2012, 03:18:25 pm » |
Hi, new here and probably being a bit dim but I've Googled and done all the obvious stuff and I cannot figure out how to program the PWM to get a 40kHz signal to drive an ultrasonic sender for a distance measurement device. I've got the example below running an giving me 8kHz but how do I scale this to get 40kHz. Also on my ATMega1280 the output is on pin 13, not pin 6 which this example code suggests (I guess the code is for a different processor). I've read the datasheet but it just went in and fell straight out again. Any help appreciated. #include <avr/io.h>
int main(void) { DDRD |= (1 << DDD6); // PD6 is now an output
OCR0A = 128; // set PWM for 50% duty cycle
TCCR0A |= (1 << COM0A1); // set none-inverting mode
TCCR0A |= (1 << WGM01) | (1 << WGM00); // set fast PWM Mode
TCCR0B |= (1 << CS01); // set prescaler to 8 and starts PWM
while (1); { // we have a working Fast PWM } }
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Edison Member
Karma: 114
Posts: 2205
|
 |
« Reply #1 on: December 30, 2012, 03:27:06 pm » |
You need a pwm mode that allows you to set the top.
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
UK
Offline
Brattain Member
Karma: 136
Posts: 18995
I don't think you connected the grounds, Dave.
|
 |
« Reply #2 on: December 30, 2012, 03:31:42 pm » |
You need a pwm mode that allows you to set the top. Was the any more to your post, dhenry?
|
|
|
|
|
Logged
|
Pete, it's a fool looks for logic in the chambers of the human heart.
|
|
|
|
Milton Keynes UK
Offline
Tesla Member
Karma: 88
Posts: 6286
-
|
 |
« Reply #3 on: December 30, 2012, 07:46:01 pm » |
You need to carefully read Nick Gammon's web site, I'd suggest starting here: Nick Gammon's description of Timers and Counters
|
|
|
|
|
Logged
|
|
|
|
|
Pittsburgh, PA, USA
Offline
Faraday Member
Karma: 29
Posts: 2879
I only know some basic electricity....
|
 |
« Reply #4 on: December 30, 2012, 08:13:26 pm » |
PWM frequency on the Playground: http://playground.arduino.cc//Code/PwmFrequencyPlease keep in mind that changing the PWM frequency changes the Atmega's timers and disrupts the normal operation of many functions that rely on time (delay(), millis(), Servo library).
|
|
|
|
|
Logged
|
Examples can be found at Learning in the Main Site and at the Playground
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 218
Posts: 13896
Lua rocks!
|
 |
« Reply #5 on: December 31, 2012, 12:50:14 am » |
You need a pwm mode that allows you to set the top.
Which mode is that?
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 218
Posts: 13896
Lua rocks!
|
 |
« Reply #6 on: December 31, 2012, 12:51:57 am » |
One of my sketches on the page below generates 50 KHz: http://www.gammon.com.au/forum/?id=11504&reply=6#reply6By changing this line you should be able to get 40 KHz: const long frequency = 50000L; // Hz
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 218
Posts: 13896
Lua rocks!
|
 |
« Reply #7 on: December 31, 2012, 12:56:21 am » |
Yep, it does, looks pretty accurate too:  Sketch: const byte LED = 3; // Timer 2 "B" output: OC2B
const long frequency = 40000L; // Hz
void setup() { pinMode (LED, OUTPUT);
TCCR2A = _BV (WGM20) | _BV (WGM21) | _BV (COM2B1); // fast PWM, clear OC2B on compare TCCR2B = _BV (WGM22) | _BV (CS21); // fast PWM, prescaler of 8 OCR2A = ((F_CPU / 8) / frequency) - 1; // zero relative OCR2B = ((OCR2A + 1) / 2) - 1; // 50% duty cycle } // end of setup
void loop() { }
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 30
|
 |
« Reply #8 on: December 31, 2012, 05:05:11 am » |
Thanks for the replies, I'll give that a go
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 30
|
 |
« Reply #9 on: February 01, 2013, 03:50:42 pm » |
Sorry to resurrect an old(ish) thread but what is the best way to stop and start this timer? I am using it for ultrasonic distance measurement so I need to send out a short ping and then listen for the echo. The ping needs to be short - is it best to just set the pin to input from output or do I need to stop the PWM, if so how?
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
Melbourne, Australia
Offline
Shannon Member
Karma: 218
Posts: 13896
Lua rocks!
|
 |
« Reply #10 on: February 01, 2013, 03:56:16 pm » |
Turning the pin to input is probably the simple way to stop it. The thing that actually starts the timer is the CS21 part of this line (the clock source): TCCR2B = _BV (WGM22) | _BV (CS21); // fast PWM, prescaler of 8
So the above line starts it. This would stop it: TCCR2B = _BV (WGM22) ; // fast PWM, timer off
|
|
|
|
|
Logged
|
|
|
|
|
Pittsburgh, PA, USA
Offline
Faraday Member
Karma: 29
Posts: 2879
I only know some basic electricity....
|
 |
« Reply #11 on: February 01, 2013, 04:29:40 pm » |
|
|
|
|
« Last Edit: February 01, 2013, 04:31:12 pm by GoForSmoke »
|
Logged
|
Examples can be found at Learning in the Main Site and at the Playground
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 30
|
 |
« Reply #12 on: February 02, 2013, 02:39:50 pm » |
Thanks for the replies
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 30
|
 |
« Reply #13 on: March 26, 2013, 04:32:19 pm » |
Apologies for reviving this thread again, but I am now trying to use a similar bit of code to generate a 1kHz signal, however it is fine down to about 8kHz but it won't go below that. I suspect that it is due to the fast PWM but I have read the datasheet and I haven't got a clue how to stop using the Fast PWM.
Any help greatly appreciated.
|
|
|
|
|
Logged
|
|
|
|
|
Pittsburgh, PA, USA
Offline
Faraday Member
Karma: 29
Posts: 2879
I only know some basic electricity....
|
 |
« Reply #14 on: March 26, 2013, 04:40:27 pm » |
Why use PWM at all? Just set up a timer and interrupt to change the pin state.
|
|
|
|
|
Logged
|
Examples can be found at Learning in the Main Site and at the Playground
|
|
|
|
|