基于STM32使用CubeIDE实现串口通信
串口的配置与使用
CubeIDE配置
首先在左侧列表中找到USART,然后选择一个你喜欢的数字,作为串口使用
选择异步模式,下面Paramete Setting中,Baud Rate就是串口的波特率,这里我们不用动,不过一会连接需要它。设置完成后保存,
Alt
+K
生成代码,串口配置完成
串口阻塞方式收发
发送数据
可以看到,这个函数一共有四个参数,
第一个参数是要使用的串口句柄地址,比如要使用U(S)ART1,参数就设置为U(S)ART1的句柄地址&huart1
第二个参数是要发送的数据缓冲区首地址
第三个参数是发送的数据长度,这里可以直接用sizeof()函数获取发送缓冲区的长度
第四个参数是超时时间,单位是ms,如果超过设置的时间,则函数返回HAL_TIMEOUT,如果设置为HAL_MAX_DELAY,处理器就会一直等到数据发送完成再执行下一条语句。
打开main.c来到如图位置,输入如下代码
HAL_UART_Transmit(&huart1,"Hello world",11,100);
Hal_Delay(999);
注意这里一定要在/* USER CODE END WHILE */ 之前输入代码,不然再生成一次就会被覆盖掉(血泪史.jpg)
接下来直接烧录(我想这个应该是不用教)
下载群里发的XCOM(正点原子推荐).rar
,解压,为了以防万一,先运行dotNetFx40_Full_x86_x64.exe
·当然,一会打不开回来再安装也不是不行。
打开XCOM V2.2.exe
,我们可以看到如下界面
首先,我们需要把右侧的波特率改为刚刚上面你自己配置的波特率(如果没改就是115200)
然后连接USB/TTL到板子上,rx,tx分别接stm32板子上tx,rx
打开串口,理论上我们就可以看到左侧上方显示每秒都会发过来的Hello world了
接收数据
同HAL_UART_Transmit()函数一样,这个函数也有四个参数
第一个参数是要使用的串口句柄地址,比如要使用U(S)ART1,参数就设置为U(S)ART1的句柄地址&huart1
第二个参数是接受数据的缓冲区首地址
第三个参数是接受的数据长度,这里可以直接用sizeof()函数获取接受缓冲区的长度
第四个参数是超时时间,单位是ms,如果超过设置的时间,则函数返回HAL_TIMEOUT,如果设置为HAL_MAX_DELAY,处理器就会一直等到接受到设置好的数据数量再执行下一条语句。
在此处初始化接收缓冲区,一个char为8bit,故此处11个成员的数组可以容纳11个char
uint8_t Rxbuf[11];
然后在原先发送处输入如图代码,此处意为当完成接收后,把接收到的内容发送回接收者
if(HAL_UART_Receive(&huart1,Rxbuf,sizeof(Rxbuf),1000) == HAL_OK)
{
HAL_UART_Transmit(&huart1,Rxbuf,sizeof(Rxbuf),100);
}
接下来我们重复发送时的操作
但现在我们需要在下面的输入框中输入不长于11个byte的文本,如
Hello world
,此时上方就会收到32发送回来的相同内容,到此,串口阻塞方式的收发教程就已经完成
UART中断方式收发
CubeIDE配置
回到原来的界面,在下方面板选择
NVIC Setting
,随后勾选Enabled
,至此,中断便配置完毕了
中断方式收发代码
中断方式的收发函数只有三个参数
第一个参数时要使用的串口句柄地址
第二个参数是发送/接受缓冲区的首地址,用于存放要发送/接收的数据
第三个参数是发送/接受缓冲区长度
前三个参数和阻塞方式完全一致,为什么没有超时时间了呢? 因为中断(IT)方式配置完成寄存器之后不需要再占用CPU,会在接受完成后触发中断。
阻塞方式就好比你要拿快递,就一遍遍都前台询问快递到没到,在这期间你不能干别的, 中断方式是你告诉前台快递到了给你打电话,在这期间你是可以腾出身子来干别的事情。
由此可见,中断方式效率大于阻塞方式,极端情况下,中断方式的安全性也高于阻塞方式
接收中断回调函数
顾名思义,该函数是当中断方式串口接收触发中断(接收完成)所调用的函数
该函数的返回值为__weak,表示这个函数需要用户自己去编写,最终会执行用户所自行编写的回调函数(如果用户不编写,也会执行自带的回调函数,只不过自带的HAL_UART_RxCpltCallback()函数是空函数,所以等同于什么也没有做)
注意:用户自行编写的回调函数返回值不能为__weak。 与接收同理,也有发送的中断,但一般情况下不会去使用,故不多赘述
接下来,我会带着你们用中断实现之前使用阻塞方式完成的信息收发
首先像阻塞方式一样建立我们的缓冲区
然后在CubeIDE生成完成之后,开始循环之前,开启中断的接收
HAL_UART_Receive_IT(&huart1,Rxbuf,sizeof(Rxbuf));
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
if(UartHandle -> Instance == USART1)
{
//发送数据
HAL_UART_Transmit(&huart1,Rxbuf,sizeof(Rxbuf),100);
//重新开启串口的接收中断
HAL_UART_receive_IT(&huart,Rxbuf,sizeof(Rxbuf));
}
}
注意要注释掉阻塞方式的代码,以免影响测试 接下来像阻塞方式一样测试,就可以得到相同的结果
DMA方式串口收发
什么是DMA
知识拓展链接:百度-DMA
前文说过中断方式就好比你告诉前台,等快递到了给你打电话,让你亲自来取,假设你正在做着一些重要的事情,正好来了电话让你取快递,这样一来就会耽误事。 这怎么办呢?雇个保姆不就好了吗,DMA就好比这个保姆,你告诉她在哪里取快递,她就会等快递到了之后自己帮你把快递拿回家。
CubeIDE配置
回到原来的界面,在下方面板选择
DMA Settings
,然后点击Add,在DMA Request
中分别选择RX
和TX
,随后单击选中,在Mode中选择Circular
,若选择Normal则只能接收一次的数据,其他的一般情况下不需要修改,配置完成后显示如下图
DMA方式收发代码
接收函数如上图所示,参数含义与中断方式的相同,可以点击此处回到中断方式处复习单击此处跳转
随后我们依旧去实现最开始我们用阻塞方式实现收发功能
依旧是设置缓冲区
uint8_t Rxbuf[11];
然后是与中断极为类似的业务代码,同样不要写在循环中
最后是与中断一模一样的回调代码,这里就不重复了,点击这里回到中断部分复习 至于最后烧录和测试,我在这里也就不过多赘述,仿照之前的操作即可
串口通讯原理
懒得写了,直接上一个我觉得讲的还可以的链接吧
Q.E.D.