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)
{
}
}
实验结果: