STM32
直播中

萧蔼晨

8年用户 1058经验值
私信 关注
[问答]

stm32定时器中断时进入不了中断服务程序是为什么?

STM32定时器中断时进入不了中断服务程序是为什么?

回帖(1)

陈婧甄

2021-11-29 10:34:51
在学习stm32 定时器中断时,发现我写的程序进入不了中断服务程序,而且我也没找到定时器服务程序的注册入口,上网查了一下,大家都使用的都是下面这个函数:void TIM3_IRQHandler(void),那为什么其他人的中断程序可以执行,而我的却执行不了呢。


经过请教得知,我的工程中没有包含该一个叫做startup_stm32f10x_hd.s的文件,而我所谓的中断服务程序的注册入口就是包含在这里。startup_stm32f10x_hd.s是用汇编语言编写的STM32处理器的初始化程序,它规定了系统的堆栈大小等系统信息,也包含了一个向量表,这个向量表中对所有的中断入口函数都进行了分配,如TIM3的中断入口是:


        …………………………………………       
DCD     TIM3_IRQHandler           ; TIM3
        DCD     TIM4_IRQHandler           ; TIM4
        DCD     I2C1_EV_IRQHandler        ; I2C1 Event
        DCD     I2C1_ER_IRQHandler        ; I2C1 Error
        ……………………………………………
TIM2_IRQHandler
        B TIM2_IRQHandler

        PUBWEAK TIM3_IRQHandler
        SECTION .text:CODE:REORDER(1)
TIM3_IRQHandler
        B TIM3_IRQHandler

        PUBWEAK TIM4_IRQHandler
        SECTION .text:CODE:REORDER(1)
TIM4_IRQHandler
        B TIM4_IRQHandler
只有包含了startup_stm32f10x_hd.s文件,系统才可以知道我们所需要的中断处理函数是哪一个,进而可以进行调用。


如果你想使用其他的函数名作为中断处理函数,需要在以上几处同时改变函数名才可以,当然为了改函数名而改函数名是没有必要的。


由于我之前搭建工程的时候不认真缺了这个文件,导致中断调不通,走了弯路。


我的TIM3中断的相关代码如下:


void Do_Timer_Init()
{
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
       
    TIM_DeInit(TIM3);
    TIM_Cmd(TIM3, DISABLE);
        TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
       
        NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;                                   //选择中断线0  
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;          //抢占优先级为 1  
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;                           //响应优先级为 0  
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                          //中断使能  
        NVIC_Init(&NVIC_InitStructure);

        TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); //将结构体赋初值
       
        TIM_TimeBaseStructure.TIM_Period = 2000*5 - 1;   //计数为9999 时产生中断
        TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
        TIM_TimeBaseStructure.TIM_Prescaler = 36000-1;  //分配为36000 则时钟变为72MHz / 36000 = 2KHz 结合前面的10000次产生中断得到 5s产生一次中断
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
       
        TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; //该元素表示多少次溢出后会产生一次中断,这个中断与每次溢出的中断不冲突
       

        TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);


        TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //中断使能


        TIM_Cmd(TIM3,ENABLE); // 计数器使能

}

extern int Timer_flag;
void TIM3_IRQHandler()
{
       
        if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)//检查是不是TIM3中断
        {
        TIM_ClearITPendingBit(TIM3, TIM_IT_Update  ); //清除TIM3中断待处理位
        if(Timer_flag != 1)
        {
          Timer_flag = 1;
        }
        }
}
举报

更多回帖

发帖
×
20
完善资料,
赚取积分