728x90

728x90

Sunday, May 24, 2020

Using timer 0 interrupt to create a PWM signal controlling a DC Motor

With the interrupt feature, we can create a fast PWM waveform. It produce a smother timing signal than using a pure delay function. But it is rougher than using a built-in PWM module of microcontroller.

Using timer 0 interrupt to create a PWM signal controlling a DC Motor
Schematic diagram. The CPU runs at 4 MHz. PC0 outputs a PWM signal to adjust the
speed of DC motor. PWM generated by a timer tick of timer 0 interrupt. SW3 decrease
the duty cycle of PWM. SW1 set the duty cycle to zero. SW2 increase the duty cycle,
speed up the DC motor.

In this example, I set the prescaler to 1:8. Since the CPU clock is 4 MHz, giving a 250 nano seconds period. With a 1:8 prescaler, timer 0 increase for every 8 x 250 nano seconds = 2 micro seconds.

At the timer 0 interrupt point, I want to trigger it at every 10 micro seconds. To get a 10 micro second timer tick, let (0.000010 second)/(0.000002 second) = 5. So, at the interrupt TCNT0 must be loaded with 256 - 5 = 251 or -5.

Source code's here.
#include <avr/io.h>
#include "avr/interrupt.h"
//A variable to count every 2 uS
unsigned int cnt=0;
unsigned char hTime=0;
#define speedUp (PIND&0x80)
#define stopPWM (PIND&0x40)
#define speedDw (PIND&0x20)
void myPWM(){
 if (speedUp==0)
 {
  if(hTime<95)
  hTime+=5;
  while(speedUp==0);
 }
 if (stopPWM==0)
 {
  hTime=0;
  while(stopPWM==0);
 }
  if (speedDw==0)
 {
  if(hTime>0) 
   hTime-=5;
  while(speedDw==0);
 }
 if (cnt<hTime)
 {   PORTC|=(1<<0);
 }
 else if(cnt>hTime){
  PORTC&=~(1<<0);
 }
 if(cnt>100) cnt=0;
}
int main(void)
{
 //Set PB0 to Output
 DDRC=0x01;
 //Clear PortC
 PORTC=0x00;
 //Set PD7, PD6 and PD5 to output
 DDRD=0x1F;
 //set PD7, PD6 and PD5 High
 PORTD=0xE0;
 //Set 1:8 pre-scaler
 TCCR0=0x02;
 //Clear overflow flag
 TIFR=0x01;
 //Enable Timer 0 interrupt
 TIMSK=0x01;
 //set global interrupt
 sei();
 while (1)
 {
  myPWM();
 }
}
ISR(TIMER0_OVF_vect){
 //Load -5 to make 10 uS interrupt time
 TCNT0=-5;
 cnt+=1;  TIFR=0x01;
}

I took a simulation screen shot.

Using timer 0 interrupt to create a PWM signal controlling a DC Motor
A Simulation screen shot.
PC0 create a PWM signal output with a period 1.5 milli seconds.
The PWM frequency is 666 Hz. 

Back to main tutorial page ATMega32 tutorials in C with Atmel Studio 7.



No comments:

Post a Comment

320x50

Search This Blog

tyro-728x90