Get Adobe Flash player
FacebookTwitterGoogle+
English Arabic French German Italian Portuguese Russian Spanish

Did you know?

An electric oven uses one kilowatt-hour of electricity in about 20 minutes, but one kilowatt-hour will power a TV for 3 hours, run a 100-watt bulb for 12 hours, and keep an electric clock ticking for 3 months.
 

Help us stay online:

small donate

pwmUsing PWM with microcontroller is often needed in projects. Whether you want fine control of electromotor speed, or you want to change intensity of LED lamp or you simply need analog output and do not want to buy expensive Digital/Analog converter (DAC), PWM is ideal solution. In this example we will show how to configure and change parameters of PWM output on AVR microcontroller.

 

 

There are many ways how to create PWM signal on AVR microcontroller. You can use simple software loops in main function. This is not good solution since it is dependable on execution time of other functions in main and this will effect effective duty ratio. There are applications that control processes that are very inertial so this presents no problem. Example for this is control of heater for temperature regulation in some casing. Heater  frequency of PWM is on the order of seconds.
For most other applications duty ratio of PWM is critical along with frequency. In these cases it is important to use PWM generated by interrupt of dedicated module or timer. More about PWM can be read at Pulse Width Modulation (PWM) article.

ATmega8535 has several timers that can be used for this purpose. We used Timer 1 module.

Let’s make project!

Open Codevision and create project using settings from pictures below:
AVR chip configurationAVR UART baud rate configurationAVR Timer 1 PWM usage setting
Codevision will generate code that will initialize few registers that are assigned to Timer 1.
These registers are:

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Ph. correct PWM top=00FFh
// OC1A output: Non-Inv.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Rising Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x81;
TCCR1B=0x02;
TCNT1H=0x00;
TCNT1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

This will initialize Timer 1 to work in Ph. correct PWM top=00FFh mode and enable OC1A output as Non-Inverting PWM output.
Main function for this example is extremely simple. We just take one byte from serial port on 9600 baud rate and put value in OCR1A register. Here is While(1) part of main code:

while (1)
      {
      OCR1A = getchar();
      };

Usage of UART module is explained in previous examples.
We will change duty ratio from 0-100% in 255 discrete steps. For sending data we will use COM port terminal - development tool.
For sending value 0-255 for duty ratio we send data formatted as decimal using #xxx, where xxx is number 0-255. Here is a snapshot of what we sent:

terminal1

 

terminal2

 

terminal3

And here is video of recorded PWM output for OCR1A values of 0,5,128,251,255 and we can see duty cycle changing from 0% to 100%.

More details about specific registers used will be found in PDF below.