一、所用工具:
1、芯片: STM32F407ZGT6
2、STM32CubeMx软件
3、IDE: MDK-Keil软件
4、STM32F4xxHAL库
二、CUBEMX配置
1、打开CUBEMX,新建工程
2、选择自己的芯片
3、选择调试器
4、配置为外部时钟源
5、配置详细时钟频率
6、开启异步串口通信
7、命名工程,不要带中文,选择IDE
8、勾选“仅生成比原的库文件”,“生成对应的.c/.h文件” 
至此,CUBEMX初始化配置完成
三、MDK_ARM配置
1、初始化设置
点击 确定 -> ok,完成配置
2、串口重定向
在自定义代码四区输入以下代码,头文件最好添加在USER CODE BEGIN Includes区
#include "stdio.h"
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
return ch;
}
int fgetc(FILE *f)
{
uint8_t ch = 0;
HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
return ch;
}
或
#include <stdio.h>
#ifndef __GNUC__ // 如果不使用ARMCCV6编译器
#pragma import(__use_no_semihosting) // 不使用半主机函数
struct __FILE{int handle;}; // 标准库需要的支持函数
void _sys_exit(int x) {x = x;} // 避免使用半主机模式
#endif
FILE __stdout; // ARMCC V6版本需要添加支持
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
return(ch);
}
3、串口接收数据
#include "string.h"
#include "stdio.h"
#include "stdlib.h"
#define RXBUFFERSIZE 256
char RxBuffer[RXBUFFERSIZE],rx_buf[5];
uint8_t aRxBuffer;
uint8_t Uart1_Rx_Cnt = 0;
int num=0;
HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
UNUSED(huart);
if(huart==&huart1){
if(Uart1_Rx_Cnt >= 255) { //数据溢出判定
Uart1_Rx_Cnt = 0;
memset(RxBuffer,0x00,sizeof(RxBuffer));
HAL_UART_Transmit(&huart1, (uint8_t *)"OVERFLOW", 10,0xFFFF);
}
else{
RxBuffer[Uart1_Rx_Cnt++] = aRxBuffer;
if((RxBuffer[Uart1_Rx_Cnt-1] == 0x0A)&&(RxBuffer[Uart1_Rx_Cnt-2] == 0x0D)) { //帧头帧尾判定
strcpy(rx_buf,RxBuffer);
num=atoi(rx_buf);
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);
}
}
四、消除中文编码警告
添加语句
-Wno-invalid-source-encoding
五、串口通信
1、基本参数
串行端口的通信方式是将字节拆分成一个接一个的位再传输出去,接收方再将此一个一个的位组合成原来的字符,如此形成一个字节的完整传输,在数据传输时,应在通信端口的初始化时设置几个通信参数。
1)波特率,即传送数据的速度。波特率的意思就是在一秒中可以传输的数据位数,单位是bps。如果采用波特率4800bps进行传输,那么每秒可以传输600个byte。
2)数据位,当接收设备收到起始位后,紧接着就会收到数据位,数据位的个数可以是5、6、7或者8位。在字符数据传输的过程中,数据位从最低有效位开始传输。
3)起始位,在串口线上,没有数据传输时处于逻辑“1”状态,当发送设备要发送一个字符数据时,首先发出一个逻辑“0”信号,这个逻辑低电平就是起始位。
4)停止位,是一个字符数据的结束标志,它可以是1位、1.5位或者2位。
5)奇偶校验位,数据位发送完之后,就可以发送奇偶校验位。奇偶校验用于有限差错校验,通信双方在通信时约定一致的奇偶校验方式。
2、串口通信API
从上一页的表中可以看出STM32的串口通信方式大致有轮询、中断和DMA三种方式,而且DMA接收方式也需要开启串口中断。
轮询方式适合简单的串口通信,但是在复杂多任务系统不适合使用,数据接收会受到高优先级任务影响,或者影响其它低优先级任务。
中 断 和 D M A 接 收 方 式 , 都 需要调用接收中断回调函数HAL_UART_RxCpltCallback或者HAL_UARTEx_RxEventCallback,用户需要重新编写该函数,以便在接收数据到来时及时处理。
STM32定义串口总线上在一个字节的时间内没有再接收到数据时,认为是串口空闲;而空闲中断是检测到有数据被接收后,总线上在一个字节的时间内没有再接收到数据的时候发生的。比如在通信速率为115200bps时,一个字节的时间可以大致计算为1000 * 10 / 115200 = 0.087ms,取整约等于100微秒。