6、USART串行通信

在STM32里,串口通信是USART,STM32可以通过串口和其他设备进行传输并行数据,是全双工,异步时钟控制,设备之间是点对点的传输。对应的STM32引脚分别是RX和TX端。STM32的串口资源有USART1、USART2、USART3.

串口的几个重要的参数:

  • 波特率,串口通信的速率
  • 空闲,一般为高电平
  • 起始位,标志一个数据帧的开始,固定为低电平。当数据开始发送时,产生一个下降沿。(空闲–>起始位)
  • 数据位,发送数据帧,1为高电平,0为低电平。低位先行。

                比如 发送数据帧0x0F 在数据帧里就是低位线性 即 1111 0000

  • 校验位,用于数据验证,根据数据位的计算得来。有奇校验,偶校验和无校验。
  • 停止位,用于数据的间隔,固定为高电平。数据帧发送完成后,产生一个上升沿。(数据传输–>停止位)
     

注意:

1.在数据传输期间不能复位TE位,否则将破坏TX脚上的数据,因为波特率计数器停止计数。 正在传输的当前数据将丢失。

2. TE位被激活后将发送一个空闲帧。

库函数配置

串口配置一般步骤:

  1. 串口时钟使能,GPIO时钟使能:RCC_APB2PeriphClockCmd();
  2. 串口复位:USART_DeInit(); 这一步不是必须的
  3. GPIO端口模式设置:GPIO_Init(); 模式可设置为推挽复用以及浮空输入或者上拉输入
  4. 串口参数初始化:USART_Init();
  5. 开启中断并且初始化NVIC(若有中断就配置这个) NVIC_Init();USART_ITConfig();
  6. 使能串口:USART_Cmd();
  7. 编写中断处理函数:USARTx_IRQHandler();
  8. 串口数据收发:void USART_SendData();//发送数据到串口//USART_ReceiveData();

串口传输状态获取:

  • FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);
  • void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT);
void RCC_Configuration(void)
{
	//----------使用外部RC晶振-----------
	RCC_DeInit();			//初始化为缺省值
	RCC_HSEConfig(RCC_HSE_ON);	//使能外部的高速时钟 
	while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);	//等待外部高速时钟使能就绪
 
	RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);	//PLLCLK = 8MHZ * 9 =72MHZ
	RCC_PLLCmd(ENABLE);			//Enable PLLCLK
	while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);	//Wait till PLLCLK is ready
 
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);	//Select PLL as system clock
	while(RCC_GetSYSCLKSource()!=0x08);		//等至PLL被用作系统时钟源
		
	RCC_HCLKConfig(RCC_SYSCLK_Div1);		//AHB使用系统时钟,HCLK = SYSCLK
	RCC_PCLK2Config(RCC_HCLK_Div1);			//APB2为HCLK/1,PCLK2 =  HCLK
	RCC_PCLK1Config(RCC_HCLK_Div2);			//PCLK1 = HCLK/2
 
	/*******配置RCC时钟,打开相应外设时钟******/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);	//使能APB2外设的GPIOA的时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);	//使能APB1外设的USART2的时钟//用到哪些开哪些
}

USART初始化配置

void USART1_Configuration(u32 bound)
{
	//定义串口1的初始化结构体
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	
	//USART1_TX   GPIOA.9初始化
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9

	//USART1_RX	  GPIOA.10初始化
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10  

	//USART 初始化设置
	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);    //初始化串口1
  USART_ITConfig(USART1, USART_IT_RXNE,ENABLE);//开启串口接受中断//中断打开,查询挂起
  USART_Cmd(USART1,ENABLE);                    //使能串口1 

}

使用GPIO_InitTypeDef和USART_InitTypeDef构体定义一个GPIO初始化变量以及一个USART初始化变量,这两个结构体这里不再赘述。

USART中断服务函数


	if( (USART_GetITStatus(USART2, USART_IT_TXE) != RESET) )
	{
        //程序
		USART_ITConfig(USART2,USART_IT_TXE,DISABLE);
	}
	if( (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) )
	{
		temp = USART_ReceiveData(USART2);
		USART_SendData(USART2, temp);
	}

void USART2_IRQHandler(void)
{
	if(USART_GetFlagStatus(USART2, USART_FLAG_RXNE) != RESET)  
	{
		Buffer_Rx[RxCNT++] = USART_ReceiveData(USART2);
	}
}

void USART2_IRQHandler(void)
{
  if (USART_GetITStatus(USART2,USART_IT_RXNE) != RESET) 
    {
      Buffer_Rx[RX_Num++] = USART_ReceiveData(USART2);
      USART_SendData(USART2,Buffer_Tx[TX_Num]);
	  if(RX_Num == buffer_size) RX_Num = 0,TX_Num = 0;	
      }	
}
void NVIC_Configuration(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;
	
	/*调用时记得选择分组,要么在main里加,要么在这里加,配置一次即可*/
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
	
/**************用哪个加哪个,加在后面就行***********************/
	/*这里用的是USART1的中断*/
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;		//对应的中断向量通道//在stm32f10x.h中可以找到对应的外部通道名字
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;//抢占优先级2
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;	 	//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);							//根据指定的参数初始化NVIC寄存器
}

主函数

int main(void)
{
	uint8_t a[10] = {65,66,67,68,69,70,71,72,73,74};
	GPIO_LED_Config();
	USART1_Config();
	USART_SendByte(DEBUG_USARTx,0x63);
  USART_SendTwoByte(DEBUG_USARTx,0x4344);
	USART_SendArray(DEBUG_USARTx,a,10);
  USART_SendString(DEBUG_USARTx, "\n欢迎来到学习STM32的世界\n");
	printf("串口测试输出\n");
	while(1)
	{
	//此处敲对应代码
	}	
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值