STM学习记录(六)————串口的发送接收


前言

一个学习单片机的小白~ 有错误评论区或私信指出~

一、串口结构体及库函数

串口USART结构体:
 typedef struct
 {
 uint32_t USART_BaudRate;           
uint16_t USART_WordLength;         
uint16_t USART_StopBits;             
uint16_t USART_Parity;            
uint16_t USART_Mode;                
uint16_t USART_HardwareFlowControl; 
} USART_InitTypeDef;
串口USART相关库函数:
void USART_DeInit(USART_TypeDef* USARTx);
void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* 
USART_InitStruct);
 void USART_StructInit(USART_InitTypeDef* USART_InitStruct);
 void USART_ClockInit(USART_TypeDef* USARTx, USART_ClockInitTypeDef* 
USART_ClockInitStruct);
 void USART_ClockStructInit(USART_ClockInitTypeDef* 
USART_ClockInitStruct);
 void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState);
 void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, 
FunctionalState NewState);
 void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, 
FunctionalState NewState);
 void USART_SetAddress(USART_TypeDef* USARTx, uint8_t USART_Address);
 void USART_WakeUpConfig(USART_TypeDef* USARTx, uint16_t USART_WakeUp);
 void USART_ReceiverWakeUpCmd(USART_TypeDef* USARTx, FunctionalState 
NewState);
 void USART_LINBreakDetectLengthConfig(USART_TypeDef* USARTx, uint16_t 
USART_LINBreakDetectLength);
 void USART_LINCmd(USART_TypeDef* USARTx, FunctionalState NewState);
 void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);
 uint16_t USART_ReceiveData(USART_TypeDef* USARTx);
 void USART_SendBreak(USART_TypeDef* USARTx);
 void USART_SetGuardTime(USART_TypeDef* USARTx, uint8_t 
USART_GuardTime);
 void USART_SetPrescaler(USART_TypeDef* USARTx, uint8_t 
USART_Prescaler);
 void USART_SmartCardCmd(USART_TypeDef* USARTx, FunctionalState 
NewState);
 void USART_SmartCardNACKCmd(USART_TypeDef* USARTx, FunctionalState 
NewState);
 void USART_HalfDuplexCmd(USART_TypeDef* USARTx, FunctionalState 
NewState);
 void USART_OverSampling8Cmd(USART_TypeDef* USARTx, FunctionalState 
NewState);
 void USART_OneBitMethodCmd(USART_TypeDef* USARTx, FunctionalState 
NewState);
 void USART_IrDAConfig(USART_TypeDef* USARTx, uint16_t USART_IrDAMode);
 void USART_IrDACmd(USART_TypeDef* USARTx, FunctionalState NewState);
 FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t 
USART_FLAG);
 void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG);
 ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT);
 void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t 
USART_IT);

二、实现串口发送(库函数)

1.程序设计

软件流程设计

  • 初始化系统
    • 初始化GPIO、串口外设时钟
    • 初始化串口引脚
  • 串口发送

2.代码

//初始化系统
void Usart_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	//TX
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	//RX
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	
	GPIO_Init(GPIOA,&GPIO_InitStructure);

	USART_InitStructure.USART_BaudRate = 115200;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	
	USART_Init(USART1,&USART_InitStructure);
	USART_Cmd(USART1,ENABLE);
	
}
	#include "stm32f10x.h"
	#include "main.h"
	#include "usart.h"
	
	int  main()
	{
		Usart_Init();
		
	   while(1)
		 {
			USART_SendData(USART1,'O');
			while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET );
			USART_SendData(USART1,'K');
			while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET );
		 }
	}

三.串口接收

1.串口接收(普通)

软件流程设计

  • 初始化系统
    • 初始化GPIO、串口外设、LED时钟
    • 初始化串口和LED引脚
  • 串口发送控制LED灯
//串口初始化
#include "usart.h"
#include "stm32f10x.h"                  // Device header
#include <stdio.h>


void Usart_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	//TX
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	//RX
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	
	GPIO_Init(GPIOA,&GPIO_InitStructure);

	USART_InitStructure.USART_BaudRate = 115200;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	
	USART_Init(USART1,&USART_InitStructure);
	USART_Cmd(USART1,ENABLE);
}
#include "stm32f10x.h"
#include "main.h"
#include "usart.h"
#include "LED.h"
#include <stdio.h>

int  main()
{
	LED_Init();
	Usart_Init();
	char temp;
	
   while(1)
	 {
			if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) != RESET)//判断是否接受到数据
			{
					temp = USART_ReceiveData(USART1);//读收到的数据
					if(temp == 'A')
					{
						USART_SendData(USART1,temp);
						GPIO_ResetBits(GPIOA,GPIO_Pin_1);
					}
					if(temp == 'B')
					{
						USART_SendData(USART1,temp);
						GPIO_SetBits(GPIOA,GPIO_Pin_1);
					}
			}
			USART_ClearFlag(USART1,USART_FLAG_RXNE);//清除标志位
	 }  
}

2.串口中断接收

软件流程设计

  • 初始化系统
    • 初始化GPIO、串口外设、串口中断、NVIC、LED时钟
    • 初始化串口和LED引脚
    • 写串口中断控制语句
  • 串口发送控制LED灯
#include "usart.h"
#include "stm32f10x.h"                  // Device header
#include <stdio.h>


void Usart_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	//TX
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	//RX
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	
	GPIO_Init(GPIOA,&GPIO_InitStructure);

	USART_InitStructure.USART_BaudRate = 115200;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	
	USART_Init(USART1,&USART_InitStructure);
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//配置串口中断
	USART_Cmd(USART1,ENABLE);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	
	NVIC_Init(&NVIC_InitStructure);
}
#include "stm32f10x.h"
#include "main.h"
#include "usart.h"
#include "LED.h"
#include <stdio.h>

int  main()
{
	LED_Init();
	Usart_Init();
	
   while(1)
	 {

	 }
		 
   
}
//串口中断函数
void USART1_IRQHandler(void)
{
	char temp;
	
	if(USART_GetITStatus(USART1,USART_IT_RXNE) != RESET )//判断串口中断接收是否产生
	{
		temp = USART_ReceiveData(USART1);//读数据
		if(temp == 'A')
		{
			putchar(temp);
			GPIO_ResetBits(GPIOA,GPIO_Pin_1);
		}
		if(temp == 'B')
		{
			putchar(temp);
			GPIO_SetBits(GPIOA,GPIO_Pin_1);
		}
		
	}
	USART_ClearITPendingBit(USART1,USART_IT_RXNE);

}

3. 串口发送字符串函数

思路:C语言字符串类似于字符数组最后一位是’\0’,可以用循环遍历,每遍历一遍发送一个数据,遍历到’\0’时结束循环,本质上还是传输一个字符数据不过是一次发一连串字符。

代码实现:

void USART_SendString(USART_TypeDef* USARTx, char * String)
{
	uint16_t i = 0;
	do
	{
		USART_SendData(USARTx,*(String + i));
		while( USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET );
		i++;
	}while(*(String + i) != '\0');
	while( USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET );	
}

4.串口实现printf(重定向)

修改printf底层代码,重载函数fputc

代码实现:

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

5. 串口实现scanf(重定向)

修改scanf底层代码,重载函数fgetc

代码实现:

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

注:使用priintf、scanf记得勾选UseMicroLIB
在这里插入图片描述

  • 14
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值