蓝桥杯嵌入式基础板模块之串口模块的发送与接收

蓝桥杯嵌入式基础板模块之串口模块的发送与接收

硬件电路

在这里插入图片描述
在国信长天提供的资料中,我们可以看出板子有两个串口,但是具体用一个呢?在这我可以肯定比赛的时候用的一定是USART2,因为USART1需要通过232转接一下,况且不是每个地方都有这玩意,所以比赛的时候一定不会用这个。所以我们只需要了解好USART2就够了。

代码实现

usart.c

#include "usart.h"
_Bool Rx_Flag=0; 	//代表数据接收完成
u8 RxBuffer1[20];	//接收到的数据放的数组
u8 RxCounter1=0;	//接收到了多少个
u8 Demo[20]="OK";	//这是一个例子,后面在数组比较中使用
void Usart2_Init(void){
	USART_InitTypeDef USART_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE); 

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);

	USART_InitStructure.USART_BaudRate = 9600;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	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(USART2, &USART_InitStructure);
	USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);
	USART_Cmd(USART2, ENABLE);
}
void USART2_IRQHandler(void)
{
	u8 temp=0;
	if(USART_GetITStatus(USART2,USART_IT_RXNE)!=RESET)
	{
		usart_State = 1;
		USART_ClearFlag(USART2, USART_IT_RXNE);
		temp= USART_ReceiveData(USART2);
		if(temp=='\n')
		{
			Rx_Flag=1;
			RxCounter1=0;
			USART_ITConfig(USART2,USART_IT_RXNE,DISABLE);
		}
		else{
			RxBuffer1[RxCounter1++] = temp;
		}
  }
}
_Bool Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2)
{
  while(*pBuffer1!=0)
  {
    if(*pBuffer1 != *pBuffer2)
    {
      return 0;
    }
    pBuffer1++;
    pBuffer2++;
  }
  return 1;
}
PUTCHAR_PROTOTYPE  //这个内容会在.h中有宏定义的
{
  USART_SendData(USART2, (uint8_t) ch);
  while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET)
  {}
  return ch;
}
void Usart_Check(void){
	u8 i =0;
	if(Rx_Flag){
		if(Buffercmp(RxBuffer1,Demo))	printf("OK");
		else	printf("ERROR");
		for(i=0;i<20;i++){
			RxBuffer1[i]=0;
		}
		USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);
		Rx_Flag=0;
	}
}

注意事项

  1. 串口中断是没接收到一个字符进入一次,那么我们先对这个字符进行判断这个字符是不是接收数据的结束标志位。如果是则另Rx_Flag=1,RxCounter1=0(这里置0是为了下次再接收数据的时候,从数组第一位开始存放),对接收中断失能(这里是为了现在主函数对这个数组进行处理完毕,再打开,避免相互影响)。
  2. Buffercmp这个函数就是一个字符串比较函数,你可以先定义一个数组内容然后与接收到的数组进行比较,这就很方便的。
  3. PUTCHAR_PROTOTYPE这是是对printf函数进行重写,当你再用printf的时候,是直接通过串口发送到PC机了。注意这里是USART_FLAG_TXE,如果用USART_FLAG_TC会造成发送第一个数据丢失的现象。这里要包含#include "stdio.h"还要勾选微库,如下图所示。在这里插入图片描述
  4. Usart_Check()是对接受到的数组进行判断,如果正确则发送OK,否则发送ERROR,这个函数放到main的循环中就可以了。这里有几个细节要注意一下,1:进入函数后要对Rx_Flag标志位要清0,防止一直进入。2:要对接受数组清0,防止上次的数据对本次有影响。3:要再次打开串口接收中断,为了处理后的再次接收。

usart.h

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __usart_H
#define __usart_H

/* Includes ------------------------------------------------------------------*/
#include "main.h"

#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
_Bool Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2);
void Usart2_Init(void);
void Usart_Check(void);
extern _Bool Rx_Flag;
extern u8 RxBuffer1[20],Demo[20];
extern u8 RxCounter1;

#endif

发布了19 篇原创文章 · 获赞 17 · 访问量 4082

猜你喜欢

转载自blog.csdn.net/qq_43605009/article/details/105205228