极客秀
搜索

GPIO模拟串口通信——完成串口中断接收

上期我们使用GPIO模拟串口成功的发送了数据,本期我们进一步实现串口接收的功能。

首先,因为波特率的统一,我们可以使用同一个定时器来接收和发送。

这里我们定义两个变量来设置发送和接收的标记。

其次,由于起始位是一个低电平,空闲状态的串口总线是高电平,因此当我们收到消息的时候,实际上是一个下降沿。


void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){  if(RXFlag==0)  {    RXFlag = 1;    Recive = 0;  }}

因此我们将RX引脚设置为下降沿的外部中断,并且收到外部中断,并且如果RX空闲(RXFlag ==
0)的话,就将接收缓存区(Recive)置零,之后将RX标志位置1,在定时器中可以处理。


void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){    if(TXFlag==1)  {  HAL_GPIO_WritePin(GPIOA,GPIO_PIN_9,Data[num++]);  if(num == 10)  {    num = 0;    HAL_TIM_Base_Stop_IT(&htim1);//关闭定时器    TXFlag = 0;  }  }      /*  外部中断触发后接收信息  */    if(RXFlag==1)  {    num++;    if(num>=1&&num<=8)    {      /*      从第二位开始总计八位,对应数据从低到高      */      Recive = Recive|(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_10)<<(num-1));          }  
    if(num == 10)    {      num = 0;      RXFlag = 0;    }  }  }

定时器的中断回调函数中,我们逐一读取数据的低位到高位,将其存入缓存区Recive中。
之后我们运行代码,Debug代码,利用串口助手发送数据,查看Recive的数据是否为我们发送的数据。

我们在设置一个接收完成的标志,当接收完成的时候,就将我们的数据利用上期我们模拟发送的代码发送回来。

可以实现接收和发送。 但是接收和发送的乱码率还是比较高的。

这可能是由于共用一个定时器的原因,导致接收的数据出现了异常。 主要代码


/* USER CODE BEGIN 4 */int TXnum = 0;int RXnum = 0;void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){    if(TXFlag==1)  {  HAL_GPIO_WritePin(GPIOA,GPIO_PIN_9,Data[TXnum++]);  if(TXnum == 10)  {    TXnum = 0;    TXFlag = 0;    TXSTA = 1;  }  }      /*  外部中断触发后接收信息  */    if(RXFlag==1)  {    if(RXnum>=1&&RXnum<=8)    {      /*      从第二位开始总计八位,对应数据从低到高      */      Recive = Recive|(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_10)<<(RXnum-1));          }    RXnum++;    if(RXnum == 10)    {      RXnum = 0;      RXFlag = 0;      RXSTA = 1;    }  }  }  
/* 中断回调函数  */void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){  if(RXFlag==0)  {    RXFlag = 1;    Recive = 0;    RXSTA = 0;  }}

/* Private includes ----------------------------------------------------------*//* USER CODE BEGIN Includes */#include <stdio.h>int Data[10];int RXFlag = 0;int TXFlag = 0;int RXSTA = 0;int TXSTA = 1;unsigned char Recive = 0;/* USER CODE END Includes */  
/* Private typedef -----------------------------------------------------------*//* USER CODE BEGIN PTD */  
/* USER CODE END PTD */  
/* Private define ------------------------------------------------------------*//* USER CODE BEGIN PD */  
/* USER CODE END PD */  
/* Private macro -------------------------------------------------------------*//* USER CODE BEGIN PM */  
/* USER CODE END PM */  
/* Private variables ---------------------------------------------------------*/  
/* USER CODE BEGIN PV */void MyPrintf(int s);/* USER CODE END PV */  
/* Private function prototypes -----------------------------------------------*/void SystemClock_Config(void);/* USER CODE BEGIN PFP */void MyPrintf(int s){  if(TXFlag==0 && TXSTA)  {    Data[0] = 0;  for(unsigned char i = 0;i<8;i++)  {    if(s & 0x01){         Data[i+1] = 1;      }      else{         Data[i+1] = 0;      }      s = s >> 1;  }  Data[9] = 1;  TXFlag = 1;  TXSTA = 0;  }}  
  
int fputc(int ch, FILE *f) {    // 发送单个字符    MyPrintf(ch);    // 返回发送的字符    return ch;}

1.转载请保留原文链接谢谢!
2.本站所有资源文章出自互联网收集整理,本站不参与制作,如果侵犯了您的合法权益,请联系本站我们会及时删除。
3.本站发布资源来源于互联网,可能存在水印或者引流等信息,请用户擦亮眼睛自行鉴别,做一个有主见和判断力的用户。
4.本站资源仅供研究、学习交流之用,若使用商业用途,请购买正版授权,否则产生的一切后果将由下载用户自行承担。
5.联系方式(#替换成@):pm#vimge.com

  相关内容