In continuation of the embedded control applications explained in Part 2, let’s now examine the use of inbuilt functions of AVR ATmega8535 (such as output compare, ADC and UART) for various applications.
PWM operation of ATmega8535
When the AVR is configured for pulse-width modulated (PWM) operation, the PWM outputs become available at output-compare pins 18 (OC1A) and 19 (OC1B) of ATmega8535. PWM, in conjunction with an analogue filter, can be used to generate analogue output signals and thus it serves as a digital-to-analogue converter.
Principle of pulse-width modulation. To generate different analogue levels, the duty cycle and thereby the pulse-width of the digital signal (base frequency) is changed. If a high analogue level is needed, the pulse width is increased and vice versa (see Figs 15 and 16).
A digital pulse train with a constant period (fixed base frequency) is used as the basis. The base frequency, which can be programmed suitably, should be much higher than the frequency of the output analogue signal obtained after filtering out the base frequency component. For example, to generate a sinewave signal of low frequency (say, 10 Hz, as used for drives or controls), the base frequency of rectangular pulses (with varying duty cycle) may be of the order of 1 kHz or more.
Pulse generation method. The scheme for pulse generation is as follows: Timer/counter 1 is used to count clock ticks. If 8-bit PWM is selected, after the timer counts up to ‘255,’ its count is decremented with each clock tick. Thus, the number increases up to ‘255’ and then decreases, resembling a triangular pattern.
When the number stored in the output-compare register (OCR) matches the loaded count value, pin 19 (output-compare action pin) becomes high or low, as programmed. For example, if the OCR is loaded with a value of ‘l00,’ the logic state of OCR pin will be:
Count value OCR pin
0 to 100 Low logic
100 to 255 High logic
255 to 100 High logic
100 to 0 Low logic
Thus, for the total time taken to count 255×2=510 clock ticks, the output pin (pin 19) will be high for (2×155)/(2×256) or 60.5 per cent of the total triangular wave time of one PWM pulse (or the PWM pulse will have a duty cycle of 60.5 per cent). Thus, effectively the voltage transmitted in this period is 60.5 per cent of the maximum, because the pulse is high only for this period of time.
The following program (avrsine.asm) will generate a 1Hz sine wave (after filtering) on pin 19 using PWM:
; File: avrsine.asm
; Description: Example of how to use the fast PWM
; of the Avr to generate “sine-wave” signal. The PWM
; output requires filtering to shape the sine wave
;Interrupt vector table
.org OVF1Addr ;OC1Aaddr
; Interrupt vector for timer1 output compare match A
; Load low byte address of end
of RAM into register R16
; Initialize stack pointer to end of internal RAM
; Load high byte address of end of RAM into
out SPH, R16
; Initialize high byte of stack pointer to end of
ldi r16, (1<
out DDRd, r16 ;since that is the PWM
output pin 19
;SELECT CLOCK SOURCE VIA TCCR1B
;8 BIT PWM NON-INV.
; Set PWM mode: toggle OC1A on compare
out TCCR1A, r16
; Enable PWM
ldi r16, 0xFF
; Set PWM top value: OCR1C = 0xFF
out OCR1AL, r16
OUT OCR1AH, R16
; Enable Timer/Set PWM clock prescaler
OUT TCCR1B,R16 ;ck/8 as pwm clock
(1MHz/8 = 125 kHz)
ldi r16, (1<
out TIMSK, r16
; Enable global interrupts
ldi r16, (1<
out MCUCR, r16
ldi ZH, high(sine_table*2)
; Set up Z to point to the beginning of
ldi ZL, low(sine_table*2)
add ZL, r17
; Offset Z by r18:r17
adc ZH, r18
; Load sine_table[Z] into OCR1A
out OCR1AL, r0
sine_table: ; 256 values
For observation of the sine wave on an oscilloscope, use a low-pass filter comprising a 1-kilo-ohm resistor (series element) and a 1µF capacitor (shunt element). However, with an analogue multimeter, the sine wave can be directly observed at pin 19.
In the avrsine.asm program, for each of the triangle wave periods, we read a table of sine values (multiplied by ‘256’) and load these values one by one into the OCR. Since the values vary in a sinusoidal pattern, the pulses that come out are also pulse-width modulated as per these values (see the oscilloscope pattern shown in Fig. 16).
To do the table look-up (as given in the example program ‘LCD Table.ASM’ of Part 1), the LPM instruction is used. The Z register is used as an indirect indexed register. As stated earlier, the LPM instruction fetches from the table one byte into r0. The actual loading of the OCR value is done by the instruction:
[stextbox id=”grey”]out OCR1AL, r0[/stextbox]
where OCR1AL refers to pin 19. (OCR1BL refers to pin 18, which is not used here.)