基于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

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

poj3468(线段树成段更新模板题)

题意:包括两个操作:1、将[a.b]上的数字加上v;2、查询区间[a,b]上的和 下面的介绍是下解题思路: 首先介绍  lazy-tag思想:用一个变量记录每一个线段树节点的变化值,当这部分线段的一致性被破坏我们就将这个变化值传递给子区间,大大增加了线段树的效率。 比如现在需要对[a,b]区间值进行加c操作,那么就从根节点[1,n]开始调用update函数进行操作,如果刚好执行到一个子节点,

hdu1394(线段树点更新的应用)

题意:求一个序列经过一定的操作得到的序列的最小逆序数 这题会用到逆序数的一个性质,在0到n-1这些数字组成的乱序排列,将第一个数字A移到最后一位,得到的逆序数为res-a+(n-a-1) 知道上面的知识点后,可以用暴力来解 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#in

hdu1689(线段树成段更新)

两种操作:1、set区间[a,b]上数字为v;2、查询[ 1 , n ]上的sum 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<queue>#include<set>#include<map>#include<stdio.h>#include<stdl

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss