【STM32F103实验(六)】定时器中断

【STM32F103实验(六)】定时器中断,第1张

一、实验目的
在正点原子精英版上采用通用定时器3中断控制DS1每隔500ms的亮灭闪烁。


二、寄存器介绍
(寄存器此处只对其功能进行介绍,寄存器具体结构请自行参考《STM32中文参考手册》)

本次实验主要涉及3个寄存器即控制寄存器1(TIMx_CR1)、DMA/中断使能寄存器(TIMx_DIER)和预分频寄存器(TIMx_PSC),同时还涉及了计数器寄存器(TIMx_CNT)、自动重装载寄存器(TIMx_ARR)和状态寄存器(TIMx_SR)。

控制寄存器1(TIMx_CR1)主要目的是使能计数器和设置计数方式。

该寄存器的最低位是计数器的使能位,只有让该位置1才能让定时器开始计数;该寄存器第4、5、6位是计数方式选择位,可以通过配置这三位选择计数方式,本实验中选用向上计数模式。

DMA/中断使能寄存器(TIMx_DIER)主要用于设置定时器更新事件产生的中断。

该寄存器的第0位是更新中断允许位,需要将其置为1才能使能更新中断。

预分频寄存器(TIMx_PSC)用于计数器的时钟选择。

该寄存器设置对时钟进行分频,然后提供给计数器,作为计数器的时钟。

定时器的时钟来源有4个,其分别是:
(1)内部时钟(CN_INT)。


(2)外部时钟模式1:外部输入脚(TIx)。


(3)外部时钟模式2:外部触发输入(ETR)。


(4)内部触发输入(ITRx):使用A定时器作为B定时器的预分频器(A为B提供时钟)。

计数器寄存器(TIMx_CNT)用于存储当前定时器的计数值。

自动重装载寄存器(TIMx_ARR)用于中存放计数总值。

该寄存器在物理上实际对应这2个寄存器。

一个是程序员直接 *** 作的,另外一个是程序员看不见的。

这个看不见的寄存器在《STM32中文参考手册》中被称为影子寄存器。

事实上真正起作用的是影子寄存器。

根据TIMx_CR寄存器中的APRE位的设置:APRE = 0时,预分频寄存器的内容可以随时传送到影子寄存器,此时两者是连通的;当APRE = 1时,在每一次更新事件(UEV)时,才把预装在寄存器的内容传送到影子寄存器。

状态寄存器(TIMx_SR)用来标记当前与定时器相关的各种事件/中断是否发生。


三、程序编写
使用库函数来进行编写。

定时器初始化步骤如下:
(1)TIM3时钟使能。


(2)初始化定时器,配置参数。


(3)设置TIM3_DIER允许更新中断。


(4)TIM3中断优先级设置。


(5)使能TIM3。


(6)编写中断服务函数。

void Timer3_init(u16 arr,u16 psc)   //arr-自动重装值,psc-时钟预分频数
{
    
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitSturct;
    NVIC_InitTypeDef NVIC_InitStuct;
    
    /*****************TIM3时钟使能**************/
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); //TIM3挂接在APB1总线上
    
    /*****************定时器TIM3参数初始化*************/
    TIM_TimeBaseInitSturct.TIM_ClockDivision = TIM_CKD_DIV1;    //设置时钟分割
    TIM_TimeBaseInitSturct.TIM_CounterMode = TIM_CounterMode_Up;  //向上计数
    TIM_TimeBaseInitSturct.TIM_Period = arr;    //自动重新装载值
    TIM_TimeBaseInitSturct.TIM_Prescaler = psc; //时钟预分频数
    TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitSturct);
    
    /*****************开启定时器TIM3更新中断*************/
    TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);    //允许更新中断
    
    /*****************中断优先级NVIC设置***************/
    NVIC_InitStuct.NVIC_IRQChannel = TIM3_IRQn; //TIM3中断
    NVIC_InitStuct.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
    NVIC_InitStuct.NVIC_IRQChannelPreemptionPriority = 0;   //从优先级3级
    NVIC_InitStuct.NVIC_IRQChannelSubPriority = 3;  //抢占优先级0级
    NVIC_Init(&NVIC_InitStuct);
    
    /*****************使能TIM3**************/
    TIM_Cmd(TIM3,ENABLE);   //使能TIM3
    
}

void TIM3_IRQHandler(void)
{
    if(TIM_GetITStatus(TIM3,TIM_IT_Update) == SET)  //检查TIM3更新中断是否发生
    {
        TIM_ClearITPendingBit(TIM3,TIM_IT_Update);  //清除TIM3更新中断标志
        LED1 = !LED1;   //LED1状态翻转
    }
}

主函数

int main(void)
{
    delay_init();   //延时初始化
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2
    LED_init(); //LED初始化
    Timer3_init(4999,7199); //10KHz计数频率,500ms
    while(1)
    {
        LED0 = !LED0;
        delay_ms(1000);
    }
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/674127.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-19
下一篇 2022-04-19

发表评论

登录后才能评论

评论列表(0条)

保存