Monday, August 30, 2021

ATMega16 Timer/Counter0 CTC Mode


Introduction

Another feature of ATMega16 AVR microcontroller Timer/Counter0 peripheral is its Clear Timer on Compare Match (CTC) Mode. In this case the controller can only generate a square wave output on its OC0 output pin.

Simulation Sample

Its free running Timer/Counter0 Register (TCNT0) starts count until it reaches the value of the Output Compare Register (OCR0). At comparison matching the TOP, the TOV0 flag is set. Output logic change at OC0 pin is selected using software – set, clear, toggle, and disconnect.

ATMega16 Timer/Counter0 CTC Mode
Timing Diagram for CTC mode of Timer/Counter0

Assigning WGM01 of Waveform Generation Mode Bit of TCCR0 register to 1, put Timer/Counter0 to operate in Clear Timer on Compare Match (CTC) mode.


ATMega16 Timer/Counter0 CTC Mode

CTC is Mode 2 by setting WGM01 of TCCR0


 To generate square wave output at OC0, the software must set the Output Compare Mode bit in non-PWM mode to toggle OC0 pin at compare match.

ATMega16 Timer/Counter0 CTC Mode
Output Compare Mode bit in non-PWM mode

Output Compare Register (OCR0) is a reference value for TCNT0. It’s changeable during run-time to change the output square wave’s frequency. Device’s datasheet states the formula of finding the frequency of square wave output as below,

ATMega16 Timer/Counter0 CTC Mode
N is prescaler factor 1, 8, 64, 256, or 1024

 

When the OCR0 register is set to 0 the maximum frequency of output waveform is haft of microcontroller clock.

ATMega16 Coding Using AVR GCC

Embedded controller’s program generates an output waveform at OC0 pin as square wave with a determined frequency. Software setting puts Timer/Counter0 module of this AVR device to work in CTC mode as we have described above.


We select CTC mode with its clock prescaler of 256, and OCR0 = 50. Then the output frequency of waveform at OC0 pin is,

ATMega16 Timer/Counter0 CTC Mode
Calculation for output frequency

Without sophisticated laboratory equipment – oscilloscope, I test this microcontroller program in Proteus simulator.

ATMega16 Timer/Counter0 CTC Mode
Simulation in Proteus – The output frequency is 613Hz in software

 AVR GCC coding is done in Atmel Studio 7 as a preferred IDE.

  1. /*
  2.  * m16_timer_0_ctc.c
  3.  *
  4.  * Created: 12/15/2020 11:00:35 AM
  5.  * Author : admin
  6.  */
  7.  
  8. #include <avr/io.h>
  9.  
  10.  
  11. int main(void)
  12. {
  13. /*CTC Mode, With 1:256 Prescaler*/
  14. TCCR0=(1<<WGM01)|(1<<COM00)|(1<<CS02);
  15. /*Set a preferred value of OCR0*/
  16. OCR0=50;
  17. /*OC0/PB3 Square Wave Output*/
  18. DDRB=(1<<3);
  19. /*Main Program Loop Stays Here*/
  20. while (1)
  21. {
  22. }
  23. }

Click here to download zip file of this AVR tutorial.

A Program to Create a 50Hz Frequency

Since Output Compare Register (OCR0) used for adjusting the frequency of output waveform in this mode, we can find its actual value to create a preferred frequency.

To get a lower 50Hz frequency we need to scale timer input to 1:1024 ( N=1024). With an equation stated by device’s manufacturer, we can find the value of OCR0 as follow,

ATMega16 Timer/Counter0 CTC Mode
Equation to find a 50Hz frequency

So in software embedded C we must set CS02=1 and CS00=1, and OCR0=155.

  1. /*
  2.  * m16_ctc_50Hz.c
  3.  *
  4.  * Created: 12/15/2020 5:48:40 PM
  5.  * Author : admin
  6.  */
  7.  
  8. #include <avr/io.h>
  9.  
  10.  
  11. int main(void)
  12. {
  13. /*CTC Mode, With 1:1024 Prescaler*/
  14. TCCR0=(1<<WGM01)|(1<<COM00)|(1<<CS02)|(1<<CS00);
  15. /*Set a preferred value of OCR0 to get
  16.   a 50Hz waveform*/
  17. OCR0=155;
  18. /*OC0/PB3 Square Wave Output*/
  19. DDRB=(1<<3);
  20. /*Main Program Loop Stays Here*/
  21. while (1)
  22. {
  23. }
  24. }

This embedded program is simulated in Proteus simulator. 

ATMega16 Timer/Counter0 CTC Mode
Simulation result in Proteus

ATMega16 Timer/Counter0 Compare Output Mode

 

Introduction

Compare Output Mode of Timer/Counter0 is also calls waveform generation. It’s different from normal mode, CTC, and PWM mode.

 

ATMega16 Timer/Counter0 Compare Output Mode

We can use this mode to create a waveform in a form of toggling , set, and clear OC0 pin on compare match. However it’s just like a normal timer mode but it’s additionally able to trigger an output at OC0 pin. Toggling OC0 at compare match is just a square wave output with a programmable frequency.

Programming

Waveform generation mode is selected by Compare Output Mode bit for non-PWM mode of the Timer/Counter Control Register (TCCR0).

ATMega16 Timer/Counter0 Compare Output Mode
Compare Output Mode bit of TCCR0

Within this example I program the ATMega16 to toggle OC0 on compare match. Crystal frequency of microcontroller is 16MHz with its clock select bit of 1:1024. Hence the toggling output occurs for every,

ATMega16 Timer/Counter0 Compare Output Mode
Equation to find the toggling time of waveform generation



 We can find the frequency of square wave output as,

ATMega16 Timer/Counter0 Compare Output Mode
Equation to find waveform generation frequency

 Finally the microcontroller program coded to toggle OC0 output with a frequency of 30.52Hz.

  1. /*
  2.  * timerCounter0_CompareOutputMode.c
  3.  *
  4.  * Created: 12/14/2020 10:36:58 PM
  5.  * Author : admin
  6.  */
  7.  
  8. #include <avr/io.h>
  9.  
  10. int main(void)
  11. {
  12. /*CTC Mode, Toggle OC0, 1:1024 Prescaler*/
  13. TCCR0=(1<<COM00)|(1<<CS02)|(1<<CS00);
  14. /*OC0 Output*/
  15. DDRB=(1<<3);
  16. while (1)
  17. {
  18. }
  19. }

Let see the hardware simulation in Proteus.

ATMega16 Timer/Counter0 Compare Output Mode
Proteus simulation for waveform generation

Click here to download zip file for this working example.

Wednesday, August 25, 2021

ATMega16 Timer/Counter0 Phase Correct PWM

 

Introduction

In previous post we demonstrate how to program for fast PWM waveform creates by Timer/Counter0 peripheral module. Beside of fast PWM waveform generation, Timer/Counter0 offers another more precise PWM mode – phase correct PWM.

ATMega16 Timer/Counter0 Phase Correct PWM

Phase Correct PWM Mode

As mentioned in previous post, fast PWM mode waveform has only 8-bit counting register. However a phase correct PWM offer a higher resolution as twice compares to fast PWM mode. This mode is preferred for a precise motor control application.

Operation Of Phase Correct PWM



A high resolution of waveform generation of this mode make by a two-direction countering of Timer/Counter0 register (TCNT0).

ATMega16 Timer/Counter0 Phase Correct PWM
Timing diagram of phase correct PWM mode from device’s datasheet
OC0 flag is set for both counting direction, TCNT0 up counting reaches MAX and TCNT0 down counting reaches BOTTOM.

Waveform generation of this PWM mode has two polarities – non-inverting and inverting output at OC0 pin. A non-inverting waveform generation occurs when up counting (BOTTOM to MAX) that TCNT0 compares with OCR0, and clear OC0 flag at compare match . OC0 flag is set when down counting (MAX to BOTTOM), and it’s clear at compare match.

An inverting phase correct PWM waveform generation its operation is inverse. These two type of waveform creation selected in Timer Control Register (TCCR0).

We can find its output frequency as follow,

ATMega16 Timer/Counter0 Phase Correct PWM
Phase correct PWM output frequency’s equation

Interfacing And Programming

It’s similar to fast PWM mode programming in previous post. However it’s different in register setting and its output frequency. I keep the hardware schematic and connection the same to the previous one’s.

Hardware Interfacing

There’s no change in hardware connection for this tutorial, as it’s already worked in previous tutorial for fast PWM mode.

ATMega16 Timer/Counter0 Phase Correct PWM
Circuit Diagram

ATMega16 supplies at +5V, clocks at 16MHz DC. The odd one’s is its output frequency at OC0/PB3 pin of Port B.



Registers Setting

There are some bits setting in Timer/Counter Control Register (TCCR0).

ATMega16 Timer/Counter0 Phase Correct PWM
Timer/Counter0 Control Register (TCCR0)

In the Waveform Generation Mode Bit, the software must set the WGM00 to force Timer/Counter0 works in phase correct PWM mode.

ATMega16 Timer/Counter0 Phase Correct PWM
Waveform Generation Mode Bit

Output Compare Register (OCR0) is also limit duty cycle of PWM waveform in this mode. Beside crystal oscillator frequency of microcontroller, Clock Select Bit define the PWM output frequency.

ATMega16 Timer/Counter0 Phase Correct PWM
Clock Select Bit of Timer/Counter0 Control Register (TCCR0)

 Polarity of waveform for this PWM mode is selected in Compare Output Mode bit.

ATMega16 Timer/Counter0 Phase Correct PWM
Compare Output Mode for Phase Correct PWM

In this tutorial I preferred a non-inverting phase correct PWM mode. Thus COM01 must be putted to ‘1’.



AVR GCC Programming for Phase Correct PWM

In this tutorial, the microcontroller generate a PWM waveform with a frequency of 122.54Hz. Since microcontroller clock is 16MHz, I set Clock Select Bit to 1:256. Phase correct PWM output frequency is calculated by,

ATMega16 Timer/Counter0 Phase Correct PWM
Calculation for frequency in phase correct PWM mode

To get a 1:256 clock prescaler, the software must set CS02=1. AVR GCC of this minor example is written in Atmel Studio 7 IDE.

  1. /*
  2.  * m16_phaseCorrectPwm.c
  3.  *
  4.  * Created: 12/14/2020 10:15:22 AM
  5.  * Author : admin
  6.  */
  7.  
  8. #include <avr/io.h>
  9.  
  10. int main(void)
  11. {
  12. /*phase correct PWM mode, Non-inverting,
  13.   1:256 Prescaler*/
  14. TCCR0=(1<<WGM00)|(1<<COM01)|(1<<CS02);
  15. /*Set duty cycle to 50%*/
  16. OCR0=127;
  17. /*OC0 outputs PWM waveform*/
  18. DDRB=(1<<3);
  19. /*Main loop do nothing*/
  20. while (1)
  21. {
  22. }
  23. }

We can see the result in Proteus simulator below.

ATMega16 Timer/Counter0 Phase Correct PWM
Simulation result in Proteus simulator

 The output frequency is 122Hz. However we can create a lower frequency using this PWM mode. Click here to download zip file of this working tutorial.

Adjusting Its Duty Cycle

Since Output Compare Register (OCR0) is changeable during run-time, the user can modify its duty cycle of phase correct PWM waveform using this register.



Adding Two Adjusting Buttons

We use two user’s input push button to increase and decrease duty cycle of phase correct PWM waveform. These two buttons change the duty cycle of PWM waveform with a rate of 15.

A button connects to PD2 decrease duty cycle while another one’s connects to PD3 increase its duty cycle.

ATMega16 Timer/Counter0 Phase Correct PWM
Proteus simulation of adjusting duty cycle of phase correct PWM mode

Its frequency remains 122Hz. It excepts its variable duty cycle of waveform.

AVR GCC Source Code



There are some additional lines of code to handle input button events. Main program loop keeps track of input changes of these two buttons, connect to PD2 and PD3.

  1. /*
  2.  * m16_phaseCorrectPwm_btn.c
  3.  *
  4.  * Created: 12/14/2020 10:33:50 AM
  5.  * Author : admin
  6.  */
  7.  
  8. #include <avr/io.h>
  9.  
  10. /*Buttons to change PWM duty cycle*/
  11. #define lower ((PIND&0x04)==0)
  12. #define higher ((PIND&0x08)==0)
  13.  
  14. int main(void)
  15. {
  16. /*phase correct PWM mode, Non-inverting,
  17.   1:256 Prescaler*/
  18. TCCR0=(1<<WGM00)|(1<<COM01)|(1<<CS02);
  19. /*Zero duty cycle*/
  20. OCR0=0;
  21. /*OC0 Pin Output*/
  22. DDRB=(1<<3);
  23. /*PD2 and PD3 as input*/
  24. DDRD&=(1<<2);
  25. DDRD&=(1<<3);
  26. /*Turn PD2 and PD3 High*/
  27. PORTD=(1<<3)|(1<<2);
  28. while (1)
  29. {
  30. /*Decreasing PWM Duty Cycle*/
  31. if (lower)
  32. {
  33. /*Wait Until PD2 released*/
  34. while(lower);
  35. /*Decrease Duty Cycle By 15*/
  36. if(OCR0>0) OCR0-=15;
  37. }
  38. /*Increasing PWM Duty Cycle*/
  39. if (higher)
  40. {
  41. /*Wait Until PD3 released*/
  42. while(higher);
  43. /*Increase Duty Cycle By 15*/
  44. if(OCR0<250) OCR0+=15;
  45. }
  46. }
  47. }
  48.  
  49.  

There’s no need to test this program on AVR development board due to duplication, as a similar work was already done in previous article. Click here to download zip file of this working example.



Labels

ADC (10) Analog (14) Arduino (12) Atmega16 (19) Audio (2) AVR (20) Charger (1) Cortex-M0 (1) Counter (10) CPLD (25) Digital I/O (22) Display (34) EEPROM (2) Environment Sensor (1) esp8266 (2) Experiment Board (10) I2C (4) Interrupt (7) LCD (1) LDmicro (29) measurement and instrumentation (7) Microchip Studio (3) MikroC (1) One-Shot (3) OpAmp (1) PCB (31) PIC16 Microcontrollers (16) PIC16F877A (2) PIC16F887 MikroC (22) PLC (35) PWM (11) Regulator (1) RTC (2) Sensor (8) Shift Registers (5) SPI (5) Timer (34) UART (2) ultra-sonic sensor (1) USB (1) VHDL (21) xc8 (1) XC95108 (9) XC9536 (15) XC9572 (1) Xilinx (23) Xilinx ISE (22)