基于串口通信的标准库函数(SPL)与基于HAL库函数的stm32编程方式的差异

由于学习STM32的过程中逐渐接触了标准外设库(SPL)和HAL库,而这两者库存在着明显差异。于是此次通过对串口通信的SPL库与HAL库的STM32编码差异上来分析这两者的不同。

一、 简介

ST为开发者提供了非常方便的开发库。到目前为止,有标准外设库(STD库)、HAL库、LL库 三种。本文主要是针对标准外设库(STD库)、HAL库进行对比分析。

1.1 标准外设库

STM32标准外设库(Standard Peripherals Library,简称SPL)之前的版本也称固件函数库或简称固件库,是一个固件函数包,它由程序、数据结构和宏组成,包括了微控制器所有外设的性能特征。该函数库还包括每一个外设的驱动描述和应用实例,为开发者访问底层硬件提供了一个中间API,通过使用固件函数库,无需深入掌握底层硬件细节,开发者就可以轻松应用每一个外设。因此,使用固态函数库可以大大减少用户的程序编写时间,进而降低开发成本。每个外设驱动都由一组函数组成,这组函数覆盖了该外设所有功能。每个器件的开发都由一个通用API (application programming interface 应用编程界面)驱动,API对该驱动程序的结构,函数和参数名称都进行了标准化。STM32固件库详解

但是,标准外设库也是针对某一系列芯片而言的,没有可移植性。

1.2 HAL库

HAL库是ST公司目前主力推的开发方式,全称就是Hardware Abstraction Layer(抽象印象层)。库如其名,很抽象,一眼看上去不太容易知道他的作用是什么。它的出现比标准库要晚,但其实和标准库一样,都是为了节省程序开发的时期,而且HAL库尤其的有效,如果说标准库把实现功能需要配置的寄存器集成了,那么HAL库的一些函数甚至可以做到某些特定功能的集成。也就是说,同样的功能,标准库可能要用几句话,HAL库只需用一句话就够了。并且HAL库也很好的解决了程序移植的问题,不同型号的stm32芯片它的标准库是不一样的,例如在F4上开发的程序移植到F3上是不能通用的,而使用HAL库,只要使用的是相通的外设,程序基本可以完全复制粘贴,注意是相通外设,意思也就是不能无中生有,例如F7比F3要多几个定时器,不能明明没有这个定时器却非要配置,但其实这种情况不多,绝大多数都可以直接复制粘贴。是而且使用ST公司研发的STMcube软件,可以通过图形化的配置功能,直接生成整个使用HAL库的工程文件,可以说是方便至极,但是方便的同时也造成了它执行效率的低下,在各种论坛帖子真的是被吐槽的数不胜数。STM32 之 HAL库

1.3 性能比较

下图是官方给出的几个常用功能:GPIO 翻转、TIM PWM 输出、ADC DMA 数据采集和 DMA M2M ,使用不同库开发出来的运行结果,可供大家参考对比,做出符合自己开发项目需要的选择。
在这里插入图片描述
STM32使用HAL库、标准库、LL库和寄存器操作的性能对比

代码效率与移植性成反比的规律是明显的。但与 Cube HAL 相比, Cube LL 的效率优势还是很明显的,几乎和直
接写寄存器的效率相差无几。
而且目前 STM32cubeMX 已经开始支持直接生成使用 Cube LL 的工程,对于以后追求效率的开
发应用人员来说,非常值得推荐给大家使用。

二、 源代码

主要是在串口通信上进行源代码分析。

  • 基于标准库的串口通信
int main(void)
 {		
 	u16 t;  
	u16 len;	
	u16 times=0;
	delay_init();	    	 //延时函数初始化	  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
	uart_init(115200);	 //串口初始化为115200
 	LED_Init();			     //LED端口初始化
	KEY_Init();          //初始化与按键连接的硬件接口
 	while(1)
	{
		if(USART_RX_STA&0x8000)
		{					   
			len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
			printf("\r\n您发送的消息为:\r\n\r\n");
			for(t=0;t<len;t++)
			{
				USART_SendData(USART1, USART_RX_BUF[t]);//向串口1发送数据
				while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
			}
			printf("\r\n\r\n");//插入换行
			USART_RX_STA=0;
		}else
		{
			times++;
			if(times%5000==0)
			{
				printf("\r\n精英STM32开发板 串口实验\r\n");
				printf("正点原子@ALIENTEK\r\n\r\n");
			}
			if(times%200==0)printf("请输入数据,以回车键结束\r\n"); 
			if(times%30==0){LED0=!LED0; LED1=!LED1;}//闪烁LED,提示系统正在运行.
			delay_ms(10);   
		}
	}	 
 }
  • 基于HAL库的串口通信
int main(void)
{
	u8 len;	
	u16 times=0;
	
    HAL_Init();                    	 	//初始化HAL库    
    Stm32_Clock_Init(RCC_PLL_MUL9);   	//设置时钟,72M
	delay_init(72);               		//初始化延时函数
	uart_init(115200);					//初始化串口
	LED_Init();							//初始化LED	
	KEY_Init();							//初始化按键
	
    while(1)
    {
			
       if(USART_RX_STA&0x8000)
		{					   
			len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
			printf("\r\n您发送的消息为:\r\n");
			HAL_UART_Transmit(&UART1_Handler,(uint8_t*)USART_RX_BUF,len,1000);	//发送接收到的数据
			while(__HAL_UART_GET_FLAG(&UART1_Handler,UART_FLAG_TC)!=SET);		//等待发送结束
			printf("\r\n\r\n");//插入换行
			USART_RX_STA=0;
		}else
		{
			times++;
			if(times%5000==0)
			{
				printf("\r\nALIENTEK 精英STM32开发板 串口实验\r\n");
				printf("正点原子@ALIENTEK\r\n\r\n\r\n");
			}
			if(times%200==0)printf("请输入数据,以回车键结束\r\n");  
			if(times%30==0)LED0=!LED0;//闪烁LED,提示系统正在运行.
			delay_ms(10);   
		} 
    }
}

以上代码均来源正点原子。

三、 编码差异

  • 标准库向串口输出的代码
			for(t=0;t<len;t++)
			{
				USART_SendData(USART1, USART_RX_BUF[t]);//向串口1发送数据
				while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
			}
  • HAL库向串口输出的代码
			HAL_UART_Transmit(&UART1_Handler,(uint8_t*)USART_RX_BUF,len,1000);	//发送接收到的数据

可以明显看出该部分内容下,HAL库的代码量明显少于SPL库。而且一个大工程中,使用HAL库将明显减少了开发时间。

四、 总结

通过两种库对串口通信的编码方式差异可以简单看出,HAL库使用的代码量更少,但之前性能分析中HAL库却相比较于SPL库有着较大的ROM占用量,同时执行代码效率降低。
然而较高的可移植性,和适配STMcube软件成为了ST公司的主推的库。

综合上述,学习HAL库有较好的未来机会,但单片机的学习并不是简简单单的库函数学习,更多还是对底层知识的理解。

推荐文献阅读:
STM32教程(三)STM32 HAL固件库介绍及使用
STM32HAL库与标准库的区别
STM32标准库与HAL库比较

五、参考资料

[1]STM32 之 HAL库
[2]STM32固件库详解
[3]STM32使用HAL库、标准库、LL库和寄存器操作的性能对比

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值