专业商城网站建设多少钱,百度关键词规划师工具,网站建设技术支持,wordpress评论编辑器目录
1. 相关寄存器介绍
1.1 控制寄存器 1(TIMx_CR1)编辑
1.2 DMA/中断使能寄存器(TIMx_DIER)
1.3 状态寄存器(TIMx_SR)
1.4 计数器(TIMx_CNT)
1.5 预分频器(TIMx_PSC)
1.6 自动重装载寄存器(TIMx_ARR)
2. 工程建立
3. 导入tim.c文件
4. 相关HAL库函数介绍
4.1 H…目录
1. 相关寄存器介绍
1.1 控制寄存器 1(TIMx_CR1)编辑
1.2 DMA/中断使能寄存器(TIMx_DIER)
1.3 状态寄存器(TIMx_SR)
1.4 计数器(TIMx_CNT)
1.5 预分频器(TIMx_PSC)
1.6 自动重装载寄存器(TIMx_ARR)
2. 工程建立
3. 导入tim.c文件
4. 相关HAL库函数介绍
4.1 HAL_TIM_Base_Init()
4.2 HAL_TIM_Base_MspInit()
4.3 HAL_TIM_Base_Start_IT()
5. 编写代码 书接上文本篇是对基本定时器实验部分进行总结 实验目标通过TIM6基本定时器定时500ms让LED0每隔500ms闪烁。 解决思路使用定时器6实现500ms产生一次定时器更新中断在中断里执行“翻转LED0”。 定时器什么时候会产生更新中断呢
有两种情况第一种是定时器计数到ARR值后溢出这时会伴随更新事件和更新中断的产生第二种是通过软件的方式设置UG位产生软件的更新中断从而产生更新中断。 1. 相关寄存器介绍
首先我们来学习控制寄存器 1(TIMx_CR1)、DMA/中断使能寄存器(TIMx_DIER)、状态寄存器(TIMx_SR)、计数器(TIMx_CNT)、预分频器(TIMx_PSC)、自动重装载寄存器(TIMx_ARR)的功能。
1.1 控制寄存器 1(TIMx_CR1)
首先介绍位7由上篇理论部分的笔记中我们知道 影子寄存器是实际起作用的寄存器不能直接访问而ARPE位决定了ARR是否具有缓冲当设置为有缓冲时ARR的预装载寄存器写入某个值这个值不会立即起作用必须等到更新事件发生时才会把ARR的预装载寄存器的值转移到影子寄存器从而真正起作用生效而设置无缓冲时给ARR的预装载寄存器写入某个值它会立即转移到影子寄存器中会立即生效。立即生效的时间可能在ns或是us级 预装载寄存器实际上起到一个缓冲的作用。 比如我们想让LED灯实现亮1s灭2s的功能那么我们就需要对应操作ARR寄存器的值。假设系统时钟为72MHz定时器预分频系数为720072000000/(71991)10000定时器将以10KHz的频率计数即1s计10000个数那么ARR值就为9999倘若定时2sARR值需要修改为19999。
当ARPE配置为0即ARR寄存器无缓冲时我们先把ARR的值设为9999定时1s1s时间到达之后需要再次操作ARR寄存器的值变为19999来定时2s而操作ARR寄存器也需要一定时间可能是ns或us级相对于秒级来说微秒可以忽略不计了但是如果定时的是50us而操作ARR寄存器的时间也是微秒级那就会有误差了
当ARPE配置为1即ARR寄存器有缓冲时先让ARR设为9999生效定时1s这时我们再次修改ARR的值为19999当1s到之后更新事件发生才会把19999从ARR预装载寄存器转移到影子寄存器从而节省了操作ARR寄存器的时间精度也会很准确
总结一下有缓冲提前写入减少误差无缓冲按时写入有误差。 再者介绍位0CEN计数器使能默认情况下该位为0计数器是关闭的状态开启时把该位置1。 总结控制寄存器1在该实验的功能用于设置ARR寄存器是否具有缓冲使能/关闭计数器 1.2 DMA/中断使能寄存器(TIMx_DIER) 默认条件下位8和位0都是0都是禁止状态。
当把位8置1即使能更新DMA请求计数器计数溢出时就会产生DMA请求
同理把位0置1当计数器溢出时会产生更新中断。此次实验用到了位0没有用到位8。 总结中断使能寄存器在该实验的功能用于使能更新中断 1.3 状态寄存器(TIMx_SR) 该寄存器只有位0有效当计数器溢出时产生更新中断该位被硬件置1由程序编写清除。 总结用于判断是否发生了更新中断由硬件置1软件清零 1.4 计数器(TIMx_CNT) 16位的计数器实时数值可用于设置计时器初始值范围0~65535
1.5 预分频器(TIMx_PSC) 用于设置预分频系数范围0~65535实际预分频系数等于PSC1。
1.6 自动重装载寄存器(TIMx_ARR) 当更新时间发生时才会把预装载寄存器的值传送到其对应的影子寄存器当中用于设置自动重装载值范围0~65535。 总结预分频器和自动重装载寄存器实际起作用的都是对应的影子寄存器。 2. 工程建立
介绍完相关寄存器之后现在开始实操训练了。也是以正点原子HAL库 实验1 跑马灯实验为基础相当于是工程模板了我们复制工程在“Drivers--BSP”目录下建立TIMER文件夹并创建tim.c和tim.h文件 3. 导入tim.c文件
导入方法和上篇帖子一样不清楚的小伙伴可以参考⬇⬇⬇⬇⬇ 正点原子--STM32中断系统学习笔记(2) 在tim.h文件中添加这部分代码之后自己新建的.c和.h文件都会按照此模板创建
#ifndef _TIM_H
#define _TIM_H
#include ./SYSTEM/sys/sys.h#endif
重要的一点是要添加hal库tim的驱动文件不然编译不通过
4. 相关HAL库函数介绍 4.1 HAL_TIM_Base_Init()
我们找到这个函数的定义分别去HAL_StatusTypeDef和TIM_HandleTypeDef里面看看。 返回值 形参为定时器的句柄 下图为TIM6定时器的基地址 定时器初始化结构体成员 Prescaler/*预分频系数*/ 对应操作PSC寄存器 CounterMode/*计数模式*/ 基本定时器只有向上计数模式 Period/*自动重载值*/ 对应操作ARR寄存器 ClockDivision/*时钟分频因子*/ 基本定时器无该寄存器只有通用/高级寄存器才需要配置 RepetitionCounter/*重复计数器寄存器的值*/ 基本/通用定时器都无该寄存器只有高级定时器才有用 AutoReloadPreload/*自动重载预装载使能*/ 对应控制寄存器1的位7ARPE 在这次实验当中我们只用到了三个Prescaler、Period、AutoReloadPreload.
4.2 HAL_TIM_Base_MspInit() 该函数没有对应的寄存器__weak是弱定义用户可自己编写主要在函数里存放NVIC、CLOCK、GPIO初始化代码。
4.3 HAL_TIM_Base_Start_IT() 中断处理函数和更新中断回调函数在之前的中断帖子有介绍大同小异 正点原子--STM32中断系统学习笔记(1) 5. 编写代码 配置思路我们按照正点原子给的步骤一步步来配置最重要的是学习配置思路一通百通 ①在定时器中断初始化函数里对定时器的参数进行配置包括基地址、自动重装载值、预分频值以及使能更新中断并开启计数器
②在定时器基础MSP初始化函数里先进行检测是否为TIM6定时器如果是TIM6那么就使能TIM6时钟并设置中断优先级和使能中断这点和标准库配置有些差别标准库是一开始就先使能时钟而HAL库是在这个函数里完成那些功能
③在TIM6中断服务函数里调用定时器中断公共处理函数在定时器中断公共处理函数里进行清中断标志位调用定时器中断回调函数HAL_TIM_IC_CaptureCallback()的操作。 ④ 在定时器溢出中断回调函数里先进行检测是否为TIM6定时器如果是TIM6那么就进行LED0的翻转。
执行流程 在main函数里先进行定时器中断初始化配置tim_it_init(4999, 7199) 定时500ms时间一到便会产生定时器更新中断进入TIM6中断服务函数执行定时器中断公共处理函数进行清中断标志位调用定时器中断回调函数在回调函数里进行LED灯的翻转 以下是tim.c的代码
#include ./BSP/TIMER/tim.h
#include ./BSP/LED/led.hTIM_HandleTypeDef tim_handle;/* 定时器中断初始化函数 */
void tim_it_init(uint16_t arr, uint16_t psc)
{tim_handle.Instance TIM6;tim_handle.Init.Prescaler psc;tim_handle.Init.Period arr;HAL_TIM_Base_Init(tim_handle); /* 配置定时器基础工作参数 */HAL_TIM_Base_Start_IT(tim_handle); /* 使能更新中断并启动计数器 */
}/* 定时器基础MSP初始化函数 */
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
{if(htim-Instance TIM6) /* 判断定时器的基地址是否为TIM6 */{__HAL_RCC_TIM6_CLK_ENABLE(); /* 使能定时器6时钟 */HAL_NVIC_SetPriority(TIM6_IRQn, 0, 0); /* 设置优先级 */HAL_NVIC_EnableIRQ(TIM6_IRQn); /* 使能中断 */}
}/* 定时器6中断服务函数 */
void TIM6_IRQHandler(void)
{HAL_TIM_IRQHandler(tim_handle); /* 定时器中断公共处理函数 */
}/* 定时器溢出中断 中断回调函数 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if(htim-Instance TIM6) /* 判断定时器的基地址是否为TIM6 */{LED0_TOGGLE();LED1_TOGGLE();}
}main.c代码
#include stm32f1xx_it.h
#include ./SYSTEM/sys/sys.h
#include ./SYSTEM/delay/delay.h
#include ./SYSTEM/usart/usart.h
#include ./BSP/LED/led.h
#include ./BSP/TIMER/tim.hint main(void)
{HAL_Init(); /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟,72M */delay_init(72); /* 初始化延时函数 */led_init(); /* 配置STM32操作LED相关的寄存器 */tim_it_init(4999, 7199); /* 初始化定时器 */while(1){}
}以上就是基本定时器实验的所有内容了 本篇完。
本人博客仅代表个人见解方便记录成长笔记。
若有不足请指出感谢您的阅读