基于HAL库的STM32嵌入式学习记录(持续更新中,若内容有误欢迎评论指正)

本文主要是介绍基于HAL库的STM32嵌入式学习记录(持续更新中,若内容有误欢迎评论指正),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

KEY(按键触发)


扫描触发

void KEY_work(void)
{if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == RESET)//检测按键电平变化{HAL_Delay(50);//延时,避免抖动if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == RESET)//再次检测电平{HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_1);//翻转PA0电平}}
}

中断触发

选择IO口中断模式

在STM32单片机中针对IO口中断总共有十五个,其中GPIO_EXIT_0中断对应每组IO口的0接口,与此对应的是PA0和PB0的中断不能同时开启

选择触发方式(上升沿、下降沿、上升或下降沿)

 重写中断回调虚函数     HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)

在IO口中断中传递参数uint16_t GPIO_PinGPIO_PIN_X,当开启多个IO口中断时为区分触发中断的IO口,重写回调函数时要进行判断

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{if(GPIO_Pin == GPIO_PIN_0)//判断触发串口(如开启中断串口不止一个则采用不同的if判断条件){HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_2);//翻转PA2串口电平while(HAL_GPIO_ReadPin(GPIOB,GPIO_0 == 0));//恢复高电平后退出(针对下降沿触发,避免多次触发中断,可忽略)}
}

点灯!!!


点灯原理:给led灯对应IO口输出相应电平

以蓝桥杯嵌入式比赛板(STM32G431RBT6)为例:

LED灯非引脚段为高电平,当引脚输出低电平时LED二极管接通发光。IO口输出间与LED以锁存器连接 ,其中引脚PD2输出高电平时使能:Q=D,通过控制锁存器的使能与否可以实现控制LED灯的同时实现引脚的复用。

void LED_work(void)
{HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8,GPIO_PIN_RESET);//PC2输出低电平,灯亮HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);//锁存器使能(使能最好在输出赋值之后)HAL_Delay(5);//延时(视情况可不加)HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);//寄存器输出锁存
}

定时器(TIM)


STM32定时器基础

时钟树设置(时钟频率):

 PS:此方法对于大部分情况已经完全够用。想深入学习stm32时钟树的知识建议移步其他大佬博客,这里不再赘述。

定时器频率计算:定时频率=时钟频率/(预分频器(Prescaler)*计数周期(Counter Period)预分频器)

预分频器与计数周期设置

 预分频器和计数周期都含0,在设置时应减一。以上截图中设置的定时器频率为80000000/(80*1000)=1Khz

定时触发:

在设置好定时频率后,我们可以让单片机间隔一段时间重复执行某些任务。例如每隔0.1秒翻转LED灯电平实现闪灯操作:

使能TIM4中断
HAL_TIM_Base_Start_IT(&htim4);//主函数中开启定时器4中断
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)//重写中断回调虚函数
{if(htim->Instance == TIM4)//判断触发定时器(在有多个不同中断触发时间的任务执行时在同一个回调函数里编写,编写时注意改变if判断条件){HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_8);//翻转电平HAL_GPIO_WritePin(GPIOD,GPIO_PIN_10,GPIO_PIN_RESET);//使能锁存器HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);//关闭锁存器(避免引脚复用干扰)}
}

PWM波输出 :

占空比:一个脉冲时间内,高电平占一个脉冲周期的时间。

占空比计算:脉冲数(Pulse)/计数周期(Counter Period)*100%

AD/DA模数转换(引脚输出电压获取)

cubemx配置:

转换函数:

HAL_ADC_Start(&hadc1);//开启ADC通道
if(HAL_ADC_PollForConversion(&hadc2,10) == HAL_OK)//检测是否有数据输入
{adc = HAL_ADC_GetValue(&hadc2);//获取数据sprintf(&adc_im,"       V2=%1.2f          ",adc*3.3/4096);//显示数据(ADC分辨率为十二位,即4096,而引脚输出电压最高为3.3V,所以需要进行变换)LCD_DisplayStringLine(Line6,(uint8_t *)&adc_im);//LCD显示
}

输入捕获

 cubemx配置:

捕获函数:

HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_2);    //开启相应通道IC捕获中断//重写捕获中断函数
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance == TIM3)                //确认信号输入通道{count = HAL_TIM_ReadCapturedValue(&htim3,TIM_CHANNEL_2);//获取计数值__HAL_TIM_SetCounter(&htim3,0);       //计数值清零f = (80000000/80)/(count+2);          //计算频率HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_2);        //重新开启IC捕获中断}
}

 I2C通讯


I2C通讯原理:

cubemx配置:

由于蓝桥杯竞赛板中采用的是软件I2C,所以这里复用这两个引脚为输出态即可 。

 收发函数:

void IIC_send(unsigned char text,unsigned char locad)//发送内容|储存地址(这里储存地址为从机寄存器地址,一般情况下为数字)
{I2CStart();//开启I2CI2CSendByte(0xa0);//发送从机地址和写数据请求I2CWaitAck();//等待响应I2CSendByte(locad);//发送从机寄存器储存地址I2CWaitAck();//等待响应I2CSendByte(text);//发送存储内容I2CWaitAck();//等待响应I2CStop();//关闭I2C
}//发送函数
//一般情况下发送内容限定为八个字节,所以发送大容量内容时要将数据截多段八字节内容,可采用左移符号'<<'和右移符号'>>'结合实现字节截断
unsigned char IIC_receive(unsigned char locad)//接收数据所在的寄存器地址
{unsigned text;//无符号型变量I2CStart();//开启I2CI2CSendByte(0xa0);//指定从机和发送写数据请求I2CWaitAck();//等待响应I2CSendByte(locad);//发送从机寄存器地址I2CWaitAck();//等待响应I2CStop();//关闭I2CI2CStart();//开启I2CI2CSendByte(0xa1);//发送从机地址和读数据请求I2CWaitAck();//等待响应text = I2CReceiveByte();//接收并储存数据I2CWaitAck();//等待响应I2CStop();//关闭I2Creturn text;//返回接收数据
}//接收函数

UART串口收发 

cubemx配置:

 

 串口发送:

char Rx[7];            //要发送的数据
HAL_UART_Transmit(&huart1,(uint8_t *)Rx,sizeof(Rx),50);
//参数意义分别为:通道编号,预发送数据,发送长度,超时重传

串口接收:

uint8_t rx,r_len;
char Rx[7];HAL_UART_Receive_IT(&huart1,&rx,1);    //开启接收中断//重写接收中断服务函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{if(huart->Instance == USART1)                 //确定中断源{Rx[r_len ++] = rx;                        //接收数据写入HAL_UART_Receive_IT(&huart1,&rx,1);       //重新开启接收中断if(r_len == 7){HAL_UART_Transmit(&huart1,(uint8_t *)Rx,sizeof(Rx),50);r_len = 0;                            //接收位置复位,发送接收的数据}}
}

这篇关于基于HAL库的STM32嵌入式学习记录(持续更新中,若内容有误欢迎评论指正)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/804199

相关文章

Java实现删除文件中的指定内容

《Java实现删除文件中的指定内容》在日常开发中,经常需要对文本文件进行批量处理,其中,删除文件中指定内容是最常见的需求之一,下面我们就来看看如何使用java实现删除文件中的指定内容吧... 目录1. 项目背景详细介绍2. 项目需求详细介绍2.1 功能需求2.2 非功能需求3. 相关技术详细介绍3.1 Ja

SpringBoot3应用中集成和使用Spring Retry的实践记录

《SpringBoot3应用中集成和使用SpringRetry的实践记录》SpringRetry为SpringBoot3提供重试机制,支持注解和编程式两种方式,可配置重试策略与监听器,适用于临时性故... 目录1. 简介2. 环境准备3. 使用方式3.1 注解方式 基础使用自定义重试策略失败恢复机制注意事项

Python UV安装、升级、卸载详细步骤记录

《PythonUV安装、升级、卸载详细步骤记录》:本文主要介绍PythonUV安装、升级、卸载的详细步骤,uv是Astral推出的下一代Python包与项目管理器,主打单一可执行文件、极致性能... 目录安装检查升级设置自动补全卸载UV 命令总结 官方文档详见:https://docs.astral.sh/

统一返回JsonResult踩坑的记录

《统一返回JsonResult踩坑的记录》:本文主要介绍统一返回JsonResult踩坑的记录,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录统一返回jsonResult踩坑定义了一个统一返回类在使用时,JsonResult没有get/set方法时响应总结统一返回

Go学习记录之runtime包深入解析

《Go学习记录之runtime包深入解析》Go语言runtime包管理运行时环境,涵盖goroutine调度、内存分配、垃圾回收、类型信息等核心功能,:本文主要介绍Go学习记录之runtime包的... 目录前言:一、runtime包内容学习1、作用:① Goroutine和并发控制:② 垃圾回收:③ 栈和

java对接海康摄像头的完整步骤记录

《java对接海康摄像头的完整步骤记录》在Java中调用海康威视摄像头通常需要使用海康威视提供的SDK,下面这篇文章主要给大家介绍了关于java对接海康摄像头的完整步骤,文中通过代码介绍的非常详细,需... 目录一、开发环境准备二、实现Java调用设备接口(一)加载动态链接库(二)结构体、接口重定义1.类型

Python实现自动化Word文档样式复制与内容生成

《Python实现自动化Word文档样式复制与内容生成》在办公自动化领域,高效处理Word文档的样式和内容复制是一个常见需求,本文将展示如何利用Python的python-docx库实现... 目录一、为什么需要自动化 Word 文档处理二、核心功能实现:样式与表格的深度复制1. 表格复制(含样式与内容)2

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

apache的commons-pool2原理与使用实践记录

《apache的commons-pool2原理与使用实践记录》ApacheCommonsPool2是一个高效的对象池化框架,通过复用昂贵资源(如数据库连接、线程、网络连接)优化系统性能,这篇文章主... 目录一、核心原理与组件二、使用步骤详解(以数据库连接池为例)三、高级配置与优化四、典型应用场景五、注意事

SpringBoot实现文件记录日志及日志文件自动归档和压缩

《SpringBoot实现文件记录日志及日志文件自动归档和压缩》Logback是Java日志框架,通过Logger收集日志并经Appender输出至控制台、文件等,SpringBoot配置logbac... 目录1、什么是Logback2、SpringBoot实现文件记录日志,日志文件自动归档和压缩2.1、