历史上的今天
返回首页

历史上的今天

今天是:2024年08月31日(星期六)

2020年08月31日 | STM32——如何配置通用定时器中断

2020-08-31 来源:eefocus

STM32的定时器

STM32F103ZET6一共有8个定时器,其中分别为:


高级定时器(TIM1、TIM8);通用定时器(TIM2、TIM3、TIM4、TIM5);基本定时器(TIM6、TIM7)。

在这里插入图片描述
在这里插入图片描述

除非APB1的分频系数是1,否则通用定时器的时钟等于APB1时钟的2倍。


默认调用SystemInit函数情况下:

SYSCLK=72M

AHB时钟=72M

APB1时钟=36M

所以APB1的分频系数=AHB/APB1时钟=2

所以,通用定时器时钟CK_INT=2*36M=72M

 

定时器中断的一般步骤

实例要求:通过TIM3的中断来控制led1的亮灭

硬件:LED——GPIOB,GPIO_Pin_5


1、使能定时器时钟。调用函数:RCC_APB1PeriphClockCmd();

2、初始化定时器,配置ARR、PSC。调用函数:TIM_TimeBaseInit();

3、开启定时器中断,配置NVIC。调用函数:void TIM_ITConfig();NVIC_Init();

4、使能定时器。调用函数:TIM_Cmd();

5、编写中断服务函数。调用函数:TIMx_IRQHandler()。

定时时间的计算公式

决定CK_CNT的频率是由分频系数决定的,分频系数PSC决定了计数器计数一次的时间 t=1/CK_CNT

CK_CNT=CK_INT/(71+1)=1MHz

1/CK_CNT=1us

APB1的预分频系数决定是36MHzx1还是36MHzx2,这里的APB1预分频系数是2则是72MHz

(PSC+1)/72MHz=1us

Arr的重装周期是1~65535,参考寄存器手册,所以不需要减一,分频系数减一,周期不需要


//通用定时器3中断初始化

//这里时钟选择为APB1的2倍,而APB1为36M

//arr:自动重装值。

//psc:时钟预分频数

//这里使用的是定时器3!


void LED_Init(void)

{

     GPIO_InitTypeDef GPIO_InitStructure;

     

     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PB端口时钟

   

     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED0-->PB.5 端口配置

     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出

     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz

     GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOB.5

     GPIO_SetBits(GPIOB,GPIO_Pin_5); //PB.5 输出高 此时状态为灭 低电平亮

 

void TIM3_Init(void)

{

    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

    

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能

//定时器TIM3初始化

TIM_TimeBaseStructure.TIM_Period = 1000; //自动重装载寄存器周期的值1/CK_CNT=1us,1000x1us=1ms

TIM_TimeBaseStructure.TIM_Prescaler =71; //设置用来作为TIMx时钟频率除数的预分频值CK_CNT=CK_INT/(71+1)=1MHz

TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //TIM_CKD_DIV1是.h文件中已经定义好的,TIM_CKD_DIV1=0,也就是时钟分频因子为0

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式

TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位

 

TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断

TIM_Cmd(TIM3, ENABLE);  //使能TIMx  

}


void NVIC_Init(void)

{

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级


  NVIC_InitTypeDef NVIC_InitStructure; //中断优先级NVIC设置

NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能

NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器

}


void TIM3_IRQHandler(void)    //TIM3中断

{

if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否

{

time++;

TIM_ClearITPendingBit(TIM3, TIM_IT_Update  ); //清除TIMx更新中断标志 

}

}

 

int main(void)

{

delay_init();     //延时函数初始化   

LED_Init();     //LED端口初始化

TIM3_Init(); //1ms的计时

  NVIC_Init(); //NVIC初始化

  while(1)

{

    if(time==500) //500x1ms=500ms

    {

    LED0=!LED0;

    delay_ms(200);

    time = 0;

    }    

}  

}  

 

库函数解析:

定时器参数初始化:


void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);


typedef struct

{

  uint16_t TIM_Prescaler;        

  uint16_t TIM_CounterMode;     

  uint16_t TIM_Period;        

  uint16_t TIM_ClockDivision;  

  uint8_t TIM_RepetitionCounter;

} TIM_TimeBaseInitTypeDef; 


IM_TimeBaseStructure.TIM_Period = 1000; 

TIM_TimeBaseStructure.TIM_Prescaler =71; 

TIM_TimeBaseStructure.TIM_ClockDivision =   TIM_CKD_DIV1;

TIM_TimeBaseStructure.TIM_CounterMode =   TIM_CounterMode_Up; 

TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); 

 

定时器使能函数: void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState)


定时器中断使能函数:void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);


状态标志位获取和清除:


FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);

void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);


ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);

void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);


推荐阅读

史海拾趣

FTDI公司的发展小趣事

FTDI公司(Future Technology Devices International)在电子行业中的发展充满了多个关键节点和故事,以下是五个相关故事,每个故事均基于事实描述:

1. 创立与早期发展

FTDI公司成立于1992年3月13日,由弗雷德·达特(Fred Dart)创立。起初,公司专注于为个人电脑市场提供服务,其首发产品是针对主板芯片组的解决方案。这些产品被成功应用于IBM的AMBRA和PS/2系列个人电脑上,为当时的计算机技术发展做出了贡献。这一时期的成功为FTDI奠定了坚实的基础,并展示了其在芯片设计领域的初步实力。

2. USB桥接芯片领域的崛起

随着计算机技术的快速发展,FTDI敏锐地捕捉到了USB接口技术的潜力。公司开始专注于USB桥接芯片的研发与生产,并逐渐在这一领域崭露头角。其MM232R和USB-COM232-PLUS1等接口产品因其出色的连接性和兼容性而广受好评。FTDI的USB桥接芯片广泛应用于汽车电子、IOT互联网、工业产品、医疗设备、新能源以及高端消费电子等多个领域,逐步确立了其在全球USB桥接芯片市场的领先地位。

3. 全球化布局与业务拓展

为了进一步扩大市场份额,FTDI积极实施全球化战略。公司在新加坡设立了业务运营总部,并在全球范围内建立了完善的销售和服务网络。这一布局不仅提升了FTDI在全球市场的竞争力,还为其带来了更多的商业机会。同时,FTDI不断拓展产品线,满足不同领域客户的需求,进一步巩固了其在USB桥接芯片领域的市场地位。

4. 并购与合作

在发展过程中,FTDI也通过并购与合作的方式不断壮大自身实力。例如,在2022年,FTDI被电连技术通过发行股份及支付现金的方式收购,成为电连技术的控股子公司。这次并购不仅为FTDI带来了更多的资金和资源支持,还为其未来的发展注入了新的动力。同时,FTDI也与其他行业巨头建立了广泛的合作关系,共同推动电子行业的发展。

5. 技术创新与市场引领

FTDI始终将技术创新作为公司发展的核心驱动力。公司不断投入研发资源,推出具有自主知识产权的新产品和技术解决方案。这些创新成果不仅提升了FTDI的产品竞争力,还为其在全球市场树立了良好的品牌形象。同时,FTDI还积极参与行业标准的制定和推广工作,致力于推动整个电子行业的技术进步和发展。

以上五个故事展示了FTDI公司在电子行业中的发展历程和关键节点。从创立初期的默默无闻到如今的全球领先企业,FTDI凭借其敏锐的市场洞察力、强大的技术实力和不懈的创新精神,在电子行业中书写了属于自己的辉煌篇章。

Daito Communication Apparatus Co Ltd公司的发展小趣事

自1948年成立以来,Daito公司一直致力于电子元器件的研发与生产。在公司的早期阶段,他们意识到保险丝在电子设备中的重要性,并决定投入大量资源进行研发。经过数年的努力,Daito公司成功开发出了高精度报警保险丝,这一创新产品凭借其卓越的性能和可靠性,迅速在市场上获得了认可。

高精度报警保险丝的成功并没有让Daito公司停止创新的步伐。他们不断对保险丝的失效原因与寿命进行预测和分析,通过全面质量管理,使产品质量得到了显著的提高。同时,Daito公司还将各系列保险丝的额定值多层次化,以满足不同客户的需求,扩大了顾客的选择余地。

DFRobot公司的发展小趣事

在竞争激烈的电子行业中,DFRobot始终保持创新精神和技术领先。他们不断推出具有创新性和实用性的新产品和技术解决方案,如基于RISC-V构架的开源硬件产品、人工智能教育产品等。这些新产品和技术不仅满足了客户的需求,也推动了行业的发展和进步。同时,DFRobot还注重知识产权保护,积极申请各类专利和软件著作权,保护公司的创新成果和知识产权。

通过以上五个故事,我们可以看到DFRobot在电子行业中的发展历程和成就。他们凭借对技术的热爱和不懈的努力,逐渐在机器人和开源硬件领域崭露头角,并通过拓展教育市场、国际合作和品牌建设等举措,不断提升公司的竞争力和影响力。

FLEX LTD公司的发展小趣事

在竞争激烈的电子行业中,DFRobot始终保持创新精神和技术领先。他们不断推出具有创新性和实用性的新产品和技术解决方案,如基于RISC-V构架的开源硬件产品、人工智能教育产品等。这些新产品和技术不仅满足了客户的需求,也推动了行业的发展和进步。同时,DFRobot还注重知识产权保护,积极申请各类专利和软件著作权,保护公司的创新成果和知识产权。

通过以上五个故事,我们可以看到DFRobot在电子行业中的发展历程和成就。他们凭借对技术的热爱和不懈的努力,逐渐在机器人和开源硬件领域崭露头角,并通过拓展教育市场、国际合作和品牌建设等举措,不断提升公司的竞争力和影响力。

Ceramics公司的发展小趣事

某家名为“创新陶瓷”的Ceramics公司,通过不断研发新技术,成功打破了传统陶瓷材料在电子领域的应用限制。该公司推出了一款具有高热导率、低电阻率的陶瓷基板,显著提高了电子设备的性能稳定性。这一创新不仅赢得了市场的广泛认可,还吸引了多家知名电子厂商的合作意向。创新陶瓷通过持续的技术创新,逐渐在电子行业树立了领先地位。

Altonics公司的发展小趣事

Altonics公司创始人在XXXX年创建了这家公司,初期面临着资金短缺、市场竞争激烈和技术人才缺乏的困境。然而,创始人凭借对电子技术的深刻理解和敏锐的市场洞察力,决定专注于工业自动化控制领域的研发与生产。经过不懈的努力,公司成功开发出一款高性能的自动化控制设备,受到了市场的广泛认可,为公司的后续发展奠定了坚实的基础。

问答坊 | AI 解惑

如何学好电子技术-致初学者

如何学好电子技术-致初学者 学习电子技术是一个循序渐进的过程,我个人认为应该分五步来走: 第一步,培养兴趣。受家庭影响,我从小就对电子技术产生了浓厚兴趣,整天把一些电池、导线、小灯泡连来连去,为搞清楚收音机里为何能发出人说 ...…

查看全部问答>

求助:有一段简单的电机正反转程序需要硬件

这也只是我写的一段简单的程序,但是硬件方面我就完全不懂了 哪位高手帮下忙啊.............. 用的是汇编语言的说 ORG 8000H AJMP DAMOT ORG 8100H DAMOT: MOV DPTR,#9000H MOV A,#80H MOVX @DPTR,A ...…

查看全部问答>

cadence学习中

用protel软件已经有半年的时间了,在做低速电路板设计时感觉还行,但现在要设计八层的核心板,protel软件已经是力不从心了。改用Cadence了,刚开始学习真有点摸不住头脑了,里面的设置比protel复杂得多。在学习完一个月后,里面遇到的问题实在是太 ...…

查看全部问答>

M0板子仿真器不能初始化

用周立功的M0板子(LPC1114)烧写时说仿真器不能初始化,报错为 AGDI fatal error :initialize fail,硬件自检不到,是不是芯片坏掉了…

查看全部问答>

请问版主:IAP程序一定小于8K吗?

IAP程序一定要小于8K吗?最近我在做程序升级,IAP程序大于8K,做程序升级时老是出错,不知道是不是因为程序大于8K的原因???…

查看全部问答>

stm32f20x能买到样吗?

                                 stm32f20x能买到样吗?…

查看全部问答>

为什么要在M3上移植操作系统,优势在哪里?

我最近想学嵌入式操作系统uc/osii,可是对它的用途和优势不是很了解。…

查看全部问答>

SDK 编译c代码时报错

\'arm-xilinx-eabi-gcc \' 不是内部或者外部命令,也不是可运行的程序 哪位高手知道是怎么回事,应该怎么解决!麻烦指导一下!谢谢!!!…

查看全部问答>

【四】【FPGA助学系列—NIOS篇】软核也疯狂1—图解NIOS建立

【FPGA助学系列—NIOS篇】软核也疯狂(1)—图解NIOS建立1.         NIOS是什么在与NIOS第一次亲密接触之前,你的底线是什么?不是是懂非懂的问NIOS有多快,NIOS能不能替代单片机,而是要搞清楚到底NIOS是什么。老样子 ...…

查看全部问答>

AVR单片机中的位操作

在标准C语言的的教材中,对于位运算的操作是基本不涉及的,但是在单片机系统的程序中,需要经常操作各类以字节为单位的寄存器,而这些寄存器通常都是以二进制中的位为控制单位的数据组合。往往一个8位寄存器中的每一位都有各自的控制对象,例如端口 ...…

查看全部问答>