我使用GD32F303单片机编写了一个应用,我的目的是在打开中断后延时1000us后打开TIMER0定时器输出,
main
{
.......
/* enable outq-timer to delaying */
timer_interrupt_enable(TIMER6,TIMER_INT_FLAG_UP);
.......
.......
}
void TIMER6_IRQHandler(void)
{
if(SET == timer_interrupt_flag_get(TIMER6,TIMER_INT_FLAG_UP)){
timer_enable(TIMER0);
/* clear channel 0 interrupt bit */
timer_interrupt_flag_clear(TIMER6,TIMER_INT_FLAG_UP);
timer_interrupt_disable(TIMER6,TIMER_INT_FLAG_UP);
//work_counter++;cur_counter++;
}
}
可是timer_interrupt_enable(TIMER6,TIMER_INT_FLAG_UP);执行后,程序马上进入中断,而不是等待1000uS后才进入中断。
请问高手,是不是只要起开中断就进入中断,等待下一个周期在中断。
引用: maychang 发表于 2022-9-20 18:26 『定时中断只要打开是否马上进入中断吗』 不是。定时器计数到某个特定值才会产生中断。
这个答案我已经通过试验知道了定时器在初始化完成后,就是timer_enable(TIMER0);这句执行后,定时器就已经开始执行了,只是这时中断标记没有打开,所以中断函数进不去而已。所以只要打开中断,这时就可以进入中断了,因为这时定时器是工作着的,所以不能用timer_interrupt_enable(TIMER6,TIMER_INT_FLAG_UP);这种方法,而是使用timer_enable(TIMER0);打开中断,这时才开始执行计数。
1000us?这你也能观察出来?不过开启定时器后就开始工作了,到达时间就会硬件置位标志位,不过你没开启中断就不会触发,这个时候开启中断就会进去中断,说明你开启定时器和开启中断之间的延时要大于你定时器的定时时间
而且你这个也有个问题,定时器6会反复进中断,这时候反复开启定时器0也没有意义啊,不能这么设计
bigbat 发表于 2022-9-20 19:15 这个答案我已经通过试验知道了定时器在初始化完成后,就是timer_enable(TIMER0);这句执行后,定时器就已 ...
timer_enable(TIMER0)这句可能触发了更新自动重装值。
你可以在中断打开前重新更新自动重装值或者定时器disable然后enable
/*以前做的一个*/
/*按周期启动定时器2*/
void TIM2_Start(uint32_t tim_period)
{
uint16_t tmpcr1 = 0;
tmpcr1 = TIM2->CR1;
/* Select the Counter Mode */
tmpcr1 &= (uint16_t)(~((uint16_t)(TIM_CR1_DIR | TIM_CR1_CMS)));
tmpcr1 |= (uint32_t)TIM_CounterMode_Up;
/* Set the clock division */
tmpcr1 &= (uint16_t)(~((uint16_t)TIM_CR1_CKD));
tmpcr1 |= 0;
TIM2->CR1 = tmpcr1;
/* Set the Autoreload value */
TIM2->ARR = tim_period;;
/* Set the Prescaler value */
TIM2->PSC = 0;
/* Generate an update event to reload the Prescaler and the Repetition counter
values immediately */
TIM2->EGR = TIM_PSCReloadMode_Immediate;
/* Prescaler configuration */
TIM_PrescalerConfig(TIM2, 3, TIM_PSCReloadMode_Immediate);
TIM2->SR = (uint16_t)~TIM_FLAG_Update;
/* Enable the Interrupt sources */
TIM2->DIER |= TIM_IT_Update;
/* TIM2 enable counter */
TIM2->CR1 |= TIM_CR1_CEN;
}
这是以前产品中用到的一个。不知道有没有借鉴意义。stm32f0标准库1.5的。直接操作寄存器做了一个。为的是效率高点。
本帖最后由 damiaa 于 2022-9-21 09:37 编辑引用: damiaa 发表于 2022-9-21 09:23 /*以前做的一个*/ /*按周期启动定时器2*/ void TIM2_Start(uint32_t tim_period) { uint16_t tmpcr ...
我是使用示波器看到的肉眼是做不到的,我的目的是:有两个开关A、B,A开启后B要延时一段时间在启动,100uS到5000us之间。所以我使用定时器作为控制定时,但是似乎两个信号是同步的。其实我想让Timer6每次开启只中断一次。
目前的方案是在中断中把Timer6关掉。不知道是否可行。
引用: bigbat 发表于 2022-9-21 09:40 我是使用示波器看到的肉眼是做不到的,我的目的是:有两个开关A、B,A开启后B要延时一段时间在启动,100u ...
定时器6中断后关掉自己这个没问题。
不过你下次在主程序每次启动定时器6时要处理一下确定自动重装值重新装了一下再开启中断允许并立刻启动定时器。这样时间就可以精确控制。
引用: damiaa 发表于 2022-9-21 09:55 定时器6中断后关掉自己这个没问题。 不过你下次在主程序每次启动定时器6时要处理一下确定自动重装值重 ...
谢谢,是不是我应该把重装关掉timer_auto_reload_shadow_enable(TIMER6);手动装载
bigbat 发表于 2022-9-21 10:09 谢谢,是不是我应该把重装关掉timer_auto_reload_shadow_enable(TIMER6);手动装载
你可以参照初始化的代码修改测试一下。如果是只一次的话应该可以手动装。可以试一下。8楼的代码也是测试过可以用的。
本帖最后由 damiaa 于 2022-9-21 10:35 编辑看具体情况,可以配置成稍后进入,也可以配置成立刻进入。
就是timer_enable(TIMER),先执行定时器了,开中断就进入中断了