5. STM32——串口发送字符、字符串 + printf 的重定向

基本框架

1. 配置时钟:配置GPIO时钟、窗口时钟、引脚复用时钟

//1.配置时钟
		
//1.1配置GPIOA、串口时钟、复用时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
		

2. 配置GPIO结构体

在 stm32f10x_gpio.h 头文件中查找相关函数函数

//2.配置GPIOA结构体
GPIO_InitTypeDef 	gpioInitStructure;
		
//2.1 A9 TX (发送)
gpioInitStructure.GPIO_Mode		= GPIO_Mode_AF_PP; //复用推挽输出
gpioInitStructure.GPIO_Pin		= GPIO_Pin_9;
gpioInitStructure.GPIO_Speed	= GPIO_Speed_50MHz;
		
GPIO_Init(GPIOA, &gpioInitStructure); //初始化A9
		
//2.2 A10 RX (接收)
gpioInitStructure.GPIO_Mode		= GPIO_Mode_IN_FLOATING; //浮空输入
gpioInitStructure.GPIO_Pin		= GPIO_Pin_10;
		
GPIO_Init(GPIOA, &gpioInitStructure); //初始化A10

3. 配置串口结构体

在 stm32f10x_usart.h 头文件中查找相关函数

//3.配置串口结构体

usartInitStructure.USART_BaudRate				=	115200; //波特率 115200
usartInitStructure.USART_HardwareFlowControl	=	USART_HardwareFlowControl_None; //无硬件数据流控制
usartInitStructure.USART_Mode					=	USART_Mode_Tx | USART_Mode_Rx; //收发模式
usartInitStructure.USART_Parity					=	USART_Parity_No; //无奇偶校验位
usartInitStructure.USART_StopBits				=	USART_StopBits_1; //1位停止位
usartInitStructure.USART_WordLength				=	USART_WordLength_8b; 字长为 8 位数据格式
		
USART_Init(USART1, &usartInitStructure); //初始化串口
USART_Cmd(USART1, ENABLE); //使能串口(比GPIO多了一步)

4. 串口的发送

在这里插入图片描述

STM32 串口通信中 USART_FLAG_TC 与 USART_FLAG_TXE 区别

在这里插入图片描述

在 stm32f10x_usart.h 头文件中查找相关函数

int main()
{
	USART_SendData( USART1, 'O'); //发送 ‘0’
	while( USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET ); //判断 '0' 是否已被发送出去
	USART_SendData( USART1, 'K'); //发送 ‘1’
	while( USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET ); //判断 '1' 是否已被发送出去
	delay(1000);
}

基本框架整合代码

usart.c

#include "usart.h"
#include "stm32f10x.h"

void usart_init()
{
		GPIO_InitTypeDef 	gpioInitStructure;
		USART_InitTypeDef	usartInitStructure;
		
		//1.配置时钟
		
		//1.1配置GPIOA、串口时钟、复用时钟
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
		
		//2.配置GPIOA结构体
		
		//2.1 A9 TX
		gpioInitStructure.GPIO_Mode		= GPIO_Mode_AF_PP;
		gpioInitStructure.GPIO_Pin		= GPIO_Pin_9;
		gpioInitStructure.GPIO_Speed	= GPIO_Speed_50MHz;
		
		GPIO_Init(GPIOA, &gpioInitStructure);
		
		//2.2 A10 RX
		gpioInitStructure.GPIO_Mode		= GPIO_Mode_IN_FLOATING;
		gpioInitStructure.GPIO_Pin		= GPIO_Pin_10;
		
		GPIO_Init(GPIOA, &gpioInitStructure);

		//3.配置串口结构体
		usartInitStructure.USART_BaudRate				= 115200;
		usartInitStructure.USART_HardwareFlowControl	= USART_HardwareFlowControl_None;
		usartInitStructure.USART_Mode					= USART_Mode_Tx | USART_Mode_Rx;
		usartInitStructure.USART_Parity					= USART_Parity_No;
		usartInitStructure.USART_StopBits				= USART_StopBits_1;
		usartInitStructure.USART_WordLength				= USART_WordLength_8b;
		
		USART_Init(USART1, &usartInitStructure);
		USART_Cmd(USART1, ENABLE);
		
}

usart.h

#include "stm32f10x.h"

void usart_init(void);

main.c

#include "stm32f10x.h"
#include "main.h"
#include "led.h"
#include "shake.h"
#include "relay.h"
#include "exti.h"
#include "usart.h"

void delay(uint16_t time)
{
	uint16_t i=0;
	
	while(time--)
	{
		i=10000;
		while(i--);
	}
}

int main()
{
	USART_SendData( USART1, 'O'); //发送 ‘0’
	while( USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET ); //判断 '0' 是否已被发送出去
	USART_SendData( USART1, 'K'); //发送 ‘1’
	while( USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET ); //判断 '1' 是否已被发送出去
	delay(1000);
}


串口发送字符、字符串

1. 串口发送字符

void USARTSendByte(USART_TypeDef* USARTx, uint16_t Data)
{
	USART_SendData( USARTx, Data);
	while( USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET ); //判断 Data 是否已被发送出去
}

2. 串口发送字符串

void USARTSendStr(USART_TypeDef* USARTx, char* str)
{
	uint16_t i=0;
	
	while( *(str+i) != '\0' )
	{
		/*
		USART_SendData( USARTx, *(str+i));
		while( USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET );
		*/
			
		USARTSendByte(USARTx, *(str+i) );
		i++;
	}
	
	while( USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET ); //判断 str 是否已被(全部!!!)发送出去
}

串口发送字符、字符串 代码整合

usart.c

#include "usart.h"
#include "stm32f10x.h"

void usart_init()
{
		GPIO_InitTypeDef 	gpioInitStructure;
		USART_InitTypeDef	usartInitStructure;
		
		//1.配置时钟
		
		//1.1配置GPIOA、串口时钟、复用时钟
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
		
		//2.配置GPIOA结构体
		
		//2.1 A9 TX
		gpioInitStructure.GPIO_Mode		= GPIO_Mode_AF_PP;
		gpioInitStructure.GPIO_Pin		= GPIO_Pin_9;
		gpioInitStructure.GPIO_Speed	= GPIO_Speed_50MHz;
		
		GPIO_Init(GPIOA, &gpioInitStructure);
		
		//2.2 A10 RX
		gpioInitStructure.GPIO_Mode		= GPIO_Mode_IN_FLOATING;
		gpioInitStructure.GPIO_Pin		= GPIO_Pin_10;
		
		GPIO_Init(GPIOA, &gpioInitStructure);

		//3.配置串口结构体
		usartInitStructure.USART_BaudRate				= 115200;
		usartInitStructure.USART_HardwareFlowControl	= USART_HardwareFlowControl_None;
		usartInitStructure.USART_Mode					= USART_Mode_Tx | USART_Mode_Rx;
		usartInitStructure.USART_Parity					= USART_Parity_No;
		usartInitStructure.USART_StopBits				= USART_StopBits_1;
		usartInitStructure.USART_WordLength				= USART_WordLength_8b;
		
		USART_Init(USART1, &usartInitStructure);
		USART_Cmd(USART1, ENABLE);
		
}

void USARTSendByte(USART_TypeDef* USARTx, uint16_t Data) //一个一个字符发送
{
		USART_SendData( USARTx, Data);
		while( USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET );
}

void USARTSendStr(USART_TypeDef* USARTx, char* str) //字符串发送
{
		uint16_t i=0;
		
		while( *(str+i) != '\0' )
		{
				/*
				USART_SendData( USARTx, *(str+i));
				while( USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET );
				*/
				
				USARTSendByte( USART1, *(str+i) );
				i++;
		}
		
		while( USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET );
}

usart.h

#include "stm32f10x.h"

void usart_init(void);

main.c

#include "stm32f10x.h"
#include "main.h"
#include "led.h"
#include "shake.h"
#include "relay.h"
#include "exti.h"
#include "usart.h"

void delay(uint16_t time)
{
	uint16_t i=0;
	
	while(time--)
	{
		i=10000;
		while(i--);
	}
}

int  main()
{
		usart_init();
		
//		USARTSendByte(USART1, 'O');
//		USARTSendByte(USART1, 'K');
		USARTSendStr(USART1, "Yinyuer is a pretty girl!");
		
		while(1)
		{
				
		}
}

printf 的重定向

在这里插入图片描述

fputc

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

fgetc

int fgetc(FILE* f)
{
	while( USART_GetFlagStatus(USART1, USART_RXNE) == RESET )
	
	return (int) USART_ReceiveData(USART1);
}

usart.c

#include "usart.h"
#include "stm32f10x.h"

void usart_init()
{
		GPIO_InitTypeDef 	gpioInitStructure;
		USART_InitTypeDef	usartInitStructure;
		
		//1.配置时钟
		
		//1.1配置GPIOA、串口时钟、复用时钟
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
		
		//2.配置GPIOA结构体
		
		//2.1 A9 TX
		gpioInitStructure.GPIO_Mode		= GPIO_Mode_AF_PP;
		gpioInitStructure.GPIO_Pin		= GPIO_Pin_9;
		gpioInitStructure.GPIO_Speed	= GPIO_Speed_50MHz;
		
		GPIO_Init(GPIOA, &gpioInitStructure);
		
		//2.2 A10 RX
		gpioInitStructure.GPIO_Mode		= GPIO_Mode_IN_FLOATING;
		gpioInitStructure.GPIO_Pin		= GPIO_Pin_10;
		
		GPIO_Init(GPIOA, &gpioInitStructure);

		//3.配置串口结构体
		usartInitStructure.USART_BaudRate				= 115200;
		usartInitStructure.USART_HardwareFlowControl	= USART_HardwareFlowControl_None;
		usartInitStructure.USART_Mode					= USART_Mode_Tx | USART_Mode_Rx;
		usartInitStructure.USART_Parity					= USART_Parity_No;
		usartInitStructure.USART_StopBits				= USART_StopBits_1;
		usartInitStructure.USART_WordLength				= USART_WordLength_8b;
		
		USART_Init(USART1, &usartInitStructure);
		USART_Cmd(USART1, ENABLE);
		
}

void USARTSendByte(USART_TypeDef* USARTx, uint16_t Data)
{
		USART_SendData( USARTx, Data);
		while( USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET );
}

void USARTSendStr(USART_TypeDef* USARTx, char* str)
{
		uint16_t i=0;
		
		while( *(str+i) != '\0' )
		{
				/*
				USART_SendData( USARTx, *(str+i));
				while( USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET );
				*/
				
				USARTSendByte( USART1, *(str+i) );
				i++;
		}
		
		while( USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET );
}

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

int fgetc(FILE* f)
{
//		USART_ReceiveData(USART1);
		while( USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET );
		
		return (int) USART_ReceiveData(USART1);
}

usart.h

#include "stm32f10x.h"
#include <stdio.h> //记得包含库函数

void usart_init(void);
void USARTSendByte(USART_TypeDef* USARTx, uint16_t Data);
void USARTSendStr(USART_TypeDef* USARTx, char* str);

main.c

#include "stm32f10x.h"
#include "main.h"
#include "led.h"
#include "shake.h"
#include "relay.h"
#include "exti.h"
#include "usart.h"

void delay(uint16_t time)
{
	uint16_t i=0;
	
	while(time--)
	{
		i=10000;
		while(i--);
	}
}

int  main()
{
		usart_init();
		
//		USARTSendByte(USART1, 'O');
//		USARTSendByte(USART1, 'K');
		printf("Yinyuer is a pretty girl!");
		
		while(1)
		{
				
		}
}

实验结果

在这里插入图片描述

使用printf函数可以将接收到的字符串打印到串口或者调试助手上,以下是一个示例代码: ``` #include "stdio.h" #include "string.h" #include "stm32f4xx.h" #define RX_BUFFER_SIZE 512 uint8_t rx_buffer[RX_BUFFER_SIZE]; // 定义接收缓存区 uint16_t rx_counter = 0; // 定义接收计数器 void USART2_IRQHandler(void) { if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) { uint8_t data = USART_ReceiveData(USART2); rx_buffer[rx_counter++] = data; if (data == '\n' || rx_counter >= RX_BUFFER_SIZE) { rx_buffer[rx_counter] = '\0'; // 在字符串末尾添加'\0' printf("Received string: %s\n", rx_buffer); rx_counter = 0; // 接收计数器清零 } } } int main(void) { // 初始化串口 USART_InitTypeDef USART_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2); GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOA, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = 115200; 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_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART2, &USART_InitStructure); USART_Cmd(USART2, ENABLE); while (1) { // 主循环中进行其他操作 } } ``` 在串口中断处理函数中,当接收到字符'\n'时或者接收计数器达到缓存区大小时,将接收缓存区中的字符串打印到串口或者调试助手上,然后将接收计数器清零。 需要注意的是,在使用printf函数进行调试时,需要在工程设置中开启printf重定向功能。具体操作方法可以参考相关资料或者开发板的用户手册。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值