PWM with MCU's

Thread Starter

Shagas

Joined May 13, 2013
804
Hello ,

I'm a beginner to Microcontrollers .
I've chosen Atmel AVR and i've been playing with them for a few days now.
Currently using the atmega48

Question #1 :

Why are there special 'modes' for PWM ? Why do I have to activate some 'fast pwm' registers or 'waveform generation mode' or those things ?

Is it not practical to just assign whatever output (PORTB for example) and use PWM using _delay_ms() ?
Edit: Or does "PWM Mode" make things simpler in a way ?


Also , what is meant by a 10 bit PWM ? I'm assuming that it means a duty cycle resolution of about 0.1% hmm?

Thanks in advance for the answers
 

MrChips

Joined Oct 2, 2009
30,802
Sure you can implement PWM with output to a port and time delays.
But what happens when your code has to do something in between outputs?
Your PWM timing is going to get messed up and will not be very stable.

That is what PWM timer modes are for. The timer hardware takes care of generating consistent and stable time delays while the code can go off and do something else.

10-bit PWM means that the timer register is 10 bits wide. It can count from 0 to 1023.
Yes, that means that your PWM signal can be adjusted to a resolution of 0.1%.
 

Thread Starter

Shagas

Joined May 13, 2013
804
Okay , makes sense.

So while i'm running other code my timer independantly generates PWM . But i'm assuming that the timer itself generates a fixed PWM for example say 50% duty cycle at 1khz. So if I want to change that I have to wait until the micro finishes executing whatever other stuff it's doing , and then update the PWM by sending data to the PWM hardware
am I right?

Thanks for the answer MRchips
 

Papabravo

Joined Feb 24, 2006
21,225
Okay , makes sense.

So while i'm running other code my timer independantly generates PWM . But i'm assuming that the timer itself generates a fixed PWM for example say 50% duty cycle at 1khz. So if I want to change that I have to wait until the micro finishes executing whatever other stuff it's doing , and then update the PWM by sending data to the PWM hardware
am I right?

Thanks for the answer MRchips
No wrong. You can start, stop, and update the registers at any time. The results will be appropriate to the situation. If you want to change things in an organized, instead of a random way, then you can arrange to do things when certain conditions are all true.
 

MrChips

Joined Oct 2, 2009
30,802
A properly designed mcu based control system would be interrupt driven. That is, internal or external input can interrupt the normal flow of program code and the PWM registers can be updated instantly.

For example, a robotic arm may employ a DC servo motor driven by a PWM signal. The mcu controller would have to update the PWM register continuously on the fly in order to effect smooth motion, at the same time while taking care of other tasks.
 

Thread Starter

Shagas

Joined May 13, 2013
804
So basically , lets say I want to update my pwm every 10 counts of the timer , then I would set up the timer to interrupt the MCU , stopping whatever it's doing , update the registers , and then continue the code until the next interrupt?
 

MrChips

Joined Oct 2, 2009
30,802
That's all there is to it.

Also, since the PWM is already periodic, you can use the PWM register to interrupt on the start of every cycle.
 

Thread Starter

Shagas

Joined May 13, 2013
804
Ok thanks , I think I am beginning to understand one of the 20 things that I don't understand in Microcontrollers :)
 

Thread Starter

Shagas

Joined May 13, 2013
804
Well my next question is a bunch of code that is giving me 6 errors upon attempt to compile. Basically it's a 'nightrider' (or whatever the internet calls it nowadays) thingy which flashed LEDs from LED0 to LED7 and then back in a sequential order . The only modification is that I have 2 buttons which manually change the direction of flashing .

There is a left button and a right button . If the pattern is progressing to the right and I press the left button , then it changes direction to the left starting from the led that was active when I pressed the button . If I press the right button while it's travelling right then nothing happens .
Vice versa for the other side.

Rich (BB code):
#include <avr/io.h>
#include <util/delay.h>

int x=0;
int y=0;

int roamleft(int x);
int roamright(int y);


DDRB = 0b11111111;
DDRD = 0b00000011;

PORTD = 1<<PIND2 | 1<< PIND3;
	


int main(void)
{
   
   	

	
   	while(1)
   	{
	
		x = roamright(y); // flash to the right  sequentially from LED Y to LED 7
		y = roamleft(x);  // flash  to the left   sequentially from LED X to LED 0
		  	   
    }
	
	   	
}

int roamright(y)
{ 
	for(x=y;x<8;x++)    // cycles through the LED ports
	{
	PORTB = 1 << x;     // Flash the led
	_delay_ms(100);     // delay before flashing next led
	PORTB = 0;          // Turn LED port off
	if(bit_is_clear(PIND,2))   // Test if button pressed
	{
		return x;             //break the cycle and call 'roamleft' carrying in the value that the led stopped at.
	}
	
	}
	
	return x;                 // if button is not pressed , then x=7 will be carried into 'roamleft' so it starts to flash to the left sequentially starting from LED 7
	
		
		
}

int  roamleft(x)
	{
		

	for(y=x;y>=0;y--)
	
	{
		
	PORTB = 1 << y;
	_delay_ms(100);
	PORTB = 0;
	
	if(bit_is_clear(PIND,3))
	{
		return y;
	}
	
	
	}
	 return y;
	
}
Can someone just skim through that and tell me if there are any coarse syntax errors or whatever that cannot be done the way I did it , i'd appreciate it.
I'm using Atmel studio 6. It tells me I have 6 errors but It doesn't show me where they are.
Thanks in advance

Edit:
I've had some experience in C++ and java in the past but some things confuse me here.
Why do I see functions declared in some tutorials and others just omit it? Does it depend on the compiler or something?
 
Last edited:
Top