学习过STM32的朋友肯定对串口通信不陌生,在之后的学习中我们会利用GPIO翻转来模拟软件I2C和模拟软件SPI,但是为什么没有人利用GPIO来模拟串口通信呢?

本期我们将利用定时器来模拟串口通信。

首先我们要明白串口通信的帧格式,有一个低电平起始位,八个数据位(可选择校验位)+停止位组成。

需要注意的是,这里的数据位从低到高!!!

通常,我们不会设置校验位,选择一个停止位。

因此我们的一帧数据共一个字节+2位,总计十位。而波特率则是一秒钟可以传输多少位的数据。例如9600的波特率则代表着一秒钟传输9600位,总计960帧,所以总共960个字节,有效位960*8位代表数据。

以9600波特率为例,每一位的持续时间约为104us.

因此在CubeMX中我们可以设置定时器的触发时间为104us。

int num = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  
  HAL_GPIO_WritePin(GPIOA,GPIO_PIN_9,Data[num++]);
  if(num == 10)
  {
    num = 0;
    HAL_TIM_Base_Stop_IT(&htim1);//关闭定时器
  }
}

我们在定时器中断回调函数中,将Data(一帧)中的数据逐位发送。


void MyPrintf(int s)
{
  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;
  HAL_TIM_Base_Start_IT(&htim1);
}

写一个函数用来写入串口数据,并且启动定时器。


    MyPrintf('H');
    HAL_Delay(100);
    MyPrintf('e');
    HAL_Delay(100);
    MyPrintf('l');
    HAL_Delay(100);
    MyPrintf('l');
    HAL_Delay(100);
    MyPrintf('o');
    HAL_Delay(100);

成功的模拟了串口!!!

  • 属于我的串口重定向!

int fputc(int ch, FILE *f) {
    // 发送单个字符
    MyPrintf(ch);
    HAL_Delay(50);//稍微延时,等待发送完成
    // 返回发送的字符
    return ch;
}

嘉立创PCB

还没有评论,抢个沙发!