NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.
Microcontroller Programming » Software PWM (because I need 9 channels)
July 01, 2012 by Hexorg |
Hey everyone! Long time no seeing! Sorry I haven't been with you guys, I've been very busy. On a bright note, I got a bachelors in EE, and I'm now enrolled in a grad school :D Anyway, I'm trying to program a software PWM, because I need to control 9 PWM channels. For now let's just try to make one channel work. I figured I'd use a timer in normal mode with an overflow interrupt to calculate PWM routine. So I have two variables - volatile uint8_t counter, and volatile uint8_t pwm1; In the interrupt routine I check if counter is smaller then pwm1, and if it is, then I set a pin HIGH, otherwise - LOW. Afterwards, if the counter equals to 255, I set it to 0, otherwise I increment it. Sounds not too hard... But I can't seem to get anything working. Here's my code:
Also, Does anyone know the recommended PWM frequency? I tried using clk/8 prescaler, and i get a TON of random blinking. |
---|---|
July 01, 2012 by pcbolt |
Hexorg - First off...congrats on the EE! It looks like the use of LED's might be part of the problem. With no prescaler, the counter variable gets updated 57,600 times per second and gets 'reset' 225 times per second, way too fast for human vision to detect. Even with using 8 as a prescaler, you may not be certain all is working as planned. If you have an O-scope, you could test your output with better precision. I think the best way to improve your code would be to make 'counter' a 16-bit UINT. You could test it against PWM1 and reset it to 0 using two variables and keep the fine resolution of the timer. Just as a side note, you don't have to set 'counter' to 0 when it reaches 255, since it is a uint8_t, it will reset to 0 automatically. |
July 01, 2012 by Hexorg |
pcbolt, "and gets 'reset' 225 times per second" well it sounds reasonable enough, I don't want the eye to detect the LED blink, I want the LED to appear dimmer. |
July 02, 2012 by Hexorg |
Actually I just got the code working, my avr-gcc was messed up. However now, the LED never reaches full brightness. even when I make led1_rch to be uint16_t and set it to 300, theoretically the pin should just stay high, but it doesn't : I'll check it with a scope today, does pin switch everytime there is a PORT change? |
July 02, 2012 by Hexorg |
I did some thinking, and replaced if {} else {} statements in the interrupt with this
Seems to be a little lighter on the logic and that changed the LED to maximum brightness! No sure why, but it did :D |
July 02, 2012 by pcbolt |
Ah...gotcha. I misunderstood the problem. Glad to see you got it to go. I'm told the 'toggle' operator (XOR) or ^ works better if you write 1 to the input port when that port is designated as an output. For example,
This apparently saves a few machine code operations each time. |
Please log in to post a reply.
Did you know that the sparks present in motors can be dangerous for your microcontroller and other electronics? Learn more...
|