วันอังคารที่ 14 พฤศจิกายน พ.ศ. 2560
universal induction cooker controller using arduino unoPRINT Go DownPages: [1] Topic: Do I need to run an ISR to get fast PWM working? (Read 299 times) Previous Topic - Next Topic Indi008 avatar_Indi008 * Newbie Posts: 4 Karma: 0 [add] Do I need to run an ISR to get fast PWM working? Aug 03, 2015, 07:08 am Hello, I am trying to generate the pwm waveform shown in the attached image using an arduino nano (atmega328). I'm using the 16 bit timer (timer 1) and I'm having trouble getting any pwm output on the pins. I've been testing with a bench top digital power supply inputting 9 V (20 mA) into Vin. The light on the micro is on but I'm not getting any output on the pwm pins (connected to an oscilloscope). I suspect there is something wrong with how I have set up my code. I thought if I selected Fast PWM then it generates an output at the pin on compare automatically and I didn't need to use an ISR. I can set one up if needed and I know it can be done that way but I didn't think it was necessary. Am I wrong and do I need to set up an ISR or is there a different reason my PWM is not working? And if I do need an ISR to get the PWM working then what's the point of having an inverted fast pwm option when you can set the output pin either low or high in the ISR? Code: [Select] void setup() { // Defining PB1 and PB2 as outputs by setting PORTB1 and PORTB2 // Setting DDB1 and DDB2 DDRB = DDRB | 00000110; //stop interrupts cli(); // Initilize OCR1A = 300 (pulse_width = 150us), OCR1B, and ICR1 ICR1 = 0xFFFF; OCR1B = 299; OCR1A = ICR1 - OCR1B; // Enable Timer/counter1 by clearing PRTIM1 PRR = PRR & 11110111; // Selecting the Prescaler to be 8, frequency is 30.5 Hz // Clearing clock select bits CS12 and CS10 TCCR1B = TCCR1B & 11111010; // Setting clock select bit CS11 TCCR1B = TCCR1B | 00000010; // We want non-inverting mode for OC1A, and inverting mode for OC1B // Clearing COM1A0 TCCR1A = TCCR1A & 10111111; // Setting COM1A1, COM1B1, and COM1B0 TCCR1A = TCCR1A | 10110000; // We want Fast PWM with ICR1 as TOP // Clearing WGM10 TCCR1A = TCCR1A & 11111110; // Setting WGM11 TCCR1A = TCCR1A | 00000010; // Setting WGM13 and WGM12 TCCR1B = TCCR1B | 00011000; // Enable PWM // Setting OCIE1A and OCEI1B TIMSK1 = TIMSK1 | 00000110; //allow interrupts sei(); } void loop() { // put your main code here, to run repeatedly: } * PWM.PNG 15.8 KB downloaded 267 times nickgammon avatar_nickgammon ***** Global Moderator Nick Gammon Brattain Member Posts: 28,094 Karma: 1357 [add] Lua rocks! http://www.gammon.com.au Re: Do I need to run an ISR to get fast PWM working? #1 Aug 03, 2015, 08:03 am You don't need interrupts and you don't want this line: Code: [Select] TIMSK1 = TIMSK1 | 00000110; That will enable an interrupt handler that you don't have. Can you please redo your sketch with proper names? My eyes are glazing over looking at all those bits. For example, instead of: Code: [Select] DDRB = DDRB | 00000110; Use: Code: [Select] DDRB |= bit (DDB1) | bit (DDB2); The days of writing code in binary have well and truly gone. Code: [Select] // Enable Timer/counter1 by clearing PRTIM1 PRR = PRR & 11110111; PRR is the power reduction register. That's not an appropriate way of starting the timer. It will be on, anyway. Please post technical questions on the forum, not by personal message. Thanks! More info: http://www.gammon.com.au/electronics nickgammon avatar_nickgammon ***** Global Moderator Nick Gammon Brattain Member Posts: 28,094 Karma: 1357 [add] Lua rocks! http://www.gammon.com.au Re: Do I need to run an ISR to get fast PWM working? #2 Aug 03, 2015, 08:28 am This is closer to what you want: Code: [Select] void setup() { // Defining PB1 and PB2 as outputs by setting PORTB1 and PORTB2 // Setting DDB1 and DDB2 DDRB |= bit (DDB1) | bit (DDB2); // stop timer 1 TCCR1A = 0; TCCR1B = 0; TCCR1A = bit (COM1B0) | bit (COM1B1) // Set OC1B on Compare Match, clear // OC1B at BOTTOM (inverting mode) | bit (COM1A1) // Clear OC1A on Compare Match, set // OC1A at BOTTOM (non-inverting mode) | bit (WGM11); // Fast PWM, top at ICR1 TCCR1B = bit (WGM12) | bit (WGM13) // ditto | bit (CS11); // Start timer, prescaler of 8 // Initialize OCR1A = 300 (pulse_width = 150us), OCR1B, and ICR1 ICR1 = 0xFFFF; OCR1B = 299; OCR1A = ICR1 - OCR1B; } // end of setup void loop() { } Please post technical questions on the forum, not by personal message. Thanks! More info: http://www.gammon.com.au/electronics nickgammon avatar_nickgammon ***** Global Moderator Nick Gammon Brattain Member Posts: 28,094 Karma: 1357 [add] Lua rocks! http://www.gammon.com.au Re: Do I need to run an ISR to get fast PWM working? #3 Aug 03, 2015, 08:33 am Output of it: Please post technical questions on the forum, not by personal message. Thanks! More info: http://www.gammon.com.au/electronics Indi008 avatar_Indi008 * Newbie Posts: 4 Karma: 0 [add] Re: Do I need to run an ISR to get fast PWM working? #4 Aug 04, 2015, 04:14 am Last Edit: Aug 04, 2015, 04:14 am by Indi008 Thank you :) Seems to be outputting nice pwm now and I just realised I had which pin I wanted to invert opposite ways but that's easy to fix. I think possibly for the binary I maybe needed to write B00000110 rather than 00000110 and that might have been another issue but I'll use the proper names rather than binary since it seems nicer way to write it anyway. Sorry for the belated reply and thanks for the help :). PRINT Go UpPages: [1] Jump to: Go NEWSLETTER ENTER YOUR EMAIL TO SIGN UP SUBSCRIBE Copyright Notice
สมัครสมาชิก:
ส่งความคิดเห็น (Atom)
ไม่มีความคิดเห็น:
แสดงความคิดเห็น