5 直接操作STM32寄存器的UART测试程序(实现printf)和仿真
5.1 串口代码
uart.h
#ifndef USART_H
#define USART_H
void usart_init(void);
void usart_send(int c);
int usart_recv(void);
#endif
uart.c
#include <stdio.h>
#include "stm32f10x.h" // Device header
void usart_init(void)
{
// 使能APB2的GPIOA的时钟
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
// 使能APB2的USART的时钟
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
// PA9和PA10配置为串口功能
GPIOA->CRH = (GPIOA->CRH & ~(0xF << 4)) | (0xB << 4);
GPIOA->CRH = (GPIOA->CRH & ~(0xF << 8)) | (0x4 << 8);
// 波特率9600
USART1->BRR = (468 << 4) | 12;
// 使能串口,帧格式8-N-1
USART1->CR1 = 0x200C;
// 清发送完成标志位
USART1->SR &= ~USART_SR_TC;
}
void usart_send(int c)
{
// 等待上一次发送完成
while (!(USART1->SR & USART_SR_TXE));
// 将发送数据写入寄存器
USART1->DR = c;
// 等待发送完成
while (!(USART1->SR & USART_SR_TC));
}
int usart_recv(void)
{
// 轮询等待接收
while (!(USART1->SR & USART_SR_RXNE));
// 返回收到的数据
return USART1->DR;
}
// C标准输入输出库stdio的底层支持函数,这样printf和scanf等就定向到了串口
// 在不同的终端下,对/r和/n要做一些特殊的处理,这里省略
int fputc(int c, FILE *stream)
{
usart_send(c);
return c;
}
int fgetc(FILE *f)
{
return usart_recv();
}
main.c
#include <stdio.h>
#include "usart.h"
int main(void)
{
usart_init();
printf("System initialized\r\n");
while (1) {
putchar(getchar());
}
}
5.2 安装虚拟串口软件
运行VSPD安装程序
用Crack目录下的文件替换安装目录下的文件。运行VSPD,创建虚拟串口对。
5.3 串口仿真
打开PuTTY,做如下设置。
保存设置方便以后使用。
这时VSPD显示COM1被PuTTY打开。
编译并运行串口测试程序,并启动调试,在MDK下方的命令行窗口中输入下面两行命令,表示打开COM2,将UART1和该COM口关联。
这时VSPD显示COM2被MDK打开。
运行程序,查看PuTTY的屏幕显示。在终端上输入字符,串口程序进行回显。