上期我们使用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 
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;
}


 


嘉立创PCB

还没有评论,抢个沙发!