学习过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;}
Win,成功的模拟了串口! 下期尝试添加标志位和设置波特率。