小白如何做网站建设公众号,wordpress春节插件,怎么做网站宣传,建一个网站需要什么资料#x1f680;write in front#x1f680; #x1f50e;大家好#xff0c;我是黄桃罐头#xff0c;希望你看完之后#xff0c;能对你有所帮助#xff0c;不足请指正#xff01;共同学习交流 #x1f381;欢迎各位→点赞#x1f44d; 收藏⭐️ 留言#x1f4dd;… write in front 大家好我是黄桃罐头希望你看完之后能对你有所帮助不足请指正共同学习交流 欢迎各位→点赞 收藏⭐️ 留言 本系列哔哩哔哩江科大STM32的视频为主以及自己的总结梳理 Projeet source code 工程代码放在了本人的Gitee仓库iPickCan (iPickCan) - Gitee.com 引用
STM32入门教程-2023版 细致讲解 中文字幕_哔哩哔哩_bilibili
Keil5 MDK版 下载与安装教程STM32单片机编程软件_mdk528-CSDN博客
STM32之Keil5 MDK的安装与下载_keil5下载程序到单片机stm32-CSDN博客
0. 江协科技/江科大-STM32入门教程-各章节详细笔记-查阅传送门-STM32标准库开发_江协科技stm32笔记-CSDN博客
江科大STM32学习笔记上_stm32博客-CSDN博客
STM32学习笔记一基于标准库学习_电平输出推免-CSDN博客
STM32 MCU学习资源-CSDN博客
术语
英文缩写描述GPIOGeneral Purpose Input Onuput通用输入输出AFIOAlternate Function Input Output复用输入输出AOAnalog Output模拟输出DODigital Output数字输出内部时钟源 CK_INTClock Internal内部时钟源外部时钟源 ETRExternal clock 时钟源 External clock 外部时钟源 ETRExternal clock mode 1外部时钟源 External 时钟模式1外部时钟源 ETRExternal clock mode 2外部时钟源 External 时钟模式2外部时钟源 ITRxInternal trigger inputs外部时钟源ITRx Internal trigger inputs内部触发输入外部时钟源 TIxexternal input pin 外部时钟源 TIx external input pin外部输入引脚 正文
0. 概述
从 2024/06/12 定下计划开始学习下江协科技STM32课程接下来将会按照哔站上江协科技STM32的教学视频来学习入门STM32 开发本文是视频教程 P2 STM32简介一讲的笔记。 定时器共四个部分分为八个小节笔记。本小节为第一部分第一节。
在第一部分是定时器的基本定时的功能定时中断功能、内外时钟源选择
在第二部分是定时器的输出比较功能最常见的用途是产生PWM波形用于驱动电机等设备
在第三部分是定时器的输入捕获功能和主从触发模式来实现测量方波频率
在第四部分是定时器的编码器接口能够更加方便读取正交编码器的输出波形编码电机测速 知识点get 滤波器工作原理可以滤掉信号的抖动干扰。在一个固定的时钟频率f下进行采样如果连续N个采样点都为相同的电平那就代表输入信号稳定了就把这个采样值输出出去如果这N个采样值不全都相同那就说明信号有抖动这时就保持上一次的输出或者直接输出低电平也行这样就能保证输出信号在一定程度上的滤波这里的采样频率f和采样点数N都是滤波器的参数频率越低采样点数越多滤波效果越好不过相应的信号延迟就越大采样频率f由内部时钟直接而来也可以是由内部时钟加一个时钟分频而来这个分频多少是由参数ClockDivision决定的这个参数其实跟时基单元关系并不大它的可选值可以选择1分频也就是不分频2分频和4分频。 1.定时中断和时钟源选择相关库函数使用
定时器相关的库函数非常多本节仅对将要使用的库函数和 亿些使用细节 进行说明即使这样也还是很多。
定时中断基本结构如下便于理解下面的库函数及程序流程。 定时器初始化步骤如下对应定时中断结构图 第一步RCC开启时钟定时器的基准时钟和整个外设的工作时钟就都打开了 第二步选择时基单元的时钟源对于定时中断就选择内部时钟源 第三步配置时基单元包括预分频器、自动重装载器、计数模式等参数用结构体配置 第四步配置输出中断控制允许更新中断输出到NVIC 第五步配置NVIC在NVIC中打开定时器中断通道并分配一个优先级 第六步运行控制使能计数器当定时器使能后计数器就开始计数了当计数器更新时触发中断 最后再写一个中断函数中断函数每隔一段时间就能自动执行一次 2.定时器TIM的库函数
基本配置、时基单元、中断输出控制、NVIC、运行控制函数
// 恢复定时器缺省配置
void TIM_DeInit(TIM_TypeDef* TIMx);// 时基单元初始化
void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);// 把时基单元初始化函数所用的结构体变量赋一个默认值
void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);// 使能计数器对应定时中断结构图中的“运行控制”功能
void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);// 使能中断输出信号对应定时中断结构图中的“中断输出控制”功能
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);
时钟源选择函数
//选择内部时钟
void TIM_InternalClockConfig(TIM_TypeDef* TIMx);//选择ITRx其它定时器时钟
void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);//选择TIx捕获通道时钟对于外部引脚的波形一般都会有极性选择和滤波器
void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource,uint16_t TIM_ICPolarity, uint16_t ICFilter);/选择ETR通过外部时钟模式1输入的时钟
void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,uint16_t ExtTRGFilter);//选择ETR通过外部时钟模式2输入的时钟如果不需触发输入功能本函数可与上面函数互换
void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);//单独用来配置ETR引脚的预分频器、极性、滤波器这些参数
void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,uint16_t ExtTRGFilter);
3.参数PSC、ARR等更改函数在程序运行过程中修改
以下单独的函数可以方便地更改PSC\ARR等参数
// 预分频值设置TIM_PSCReloadMode为是否应用输入缓冲功能配置
void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode);// 改变计数器的计数模式
void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode);// 自动重装寄存器预装功能配置计数器有无预装功能
void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);// 手动给计数器写入一个值
void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter);// 手动给自动重装寄存器写入一个值
void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint16_t Autoreload);// 获取当前计数器的值
uint16_t TIM_GetCounter(TIM_TypeDef* TIMx);// 获取当前的预分频器的值
uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx);
获取定时器中断标志位和清除定时器中断标志位使用方法和EXTI外部中断相同。
//在主函数中获取定时器中断标志位
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);
4.使用定时器库函数的一些细节
* 选择内部时钟函数定时器上电后默认选择内部时钟如果要选择内部时钟这一句可以省略。 TIM_InternalClockConfig(TIM_TypeDef* TIMx); * 时基单元初始化函数TIN_TimeBaseInit在配置结构体变量时会遇到以下几个细节问题 1.TIM_TimeBaseInitStructure.TIM_ClockDivision 采样时钟分频频率选择 在定时器的外部信号输入引脚一般都有一个滤波器来消除信号的抖动干扰它的工作原理是在一个固定的时钟频率f下进行采样如果连续N个采样点都是相同的电平就代表输入信号稳定了就将采样值输出到下一级电路如果N个采样点不全都相同就说明信号有抖动这时保持上一次的输出或直接输出低电平。 这样就能保证输出信号在一定程度上的滤波。这里的采样频率f 和采样点数Nf和N是滤波器的参数频率越低采样点数越多滤波效果就越好不过相应的信号延迟就越大。 采样频率f的来源可以是内部时钟直接提供也可以是内部时钟加一个时钟分频而来。 分频是多少就由参数TIM_ClockDivision决定。可见 TIM_ClockDivision与时基单元的关系并不大它的可选值可以选择1分频2分频和4分频。 2.TIM_TimeBaseInitStructure.TIM_CounterMode 计数器模式 TIM_CounterMode_Up 向上计数 TIM_CounterMode_CenterAligned1 中央对齐计数 3.TIM_TimeBaseInitStructure.TIM_Period 周期ARR自动重装器的值4.TIM_TimeBaseInitStructure.TIM_Prescaler PSC预分频器的值 以上2-3-4参数就是时基单元里面每个关键寄存器的参数在配置结构体变量时并没有能直接操作计数器CNT的参数。如果需要可以采用SetCounter和GetCounter两个函数来操作计数器。 5.TIM_TimeBaseInitStructure.TIM_RepetitionCounter 重复计数寄存器通过这个参数可以设置重复计数寄存器。但是通用定时器中没有这一个寄存器故可以直接设置为0。 6.定时时间的计算 决定定时时间的参数是TIM_Period和TIM_Prescaler 参考公式 计数器溢出频率CK_CNT_OV CK_CNT / (ARR 1) CK_PSC / (PSC 1) / (ARR 1) * 定时1s也就是定时频率为1Hz定时频率72M/ (PSC 1) / (ARR 1) 1s 1Hz那就可以PSC给7200ARR给100001MHz等于10^6Hz,然后两个参数再减1。 * 注意PSCTIM_Prescaler和ARRTIM_Period的取值都要在0~65535之间。 * PSC和ARR的取值不是唯一的。可以预分频给少点自动重装给多点这样就是以一个比较高的频率计比较多的数也可以预分配给多点自动重装给少点这样就是以一个比较低的频率计比较少的数两种方法都可以达到目标的定时时间。 * 在这里预分频是对72M进行7200分频得到的就是10k的计数频率在10k的频率下计10000个数就是1s的时间。 7.在TIM_TimeBaseInit函数的最后会立刻生成一个更新事件来重新装载预分频器和重复计数器的值。预分频器有缓冲寄存器我们写入的PSC和ARR只有在更新事件时才会起作用。但是更新事件和更新中断是同时发生的更新中断会置更新中断标志位手动生成一个更新事件就相当于在初始化时立刻进入更新函数执行一次在开启中断之前手动清除一次更新中断标志位就可以避免刚初始化完成就进入中断函数的问题。 * 使能中断函数TIM_ITConfig TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE); //开启更新中断到NVIC的通道 * 启动定时器 TIM_Cmd(TIM2,ENABLE);//当产生更新时就会触发中断 * 外部时钟配置函数TIM_ETRClockMode2Config 1.TIM_ExtTRGPrescaler外部时钟预分频器可以选择外部时钟分频关闭1分频、2分频、4分频、8分频。 2.TIM_ExtTRGPolarity 外部触发的极性TIM_ExtTRGPolarity_Inverted为反向极性即低电平和下降沿有效TIM_ExtTRGPolarity_NonInverted为不反向即高电平和上升沿有效。 3.ExtTRGFilter 外部输入滤波器工作原理与内部时钟的滤波器相似它的值可以是0x00到0x0F之间的一个值其决定了采样的f和N具体的对应关系在手册中有对应表 4.GPIO配置因为是使用外部接口输入时钟故在使用该函数之前还需要配置GPIO端口。对于定时器手册中给的推荐配置是浮空输入。但是浮空输入会导致引脚的输入电平极易受干扰所以输入信号的功率不小时一般选择上拉或下拉输入。当外部的输入信号功率很小内部的上拉/下拉电阻较大可能会影响到这个输入信号这时就需要用浮空输入防止影响外部输入的电平。 5. STM32F103 本节使用到的TIM定时器函数介绍
打开Keil5中文件 stm32f10x_tim.h 在文件的尾部位置就是 stm32f103 TIM 定时器的操作函数原型可以看到定时器操作的函数还是比较多的我们先学习本节要使用到的函数后面的在使用的时候再慢慢学习。
void TIM_DeInit(TIM_TypeDef* TIMx);定时器去恢复默认配置void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);定时器“时基单元”配置void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);“时基单元”结构体初始化为默认配置void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);定时器控制启动停止 定时器void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);定时器中断配置允许产生定时器中断void TIM_InternalClockConfig(TIM_TypeDef* TIMx);定时器选择内部时钟源void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);定时器选择外部时钟源 ITRxvoid TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource, uint16_t TIM_ICPolarity, uint16_t ICFilter);定时器选择外部时钟源 TIx参数预分频极性过滤器void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);定时器选择外部时钟源 ETR时钟模式1参数预分频极性过滤器void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);定时器选择外部时钟源 ETR时钟模式2参数预分频极性过滤器void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);定时器外部时钟源ETR配置预分频极性过滤器 5.1 ➡️定时器使用的步骤
按照如下stm32f10x 定时器的框图使用stm32 定时器基本按照如下的基本步骤 启用RCC内部时钟这样stm32外设和定时器才有时钟源输入。定时钟时钟源选择可以选择内部时钟源外部时钟源ETR外部ITRx外部TIx捕获通道。时基单元配置配置时钟预分频器自动重装载器定时器中断输出控制允许定时器更新中断进入NVICNVIC中配置定时器中断的优先级定时器运行控制启动定时器 5.2 ➡️定时器时基单元配置
在stm32f10x_tim.h中定时器时基单元配置函数原型如下
void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);定时器“时基单元”配置
‘TIM_TimeBaseInit’接收两个输入参数一个是定时器TIMx一个是时基单元配置结构体该函数配置定时器框图中的如下红框部分。 5.3 ➡️定时器时钟源选择 5.3.1 定时器选择内部时钟源函数原型如下
void TIM_InternalClockConfig(TIM_TypeDef* TIMx);定时器选择内部时钟源
该函数选择stm32定时器的时钟源为内部时钟源也就是如下图中箭头所示从内部时钟源进入时基单元。 5.3.2 定时器选择外部时钟源ITRx函数原型如下
void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);定时器选择外部时钟源 ITRx
该函数选择stm32定时器的时钟源为外部时钟源ITRx也就是如下图中箭头所示从外部时钟源ITRx进入时基单元。 5.3.3 定时器选择外部时钟源TIx函数原型如下
void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource, uint16_t TIM_ICPolarity, uint16_t ICFilter);定时器选择外部时钟源 TIx参数预分频极性过滤器
该函数选择stm32定时器的时钟源为外部时钟源TIx也就是如下图中箭头所示从外部时钟源TIx进入时基单元。 5.3.4 定时器选择外部时钟源ETR 外部时钟模式2函数原型如下
void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);定时器选择外部时钟源 ETR时钟模式2参数预分频极性过滤器
该函数选择stm32定时器的时钟源为外部时钟源ETR 外部时钟模式2也就是如下图中箭头所示从外部时钟源进入时基单元。 5.3.5 定时器选择外部时钟源ETR 外部时钟模式1函数原型如下 该函数选择stm32定时器的时钟源为外部时钟源ETR 外部时钟模式1也就是如下图中箭头所示从外部时钟源进入时基单元。 5.4 ➡️定时器除上面的时基单元配置内/外时钟源选择本节可能用到的函数
定时器除上面的时基单元配置内/外时钟源选择外本节可能用到的函数还有如下
void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode);定时器预分频值设置函数参数处预分频值外还有预分频值Reload重加载模式设置是否使用预分频值“影子寄存器”是预分频值设置立即生效还是预分频值先写入“影子寄存器”等到“更新事件”时再生效void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode);定时器计数器计数模式向上计数向下计数void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);定时器ARR重装载寄存器预装载功能是否启用void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter);给定时器计数器设置一个值void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint16_t Autoreload);给定时器自动重装载寄存器设置一个值uint16_t TIM_GetCounter(TIM_TypeDef* TIMx);获取计数器的值uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx);获取预分频器的值 6.实验1-定时器定时中断实例
本次实验要完成的现象是定义一个 uint16_t 的 Num 变量使其每秒1。器件连接图和程序源码如下所示 timer.c
#include stm32f10x.h // Device header
#include Timer.hvoid Timer_Init(void)
{//Setp 1.//RCC APB1的外设时钟控制因为TIM2在STM32的APB1外设总线上RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//Setp 2.//选择时基单元的时钟使用内部RCC时钟 CLK_INT (Clock_Internal)TIM_InternalClockConfig(TIM2);//Setp 3.//配置时基单元TIM_TimeBaseInitTypeDef TimeBaseInitStruct;TimeBaseInitStruct.TIM_ClockDivision TIM_CKD_DIV1; //时钟信号滤波使用滤波的采样频率采样点数TimeBaseInitStruct.TIM_CounterMode TIM_CounterMode_Up; //计数器向上计数TimeBaseInitStruct.TIM_Period 10000 - 1; //Auto-Reload Register 自动重装载寄存器的值记得需要减一TimeBaseInitStruct.TIM_Prescaler 7200 - 1; //预分频器的值记得需要减一TimeBaseInitStruct.TIM_RepetitionCounter 0; //重复计数器的值 TIM_TimeBaseInit(TIM2, TimeBaseInitStruct);//Setp 4.//使能定时中断TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);//Setp 5.//NVIC配置NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //NVIC优先级分组NVIC_InitTypeDef NVIC_InitStruct;NVIC_InitStruct.NVIC_IRQChannel TIM2_IRQn;NVIC_InitStruct.NVIC_IRQChannelCmd ENABLE;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority 2;NVIC_InitStruct.NVIC_IRQChannelSubPriority 1;NVIC_Init(NVIC_InitStruct); //NVIC配置定时器中断优先级//Setp 6.//定时器启动TIM_Cmd(TIM2, ENABLE);
}uint16_t Num;//定时器TIM2中断处理函数
void TIM2_IRQHandler(void)
{//检查中断标志位if(SET TIM_GetITStatus(TIM2, TIM_IT_Update)){Num;//清除中断标志位TIM_ClearITPendingBit(TIM2, TIM_IT_Update);}
}timer.h
#ifndef __TIMER_H__
#define __TIMER_H__
void Timer_Init(void);
#endifmain.c
#include stm32f10x.h // Device header
#include oled.h
#include Countersensor.h
#include Encoder.h
#include Timer.hextern uint16_t Num;int main(int argc, char *argv[])
{ OLED_Init();OLED_ShowString(1, 1, Cnt:);Timer_Init();while(1){OLED_ShowNum(1,5,Num,5);}return 1;
} 6.1 实验结果
实验结果如下 6.1 实验一个小问题按下Reset键之后Cnt值从1开始增加 江科大STM32本节教程里提到本TIM定时器中断实验一个小问题按下Reset键之后Cnt值从1开始增加。本地测试结果的确也是按下开发板上Reset按键之后OLED显示屏上Cnt的值从1开始增加。 江科大STM32本节教程讲解了出现这个问题的原因在stm32f10x_timeer.c 中找到 TIM_TimeBaseInit()的函数实现。 在函数的结尾 为什么要加这个我们知道预分频器是有一个缓冲寄存器的我们写的值只有在更新事件时才真正起作用所以这里为了让值立即起作用就在这里最后手动生成了一个更新事件这样预分频器的值就有效了但同时它的副作用是更新事件和更新中断是同时发生的更新中断会置更新中断标志位当我们之后一旦初始化晚了更新中断就会立刻进入。这就是我们刚一上电就立刻进中断的原因。 那解决方法也非常简单。 就是在Time_BaseInit()的后面在开启中断的前面手动调用一下 Time_CleanFlag(TIME2, X) 将更新中断标志位清除一下就能避免刚初始化我那侧灰姑娘就进中断的问题了。 Timer.c
#include stm32f10x.h // Device header
#include Timer.hvoid Timer_Init(void)
{//Setp 1.//RCC APB1的外设时钟控制因为TIM2在STM32的APB1外设总线上RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//Setp 2.//选择时基单元的时钟使用内部RCC时钟 CLK_INT (Clock_Internal)TIM_InternalClockConfig(TIM2);//Setp 3.//配置时基单元TIM_TimeBaseInitTypeDef TimeBaseInitStruct;TimeBaseInitStruct.TIM_ClockDivision TIM_CKD_DIV1; //时钟信号滤波使用滤波的采样频率采样点数TimeBaseInitStruct.TIM_CounterMode TIM_CounterMode_Up; //计数器向上计数TimeBaseInitStruct.TIM_Period 10000 - 1; //Auto-Reload Register 自动重装载寄存器的值记得需要减一TimeBaseInitStruct.TIM_Prescaler 7200 - 1; //预分频器的值记得需要减一TimeBaseInitStruct.TIM_RepetitionCounter 0; //重复计数器的值 TIM_TimeBaseInit(TIM2, TimeBaseInitStruct);//在TIM_TimeBaseInit()之后在启用中断之前手动清除一下定时器更新中断标志位//就能避免初始化之后就立即进入中断的问题了。TIM_ClearITPendingBit(TIM2, TIM_IT_Update);//Setp 4.//使能定时中断TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);//Setp 5.//NVIC配置NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //NVIC优先级分组NVIC_InitTypeDef NVIC_InitStruct;NVIC_InitStruct.NVIC_IRQChannel TIM2_IRQn;NVIC_InitStruct.NVIC_IRQChannelCmd ENABLE;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority 2;NVIC_InitStruct.NVIC_IRQChannelSubPriority 1;NVIC_Init(NVIC_InitStruct); //NVIC配置定时器中断优先级//Setp 6.//定时器启动TIM_Cmd(TIM2, ENABLE);
}
此时再使用Keil5 MDK编译STLink下载到开发板测试一下按下 Reset 按钮之后OLED屏幕上Cnt值就从 0 开始增加了问题解决。 7.实验2-定时器外部时钟选择
本实验使用定时器外部时钟源 EXT mode2 (External Trigger mode2)。 * 可以在引脚定义图里找TIMx的ETR引脚是哪个 * 在上一个定时中断实例程序基础上进行更改基本任务仍然是定时中断时钟部分就不使用内部时钟了 本次实验要完成的现象是用光敏传感器手动模拟一个外部时钟定义一个 uint16_t 的 Num 变量当外部时钟触发10次预分频之后的脉冲后Num 1。器件连接图和程序源码如下所示 timer.c
#include stm32f10x.h // Device header
#include Timer.hvoid Timer_Init(void)
{//Setp 1.//RCC APB1的外设时钟控制因为TIM2在STM32的APB1外设总线上RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//GPIO初始化//开启GPIO外设时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode GPIO_Mode_IPU; //上拉输入GPIO_InitStruct.GPIO_Pin GPIO_Pin_0;GPIO_InitStruct.GPIO_Speed GPIO_Speed_50MHz;GPIO_Init(GPIOA, GPIO_InitStruct);//Setp 2.//选择时基单元的时钟使用内部RCC时钟 CLK_INT (Clock_Internal)//TIM_InternalClockConfig(TIM2);//选择时基单元的时钟使用外部时钟ETR mode2TIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x0f);//Setp 3.//配置时基单元TIM_TimeBaseInitTypeDef TimeBaseInitStruct;TimeBaseInitStruct.TIM_ClockDivision TIM_CKD_DIV1; //时钟信号滤波使用滤波的采样频率采样点数TimeBaseInitStruct.TIM_CounterMode TIM_CounterMode_Up; //计数器向上计数TimeBaseInitStruct.TIM_Period 10 - 1; //Auto-Reload Register 自动重装载寄存器的值记得需要减一TimeBaseInitStruct.TIM_Prescaler 1 - 1; //预分频器的值记得需要减一TimeBaseInitStruct.TIM_RepetitionCounter 0; //重复计数器的值 TIM_TimeBaseInit(TIM2, TimeBaseInitStruct);//在TIM_TimeBaseInit()之后在启用中断之前手动清除一下定时器更新中断标志位//就能避免初始化之后就立即进入中断的问题了。TIM_ClearITPendingBit(TIM2, TIM_IT_Update);//Setp 4.//使能定时中断TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);//Setp 5.//NVIC配置NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //NVIC优先级分组NVIC_InitTypeDef NVIC_InitStruct;NVIC_InitStruct.NVIC_IRQChannel TIM2_IRQn;NVIC_InitStruct.NVIC_IRQChannelCmd ENABLE;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority 2;NVIC_InitStruct.NVIC_IRQChannelSubPriority 1;NVIC_Init(NVIC_InitStruct); //NVIC配置定时器中断优先级//Setp 6.//定时器启动TIM_Cmd(TIM2, ENABLE);
}uint16_t Num;//定时器TIM2中断处理函数
void TIM2_IRQHandler(void)
{//检查中断标志位if(SET TIM_GetITStatus(TIM2, TIM_IT_Update)){Num;//清除中断标志位TIM_ClearITPendingBit(TIM2, TIM_IT_Update);}
}7.1 实验结果 7.2 实验注意和经验总结 1.初始化GPIOA PA0的时候需要注意使用的是 RCC_APB2PeriphClockCmd 别错误的写成了 RCC_APB1PeriphClockCmd编译器并不会报错但是GPIOA却没有启用RCC时钟是因为 GPIOA 是挂载 APB2上的外设不能使用RCC_APB1开启它的时钟。 2. 在做定时器外部时钟源选择 ETR mode2的实验的时候需要注意调小时钟源的预分频器值和重装载器的值。因为手动使用红外对射传感器的方式来产生方波信号的频率很低如果有一个很大的预分频值则需要产生很多的预分频方波信号之后才能产生一个计数器时钟信号让计数器加一。 8. 结束
本章至此结束 文章转载自: http://www.morning.wtdhm.cn.gov.cn.wtdhm.cn http://www.morning.nlgyq.cn.gov.cn.nlgyq.cn http://www.morning.hongjp.com.gov.cn.hongjp.com http://www.morning.ptwrz.cn.gov.cn.ptwrz.cn http://www.morning.yqtry.cn.gov.cn.yqtry.cn http://www.morning.wfmqc.cn.gov.cn.wfmqc.cn http://www.morning.lnsnyc.com.gov.cn.lnsnyc.com http://www.morning.fplqh.cn.gov.cn.fplqh.cn http://www.morning.tqqfj.cn.gov.cn.tqqfj.cn http://www.morning.cfnsn.cn.gov.cn.cfnsn.cn http://www.morning.pflry.cn.gov.cn.pflry.cn http://www.morning.zrlms.cn.gov.cn.zrlms.cn http://www.morning.dgsr.cn.gov.cn.dgsr.cn http://www.morning.ngzkt.cn.gov.cn.ngzkt.cn http://www.morning.gcbhh.cn.gov.cn.gcbhh.cn http://www.morning.znqxt.cn.gov.cn.znqxt.cn http://www.morning.mlpmf.cn.gov.cn.mlpmf.cn http://www.morning.wrtpk.cn.gov.cn.wrtpk.cn http://www.morning.hxrg.cn.gov.cn.hxrg.cn http://www.morning.tlpgp.cn.gov.cn.tlpgp.cn http://www.morning.jpmcb.cn.gov.cn.jpmcb.cn http://www.morning.yxwrr.cn.gov.cn.yxwrr.cn http://www.morning.rnsjp.cn.gov.cn.rnsjp.cn http://www.morning.qpntn.cn.gov.cn.qpntn.cn http://www.morning.ptmgq.cn.gov.cn.ptmgq.cn http://www.morning.sfsjh.cn.gov.cn.sfsjh.cn http://www.morning.wypyl.cn.gov.cn.wypyl.cn http://www.morning.pnjsl.cn.gov.cn.pnjsl.cn http://www.morning.qyxwy.cn.gov.cn.qyxwy.cn http://www.morning.sgqw.cn.gov.cn.sgqw.cn http://www.morning.xrlwr.cn.gov.cn.xrlwr.cn http://www.morning.grxsc.cn.gov.cn.grxsc.cn http://www.morning.rxnxl.cn.gov.cn.rxnxl.cn http://www.morning.wqkzf.cn.gov.cn.wqkzf.cn http://www.morning.sbwr.cn.gov.cn.sbwr.cn http://www.morning.byrlg.cn.gov.cn.byrlg.cn http://www.morning.xmxbm.cn.gov.cn.xmxbm.cn http://www.morning.zgztn.cn.gov.cn.zgztn.cn http://www.morning.msbmp.cn.gov.cn.msbmp.cn http://www.morning.blxlf.cn.gov.cn.blxlf.cn http://www.morning.bzlfw.cn.gov.cn.bzlfw.cn http://www.morning.jbmsp.cn.gov.cn.jbmsp.cn http://www.morning.lnbyk.cn.gov.cn.lnbyk.cn http://www.morning.fpzpb.cn.gov.cn.fpzpb.cn http://www.morning.tgfsr.cn.gov.cn.tgfsr.cn http://www.morning.wnhgb.cn.gov.cn.wnhgb.cn http://www.morning.gfqj.cn.gov.cn.gfqj.cn http://www.morning.lxwjx.cn.gov.cn.lxwjx.cn http://www.morning.qjghx.cn.gov.cn.qjghx.cn http://www.morning.wpmlp.cn.gov.cn.wpmlp.cn http://www.morning.glnmm.cn.gov.cn.glnmm.cn http://www.morning.nnwpz.cn.gov.cn.nnwpz.cn http://www.morning.jzgxp.cn.gov.cn.jzgxp.cn http://www.morning.nnttr.cn.gov.cn.nnttr.cn http://www.morning.alwpc.cn.gov.cn.alwpc.cn http://www.morning.rqsnl.cn.gov.cn.rqsnl.cn http://www.morning.pwsnr.cn.gov.cn.pwsnr.cn http://www.morning.bpmdn.cn.gov.cn.bpmdn.cn http://www.morning.zlgth.cn.gov.cn.zlgth.cn http://www.morning.wnpps.cn.gov.cn.wnpps.cn http://www.morning.tmtrl.cn.gov.cn.tmtrl.cn http://www.morning.rnmmh.cn.gov.cn.rnmmh.cn http://www.morning.lhxrn.cn.gov.cn.lhxrn.cn http://www.morning.pphbn.cn.gov.cn.pphbn.cn http://www.morning.xbptx.cn.gov.cn.xbptx.cn http://www.morning.jwxmn.cn.gov.cn.jwxmn.cn http://www.morning.txmkx.cn.gov.cn.txmkx.cn http://www.morning.ftmp.cn.gov.cn.ftmp.cn http://www.morning.xnlj.cn.gov.cn.xnlj.cn http://www.morning.rhmk.cn.gov.cn.rhmk.cn http://www.morning.chmkt.cn.gov.cn.chmkt.cn http://www.morning.kbkcl.cn.gov.cn.kbkcl.cn http://www.morning.nhlnh.cn.gov.cn.nhlnh.cn http://www.morning.rywr.cn.gov.cn.rywr.cn http://www.morning.tdxlj.cn.gov.cn.tdxlj.cn http://www.morning.bpmnj.cn.gov.cn.bpmnj.cn http://www.morning.qgghj.cn.gov.cn.qgghj.cn http://www.morning.rtmqy.cn.gov.cn.rtmqy.cn http://www.morning.lbpfl.cn.gov.cn.lbpfl.cn http://www.morning.hjrjy.cn.gov.cn.hjrjy.cn