Home ==> Micro beginner ==> 5. LED with PWM

Lecture 5: To control the intensity of a LED via PWM

So far we used blinkling of a LED. Now we continue blinking, but with a high frequency. With that blinking we change the intensity from weak to high. And this in an exact linear manner and not with a non-linear current.

5.0 Overview

  1. Introduction to the PWM mode of the timer
  2. Hardware, components, mounting
  3. Timer in fast PWM mode
  4. Timer in phase-correct PWM mode

5.1 Introduction to the PWM mode of the timer

5.1.1 8 bit PWM

Pulse width modulation PWM means pulse width modulation. To do this the timer, on restarting, sets or clears an output (OC0A and/or OC0B). If a compare match occurs (A or B) the polarity of the output changes (clear, set). By reaching the largest value the polarity of the output again changes and the cycle starts again.

PWM motor driver The later the compare match occurs within the whole cycle the longer gets the first phase and the shorter gets the second phase. This behaviour allows to control the power of a DC motor as well as the intensity of LEDs. Please note that during the ON period the transistor drives the motor with maximum available power and that only the duration is limited. So the motor power is really linear.

Fast PWM output A control The bits COM0A1 and COM0A0 in the TCCR0A port determine, how the output behaves. With 0b10 the output is set at the beginning of the PWM cycle, with 0b11 it is cleared. Similar to this COM0B1 and COM0B0 in the same port control the output pin OC0B.

Fast PWM example This shows how the voltage on the output OC0A changes in Fast PWM mode with TOP at 255 and a compare match at 100. The resulting pulse width is 100 / 256 = 39% high.

Within the Fast PWM mode the selection of the timer prescaler determines the PWM's frequency. At the different clock frequencies and prescaler values the following frequencies result and offer a wide range.
9.6 Mcs/s37.5 kcs/s4.69 kcs/s586 cs/s146.5 cs/s36,6 cs/s
4.8 Mcs/s18.8 kcs/s2.35 kcs/s293 cs/s73.3 cs/s18.3 cs/s
2.4 Mcs/s9.4 kcs/s1.68 kcs/s147 cs/s36.7 cs/s9.15 cs/s
1.2 Mcs/s4.69 kcs/s586 cs/s73.2 cs/s18.3 cs/s4.6 cs/s
128 kcs/s500 cs/s62.5 cs/s7.8 cs/s1.95 cs/s0.49 cs/s

At 1.2 and 2.4 Mcs/s all PWM frequencies are in an audible range (with motors this can result in incomfortable humming). A clock frequency of 128 kcs/s is inappropriate for that purpose, at a prescaler value of 1,024 we can visually follow the PWM process.

5.1.2 Phase correct 8 bit PWM

Phase correct This is the signal process in the phase-correct mode. The timer counts up- and downwards, each time the compare match is reached the polarity of the output changes. The PWM frequency is half that in Fast PWM mode.

Phase correct PWM mode is used if the compare value changes very often and with large changes. The change of the compare match value is buffered, the changed value comes only into effect when the TOP value has been reached. So there are always two periods (up-counting, down-counting) performed for each compare value. With this, the jitter is strongly reduced.

5.1.3 PWM with different resolution

PWM with CTC It is not always necessary to use 8 bit resolution, with 256 counting steps (0.39% accuracy). In some cases it is sufficient to have only four (6.25%) or five (3.1%) bits resolution of the PWM signal. For a small motor 8 bits might be overdone. If at a count of 16 (four bit resolution) the cycle restarts, the PWM frequency increases accordingly. This can be reached by combining the PWM mode with CTC: In that case compare match port A is used as CTC and compare match B as PWM signal. Those two modes are possible, as the mode table shows.

In case of a 4 bit resolution (Compare Match A = 15), with 1.2 Mcs/s clock and a timer prescaler of 1 the PWM frequency will be at 37.5 kcs/s, well above any audible regions for humans and most wildlife (excluding bats).

In case of 16 bit timers/counters, of which ATtiny13 has none, the normal phase correct PWM mode would have a resolution of 16 bits (accuracy: 0.0015%), which is by far higher than any practical requirements. It is therefore nearly always necessary to reduce the resolution. To relief Compare Match A from this CTC task and allow it to use as additional PWM channel, an additional port (ICR) provides this task.

5.2 Hardware, components and mounting

For the PWM intensity regulation the same hardware is used as for the previous lectures.

Home Top Introduction Hardware Fast PWM Phase correct PWM mode

5.3 Fast PWM mode

With the previous information on functions, properties and methods a PWM intensity regulation can be programmed in a simple way. As PWM cycle frequency we select at 1.2 Mcs/s clock and a prescaler of 1, resulting in 1,200 / 256 = 4.7 kcs/s. This is fast enough for the human eye and for any digital camera.

5.3.1 Source code for Fast PWM

By changing the polarity of the PWM output we reverse the inversion by the LED. The source code is here.

; ***************************************
; * PWM control of a LED in Fast mode   *
; * (C)2017 by www.avr-asm-tutorial.net *
; ***************************************
.INCLUDE "tn13def.inc"
; -------- Register -------------------------
.def rmp = R16 ; multi purpose register
; -------- Program --------------------------
	; Init output pin OC0A
	sbi DDRB,DDB0 ; OC0A as output
	; PWM compare value to timer 0
	ldi rmp,20 * 256 / 100 ; 20% intensity
	out OCR0A,rmp ; to compare match port A
	; Timer 0 in Fast PWM mode, output A low at cycle start
	ldi rmp,(1<<COM0A1)|(1<<COM0A0)|(1<<WGM01)|(1<<WGM00)
	out TCCR0A,rmp ; to timer control port A
	; Start Timer 0 with prescaler = 1
	ldi rmp,1<<CS00 ; Prescaler = 1
	out TCCR0B,rmp ; to timer control port B
	; Enable sleep mode
	ldi rmp,1<<SE ; Sleep enable, mode idle
	out MCUCR,rmp ; to Universal control port
	sleep ; go to sleep
	nop ; in case of wakeup
	rjmp Loop ; again to sleep
; End of source code

One line in this code requires deeper understanding and some background knowledge:

	ldi rmp,20 * 256 / 100 ; 20% intensity

5.3.2 Calculations in assembler

The term 20 * 256 / 100 usually would result in 51.2. Not so in assembler. All mathmatical expressions in assembler are integer operations. That means the result is 51, not 51.2. But even more strange: if we write the term "20 / 100 * 256", which would be - mathmatically spoken - equivalent, the result would be 0. We can test that astounding result by adding the line

; -------- Constants ------------------------
.equ cIntensity = 20 / 100 * 256

and reformulate the above line by

	ldi rmp,cIntensity

If we assemble that changed code using gavrasm and the -s option (note that other assemblers do not provide such a symbol list) we will see the following in the symbol list:
List of symbols:
Type nDef nUsed Decimalval  Hexvalue Name
  T     1     1          18       12 ATTINY13
  L     1     2           9        9 LOOP
  R     1     8          16       10 RMP
  C     1     1           0        0 CINTENSITY
   No macros.
The reason for this is that the assembler ALWAYS a) uses integer math, including interim results, and b) that he always processes expressions from left to right, and c) follows priority rules such as "*" and "/" higher than "+" and "-". So the constant calculation term is processed as follows:
  1. Divide 20 by 100 in integer mode, result = 0 (!)
  2. Multiply result with 250, result = 0 (!)
If you want to overrule the standard processing scheme you'll have use brackets. So the formulation

.equ cIntensity = (20 * 250) / 100

is always more correct as it overrules any priority and processing sequences. See this page for a complete list of mathmatical expressions in assembler. This list is sorted by increasing priority.

5.3.3 LED intensities

The PWM intensity control is rather simple code. And here is the result:
0% 1% 2% 3% 4%
5% 10% 20% 50% 100%

The differences in intensities are clearly visible.

Please note that the PWM cannot be set to 0% intensity because the first clock pulse is always executed. If 0% should be really switching the LED off one has to decouple the output pin from the PWM control and to set the port pin to high level.

Home Top Introduction Hardware Fast PWM Phase correct PWM mode

5.3.4 Simulation of the PWM mode

avr_sim can be used to test the timing characteristics.

Fast PWM init Fast PWM TC init After the 6.67 µs init phase the timer 0 is in Fast PWM mode. The compare value in A is 51, PB0 is cleared on the start and, on compare match, PB0 will be set.

Fast PWM port init That means the LED will be on over the first 51 clock cycles and off for the remaining cycles to 256.

Fast PWM first match Fast PWM simulate first match This is the situation after the first compare match comes into effect (the timer exceeds the compare match value). 42.5 µs are over.

Fast PWM first match port The first match has set the portbit PORTB0, by that switching the LED off.

Fast PWM timer overflow Fast PWM simulate overflow Here, the timer overflowed from 255 to 0 after 212,5 µs (corresponding to a PWM frequency of 1,200 / 256 = 4.7 kHz).

Fast PWM overflow port The overflow has cleared PORTB0, the LED is on again and the PWM cycle restarts.

5.4 Timer in phase correct PWM mode

The phase correct PWM mode is achieved by removing the WGM01 bit in the above source code (WGM01 = 0). Now the PWM works at 2.34 kcs/s. Still fast enough for this application, but a motor might hum in an audible frequency range.

PWM phase correct at TOP PWM phase correct counting down The difference to Fast PWM mode is that the timer, when it reaches TOP at 255, it does not restart but it counts downwards, and it clears PORTB0 only later when the downcount reaches the compare value again during downcount. If we would have changed the compare value in between, which we did not in this simple program, this new compare value would not come into effect immediately but only until TOP has been reached: the compare value is temporarily stored and loaded only at TOP.

That demonstrates how the timer can be used to largely simplify the overhead by the controller: complex up-and-down loops with exact timing and counting are automated, the controller sleeps instead - or can do other things without disturbing counting and timing (as we will see in the next lecture). So whenever you need exact pin switching, use a timer to do the whole work and do not undertake efforts to use loops and counting - this will leave you frustrated, unnecessarily twists your brain and inks your hair in direction to gray. A timer is a clever solution, so you can concentrate on the other tasks that really need your valuable and full attention.

Be aware that timer controlled output pins are generally fixed to certain locations in the output port called OCnA and OCnB. Those pins are sacrosanct and should be banned from other uses, so respect this design constraint with a very high priority.

Home Top Introduction Hardware Fast PWM Phase correct PWM mode

©2017 by http://www.avr-asm-tutorial.net