一、基于Arduino IDE完成STM32开发板的串口通信
(一)安装Arduino IDE
1.在Arduino IDE官网下载相关安装包
2.对下载的压缩包进行解压,安装。
(二)配置Arduino IDE
1.打开Arduino,点击左上角的工具->开发板->开发板管理器
2.搜索ARM,选择 Arduino SAM Boards(32-bit ARM Cortex-M3) 进行安装.
3.安装后可以找到对应的开发板
4.在官网下载Arduino STm32板型文件
5.将下载好的stm32文件夹复制到软件安装地址的hardware文件夹下
6.此时Arduino的开发板中出现了STM32板型
7.利用软件的例程来检查环境是否搭建成功
8.点击左上角编译,上传
(三)连接STM32开发板
1.将usb线连接开发板的USB转串口
2.利用跳帽将BOOT0与3v3相连,BOOT1与GND相连,RXD与A9相连,TXD与A10相连。
(四)程序及烧录
1.点击文件,新建
2.编写程序:
int flag=1;
char Stop[]="stop\n";
void setup() {
//初始化
pinMode(PB1, OUTPUT);//PB0为绿色,PB1为蓝色,PB5为红色,可根据需要改动
Serial.begin(115200);
}
void loop()
{
int i=0,flag=1;
char inByte[1000];
digitalWrite(PB1, HIGH); //小灯亮
delay(500); // 延迟
digitalWrite(PB1, LOW); //小灯灭
delay(500); // 延迟
while (Serial.available()> 0) //当发送缓冲区有数据时
{
inByte[i] = Serial.read(); //从串口的缓冲区取出并读取一个Byte的数据
delay(10);
i++ ;
}
if(Stop[i]=inByte[i])
{
if(Stop[i-1]==inByte[i-1]&&Stop[i-2]==inByte[i-2]&&Stop[i-3]==inByte[i-3])
{
flag=0;
}
}
if(flag==0)
{
Serial.println("收到!");//当收到stop命令时停止并回复收到!
while(1)
{continue;}
}
if(flag==1)
{
Serial.println("Hello world!");//向串口发送数据
delay(100); // 延迟
}
}
3.保存,选择自己的开发版,上传方式,端口等
4.编译,上传
(五)实验结果
1.观察到开发版的led灯闪烁
2.打开工具中的串口监视器
3.波特率设置为115200,可观察到串口持续输出”Hello world“,输入”stop“后停止输出
二、基于串口通信的标准库函数(SPL)与基于HAL库函数的stm32编程方式的差异
(一)关于标准外设库和HAL库
1.标准外设库
STM32标准外设库(Standard Peripherals Library,简称SPL)之前的版本也称固件函数库或简称固件库,是一个固件函数包,它由程序、数据结构和宏组成,包括了微控制器所有外设的性能特征。该函数库还包括每一个外设的驱动描述和应用实例,为开发者访问底层硬件提供了一个中间API,通过使用固件函数库,无需深入掌握底层硬件细节,开发者就可以轻松应用每一个外设。因此,使用固态函数库可以大大减少用户的程序编写时间,进而降低开发成本。每个外设驱动都由一组函数组成,这组函数覆盖了该外设所有功能。每个器件的开发都由一个通用API (application programming interface 应用编程界面)驱动,API对该驱动程序的结构,函数和参数名称都进行了标准化。STM32固件库详解
但是,标准外设库也是针对某一系列芯片而言的,没有可移植性。
2.HAL库
HAL库是ST公司目前主力推的开发方式,全称就是Hardware Abstraction Layer(抽象印象层)。库如其名,很抽象,一眼看上去不太容易知道他的作用是什么。它的出现比标准库要晚,但其实和标准库一样,都是为了节省程序开发的时期,而且HAL库尤其的有效,如果说标准库把实现功能需要配置的寄存器集成了,那么HAL库的一些函数甚至可以做到某些特定功能的集成。也就是说,同样的功能,标准库可能要用几句话,HAL库只需用一句话就够了。并且HAL库也很好的解决了程序移植的问题,不同型号的stm32芯片它的标准库是不一样的,例如在F4上开发的程序移植到F3上是不能通用的,而使用HAL库,只要使用的是相通的外设,程序基本可以完全复制粘贴,注意是相通外设,意思也就是不能无中生有,例如F7比F3要多几个定时器,不能明明没有这个定时器却非要配置,但其实这种情况不多,绝大多数都可以直接复制粘贴。是而且使用ST公司研发的STMcube软件,可以通过图形化的配置功能,直接生成整个使用HAL库的工程文件,可以说是方便至极,但是方便的同时也造成了它执行效率的低下,在各种论坛帖子真的是被吐槽的数不胜数。
3.两者官方比较图
(二)代码比较
基于标准库的串口通信代码
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库使用的代码量更少,但之前性能分析中HAL库却相比较于SPL库有着较大的ROM占用量,同时执行代码效率降低。
然而较高的可移植性,和适配STMcube软件成为了ST公司的主推的库。