UART
目标:实现使用串口0完成数据收发,波特率115200、数据长度8bits,无校验位,1停止位。
1.UART串行通信模块特点:
- 波特率软件可配置4路独立通道(UART0, UART1, UART4, UART5)
- 全双工通信口
- UART具有数据接收完成/接收错误中断,并提示错误类型
- 可配置数据长度,支持6、 7、 8、 9bits
- 可配置的停止位-支持1个停止位或2个停止位
- 可配置为红外调制输出功能,且载波频率可设置,及载波占空比可设置
- 支持DMA
- 支持接收超时机制
2.结构框图
3.引脚定义
RX和TX都要配置成数字外设功能。
4.数据帧格式配置
注:
目标帧结构:1+8+0+1;
寄存器PDSEL:01;PARITY:00;
5.时钟结构
UART0 和 UART1 采用了双时钟结构:
- 总线寄存器时钟用 pclk 表示,来源于 APBCLK。当 CPU 或者 DMA 需要访问 UART 内部寄存器时,必须使能 pclk
- 数据收发时钟用 uclk 表示,除了可以来源于 APBCLK,还可以来源于 RCHF、 SYSCLK、 RCMF,能够独立于 APBCLK 工作。必须使能 uclk 才能进行数据收发。
pclk用于配置,uclk用于传输,都要使能。
Pclk 和 uclk 的控制都在 CMU 模块内完成,进行 UART 通信前必须正确配置相应的 CMU 控制寄存器
CMU:时钟管理单元。
由于 UART 对输入信号进行 16 倍过采样,要求 SPBRG 配置不能小于 16,即 UART 工作时钟必须至少是波特率的 16 倍。
SPBRG:波特率发生寄存器
6.软件实现步骤
- 串口初始化
- 中断函数编写
- 串口助手测试通信
这部分验证之后再写
7.串口重定向
到手之后先配置了留的调试串口,UART0
进行串口0初始化之后加上重定向的代码即可实现printf打印数据
重定向部分放在main.c开头,或者main.h中。
注意我这里的初始化的奇偶校验为EVEN,波特率为115200.
void UART0_Init(void)
{
FL_GPIO_InitTypeDef GPIO_InitStruct;
FL_UART_InitTypeDef defaultInitStruct;
GPIO_InitStruct.pin = FL_GPIO_PIN_13;
GPIO_InitStruct.mode = FL_GPIO_MODE_DIGITAL;
GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.pull = FL_ENABLE;
GPIO_InitStruct.remapPin = FL_DISABLE;
FL_GPIO_Init( GPIOA, &GPIO_InitStruct );
GPIO_InitStruct.pin = FL_GPIO_PIN_14;
GPIO_InitStruct.mode = FL_GPIO_MODE_DIGITAL;
GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.pull = FL_DISABLE;
GPIO_InitStruct.remapPin = FL_DISABLE;
FL_GPIO_Init( GPIOA, &GPIO_InitStruct );
defaultInitStruct.clockSrc = FL_RCC_UART0_CLK_SOURCE_APB1CLK;
defaultInitStruct.baudRate = 115200;
defaultInitStruct.dataWidth = FL_UART_DATA_WIDTH_8B;
defaultInitStruct.stopBits = FL_UART_STOP_BIT_WIDTH_1B;
defaultInitStruct.parity = FL_UART_PARITY_EVEN;
defaultInitStruct.transferDirection = FL_UART_DIRECTION_TX_RX;
FL_UART_Init(UART0,&defaultInitStruct );
}
#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)
{
UART0->TXBUF = ch;
while (!(UART0->ISR & (0x1 << 0)));
UART0->ISR |= (0x1 << 0);
return ch;
}
#endif
while(1)
{
printf("111111111\n");
FL_DelayMs(500);
}
@文章主要内容来自芯片产品说明书