STM32学习笔记(CubeMX配HAL)(第五天:串口通信)

今天要开始学习串口数据的一个收和发

很多单片机存在多个串口收发,比如wifi开发等,都需要通过串口来进行数据交互。

首先需要了解下并行通信和串行通信:这两种方式大多都是用来外部和微处理器进行通信的主要方式。

其中,并行就是传输速度块,但是占用资源大,需要引脚比较多

      串行的话,占用资源和引脚都比较少,但是传输速度比较慢。

接下来看看,串行通信种存在三种模式:单工,半双工,全双工

单工就是:只有一个方向,要么只能发送或者只能接受

半双工:就是可以接收也可以发送,但是不能同时进行。需要调整模式在下一个时间段进行接收或者发送的动作。比较典型的就是RS450这种总线

全双工:就是同时进行,比较牛逼。基本现在都是全双工。

然后看看啥叫异步串行通信:通信双方在没有同步时钟的前提下,将一个字符按位进行传输的通信方式。一般来说没有同步时钟,很难准确接受。这里我们就需要用到一个新的东西。叫做波特率、只要波特率相同,就可以进行传输了。

比特率:每秒传输的二进制数,单位是BPS。

TTL----->RS232:由TTL到电脑的串口,就需要MAX3232或者SP3232来达到波特率相同。

串口------->USB接口:CH340或者CP2012来进行波特率转换。

STM32一般用的都是由UASRT的,不过一般使用异步串行通信。

比如USART1_TX和PA9复用         USART1_RX与PA10复用

USART2_TX和PA2复用         USART2_RX与PA3复用

当然这玩意儿看你的芯片手册是咋安排的具体。

首先对于HAL库里的串口函数需要率先认识一些:
第一种是阻塞式发送函数:

HAL_StatusTypeDef   HAL_UART_Transmit(UART_HandledTypeDef*huart,//一个外设的地址
                                    Uint8_t*pData,//发送的内容
                                    Uint16_t Size,//发送的字节大小
                                    Uint32_t Timeout);//超时时间

为啥叫阻塞式发送函数呢?就是说发送完,函数才执行完,不然单片机只能执行这个函数,无法干其他事情。所以说虽然逻辑上比较方便,但是应用上其实不太有优势。

接下来看一下非阻塞式的发送函数

HAL_StatusTypeDef   HAL_UART_Transmit_IT(UART_HandleTypeDef*huart,
                                       Uint8_t *pData,
                                       Uint16_t Size);

这个函数是自带发送中断的,首先同样的也需要使能发送中断的,然后数据完成后又进行回调。就可以做些其他事儿了。

一般来说,上述发送完毕之后,就需要用到回调函数

一个是:

void  HAL_UART_TxCpltCallback(UART_HandledTypeDef*huart);
void  HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef*huart);//这是执行一半就回调的函数。

那么接下来,我们就来举个例子

使用非阻塞式的串口发送函数,将数组的前五个数据发送到USART1,在数据发送完成后,翻转LED的输出电平。

那么程序呢大概如下:

HAL_UART_Transmit_IT(&huart1/*串口一的地址*/),&dat_Txd/*缓冲区的地址*/,5/*5个数据*/);
void HAL_UART_TxCpltCallback(UART_HandleTypeDef*huart)
{
If(huart->instance == USART1)//判断是否是串口一在调用
{
HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_2);
}

}

如果说是阻塞式的函数,就会很简单

HAL_UART_Transmit(&huart1,dat_Txd,5,10000);//最后那个就是超时时间,超时后就会自动结束。
HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_2);

第二种例子就是接受函数:

首先这次就用阻塞式来接受:

HAL_StatusTypeDef  HAL_UART_Receive(UART_HandleTypeDef *huart,
                                  Uint8_t *pData,
                                  Uint16_t Size,
                                  Uint32_t Timeout);

 第二种是非阻塞式的(一般来说都是用非阻塞式的):

HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart,
                                   Uint8_t*pData,
                                   Uint16_t Size);

发送完毕后呢需要调用中断回调函数:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef*huart);
void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef*huart);

同样的举个例子:

使用非阻塞式的串口接受USART中的一个字节,保存在dat_Rxd变量中,在数据发送完成后,若该字节为0x5A,则翻转LED输出电平。

HAL_UART_Receive_IT(&huart1,&dat_Rxd,1);
Void HAL_UART_RxCpltCallback(UART_HandleTypeDef*huart)
{
If(huart->Instance == USART1){

If(dat_Rxd == 0x5A){
HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_2);
}
}
}

那么接下来就是CubeMX的一个设置

 首先对USART1中断使能

 接着把波特率改成9600(常用)

然后设置两个LED的OUTPUT大致就可以了,然后生成代码

打开后可以看见代码中多了新的.c文件和一些新的初始化函数。

 我们打开usart.c看一下

CubeMX已经把我们需要配置的具体参数,在USART1的初始化函数中配置了。

那么接下来,我们需要完成一下一些比较简单的应用

第一个是向串口1发送“hello world”

其次分别需要发送接收数据。同时提示LED1 OPEN之类的;

 

用uint8_t来定义一下数组和缓冲区。

然后就开始写阻塞式(非阻塞式)的串口发送函数。

 写好之后用串口助手试验一下。

 

那么这是发送,接下来就需要进行一个接收的功能

首先为了方便,把LED的开关,定义成宏定义的形式,这样会比较的简便,

然后定义一个接收的数据; 

 接下来同样的,使用Receive函数,然后再启用回调,就是我们上面所提到的步骤。

 回调函数乐意直接找到然后自己进行更改;

 

一定要记住需要再if里面添加再一次的HAL_UART_Receive_IT(&huart1,&Rx__dat,1);

不然只会接受一次!!!

最后进行调试,就非常简单了。

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ReedswayYuH.C

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值