STM32HAL库
概述
本文本是我对我自己平日里使用STM32的总结,结合了网上和自己的理解,方便自己以后回顾学习。只包含在学习过程有用到的。
1.GPIO
(1)HAL_GPIO_DeInit
功能:这个函数的主要功能是将我们在引脚初始化之后的引脚恢复成默认的状态,即各个寄存器复位时的值
例:HAL_GPIO_DeInit(GPIOx,GPIO_PIN_X);
(2)HAL_GPIO_EXTI_Callback
功能:这个函数是中断回调函数,可以理解为中断函数具体要响应的动作
例:HAL_GPIO_EXTI_Callback(GPIO_PIN_X);
注意:禁止使用HAL_Delay在中断中进行延时,会导致程序卡死。因HAL_Delay也是利用中断进行延时,但是中断等级为最低级,会导致进不去中断,读取不到时间,导致卡死。可以自己编写延时程序。或者修改滴答定时器的中断优先级,至少比所用的中断高。
(3)HAL_GPIO_EXTI_IRQHandler
功能:这个函数是外部中断服务函数,用来响应外部中断的触发,函数实体里面有两个功能,首先清楚中断标志,调用HAL_GPIO_EXTI_Callback函数进行具体要处理的事情
例:HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_PIN_X);
(4)HAL_GPIO_Init
功能:这个函数主要用来初始化我们需要用到的引脚的工作模式,包括具体引脚的工作速度、是否复用模式、上下拉等等参数。
例:GPIO_InitTypeDef GPIO_Init_Structure;
GPIO_Init_Structure. Pin = GPIO_PIN_10 | GPIO_PIN_11; //选择对PB10和PB11进行设置
GPIO_Init_Structure. Mode = GPIO_MODE_OUTPUT_OD; //设置输出为上拉模式(PP改为OD为开漏)
GPIO_Init_Structure. Speed = GPIO_SPEED_FREQ_HIGH; //速度设置为高速100M
HAL_GPIO_Init(GPIOB,&GPIO_Init_Structure);
(5)HAL_GPIO_LockPin
功能:这个函数看函数名称就是锁住的意思,比如说一个引脚的当前状态是1,使用此函数后,当此引脚电平保持为高电平,并无法更改。
例:HAL_GPIO_LockPin(GPIOX,GPIO_PIN_X);
(6)HAL_GPIO_ReadPin
功能:检测这个引脚当前状态值,函数返回值为0或1。
例:HAL_GPIO_ReadPin(GPIOX,GPIO_PIN_X);
(7)HAL_GPIO_TogglePin
功能:这个函数用来翻转某个引脚的电平状态,我用的最多的场合是LED灯的翻转,也就是LED闪烁。
例:HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_10);
(8)HAL_GPIO_WritePin
功能:这个函数从字面意思来看就是给某个引脚写0或1,但是不要理解成,写1就是使能之类的意思,有些寄存器写1是擦除的意思,这一点要谨记。
例:HAL_GPIO_WritePin(GPIOB,GPIO_PIN_10,GPIO_PIN_SET) //设置为高电平
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_10,GPIO_PIN_RESET) //设置为低电平
2.延时Delay
(1)毫秒延时
说明:STM32HAL库自带毫秒延时
例:HAL_Delay(x);
(2)微秒延时
说明:我利用示波器写的微秒延时(只在STM32F103FZET6用过)
例
#define CPU_FREQUENCY_MHZ 72
void delay_xus(__IO uint32_t nTime)//1为2uM 2为4uM 4为5uM
{
int old_val,new_val,val;
if(nTime > 900)
{
for(old_val = 0; old_val < nTime/900; old_val++)
{
delay_xus(900);
}
nTime = nTime%900;
}
old_val = SysTick->VAL;
new_val = old_val - CPU_FREQUENCY_MHZ*nTime;
if(new_val >= 0)
{
do
{
val = SysTick->VAL;
}
while((val < old_val)&&(val >= new_val));
}
else
{
new_val +=CPU_FREQUENCY_MHZ*1000;
do
{
val = SysTick->VAL;
}
while((val <= old_val)||(val > new_val));
}
}
void delay_1us(void)//1us延时
{
uint8_t i;
for(i=0;i<5;i++)
{
__NOP();
}
}
void delay_20us(void)//20us??
{
uint8_t i,j;
for(j=0;j<30;j++)
{
for(i=0;i<5;i++)
{
__NOP();
}
}
}
void delay_200us(void)//200us??
{
uint8_t i,j;
for(j=0;j<33;j++)
{
for(i=0;i<50;i++)
{
__NOP();
}
}
}
3.串口通讯
(1)HAL_UART_Init(&huartx)
功能:这个函数主要用来初始化我们需要用到的串口的波特率,起始位,数据位(8位或者9位),奇偶校验位(第9位),停止位(1,1.5,2位)
例:
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200; //波特率
huart1.Init.WordLength = UART_WORDLENGTH_8B; //数据长度
huart1.Init.StopBits = UART_STOPBITS_1; //停止位
huart1.Init.Parity = UART_PARITY_NONE; //校验位
huart1.Init.Mode = UART_MODE_TX_RX; //发送接收模式
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; //硬件控制流
huart1.Init.OverSampling = UART_OVERSAMPLING_16; //过采样
HAL_UART_Init(&huart1);
(2)HAL_UART_Receive
功能:串口轮询模式接受,使用超时管理机制
例:HAL_UART_Receive(&huart1,Rec,20,0xff);
说明:HAL_UART_Receive(串口号,接收放哪,要读取多少位,延时)每当程序执行到时读取一次
(3)HAL_UART_Transmit
功能:串口轮询模式发送,使用超时管理机制
例:HAL_UART_Transmit(&huart1,Rec,20,0XFF);
说明:HAL_UART_Transmit(串口号,发送什么,要发送多少位,延时)每当程序执行到时发送一次
(4)HAL_UART_Transmit_IT();
功能:串口中断模式发送
例:HAL_UART_Transmit_IT(&huart1,Rec,20);
说明:HAL_UART_Transmit_IT(串口号,发送的数据,要发送多少位)
一般发送不用中断进行发送,直接使用轮询或DMA发送数据。因为什么时候发送数据是可控的,而接收数据是不可预料的。
(5)HAL_UART_Receive_IT();
功能:串口中断模式读取
例:HAL_UART_Receive_IT(&huart1,Rec,1);
说明:开启接收中断
(6)HAL_UART_Transmit_DMA();
功能:串口DMA模式发送
例:HAL_UART_Transmit_DMA(&huart1,TxMsg,sizeof(TxMsg));
说明:HAL_UART_Transmit_DMA(串口号,发送的数据,要发送多少位);
(7)HAL_UART_Receive_DMA();
功能:;串口DMA模式接受
例:HAL_UART_Receive_DMA(&huart1,RxMsg,sizeof(RxMsg));
说明:HAL_UART_Receive_DMA(串口号,接收数据存放的数组,要接收多少位);
(8)__HAL_UART_GET_FLAG
功能:检测串口是否处于空闲状态
例:if((__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE)!=RESET))
说明:检测到标志位IDLE置1,说明串口收发处于空闲状态,执行IF语句中的代码
(9)__HAL_UART_GET_RXNE
功能:接收到的数据不为空时,标志位置1
例:if((__HAL_UART_GET_FLAG(&huart1,UART_FLAG_RXNE)!=RESET))
说明:检测到标志位RXNE置1,说明接收到的消息不为空(有数据传输过来),准备接受消息。执行IF语句中的代码
(10)__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE)
功能:开启IDLE串口中断。IDLE(当串口处于空闲状态时,IDLE置1)
(11)__HAL_UART_DISABLE_IT(&huart1,UART_IT_IDLE)
功能:禁用IDLE串口中断。IDLE(当串口处于空闲状态时,IDLE置1)
(12)__HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE)
功能:开启RXNE串口中断。RXNE(当接受的数据不为空时,RXNE置1)
4.SPI
(1)HAL_SPI_TransmitReceive
功能:SPI接收并发送
例:HAL_SPI_TransmitReceive(&SPI2_Handler,&TxData,&Rxdata,1, 1000);
说明:HAL_SPI_TransmitReceive(SPIX,发送,接收,多少位,延时);
(2)HAL_SPI_Receive
功能:SPI接收
例:HAL_SPI_Receive(&SPI2_Handler,&Rxdata,1,1000);
说明:HAL_SPI_Receive(SPIX,接收变量,数据位数,超时);
(3)HAL_SPI_Transmit
功能:SPI发送
例:HAL_SPI_Transmit(&SPI2_Handler,&TxData,1,1000);
说明:HAL_SPI_Transmit(SPIX,发送变量,数据位数,超时);
5.定时器
(1)__HAL_TIM_SET_COMPARE
功能:修改PWM占空比
例:__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_1,Duty) ;
说明:修改定时器4通道1的PWM占空比,Duty代表了占空比的大小与设定值对比.
(2)HAL_TIM_Base_Start_IT
功能:main.c程序中添加(放置于定时器配置之后)开启 TIM1计时中断
例:HAL_TIM_Base_Start_IT(&htim3);
说明:开启定时器3的计时中断
(3)HAL_TIM_PWM_Start
功能:main.c程序中添加(放置于定时器配置之后)开启定时器通道3输出PWM方波。
例:HAL_TIM_PWM_Start(&htimx,TIM_CHANNEL_3);
说明:开启定时器通道3输出PWM方波。
(4)HAL_TIM_Encoder_Start
功能:开启启动TIM编码器接口
例:HAL_TIM_Encoder_Start(&htim1, TIM_CHANNEL_ALL);
说明:选择定时器1,开启通道1和通道2
6.ADC
(1)HAL_ADC_Start
功能:开启ADC
例:HAL_ADC_Start(&hadc1);
说明:hadc1由STM32Cube自动生成,为结构体变量
(2)HAL_ADC_PollForConversion
功能:等待转化完成,完成跳过
例:HAL_ADC_PollForConversion(&hadc1,100);
说明:第一空填写第个ADC,第二个填写超时时间或最多等多久(单位为毫秒)
(3)HAL_ADC_GetValue(&hadc1)
功能:读取ADC转换数据,数据为12位(最大为4096)。
7.CAN
(1)HAL_CAN_Start();
功能:启动CAN模块
例:HAL_CAN_Start(&hcan);
说明:hcan由STM32Cube自动生成,为结构体变量
(2)HAL_CAN_Stop();
功能:停止CAN模块并启用对配置寄存器的访问
例:HAL_CAN_Stop(&hcan);
说明:hcan由STM32Cube自动生成,为结构体变量
(3)HAL_CAN_AddTxMessage()
功能:向邮箱发送消息并激活
例:HAL_CAN_AddTxMessage(&hcan, &TxMeg, data, &TxMailbox)
说明:
hcan:哪个CAN
&TxMeg: CAN_TxHeaderTypeDef TxMeg;结构体变量
TxMeg.StdId=0x12; //标准标识符
TxMeg.ExtId=0x12; //扩展标识符
TxMeg.IDE=CAN_ID_STD; //标准桢
TxMeg.RTR=CAN_RTR_DATA; //数据桢
TxMeg.DLC=len; //要发送的数据长度
data:要发送的数据
&TxMailbox:uint32_t TxMailbox;默认此配置
(4)void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
功能:CAN的中断回调函数,当接收到数据,跳到此函数处理
例:void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
说明:hcan由STM32Cube自动生成,为结构体变量
(5)CAN总线配置
void CAN_User_Config(CAN_HandleTypeDef* hcan )
{
CAN_FilterTypeDef sFilterConfig;
HAL_StatusTypeDef HAL_Status;
sFilterConfig.FilterBank = 0; //过滤器屏蔽位模式
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;//32位宽
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; //32λ¿í
sFilterConfig.FilterIdHigh = 0x55<<6; //32位ID
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0xFFFF; //32位MASK 屏蔽位
sFilterConfig.FilterMaskIdLow = 0xFFFF;
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
//接收到的报文放入到FIFO0中
sFilterConfig.FilterActivation = ENABLE; //激活过滤器
sFilterConfig.SlaveStartFilterBank = 0;
HAL_Status=HAL_CAN_ConfigFilter(hcan, &sFilterConfig);
HAL_Status=HAL_CAN_Start(hcan); //开启CAN
if(HAL_Status!=HAL_OK)
{
printf("开启CAN失败\r\n");
}
HAL_Status=HAL_CAN_ActivateNotification(hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
if(HAL_Status!=HAL_OK)
{
printf("开启挂起中断允许失败\r\n");
}
}
(6)HAL_CAN_GetRxMessage();
功能:读取发送过来的数据
例:HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxMeg, Data);
说明:
hcan:hcan由STM32Cube自动生成,为结构体变量
CAN_RX_FIFO0: FIFO:表面的意思是“先入先出”,是指有层级深度的接收邮箱。
STM32F103系列单片机上有2个FIFO邮箱( FIFO0和FIFOl ),每个FIFO有3层深度。
与过滤器匹配的报文会被放入FIFO邮箱。
&RxMeg:接收桢ID
CAN_RxHeaderTypeDef RxMeg;
RxMeg.StdId=0x00;
RxMeg.ExtId=0x00;
RxMeg.IDE=0;
RxMeg.DLC=0;
Data:读取数据存放的缓冲区
8.清除数据
(1)清除数据
函数:memset(uart1RxBuff,0,128);
功能:把0复制到uart1RxBuff的前128项
说明:第一个填写要清除的数组,第二项填写要写入的值,第三项填写写入多少字节