【发布时间】:2021-06-12 03:54:49
【问题描述】:
我正在尝试使用 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
}
}
【问题讨论】:
-
通常我们使用定时器来产生小的延迟(纳秒或微秒)。我宁愿使用系统滴答声来产生这个延迟范围。你有什么问题?
-
晦涩难懂的 BIT 结构有什么用?为什么不能使用布尔值?从主循环调用
timer_on();看起来很奇怪,你确定它不会重置一些标志吗? -
另外,为什么不编写自文档代码
DDRD |= CRO;或DDRD |= 1u << CRO; -
尝试简化代码并在组合它们之前测试它的不同部分。您是否能够编写立即打开 PWM 输出的代码?您是否能够将该 PWM 代码移动到 TIMER1_OVF_vect ISR 并仍然使其运行(只是为了证明您正在让该 ISR 运行)?
-
@Lundin 这不是我完整的项目,我正在努力解决计时器溢出部分,所以我将其与原始代码分开,我必须在一个特定事件中启动溢出以创建 10 秒延迟,所以我没有在 timer_configuration() 期间指定 timer_on(),而是单独给出了它。我不知道这是否是正确的方法,请提供任何建议。