上一篇文章中已经介绍了CubeMX的基本使用方法了,本文将实现串口通信
实验工具
单片机:正点原子STM32F4探索者 软件:CubeMX、Keil5 参考文档: 《STM32F4xx中文参考手册》 《正点原子 STM32F4 开发指南V1.2–HAL 库版本 》 ST32 HAL库使用手册
硬件配置
经过上一次实验的学习已经知道了CubeMX的美妙之处,只需要点击几下鼠标就可以跳过繁琐的硬件配置步骤,让我们能把经理集中到功能代码的设计上。本次实验将继续使用CubeMX实现单片机的串口通信。 时钟配置不过多介绍,和上一次配置的一样。 串口配置 这里的串口模式选择异步通信,下方的参数设置根据自己的需求进行设置,每一个参数的设置以及带来的作用 stm32f4的参考手册里都写的很清楚,需要详细了解可以下载手册进行学习。 右侧的引脚要注意是否是自己需要用到的引脚,因为存在引脚复用的情况,有时候出现引脚被占用或者其他时,软件可能会用其他引脚复用去实现。
配置选项卡的中断设置需要打开,在串口接收是我们需要用到中断。
代码添加
HAL库中使用到的串口收发函数,函数都可以在HAL库的手册中找到,有兴趣可以下载手册进行详细了解
串口发送
以下代码添加到stm32f4xx_hal.c中,不清楚添加到其他c文件中能不能起效。 重定向printf,代码是我在网上找到的,怎么就实现printf我还不是很明白
#include "stdio.h"
#if SYSTEM_SUPPORT_OS
#include "includes.h"
#endif
#if 1
#pragma import(__use_no_semihosting)
struct __FILE
{
int handle;
};
FILE __stdout;
void _sys_exit(int x)
{
x = x;
}
int fputc(int ch, FILE *f)
{
while((USART1->SR&0X40)==0);
USART1->DR = (uint8_t) ch;
return ch;
}
#endif
发送信息
while (1)
{
printf("Hello World!\r\n");
HAL_Delay(1000);
}
在串口助手下成功接收到信息(第一行是我连接的LCD屏初始化返回的信息)
串口接收
HAL的串口中断调用比较繁琐, 下图摘自 正点原子 STM32F4手册 这个流程我们可以从stm32f4xx_it.c中的USART1_IRQHandler()函数找起 main.c中添加定义
#include "stdio.h"
#include "string.h"
#define RXBUFFERSIZE 256
char RxBuffer[RXBUFFERSIZE];
uint8_t aRxBuffer;
uint8_t Uart1_Rx_Cnt = 0;
在主函数中需要调用一次接收中断,进入中断 HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, size), size指多少个字节执行一次回调函数接下来就会按照上图流程进行
最后在main.c 中设置回调函数,通过串口发送给单片机的数据回被发回
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
UNUSED(huart);
if(Uart1_Rx_Cnt >= 255)
{
Uart1_Rx_Cnt = 0;
memset(RxBuffer,0x00,sizeof(RxBuffer));
HAL_UART_Transmit(&huart1, (uint8_t *)"data over", 10,0xFFFF);
}
else
{
RxBuffer[Uart1_Rx_Cnt++] = aRxBuffer;
if((RxBuffer[Uart1_Rx_Cnt-1] == 0x0A)&&(RxBuffer[Uart1_Rx_Cnt-2] == 0x0D))
{
HAL_UART_Transmit(&huart1, (uint8_t *)&RxBuffer, Uart1_Rx_Cnt,0xFFFF);
while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX);
Uart1_Rx_Cnt = 0;
memset(RxBuffer,0x00,sizeof(RxBuffer));
}
}
HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);
}
|