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)
		{
				
		}
}

实验结果

在这里插入图片描述