STM32学习之串口

一、串口配置

串口设置的一般步骤可以总结为如下几个步骤:

  1. 串口时钟使能,GPIO 时钟使能
  2. 串口复位
  3. GPIO端口模式设置
  4. 串口参数初始化
  5. 开启中断并且初始化NVIC(如果需要开启中断才需要这个步骤)
  6. 使能串口
  7. 编写中断处理函数

串口时钟使能

(串口是挂载在APB2 下面的外设,所以使能函数为)

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1);

串口复位

(当外设出现异常的时候可以通过复位设置,实现该外设的复位,然后重新配置这个外设达到让其重新工作的目的。一般在系统刚开始配置外设的时候,都会先执行复位该外设的操作)

void USART_DeInit(USART_TypeDef* USARTx);//串口复位
比如:USART_DeInit(USART1); //复位串口 1

串口参数初始化

使用这个函数 
void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);
USART_InitStructure.USART_BaudRate = bound;   //波特率设置; 
USART_InitStructure.USART_WordLength = USART_WordLength_8b;  //字长为 8 位数据格式
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(USART1, &USART_InitStructure);     //初始化串口

数据发送与接收

STM32 库函数操作USART_DR寄存器发送数据的函数是:(写入一个数据)
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);

STM32 库函数操作USART_DR寄存器读取串口接收到的数据的函数是:(接受数据)
uint16_t USART_ReceiveData(USART_TypeDef* USARTx);

串口状态

读取串口状态的函数是:

 FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);
例如我们要判断读寄存器是否非空(RXNE),操作库函数的方法是: 
USART_GetFlagStatus(USART1, USART_FLAG_RXNE);
我们要判断发送是否完成(TC),操作库函数的方法是: 
USART_GetFlagStatus(USART1, USART_FLAG_TC);

串口使能

USART_Cmd(USART1, ENABLE); //使能串口

开启串口响应中断

void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState)
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);  //开启中断,接收到数据中断

我们在发送数据结束的时候(TC,发送完成)要产生中断,那么方法是:

USART_ITConfig(USART1,USART_IT_TC,ENABLE);

获取相应中断状态

ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT)

比如我们使能了串口发送完成中断,那么当中断发生了, 我们便可以在中断处理函数中调用这 个函数来判断到底是否是串口发送完成中断,方法是:

USART_GetITStatus(USART1, USART_IT_TC)

二、代码

初始化代码

//初始化 IO 串口 1 //bound:波特率 
void uart_init(u32 bound)   
{
 GPIO_InitTypeDef GPIO_InitStructure; 
 USART_InitTypeDef USART_InitStructure; 
 NVIC_InitTypeDef NVIC_InitStructure; 
   //①串口时钟使能,GPIO时钟使能,复用时钟使能 
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
  //②串口复位 
 USART_DeInit(USART1);
  //③GPIO端口模式设置 
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 
 GPIO_Init(GPIOA, &GPIO_InitStructure);
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
 GPIO_Init(GPIOA, &GPIO_InitStructure);
 //④串口参数初始化 
 USART_InitStructure.USART_BaudRate = bound;
//使能USART1,GPIOA时钟 //复位串口 1 //ISART1_TX PA.9
//复用推挽输出 //初始化GPIOA.9
//USART1_RX PA.10 //浮空输入
//初始化GPIOA.10 //波特率设置
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长为 8 位 
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(USART1, &USART_InitStructure);   //初始化串口
#if EN_USART1_RX  //如果使能了接收
//⑤初始化NVIC 
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;   //抢占优先级 3 
 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;    //子优先级 3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;   //IRQ通道使能
NVIC_Init(&NVIC_InitStructure);    //中断优先级初始化
//⑤开启中断 
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);   //开启中断
#endif
//⑥使能串口 
USART_Cmd(USART1, ENABLE);    //使能串口
}

GPIO外设配置:
在这里插入图片描述

中断函数代码

void USART1_IRQHandler(void)                	//串口1中断服务程序
{
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
	    {
		  Res =USART_ReceiveData(USART1);	//读取接收到的数据
		  USART_SendData(USART1,Res);	  		 
        } 
} 

主函数部分代码

while(1)
	{
		if(USART_RX_STA&0x8000)
		{					   
			len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
			printf("\r\n您发送的消息为:\r\n\r\n");
			for(t=0;t<len;t++)
			{
				USART_SendData(USART1, USART_RX_BUF[t]);//向串口1发送数据
				while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
			}
			printf("\r\n\r\n");//插入换行
			USART_RX_STA=0;
		}
	}	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值