HAL库学习
一些小细节!
-
alt + / 触发自动补全
-
定时器初始化函数MX_TIM2_Init在进行初始化的时候会把中断标志位至1,导致每次启动时钟都会调用一次中断回调函数!
如果影响了程序的正确运行则需要在初始化后立马将标志位至0
-
相较于TI1和TI2组成的输入捕获通道组合,TI3和TI4的这个组合的线路没有接入到从模式控制器当中,没有接入到编码器上。
-
在设置定时器的启动的时候,如
-
HAL_TIM_Base_Start(&htim1); 和 HAL_TIM_Base_Start_IT(&htim1); 的区别在于加了TI的会启用定时器更新中断。
-
中断函数重定义要写void
GPIO
GPIO的变量类型
GPIO_PinState state = GPIO_PIN_SET;
GPIO的输入输出
GPIO的输出
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
GPIO的输入
输入捕获模式
捕获寄存器
每一个通用定时器和高级定时器的每一个通道都会存在一个捕获寄存器
定时器启动计数之后,如果设置的信号源产生的相应的电平,则会立马将计数器当中的数值存储到捕获寄存器当中
与此同时如果设置了输入捕获中断,则还会触发一次输入捕获中断
输入捕获通道不可以设置下降沿和上升沿同时触发,所以可以使用直接模式连接和间接模式连接来将另一个边沿对应的计数器的值记录。
直接模式和间接模式的定义是相对的,如果TI1为信号输入线,则捕获寄存器1对应的模式为直接,寄存器2为间接
- 其中,TI1和TI2、TI3和TI4分别为两对,它们在输入捕获的线路原理图方面是相同的。
输入捕获的软件配置
输入捕获函数的配置并非在此界面!
如上图,向下寻找到通道3和4的设置界面,其中我配置通道三为上升沿触发,直接模式,没有分频且不滤波。
而通道四为下降沿触发,间接模式,没有分频且不滤波。
在NVIC当中使能输入捕获中断即可,不需要调整从模式控制器
输入捕获模式不需要定时器更新中断,于是在使能定时器的函数中删去IT
使能计数器和输入捕获IC的代码如下
HAL_TIM_Base_Start(&htim1);
HAL_TIM_IC_Start(&htim,TIM_CHANNEL_3);
HAL_TIM_IC_Start_IT(&htim,TIM_CHANNEL_4);
- 注意到通道4增加了IT后缀,会触发输入捕获中断函数!
- 在输入捕获中断函数中,读取两个寄存器的值,做差,再进行计算就可知晓信号源高电平的时间长短
想象一个情况:通道3记录的计数器的值为65534,随后通道4因为计数器重装载记录到的值为一个小于65534的读数,就会导致计算错误
解决方法:触发通道3的中断之后,立马重置计数器的值,使得通道4存储的值即为时间差
重置函数为
__HAL_TIM_SET_COUNTER(&htim1,0);
输入捕获中断回调函数的配置
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if (htim == &htim1 && htim -> Channel == HAL_TIM_ACTIVE_CHANNEL_4)
{
upEdge = HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_3);
downEdge = HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_4); //读取通道3/4的捕获寄存器
//code
}
}
其中,每次触发通道3/4的设定电平变化条件,就会自动设置通道标志位 htim -> Channel
输入比较模式
- 冻结模式:屁用没有,开启后输出维持原样
- 强制有效模式:屁用没有,强制输出100%占空比信号
- 强制无效模式:屁用没有,强制输出0%占空比信号
- 匹配时有效模式:寄存器和计数器相同时输出有效电平
- 匹配时无效模式:寄存器和计数器相同时输出无效电平
- 匹配时翻转模式:寄存器和计数器相同时翻转输出电平
- PWM模式:最有存在感的模式,包含PWM1和PWM2模式(详见PWM部分)
输入比较寄存器
在一开始设定比较寄存器的值,然后定时器不断比较比较寄存器和计数器的值,根据大小关系来决定输出的是高电平还是低电平
DMA
- DMA触发的中断不会阻塞程序的执行
UART-串口
- UART触发的中断不会阻塞程序的执行
串口的发送
在软件界面设置即可,其中
- Asynchronous模式:
- 在这种模式下,USART的工作方式是异步的,也就是说,它不依赖于外部时钟信号进行同步。数据以特定的波特率进行传输,发送和接收端必须在同一波特率下工作。通常用于标准的串口通讯,如RS-232协议。
- Synchronous模式:
- 如果讨论同步模式,则USART在发送和接收数据时使用一个共享的时钟信号,这样可以更精确地控制数据传输,适合于高速数据传输场景。
设置好下方的波特率即可使用串口
通过串口发送函数发送内容
HAL_UART_Transmit(&huart2(uint8_t)message,strlen(string),100);
其中,message是需要发送的内容的指针,最后一个参数是等待时间,最高为HAL_MAX_DELAY
- 一般发送内容时等待时间写100(ms),接收写HAL_MAX_DELAY(无限时间等待)
串口的接收
uint8_t receiveData [2]; //设置好接收串口内容的数组
HAL_UART_Receive(&huart2,receiveData,2,HAL_MAX_DELAY); //这次使用了uint8_t为接收数组,所以不需要类型转换
如上图,定义了一个GPIO_PinState
类型的、名为state的变量,随后根据计算机发送的信息控制灯的亮灭
(R、G、B控制颜色,0、1控制亮灭)
串口中断发送数据的内容在下面的中断内容中提及
时钟、时钟树、两者和总线的联系
在RCC中设置时钟为晶振,且在时钟树中选择72MHz回车修改即可
关于时钟树更底层的内容----时钟与时钟树
时钟源是心脏,而时钟树则是时钟的动脉。
AHB 先进高性能总线当中的HCLK时钟线
其中内存、处理器和DMA直连HCLK(72MHz)
处理器内部存在一个Sys Tick 滴答定时器,由HCLK分频而来,HAL_Delay就是根据此定时器实现延时功能
APB 先进外设总线
挂载在AHB上,为外设提供时钟支持
APB1(IIC USB CAN SPI2/3 USART1 通用定时器 基本定时器)
APB2 (USART1 SPI1 GPIO ADC 中断 高级定时器TIM)
高速内部时钟(HSI)、高速外部时钟(HSE)、系统时钟(SYSCLK)
HSI
存在于芯片内部,8MHz,精度较低
HSE
外接晶振,精度高,频率根据型号有所区别,能耗高
LSE
内部时钟源,速度慢但是节能!
SYSCLK
区别于滴答时钟SYSTick
SYSCLK可以接入HSI或者HSE,而HSE经过锁相环倍频可产生72MHz的频率
定时器
定时器就是计数器
通过设定APB接入的时钟信号来确定方波信号,而方波信号连接一个最大为65535的寄存器,然后通过预分频器,通过时钟频率和寄存器的数值来计算出时间(103c8t6上只有TIM1-4)
- 通用定时器 TIM 2-5
- 基本定时器 TIM 6-7
- 高级定时器 TIM 1 and 8
当预分频器设置为0时不分频,为1时二分频,以此类推
自动重装载寄存器
监控计数器的值是否和自己(自动重装载寄存器)相同,当相同时则将计数器归零,并且触发定时中断回调函数
- 如果需要设置收到m个脉冲重装载的话,则自动装载寄存器的值应该设置为m-1
定时器的使能
勾选Internal clock
在STM32CubeMX中,TIM的Internal Clock来自下方的APBx Timer clock(MHz)
在参考的样例当中,APB1和APB2的28均改为72MHz
设置计数器的分频和自动重装载
在这里使用了7200分频,使得72MHz的信号变为10000Hz,随后重装载为10000,所以当计数满10000的时候会触发中断,也就意味着每一秒会触发一次中断
代码部分
写入HAL_TIM_Base_Start(&htim4);在while函数之前,tim4init函数之后。随后tim4就会按照设置好的工作状态工作
HAL_TIM_Base_Start(&htim4);
__HAL_TIM_GET_COUNTER(&htim4); //通过函数获取计数器的值
__HAL_TIM_SET_COUNTER(&htim4); //通过函数设置计数器的值
__HAL_TIM_GET_COUNTER(&htim4); //通过函数获取重装载寄存器的值
__HAL_TIM_SET_COUNTER(&htim4); //通过函数设置重装载寄存器的值
__HAL_TIM_SET_PRESCALER(&htim4); //通过函数设置预分频器的值
这个是影子寄存器的使能,如果使能了影子寄存器,则更改完预分频器之后不会立马生效,会等到下一个周期才生效更改的值
如果失能可能会导致一些bug,使得计数器和重装载器的值错过,导致计数器到65535才能触发
TIM的中断函数
打开TIM4的NVIC,勾选即可
触发条件:计数器数值达到设定值时触发中断
将HAL_TIM_Base_Start(&htim4);函数改为如下即可
HAL_TIM_Base_Start_IT(&htim4);
然后找到中断回调函数,编写中断时需要执行的代码内容(此函数写在main.c当中ji'ke
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim == &htim4)
{
//执行的代码内容
}
}
中断
定时器的计数不需要cpu的参与,但是中断回调函数的内容需要cpu来执行
中断回调函数采用__weak若定义声明,旨在用户自己在主程序当中自发定义其内容
此函数功能对应了每次触发中断后在屏幕上显示字符串内容
定时器更新中断
slave mode 设定为reset mode,实现每次上升或下降沿触发一次定时器重装载中断,在更新定时器数字为0后,还可以同时执行弱定义的中断回调函数当中的内容。也就意味着中断回调函数的内容会有两个执行入口,一个是计数器重装载时产生的自发性质的中断,另一个是指定引脚接入的信号跳变产生的中断
如何判断中断究竟是因为定时器溢出还是由于信号跳变?
当信号触发reset中断的时候,存在
__HAL_TIM_GET_FLAG(htim,TIM_FLAG_TRIGGER) == SET;
如果中断回调函数加入了if语句判断中断源的逻辑,则需要手动使用如下函数,将标志位至0
__HAL_TIM_CLEAR_FLAG(htim,TIM_FLAG_TRIGGER);
输入信号为门模式
当电平为高电平时,才允许时钟信号流入触发控制器,即只在高电平期间计数,如果改变边沿检测器器极性,则低电平计数,高电平不计数。
需要注意:门模式触发的中断和上一个“定时器更新”中断相比,门模式触发的中断不会给计数器重装载。
输入信号TI1FP1跳变,即当门模式被触发的时候,虽然标志位也会被至1,但是并不会触发定时器更新中断(因为定时器没有被重装载),判断是否触发门模式的逻辑代码应该写在main.c的while循环当中,而并非像定时器更新中断一样写在中断回调函数当中。
触发模式
检测到上升或者下降边沿后让计数器开始计数,其代码逻辑和门模式一样。
触发一次之后再次触发并不会停止计数,但是按照上述代码逻辑(即触发时的逻辑判断写在while循环当中),依旧会执行判断当中的内容,视频当中的案例就是串口输出字符串
单脉冲模式
搭配Trigger mode(触发模式)这种从模式使用最佳,勾选后计数器只计数一次,溢出后不再重装载而是停止计数
在停止计数期间,如果再次触发上升/下降沿,则会开始新一轮的计数
输入捕获中断
设置相应的两个TIM通道后,选择直接模式和间接模式,然后在NVIC使能即可,过程详见二级标题“输入捕获模式”
串口中断
串口中断发送
当发送数据寄存器为空时,发送数据寄存器空中断标志位至1,触发对应中断,
使得发送数据寄存器在瞬间装载完毕,多次执行后完整数据被发出。
打开USART2的串口中断功能,其对应发送数据的函数为
HAL_UART_Transmit_IT(&huart2,(uint8_t)message,strlen(string));
即相较于一般的发送数据,串口中断发送数据的函数增加了IT后缀,由于串口中断是非阻塞中断,
所以不需要第四个参数(延时设置)的填写。
串口中断接收
与上方的设置同理,其对应的函数为
HAL_UART_Receive_IT(&huart2,(uint8_t)message,strlen(string));
当接收移位寄存器将内容放置到数据接收寄存器的时候,触发接收数据寄存器非空中断
关于串口的回调函数
因为很多标志位都指向了如下的这个串口中断函数,所以需要使用更具体的中断回调函数来处理串口的各种中断
当串口接收完成的时候,会触发如下函数内容
只需要在main.c重新定义这个回调函数,就可以在串口接收完毕后立马对收到的数据进行处理了
和串口章节实现了相同的功能,但通过串口中断实现的程序内容是非阻塞的
注意:因为HAL_UART_Receive_IT
运行一次就会预备触发一次中断内容,所以不能在while循环调用,如果要实现复用,则在上图中
结束的位置再次启动串口中断接收。
串口中断拓展函数
串口空闲中断(收取不定长度的信息)
当串口接收完所有数据的时候,会触发串口空闲中断,它是一个关于串口中断的拓展函数,
可以替代下文的HAL_UART_Receive_DMA
函数实现相同的功能
这种中断可以处理不定长度的数据,所以第三个选项和接收的数组大小需要设置的较大才行
uint8_t message[50];
HAL_UARTEx_ReceiveToIdle_DMA(&huart2,message,50);
串口空闲中断函数和HAL_UART_Receive_DMA写在一样的位置,并且和其一样存在回调函数,写法在其基础上多出了一个SIZE参数
注意:RxEventCallback回调还会在数组被填满一半的时候触发一次,所以每一个
HAL_UARTEx_ReceiveToIdle_DMA(&huart2,message,50);
之后还要加入失能DMA传输半中断
__HAL_DMA_DISABLE_TI(&hdma_usart2_rx,DMA_IT_HT);
串口中断+DMA转运--实现CPU的完全解放!?
来到cube MX,设置串口的输出(TX)功能和DMA绑定,其中搬运方向为内存---->外设(发送数据寄存器)
increment address是地址自增选项。因为发送数据寄存器地址固定,而内存地址是一块连续的区域,所以因当勾选memory的自增选项
Mode可以选择循环模式和正常模式(这个以后填坑)
当然,串口的输出(RX)功能也是如上设置即可。
如何使用DMA转运串口并且将数据发送/接收?
在上述发送和接收回调函数的基础上,将_IT
改为_DMA
即可!
注意:程序的发送(TX)不需要在main.c处增加类似于HAL_UART_Receive_DMA(&huart2,(uint8_t)message,strlen(string));
而接收数据(RX)则需要添加上述函数在while循环和中断回调函数内部!
外部时钟和外接模块
TIE_ED只能通过双边沿产生
TI2FP2和TI1FP1可以自由配置下降沿/上升沿触发
采用外部时钟模式2,通过高级定时器的外部触发器计数(少用)
(slave mode:external clock mode2)
clock filiter : 滤波器设置,可以有效防止抖动的产生,滤波方法如下图,绝大多数情况下填写15(最大值)即可。
注意:clock filiter的计次依据于如下区域,如果采用高频率,则需要调节prescaler来使得输入到定时器的时钟不那么快
polarity : 选择是否高低电平反转(极性选择)
prescaler : 预分频大小设置
采用外部时钟模式1
将时钟源disable,随后如上选择外部时钟模式1,选择ETR1也能达成上面的效果,且ETR1还可以改为更多选项
发现先前的clock设置变成了Trigger设置,但三个选项选择的含义是和之前一样的
将Trigger Source更改为TI1_ED发现计数次数是原先的两倍,因为此通道是上下降沿都会触发
将Trigger Source更改为TI2FP2发现下方多出了上下降沿的选择项
中断函数汇总
在 STM32 微控制器中,所有外设和核心功能都有各自的中断函数。当发生特定事件时,处理器会自动跳转到相应的中断函数进行处理。STM32 的中断函数都是按照其外设的中断源来命名的,每个外设通常会有一到多个中断源,并为每个中断源提供一个对应的中断处理函数。
1. 外部中断(External Interrupts)
外部中断用于响应外部信号(例如按钮按下或引脚电平变化):
EXTI0_IRQHandler
- 外部中断 0EXTI1_IRQHandler
- 外部中断 1EXTI2_IRQHandler
- 外部中断 2EXTI3_IRQHandler
- 外部中断 3EXTI4_IRQHandler
- 外部中断 4EXTI9_5_IRQHandler
- 外部中断 5 至 9EXTI15_10_IRQHandler
- 外部中断 10 至 15
2. 定时器中断(Timers Interrupts)
STM32 的定时器(如 TIM1, TIM2 等)具有多种中断源:
TIM1_BRK_IRQHandler
- TIM1 断路中断(Break)TIM1_UP_IRQHandler
- TIM1 更新中断(Update)TIM1_TRG_COM_IRQHandler
- TIM1 触发和换相中断(Trigger and Commutation)TIM1_CC_IRQHandler
- TIM1 捕获/比较中断(Capture/Compare)TIM2_IRQHandler
- TIM2 更新中断TIM3_IRQHandler
- TIM3 更新中断TIM4_IRQHandler
- TIM4 更新中断TIM5_IRQHandler
- TIM5 更新中断TIM6_IRQHandler
- TIM6 更新中断TIM7_IRQHandler
- TIM7 更新中断TIM8_BRK_IRQHandler
- TIM8 断路中断(Break)TIM8_UP_IRQHandler
- TIM8 更新中断(Update)TIM8_TRG_COM_IRQHandler
- TIM8 触发和换相中断(Trigger and Commutation)TIM8_CC_IRQHandler
- TIM8 捕获/比较中断(Capture/Compare)
3. 串口中断(USART Interrupts)
用于串口通信的中断:
USART1_IRQHandler
- USART1 中断USART2_IRQHandler
- USART2 中断USART3_IRQHandler
- USART3 中断UART4_IRQHandler
- UART4 中断UART5_IRQHandler
- UART5 中断USART6_IRQHandler
- USART6 中断UART7_IRQHandler
- UART7 中断UART8_IRQHandler
- UART8 中断
4. SPI 中断(SPI Interrupts)
用于 SPI 外设的中断:
SPI1_IRQHandler
- SPI1 中断SPI2_IRQHandler
- SPI2 中断SPI3_IRQHandler
- SPI3 中断SPI4_IRQHandler
- SPI4 中断
5. I2C 中断(I2C Interrupts)
用于 I2C 外设的中断:
I2C1_EV_IRQHandler
- I2C1 事件中断I2C1_ER_IRQHandler
- I2C1 错误中断I2C2_EV_IRQHandler
- I2C2 事件中断I2C2_ER_IRQHandler
- I2C2 错误中断I2C3_EV_IRQHandler
- I2C3 事件中断I2C3_ER_IRQHandler
- I2C3 错误中断
6. DMA 中断(DMA Interrupts)
DMA 控制器的中断:
DMA1_Stream0_IRQHandler
- DMA1 流 0 中断DMA1_Stream1_IRQHandler
- DMA1 流 1 中断DMA1_Stream2_IRQHandler
- DMA1 流 2 中断DMA1_Stream3_IRQHandler
- DMA1 流 3 中断DMA1_Stream4_IRQHandler
- DMA1 流 4 中断DMA1_Stream5_IRQHandler
- DMA1 流 5 中断DMA1_Stream6_IRQHandler
- DMA1 流 6 中断DMA1_Stream7_IRQHandler
- DMA1 流 7 中断DMA2_Stream0_IRQHandler
- DMA2 流 0 中断DMA2_Stream1_IRQHandler
- DMA2 流 1 中断DMA2_Stream2_IRQHandler
- DMA2 流 2 中断DMA2_Stream3_IRQHandler
- DMA2 流 3 中断DMA2_Stream4_IRQHandler
- DMA2 流 4 中断DMA2_Stream5_IRQHandler
- DMA2 流 5 中断DMA2_Stream6_IRQHandler
- DMA2 流 6 中断DMA2_Stream7_IRQHandler
- DMA2 流 7 中断
7. ADC 中断(ADC Interrupts)
用于 ADC 的中断:
ADC1_2_IRQHandler
- ADC1 和 ADC2 中断ADC3_IRQHandler
- ADC3 中断
8. CAN 中断(CAN Interrupts)
用于 CAN 总线控制器的中断:
CAN1_TX_IRQHandler
- CAN1 发送中断CAN1_RX0_IRQHandler
- CAN1 接收 FIFO 0 中断CAN1_RX1_IRQHandler
- CAN1 接收 FIFO 1 中断CAN1_SCE_IRQHandler
- CAN1 状态改变中断CAN2_TX_IRQHandler
- CAN2 发送中断CAN2_RX0_IRQHandler
- CAN2 接收 FIFO 0 中断CAN2_RX1_IRQHandler
- CAN2 接收 FIFO 1 中断CAN2_SCE_IRQHandler
- CAN2 状态改变中断
9. RTC 中断(RTC Interrupts)
RTC(实时时钟)的中断:
RTC_WKUP_IRQHandler
- RTC 唤醒中断RTC_ALARM_IRQHandler
- RTC 闹钟中断
10. 外设复位和系统控制中断(System Control Interrupts)
这些中断与系统控制和复位相关:
NMI_Handler
- 非屏蔽中断HardFault_Handler
- 硬故障中断MemManage_Handler
- 内存管理故障中断BusFault_Handler
- 总线故障中断UsageFault_Handler
- 使用故障中断SVCall_Handler
- 系统服务调用中断DebugMon_Handler
- 调试监视中断PendSV_Handler
- 挂起系统中断SysTick_Handler
- 系统滴答定时器中断
11. 其他外设中断
其他外设可能有各自的中断函数,以下是几个常见的:
ETH_IRQHandler
- 以太网中断USB_LP_CAN1_RX0_IRQHandler
- USB 低优先级和 CAN1 接收 FIFO 0 中断USB_HP_CAN1_TX_IRQHandler
- USB 高优先级和 CAN1 发送中断FPU_IRQHandler
- 浮点单元中断SPI5_IRQHandler
- SPI5 中断USART6_IRQHandler
- USART6 中断
这些是 STM32 处理器上常见的一些中断函数的列表。每个 STM32 微控制器可能会有所不同,具体的中断函数与外设配置有关。中断函数命名通常遵循以下规则:
- 外设的名称 + 功能类型,例如:
USART1_IRQHandler
、TIM2_IRQHandler
。 - 如果一个外设有多个中断源(例如定时器的多个通道、DMA 的多个流),会为每个中断源定义一个相应的中断函数。
这些中断处理程序通常在启动时被编译器或启动文件链接到适当的位置,在中断发生时由硬件自动调用。如果你想了解更多特定微控制器的中断函数,推荐查看其参考手册中的“中断向量表”章节。
PWM
通过定时器的输出比较模式输出PWM波
比较寄存器
在一开始设定比较寄存器的值,然后定时器不断比较比较寄存器和计数器的值,根据大小关系来决定输出的是高电平还是低电平
其中向下计数模式和中央对齐模式基本上不用
随后信号连接输出控制器(CH Polarity),对其的设置可以分配有效无效电平和高低电平的对应关系
同一个时钟的不同通道可输出不相干PWM波
PWM波的发生
将TIM3的通道1设置为PWM模式
其中pulse是比较寄存器的值
此时使用的是PWM模式1,意味着计数器小于比较寄存器的值的时候,输出有效电平,除此之外输出无效电平
CH Polarity:输出控制器设置,此时设置的High使得有效电平对应高电平,无效电平对应低电平
output compare preload:设置影子寄存器,使得PWM新的一轮改动在下一次出波时生效
配置输出启动
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);
随后可以更改比较寄存器的值,使得PWM波的占空比改变
__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,cnt); //其中cnt就是比较寄存器的值
小细节:此时GPIO模式为复用推挽输出
编码器的使用
将编码器作为外部输入对方波信号进行处理。
HAL库存在专用的编码器模式,只需要将编码器的两路信号分别接入到TI1FP1和TI2FP2即可,
注意:编码器接口对上下边沿都会计数,对此,需要在数据处理的时候对计数次数除以2!
编码器计次代码部分
此笔记以TIM1时钟的CH1和CH2作为示例,且每个通道有指定的编码器通道,不能随意设置引脚!
设置为编码器模式,CH1和CH2被自动配置成对应的引脚
设置TI1通道(TI1FP1)计数,随后直接将通道滤波拉满即可,其余的设置没啥用,一个是选择上升/下降沿计次,另外有选择通道直连和
是否预分频的设置罢了
提前在main.c函数当中设置一个int类型的变量存放读入的计数器的值
首先使能我们的两路编码器通道
int cnt = 0;
HAL_TIM_Encoder_Start(&htim1,TIM_CHANNEL_ALL);
对于AB两个波的编码器可以使用全部通道TIM_CHANNEL_ALL
通过__HAL_TIM_GET_COUNTER(&htim);来获取计数器的值
__HAL_TIM_GET_COUNTER(&htim);
将结果输出到屏幕上发现数值以2/-2的值加到计数器上,于是考虑直接使用整个TIM1通道预分频或者单独对CH1通道和CH2通道进行分频
随后还可以设置通道1或者通道2的上/下沿计次选项,反转其中一个通道即可使得计数方向改变
可以使用如下函数更改计数器的值,使得其在我们需要的可控范围当中
__HAL_TIM_SET_COUNTER(&htim);
标签:定时器,HAL,中断,IRQHandler,TIM,串口,hal
From: https://www.cnblogs.com/Stramazing/p/18541337