[英]Creating a 10 second delay using ISR in TIMER1 of atmega328p
我正在嘗試在 atmega328p 中使用 TIMER1(16 位)創建 10 秒延遲,我不知道是否已創建延遲,因為它需要比 10 秒更長的持續時間和預期輸出(即創建 pwm 波) 未獲得。 這里我創建了一個 1 秒的延遲並循環了 10 次,TIMER0 用於創建 pwm 波。
#include <stdint.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include "interrupt.h"
#define SET_BIT(PORT,BIT) PORT |= (1<<BIT)
#define CLR_BIT(PORT,BIT) PORT &= ~(1<<BIT)
struct {
volatile unsigned int BIT: 1;
}
FLAG_TIMER;
void timer_configuration() //16 bit timer
{
TCCR1A = 0x00; // Normal mode of operation
TCNT1 = 0xC2F8;
TCCR1B |= ((1 << CS10) | (1 << CS12));
TCCR1B &= ~(1 << CS11); //101
sei(); // Global interrupt
}
void timer_on()
{
TIMSK1 |= (1 << TOIE1);
}
void pwm_configuration() //TIMER0 - 8 bit
{
TCCR0A |= ((1<<WGM00) | (1<<WGM01)); //setting it to fast PWM mode
TCCR0A |= (1<<COM0A1);
TCCR0A &= ~(1<<COM0A0);
TCNT0 = 0x00;
TCCR0B |= ((1<<CS00) | (1<<CS02)); //Prescaler setting 1024
TCCR0B &= ~(1<<CS01);
sei();
}
ISR(TIMER1_OVF_vect)
{
static unsigned int counter;
counter++;
if(counter >= 10)
{
FLAG_TIMER.BIT=1;
counter = 0;
TCNT1 = 0xC2F8;
TIMSK &= ~(1<< TOIE1);
}
else
{
FLAG_TIMER.BIT=0;
}
}
int main(void)
{
SET_BIT(DDRD,PD6); //CRO
timer_configuration();
pwm_configuration();
while(1)
{
timer_on();
if(FLAG_TIMER.BIT == 1)
{
OCR0A = 128; //50% dutycycle
}
}
您在初始化時將計數器設置為 49912,並在溢出時增加計數,但它會從 0 開始,因此如果 15624 計數 = 1 秒,那么您的計數器將在 15624 + 9 x 2 16計數或大約 38.75 后增加到 10秒。
移動TCNT1 = 0xC2F8;
ISR 中的行:
ISR(TIMER1_OVF_vect)
{
static unsigned int counter;
TCNT1 = 0xC2F8;
counter++;
if(counter >= 10)
{
FLAG_TIMER.BIT=1;
counter = 0;
TIMSK &= ~(1<< TOIE1);
}
else
{
FLAG_TIMER.BIT=0;
}
}
我不熟悉 ATmega,但我不敢相信這是使用計時器的合適方式。 通常,您會在自動重置為零的情況下向上計數到比較值,或者從自動重新加載值向下計數到零,然后讓硬件重新加載計數器。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.