STM32-微项目11-USART传输+printf重定向串口打印

一、微项目实现目标:

使用STM32,通过USART通讯方式,将数据传输到CH340端口,由CH340端口将数据转为USB协议,最终在笔记本上,通过上位机 查看;

二、微项目硬件配置需求:

 stm32F103C8T6核心板一块

0.96寸OLED显示,用于显示计数

CH340一块,用于笔记本到串口的传输

 

 

三、前置知识:

1,常见的数据通讯方式

 2,USART的硬件配置

①USART通讯,合适点对点的通讯。即通讯只有一个发送方和一个接收方;

②通讯端口只有RX和DX,需要注意的是,RX要和对方的TX链接,TX要和对方的RX链接,硬件上无比交叉连接;

③接地端一定要共地连接,否则数据传递会出现乱码、解析错误;

 3,USART数据传输的关键参数

①波特率:每秒钟发送数据的个数,如9600波特率,即1s传输9600个有效数据;

②起始位:标志一个数据帧的开始,固定为低电平,一般是从高置低;

③数据位:数据帧的有效载荷,1为高电平,0为低电平,低位先行;

④校验位:用于数据验证,根据数据位计算得来;

⑤停止位:用于数据帧间隔,固定为高电平,一般是从低置高;

 4,USART固件库配置的关键参数

①波特率;②数据长度;③停止位模式;④校验位模式

5,运行框图

1-传输端口TX,RX

2-波特率发生器,根据寄存器中配置的参数,控制输出周期

3-发送控制器和接受控制器

4-数据寄存器

数据发送:发送数据存放在发送数据寄存器TDR-----放到发送移位寄存器---按位逐步发送

数据接受:外部数据---到接受移位寄存器---满足一个字节后,转到RDR数据接受寄存器

 

 

四、代码模块逻辑分析:

①配置对应GPIO时钟\USART时钟;

②配置GPIO模式,输出TX位是推挽输出;

③配置USART参数

④开启USART

⑤重定向printf函数,复写fputc函数

五、代码示例:

①配置对应GPIO时钟\USART时钟;

//开启GPIO、USART 时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);

②配置GPIO模式,输出TX位是推挽输出;

	//配置GPIO端口,仅使用TX端口,PA9配置为复用推挽输出端口
	 GPIO_InitTypeDef GPIO_InitStruct;
	 GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;
	 GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,& GPIO_InitStruct);

③配置USART参数

比特率:9600

硬件流:无

模式:tx模式

校验位:不使用

停止位:1bit

字长:8b

	//配置usart
	USART_InitTypeDef USART_InitStruct;
	USART_InitStruct.USART_BaudRate=9600;
	USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
	USART_InitStruct.USART_Mode=USART_Mode_Tx;
	USART_InitStruct.USART_Parity=USART_Parity_No ;
	USART_InitStruct.USART_StopBits=USART_StopBits_1;
	USART_InitStruct.USART_WordLength=USART_WordLength_8b;
	USART_Init( USART1, &USART_InitStruct);
	

④开启USART

	USART_Cmd(USART1,ENABLE);

⑤重定向printf函数,复写fputc函数

其中USART_FLAG_TX表示传输寄存器为空,表示数据已经进入到移位寄存器中

int fputc( int ch, FILE *f )
{
	USART_SendData(USART1, ch);
	while(USART_GetFlagStatus( USART1,USART_FLAG_TXE)==RESET);
	return ch;
}

主函数简单配置

#include "stm32f10x.h"                  // Device header
#include "delay.h"
#include "OLED.H"
#include "SERIAL.H"
#include <cstdio>



int main()
{
	OLED_Init();

	OLED_ShowString(1,3,"HELLOWORLD");
	serial_init();
	senddata(0x42);
	printf("\r\nhello");
	printf("%s","hello world\r\n");

	while(1)
	{
	
		
	}
}

STM32F407单片机是一款基于Cortex-M4内核的控制器,它集成了USART2和USART3两个通用同步异步通信(UART)接口,可以同时支持双串口通信。要实现在这两个串口上使用printf函数的功能,你需要做以下几个步骤: 1. **初始化串口**: 首先,你需要在主程序中对USART2和USART3进行初始化,设置好波特率、数据位数、停止位以及奇偶校验等配置。 ```c void USART_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; // 初始化USART2 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; // TX/RX pins for USART2 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART2); GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART2); // 初始化USART3 (类似地配置) // ... // 设置USART parameters, like baud rate, data format etc. USART_InitStructure.USART_BaudRate = YOUR_BAUD_RATE; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_Init(USART2); // Initialize USART2 USART_Init(USART3); // Initialize USART3 } ``` 2. **创建printf重定向**: 使用第三方库如`stm32_printf`或自定义printf-like函数,将打印信息转换为字节流,然后发送到对应的串口。例如,你可以有一个宏或者全局函数来处理这个过程。 ```c #define PRINTF_USART2(format, ...) USART_SendString_Prototype((format), __VA_ARGS__, USART2) #define PRINTF_USART3(format, ...) USART_SendString_Prototype((format), __VA_ARGS__, USART3) // 自定义函数,用于发送字符串到指定的USART void USART_SendString_Prototype(const char *fmt, ...) { va_list argptr; static uint8_t buffer[256]; int len; va_start(argptr, fmt); vsnprintf(buffer, sizeof(buffer), fmt, argptr); va_end(argptr); len = strlen((char *)buffer); while(len--) USART_SendData(<USART2|R3>, buffer[len]); } ``` 3. **中断处理**: 如果有较高的实时性需求,可以考虑使用串口中断来接收来自对方的数据。通过读取RX寄存器,你可以在串口接收新字符时响应。 ```c void USART2_IRQHandler(void) { if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) { USART_ReadData(USART2); // Read received character // Handle the received data here } } // Similarly for USART3_IRQHandler() ```
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值