首页 > 其他分享 >hal库

hal库

时间:2024-11-12 10:42:36浏览次数:1  
标签:定时器 HAL 中断 IRQHandler TIM 串口 hal

HAL库学习

解疑网站

参考视频

一些小细节!

  • alt + / 触发自动补全

  • 定时器初始化函数MX_TIM2_Init在进行初始化的时候会把中断标志位至1,导致每次启动时钟都会调用一次中断回调函数!

    如果影响了程序的正确运行则需要在初始化后立马将标志位至0

    image-20241107205358650

  • 相较于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的输入

输入捕获模式

image-20241107210454165

捕获寄存器

每一个通用定时器和高级定时器的每一个通道都会存在一个捕获寄存器

定时器启动计数之后,如果设置的信号源产生的相应的电平,则会立马将计数器当中的数值存储到捕获寄存器当中

与此同时如果设置了输入捕获中断,则还会触发一次输入捕获中断

输入捕获通道不可以设置下降沿和上升沿同时触发,所以可以使用直接模式连接间接模式连接来将另一个边沿对应的计数器的值记录。

image-20241107211634152

直接模式和间接模式的定义是相对的,如果TI1为信号输入线,则捕获寄存器1对应的模式为直接,寄存器2为间接

  • 其中,TI1和TI2、TI3和TI4分别为两对,它们在输入捕获的线路原理图方面是相同的。

输入捕获的软件配置

image-20241107213047674

输入捕获函数的配置并非在此界面

image-20241107213233371

如上图,向下寻找到通道3和4的设置界面,其中我配置通道三为上升沿触发直接模式,没有分频且不滤波。

而通道四为下降沿触发间接模式,没有分频且不滤波。

在NVIC当中使能输入捕获中断即可,不需要调整从模式控制器

image-20241107213550386

输入捕获模式不需要定时器更新中断,于是在使能定时器的函数中删去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触发的中断不会阻塞程序的执行

串口的发送

image-20241108084327934

在软件界面设置即可,其中

  1. Asynchronous模式:
    • 在这种模式下,USART的工作方式是异步的,也就是说,它不依赖于外部时钟信号进行同步。数据以特定的波特率进行传输,发送和接收端必须在同一波特率下工作。通常用于标准的串口通讯,如RS-232协议。
  2. 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为接收数组,所以不需要类型转换

image-20241108090238195

如上图,定义了一个GPIO_PinState类型的、名为state的变量,随后根据计算机发送的信息控制灯的亮灭

(R、G、B控制颜色,0、1控制亮灭)

串口中断发送数据的内容在下面的中断内容中提及

时钟、时钟树、两者和总线的联系

在RCC中设置时钟为晶振,且在时钟树中选择72MHz回车修改即可image-20241103092137894

关于时钟树更底层的内容----时钟与时钟树

时钟源是心脏,而时钟树则是时钟的动脉。

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)

image-20241103093120362

高速内部时钟(HSI)、高速外部时钟(HSE)、系统时钟(SYSCLK)

HSI

存在于芯片内部,8MHz,精度较低

HSE

外接晶振,精度高,频率根据型号有所区别,能耗高

LSE

内部时钟源,速度慢但是节能!

SYSCLK

区别于滴答时钟SYSTick

SYSCLK可以接入HSI或者HSE,而HSE经过锁相环倍频可产生72MHz的频率

image-20241103094106948 屏幕截图 2024-11-03 093354

定时器

定时器就是计数器

通过设定APB接入的时钟信号来确定方波信号,而方波信号连接一个最大为65535的寄存器,然后通过预分频器,通过时钟频率和寄存器的数值来计算出时间(103c8t6上只有TIM1-4)

  • 通用定时器 TIM 2-5
  • 基本定时器 TIM 6-7
  • 高级定时器 TIM 1 and 8

image-20241103113639448

当预分频器设置为0时不分频,为1时二分频,以此类推

自动重装载寄存器

监控计数器的值是否和自己(自动重装载寄存器)相同,当相同时则将计数器归零,并且触发定时中断回调函数

  • 如果需要设置收到m个脉冲重装载的话,则自动装载寄存器的值应该设置为m-1

定时器的使能

勾选Internal clock

image-20241103114538239

在STM32CubeMX中,TIM的Internal Clock来自下方的APBx Timer clock(MHz)

在参考的样例当中,APB1和APB2的28均改为72MHz

image-20241103114813222

设置计数器的分频和自动重装载

image-20241103115052373

在这里使用了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); //通过函数设置预分频器的值

image-20241103130221567

image-20241103130349837

这个是影子寄存器的使能,如果使能了影子寄存器,则更改完预分频器之后不会立马生效,会等到下一个周期才生效更改的值

如果失能可能会导致一些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若定义声明,旨在用户自己在主程序当中自发定义其内容

image-20241107194803932

此函数功能对应了每次触发中断后在屏幕上显示字符串内容

定时器更新中断

image-20241107195323469

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);

输入信号为门模式

当电平为高电平时,才允许时钟信号流入触发控制器,即只在高电平期间计数,如果改变边沿检测器器极性,则低电平计数,高电平不计数。

image-20241107201025109

image-20241107201238074

需要注意:门模式触发的中断和上一个“定时器更新”中断相比,门模式触发的中断不会给计数器重装载。

输入信号TI1FP1跳变,即当门模式被触发的时候,虽然标志位也会被至1,但是并不会触发定时器更新中断(因为定时器没有被重装载),判断是否触发门模式的逻辑代码应该写在main.c的while循环当中,而并非像定时器更新中断一样写在中断回调函数当中。

image-20241107202611448

触发模式

image-20241107202810148

检测到上升或者下降边沿后让计数器开始计数,其代码逻辑和门模式一样。

触发一次之后再次触发并不会停止计数,但是按照上述代码逻辑(即触发时的逻辑判断写在while循环当中),依旧会执行判断当中的内容,视频当中的案例就是串口输出字符串

image-20241107203116253

单脉冲模式

搭配Trigger mode(触发模式)这种从模式使用最佳,勾选后计数器只计数一次,溢出后不再重装载而是停止计数

image-20241107203339853

在停止计数期间,如果再次触发上升/下降沿,则会开始新一轮的计数

输入捕获中断

设置相应的两个TIM通道后,选择直接模式和间接模式,然后在NVIC使能即可,过程详见二级标题“输入捕获模式”

串口中断

image-20241108135613377

串口中断发送

当发送数据寄存器为空时,发送数据寄存器空中断标志位至1,触发对应中断,

使得发送数据寄存器在瞬间装载完毕,多次执行后完整数据被发出。

image-20241108142307212

打开USART2的串口中断功能,其对应发送数据的函数为

HAL_UART_Transmit_IT(&huart2,(uint8_t)message,strlen(string));

即相较于一般的发送数据,串口中断发送数据的函数增加了IT后缀,由于串口中断是非阻塞中断,

所以不需要第四个参数(延时设置)的填写。

串口中断接收

与上方的设置同理,其对应的函数为

HAL_UART_Receive_IT(&huart2,(uint8_t)message,strlen(string));

image-20241108143442217

当接收移位寄存器将内容放置到数据接收寄存器的时候,触发接收数据寄存器非空中断

关于串口的回调函数

因为很多标志位都指向了如下的这个串口中断函数,所以需要使用更具体的中断回调函数来处理串口的各种中断

image-20241108144247683

当串口接收完成的时候,会触发如下函数内容

image-20241108144415244

只需要在main.c重新定义这个回调函数,就可以在串口接收完毕后立马对收到的数据进行处理了

image-20241108145029898

串口章节实现了相同的功能,但通过串口中断实现的程序内容是非阻塞

注意:因为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参数

image-20241108155558807

注意:RxEventCallback回调还会在数组被填满一半的时候触发一次,所以每一个

HAL_UARTEx_ReceiveToIdle_DMA(&huart2,message,50);

之后还要加入失能DMA传输半中断

__HAL_DMA_DISABLE_TI(&hdma_usart2_rx,DMA_IT_HT);

串口中断+DMA转运--实现CPU的完全解放!?

image-20241108150510827

来到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)

image-20241107184446368

image-20241107181843333

clock filiter : 滤波器设置,可以有效防止抖动的产生,滤波方法如下图,绝大多数情况下填写15(最大值)即可。

注意:clock filiter的计次依据于如下区域,如果采用高频率,则需要调节prescaler来使得输入到定时器的时钟不那么快

image-20241107182738957

image-20241107182419467

polarity : 选择是否高低电平反转(极性选择)

prescaler : 预分频大小设置

采用外部时钟模式1

image-20241107184502689

image-20241107184538046

将时钟源disable,随后如上选择外部时钟模式1,选择ETR1也能达成上面的效果,且ETR1还可以改为更多选项

发现先前的clock设置变成了Trigger设置,但三个选项选择的含义是和之前一样的

image-20241107184756443

将Trigger Source更改为TI1_ED发现计数次数是原先的两倍,因为此通道是上下降沿都会触发

将Trigger Source更改为TI2FP2发现下方多出了上下降沿的选择项

中断函数汇总

在 STM32 微控制器中,所有外设和核心功能都有各自的中断函数。当发生特定事件时,处理器会自动跳转到相应的中断函数进行处理。STM32 的中断函数都是按照其外设的中断源来命名的,每个外设通常会有一到多个中断源,并为每个中断源提供一个对应的中断处理函数。

1. 外部中断(External Interrupts)

外部中断用于响应外部信号(例如按钮按下或引脚电平变化):

  • EXTI0_IRQHandler - 外部中断 0
  • EXTI1_IRQHandler - 外部中断 1
  • EXTI2_IRQHandler - 外部中断 2
  • EXTI3_IRQHandler - 外部中断 3
  • EXTI4_IRQHandler - 外部中断 4
  • EXTI9_5_IRQHandler - 外部中断 5 至 9
  • EXTI15_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_IRQHandlerTIM2_IRQHandler
  • 如果一个外设有多个中断源(例如定时器的多个通道、DMA 的多个流),会为每个中断源定义一个相应的中断函数。

这些中断处理程序通常在启动时被编译器或启动文件链接到适当的位置,在中断发生时由硬件自动调用。如果你想了解更多特定微控制器的中断函数,推荐查看其参考手册中的“中断向量表”章节。

PWM

通过定时器的输出比较模式输出PWM波

比较寄存器

在一开始设定比较寄存器的值,然后定时器不断比较比较寄存器和计数器的值,根据大小关系来决定输出的是高电平还是低电平

image-20241108181638592

其中向下计数模式中央对齐模式基本上不用

随后信号连接输出控制器CH Polarity),对其的设置可以分配有效无效电平高低电平的对应关系

同一个时钟的不同通道可输出不相干PWM波

PWM波的发生

image-20241108185111996

将TIM3的通道1设置为PWM模式

image-20241108185752895

其中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就是比较寄存器的值

image-20241109113849250

小细节:此时GPIO模式为复用推挽输出

编码器的使用

image-20241109114418455

将编码器作为外部输入对方波信号进行处理。

HAL库存在专用的编码器模式,只需要将编码器的两路信号分别接入到TI1FP1和TI2FP2即可,

image-20241109125413620

注意:编码器接口对上下边沿都会计数,对此,需要在数据处理的时候对计数次数除以2

编码器计次代码部分

此笔记以TIM1时钟的CH1CH2作为示例,且每个通道有指定的编码器通道,不能随意设置引脚!

image-20241109130549219

设置为编码器模式,CH1和CH2被自动配置成对应的引脚

image-20241109130825951

设置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

相关文章

  • 使用halcon完成一维码、二维码的识别
    图片素材 通过网盘分享的文件:图片5链接:https://pan.baidu.com/s/1r9SG4lZ3ZQ5S-NGVsFx70w?pwd=BFDJ提取码:BFDJ读码一维码创建读码句柄create_bar_code_model([],[],BarCodeHandle)参数一:输入通用参数可以调整条形码模型的名称。参数二:通用参数可以调整条形码......
  • Halcon 灰度形态学及太阳能电池片缺陷检测应用
    一、基本概念        Halcon灰度形态学是图像处理领域中的一种重要技术,它允许对图像中的灰度值进行非线性操作,这些操作取决于像素的邻域。        灰度形态学是形态学的一种推广,与二值形态学相比,它不仅在图像本身的空间尺寸上有所变化,而且图像本身的灰度值也......
  • stm32 HAL 添加 FREERTOS系统(使用stm32cubemx)
    #学习笔记,留存#1.ClockConfiguration(时钟配置)​​​​​​​HSE,LSE选择外部晶振系统时钟选择TIM6,systick(滴答时钟)给FREERTOS用根据自己的芯片配置时钟(我用的是stm32f103zet6)AHB总线72MHZAPB1总线36MHZ APB2总线72MHZ2.ADDFREERTOS(添加实时系统)在Pinout&Co......
  • MAC下使用Clion软件进行STM32的HAL库的开发
    1、准备的软件(1)clion:链接:https://www.jetbrains.com.cn/clion/破解:方法可在某宝上去找。(2)STM32CubeMX与ST_Link:链接:https://www.st.com.cn/content/st_com/zh/stm32cubemx.htmlmac电脑在安装的时候会出现上面的界面,依次安装即可。(3)macOS的包管理器‌brew:打开终端......
  • halcon中将xld轮廓或者region区域绘制在图像上并保存
    1)单通道图像的绘制draw_circle(WindowHandle,Row,Column,Radius)gen_circle(Circle,Row,Column,Radius)paint_region(Circle,Image,ImageR,0,'fill')paint_region(Circle,Image,ImageG,255,'fill')paint_region(Circle,Image,ImageB,......
  • STM32(hal库)中的定时器从模式TIM_SlaveConfigTypeDef结构体中的含义,以及可选参数的含义
            在STM32的HAL库中,定时器从模式配置结构体TIM_SlaveConfigTypeDef用于配置定时器作为从定时器时的相关参数。该结构体及其可选参数的含义对于理解和配置STM32定时器的从模式至关重要。以下是对该结构体及其参数的详细解释:TIM_SlaveConfigTypeDef结构体该结构......
  • 【人脸伪造检测】Spatial-Phase Shallow Learning: Rethinking Face Forgery Detectio
    一、研究动机[!note]创新点:利用相位谱实现伪造检测,并且证明了卷积模型可以提取隐性特征。由于上采样是伪造模型的关键步骤,这篇论文通过相位信息检测上采样的伪影。对比之前的频率模型:F3-Net:通过离散余弦变换后的统计特征实现伪造检测二、检测模型可学习的知识点......
  • Halcon 矫正图像 图像矫正
    目录1、图像预处理和形状校正2、源码 1.原图2.矫正后的图像3.示例代码         在图像处理领域中,Halcon是一种广泛使用的编程语言和库,它提供了丰富的图像处理功能。本文将详细解析一段Halcon代码,这段代码主要用于图像处理和形状校正。代码分为两部分,本文将逐......
  • Android Audio中 AudioTrack、 AudioFlinger和 HAL 使用dump的区别
    Audiodump在定位音频的各种问题非常重要,我们主要在AudioTrack、AudioFlinger和HAL层中会用到,这里我们先明确一下在不同层使用dump的区别。以下是关于AudioTrack、AudioFlinger和HAL(HardwareAbstractionLayer,硬件抽象层)中dump的区别和使用场景:一、区别Audi......
  • Halcon刚性变换
       刚性仿射变换(RigidAffineTransformation)是一种机械视觉和图像处理常用的技术,通常用于在保持物体形状和大小不变的情况下,对物体进行旋转和平移。常见于模板匹配,定位跟随等场景。1:vector_angle_to_rigid(::Row1,Column1,Angle1,Row2,Column2,Angle2:HomMat......