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.
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