STM32F103RCT6开发板M3单片机教程06--定时器中断
前言
除非特别说明,本章节描述的模块应用于整个STM32F103xx微控制器系列,因为我们使用是STM32F103RCT6开发板是mini最小系统板。
本教程使用是(光明谷SUN_STM32mini开发板)
?
STM32F10X定时器(Timer)基础
首先了解一下是STM32F10X定时器(Timer)
?
注:
小容量产品是指闪存存储器容量在16K至32K字节之间的STM32F101xx,?STM32F102xx和STM32F103xx微控制器。
中容量产品是指闪存存储器容量在64K至128K字节之间的STM32F101xx,?STM32F102xx和STM32F103xx微控制器。
大容量产品是指闪存存储器容量在256K至512K字节之间的STM32F101xx和STM32F103xx微控制器。
定时器类型
大容量的STM32F103xx增强型系列产品包含最多2个高级控制定时器、 4个普通定时器和2个基本定时器,以及2个看门狗定时器和1个系统嘀嗒定时器。
下表比较了高级控制定时器、普通定时器和基本定时器的功能:
高级控制定时器(TIM1和TIM8)
两个高级控制定时器(TIM1和TIM8)可以被看成是分配到6个通道的三相PWM发生器,它具有带死区插入的互补PWM输出,还可以被当成完整的通用定时器。四个独立的通道可以用于:
● 输入捕获
● 输出比较
● 产生PWM(边缘或中心对齐模式)
● 单脉冲输出
配置为16位标准定时器时,它与TIMx定时器具有相同的功能。配置为16位PWM发生器时,它具有全调制能力(0~100%)。
在调试模式下,计数器可以被冻结,同时PWM输出被禁止,从而切断由这些输出所控制的开关。
很多功能都与标准的TIM定时器相同,内部结构也相同,因此高级控制定时器可以通过定时器链接功能与TIM定时器协同操作,提供同步或事件链接功能。
通用定时器(TIMx)
STM32F103xC、?STM32F103xD和STM32F103xE增强型系列产品中,内置了多达4个可同步运行的标准定时器(TIM2、?TIM3、?TIM4和TIM5)。每个定时器都有一个16位的自动加载递加/递减计数器、一个16位的预分频器和4个独立的通道,每个通道都可用于输入捕获、输出比较、?PWM和单脉冲模式输出,在最大的封装配置中可提供最多16个输入捕获、输出比较或PWM通道。
它们还能通过定时器链接功能与高级控制定时器共同工作,提供同步或事件链接功能。在调试模式下,计数器可以被冻结。任一标准定时器都能用于产生PWM输出。每个定时器都有独立的DMA请求机制。
这些定时器还能够处理增量编码器的信号,也能处理1至3个霍尔传感器的数字输出。
基本定时器-TIM6和TIM7
这2个定时器主要是用于产生DAC触发信号,也可当成通用的16位时基计数器。
独立看门狗
独立的看门狗是基于一个12位的递减计数器和一个8位的预分频器,它由一个内部独立的40kHz的RC振荡器提供时钟;因为这个RC振荡器独立于主时钟,所以它可运行于停机和待机模式。它可以被当成看门狗用于在发生问题时复位整个系统,或作为一个自由定时器为应用程序提供超时管理。通过选项字节可以配置成是软件或硬件启动看门狗。在调试模式下,计数器可以被冻结。
窗口看门狗
窗口看门狗内有一个7位的递减计数器,并可以设置成自由运行。它可以被当成看门狗用于在发生问题时复位整个系统。它由主时钟驱动,具有早期预警中断功能;在调试模式下,计数器可以被冻结。
系统时基定时器
这个定时器是专用于实时操作系统,也可当成一个标准的递减计数器。它具有下述特性:
●?24位的递减计数器
● 自动重加载功能
● 当计数器为0时能产生一个可屏蔽系统中断
● 可编程时钟源
?
高级控制定时器框图
了解基本概念后,今天用通用定时器(TIM2), 写一个定时中断的程序
?
编写代码
建工程写代码
复制上节工程文件夹打开(这个方法比较方便)
?
- 新建源文件,编辑代码
编辑main.c, 在上节基础上增加TIM配置及中断服务函数。/********************************************************************************** * Sun STM32 mini Demo *? ?Description ? ? ? TIM2 Interrupt Demo ? ? * Version? ? Date? ?? ? Auther? ?? ?Reversed History ??---------------------------------------------------------------------------- ??V1.0.0? ? 2021-11-07??Lojam Fan??Fisrt Created ?? * (C) Sunshine Silicon Corporation *??Website: http://www.sunsili.com??http://sunsili.taobao.com http://bbs.sunsili.com *??E-Mail : fan@sunsili.com **********************************************************************************/ #include "stm32f10x.h" #include "usart.h" #include "SysTick.h" #include "led.h" #include "key.h" #include <stdio.h> static u8 flag; static u8 tim2_tick; void Timer2_Init_Config(void); void RCC_Configuration(void); /******************************************************************************* * 函数名??: main * 描述? ? : 主函数,用户程序从main函数开始运行 * 输入? ? : 无 * 输出? ? : 无 * 返回值??: int:返回值为一个16位整形数 * 说明? ? : 无 *******************************************************************************/ int main(void) { ? ? u8 keyVal; ? ? RCC_Configuration(); ? ? SysTick_Init_Config(); ? ?? ???USART1_Init_Config(115200);//USART1初始化配置 ? ? LED_GPIO_Config(); ? ? Key_GPIO_Config(); ? ? Timer2_Init_Config();? ?? ???//Timer2初始化配置 ? ? printf ("*===================================================*\n"); ? ? printf ("*??*??Name: Sun STM32 mini Demo Code.? ? *************\n"); ? ? printf ("*??* (C) Sunshine Silicon Corporation? ? *************\n"); ? ? printf ("*??*??Website: http://www.sunsili.com? ? *************\n"); ? ? printf ("*??*? ?E-Mail : fan@sunsili.com? ?? ?? ? *************\n"); ? ? printf ("*===================================================*\n"); ? ? printf ("* Sun STM32 mini TIM2 Interrupt Demo code .*\n"); ? ? ? ?? ???while (1) ? ?? ???{ ? ?? ???if(tim2_tick) ? ?? ???{ ? ?? ?? ?? ?tim2_tick = 0; ? ?? ?? ?? ?if(flag) ? ?? ?? ?? ?{ ? ?? ?? ?? ?? ? printf("LED ON\n");? ?? ?? ?? ?? ? ? ?? ?? ?? ?} ? ?? ?? ?? ?else ? ?? ?? ?? ?{ ? ?? ?? ?? ?? ? printf("LED OFF\n"); ? ?? ?? ?? ?} ? ?? ???} ? ?? ???} } /******************************************************************************* * 函数名??: Timer2_Init_Config * 描述? ? : Timer2初始化配置 * 输入? ? : 无 * 输出? ? : 无 * 返回? ? : 无 * 说明? ? : 无 *******************************************************************************/ void Timer2_Init_Config(void) { ? ?? ???TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; ? ?? ???NVIC_InitTypeDef NVIC_InitStructure; ?? ??? ? ?? ???RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);? ?? ?? ?? ?? ? //使能Timer2时钟?? ??? ? ?? ???TIM_TimeBaseStructure.TIM_Period = 4999;? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? //设置在下一个更新事件装入活动的自动重装载寄存器周期的值(计数到5000为500ms) ? ?? ???TIM_TimeBaseStructure.TIM_Prescaler = 7199;? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? //设置用来作为TIMx时钟频率除数的预分频值(10KHz的计数频率) ? ?? ???TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;? ?? ?? ?? ?? ? //设置时钟分割:TDTS = TIM_CKD_DIV1 ? ?? ???TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;? ?? ???//TIM向上计数模式 ? ?? ???TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);? ?? ?? ?? ?? ?? ?? ?? ?? ?? ???//根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位 ? ?? ???/*中断优先级NVIC设置*/ ? ?? ???NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;? ?? ?? ?? ?? ?? ?? ?? ?? ?? ???//TIM2中断 ? ?? ???NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;? ?? ???//先占优先级1级 ? ?? ???NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;? ?? ?? ?? ?? ?? ?? ?? ?//从优先级1级 ? ?? ???NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;? ?? ?? ?? ?? ?? ?? ?? ?? ?? ???//使能IRQ通道 ? ?? ???NVIC_Init(&NVIC_InitStructure);? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?//初始化NVIC寄存器? ?? ?? ? ? ?? ???TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE );? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?//使能TIM2指定的中断?? ??? ? ?? ???TIM_Cmd(TIM2, ENABLE);? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ???//使能TIMx外设 }? ?? ?? ? /******************************************************************************* * 函数名??: TIM2_IRQHandler * 描述? ? : 定时器2中断服务函数 * 输入? ? : 无 * 输出? ? : 无 * 返回? ? : 无 * 说明? ? : 无 *******************************************************************************/ void TIM2_IRQHandler(void)? ?//TIM2中断服务函数 { ? ? tim2_tick = 1; ? ?? ???if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)??//检查TIM3更新中断发生与否 ? ?? ???{ ? ?? ?? ?? ?? ? TIM_ClearITPendingBit(TIM2, TIM_IT_Update??);??//清除TIMx更新中断标志 ? ?? ?? ?? ?? ? if(flag) ? ?? ?? ?? ?? ? { ? ?? ?? ?? ?? ?? ?? ?? ?LED4_ON(); ? ?? ?? ?? ?? ?? ?? ?? ?flag=0; ? ?? ?? ?? ?? ? } ? ?? ?? ?? ?? ? else ? ?? ?? ?? ?? ? { ? ?? ?? ?? ?? ?? ?? ?? ?LED4_OFF(); ? ?? ?? ?? ?? ?? ?? ?? ?flag=1; ? ?? ?? ?? ?? ? } ? ?? ???} } /******************************************************************************* * 函数名??: RCC_Configuration * 描述? ? : 设置系统时钟为72MHZ(这个可以根据需要改) * 输入? ? : 无 * 输出? ? : 无 * 返回值??: 无 * 说明? ? : STM32F107x和STM32F105x系列MCU与STM32F103x系列MCU时钟配置有所不同 *******************************************************************************/ void RCC_Configuration(void) { ??ErrorStatus HSEStartUpStatus;? ?? ?? ?? ?? ?//外部高速时钟(HSE)的工作状态变量?? ??RCC_DeInit();? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? //将所有与时钟相关的寄存器设置为默认值 ??RCC_HSEConfig(RCC_HSE_ON);? ?? ?? ?? ?? ?? ?//启动外部高速时钟HSE ??HSEStartUpStatus = RCC_WaitForHSEStartUp(); //等待外部高速时钟(HSE)稳定 ??if(SUCCESS == HSEStartUpStatus)? ?? ?? ?? ? //如果外部高速时钟已经稳定 ??{ ? ? /* Enable Prefetch Buffer */ ? ? FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //Flash设置 ? ? /* Flash 2 wait state */ ? ? FLASH_SetLatency(FLASH_Latency_2);?? ? ? RCC_HCLKConfig(RCC_SYSCLK_Div1); //设置AHB时钟等于系统时钟(1分频)/72MHZ ? ? RCC_PCLK2Config(RCC_HCLK_Div1);??//设置APB2时钟和HCLK时钟相等/72MHz(最大为72MHz) ? ? RCC_PCLK1Config(RCC_HCLK_Div2);??//设置APB1时钟是HCLK时钟的2分频/36MHz(最大为36MHz) ? ? RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); //PLLCLK = 8MHz * 9 = 72 MHz ? ? RCC_PLLCmd(ENABLE); //使能PLL ? ? while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); //等待PLL稳定 ? ? RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);? ?? ?? ? //设置系统时钟的时钟源为PLL ? ? while(RCC_GetSYSCLKSource() != 0x08);? ?? ?? ?? ?? ?//检查系统的时钟源是否是PLL ? ? RCC_ClockSecuritySystemCmd(ENABLE);? ?? ?? ?? ?? ???//使能系统安全时钟 ? ? ? ? RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO,ENABLE); ??} } /******************* (C) COPYRIGHT SUNSHINE SILICON??************************** ********************? ?? ???END OF FILE main.c? ?? ???*******************/
编译调试程序
编译调试
保存直接编译,发现编译出错, 因为未添加tim库。解决方法添加库文件stm32f10x_tim.c
重新编译,通过。
调试
方法不再重复,经过前两节练习,大家应该是会了.
看到效果是, LED 1s闪烁一次,??uart1 定时打印LED状态
总结课后练习
改变TIM定时中断频率
工程源码
查看原文,可下载工程源码
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!