AVR ATMEGA328P Startup PWM - Page 1
Forum section: electronics / general

author: CM800
author_rank: Frequent Contributor
timestamp: August 19, 2015, 09:10:39 am
content: When I turn on my chip, the pwm seems to have issues, likely due to the chip starting up, but is there any way I can detect when it is ready and then begin the PWM? (flickery PWM is far more dangerous that no PWM in my application)When I supply power to the chip I get several flickers changing the PWM on the chip, along side that, the entire pwm goes on and off (like toggling the connection to the scope with a switch)This really doesn't do as I am using the PWM to provide signals to the gate drivers of some very powerful (not to mention expensive IGBTs in a high voltage application. (I have additional circuitary in mind for safety and fault prevention / safe faliure)

author: Dago
author_rank: Frequent Contributor
timestamp: August 19, 2015, 10:24:34 am
content: What type of "flickers" or "issues"? How long after startup?It is not supposed to flicker or have issues even right after start-up, so my guess is that you are enabling the PWM output before the PWM-timer (or something else like the clock system on the MCU) has been fully configured. Or maybe the registers are not properly reset on boot, maybe try to set all of them to a known state before turning on the PWM.

author: Psi
author_rank: Super Contributor
timestamp: August 19, 2015, 10:40:36 am
content: +1 for something in code, like enabling the PWM output andthensetting up all its registers

author: rollatorwieltje
author_rank: Unknown
timestamp: August 19, 2015, 10:54:26 am
content: Are you sure it's not caused by the pins being floating inputs after reset until they are configured? If you drive stuff like FETs (or anything else that doesn't like floating input) you should pretty much always use external pullup or pulldown resistors.

author: CM800
author_rank: Frequent Contributor
timestamp: August 19, 2015, 12:20:01 pm
content: Looking at it further, it seems this only happens with my Analogue input -> PWM out code, the UART ->PWM doesn't have this issue, it's probibly the ADC code then?here is said code:Code:* A PWM example for the ATmega328P using the 8-Bit Fast PWM mode.*/#include <avr/io.h>#include <avr/interrupt.h>#include <stdbool.h>#include <util/delay.h>#define F_CPU 16000000ULint main (void) {//PWM SET UPDDRB |= _BV(PB1) | _BV(PB2);TCCR1A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM20);TCCR1B = _BV(CS20);//ADC SET UPADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);ADMUX |= (1 << REFS0);ADMUX |= (1 << ADLAR);ADCSRA |= (1 << ADEN);ADCSRA |= (1 << ADSC);ADCSRA |= (1 << ADATE);for(;;){OCR1A = ADCH*0.47;OCR1B = 0xff - ADCH*0.47;}}

author: Psi
author_rank: Super Contributor
timestamp: August 19, 2015, 12:24:47 pm
content: Ignore the first few adc samples after you enable the ADC. they aren't valid.There is more about this in the datasheet.

author: madires
author_rank: Super Contributor
timestamp: August 19, 2015, 12:51:14 pm
content: Another issue the startup time of the oscillator. Since you've set 16MHz in the source code I assume that you have an external crystal. The worst case number of required cycles for a stable clock is 16384 for an external crystal. Based on the fuse settings that number could decrease to 1024 or 256. The internal RC oscillator has the shortest startup time (6 cycles).

author: Brutte
author_rank: Frequent Contributor
timestamp: August 19, 2015, 03:46:35 pm
content: Code:TCCR1A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM20);TCCR1B = _BV(CS20);That is setting TCNT2 flags in TCNT1 register.

author: FreddyVictor
author_rank: Regular Contributor
timestamp: August 19, 2015, 04:05:59 pm
content: just a minor point regarding the line:#define F_CPU 16000000ULif using AVR Studio 4.x, setting the Frequency in the 'Project Options' does this for you (but in 5 & 6 this isn't the case) so no need for this lineif you are are going to use this line, then it needs to be put before the line:#include <util/delay.h>

author: Quarlo Klobrigney
author_rank: Super Contributor
timestamp: August 20, 2015, 10:45:00 pm
content: The last thing I set is the Clock Divider bits. This ensures that the timer cannot run until it is set. Even for CLK ÷ 1.I guess you could wait till everything settles down and then enable the Clock.The way I notate is not with the _BV macro but like this TCCR1B |= (1<<CS20) A straight = would be an overwrite of all the bits and not just setting them. To clear them it's &= and not (0<<CS10).The Freaks will like you better if you do it this way."That is setting TCNT2 flags in TCNT1 register." You are right It should be TCCR1B |= (1<<CS10).TCCR1A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM20); Also the wrong bits for the register.

author: CM800
author_rank: Frequent Contributor
timestamp: August 21, 2015, 02:53:52 pm
content: Alright then, thanks for all your help. I will give these a try when I get back home.