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