stm32使用IO模拟串口

STM32使用IO口模拟串口

期望效果:
使用普通IO模拟串口,实现非阻塞全双工通讯功能。
硬件资源:
1.2个IO口
2.1个外部中断
3.1个定时器
串口相关知识简述:
1.波特率
波特率,即每秒传输的位个数。例9600bps,即每秒传输9600个bit,每位电平状态保持时长为:t = 1000000/9600 ≈104.16us
2.时序
1个起始位+8个数据位+1个停止位
注:起始位为低电平,停止位为高电平,数据位低有效位在前。空闲状态下,TX Line和RX Line均为高电 平。
初始化:
发送IO口配置为推挽输出模式,并设置初始电平状态为高电平。接收IO口配置为上拉输入模式。定时器配置为向上计数模式并使能更新中断,每隔104us产生一次中断事件。外部中断配置为下降沿触发模式,当检测到下降沿时,产生一次中断事件。
发送:
先将待发送数据存入FIFO(先入先出队列)中,然后从FIFO中取出首字节赋值到文件全局变量txData,并置位发送txFlag和清零发送位计数器txBitCount。在定时器中断事件中执行发送。示意代码如下所示:

if( txFlag )
{
	if( txBitCount == 0 ) //发送起始位
	{
		PIN_CLR( TX );
		txBitCount++;
	}
	else if( txBitCount < 9 ) //发送8个数据位
	{
		(txData & 0x01)? PIN_SET( TX ):PIN_CLR( TX );
		txData >>= 1;
		txBitCount++;
	}
	else if( txBitCount == 9 ) //发送1个停止位
	{
		PIN_SET( TX );
		txBitCount++;
	}
	else //检查FIFO中是否有未发送数据
	{
		if( txFifo.count )
		{
			txData = txFifo.buf[txFifo.head];
			txFifo.head++;
			txFifo.head &= txFifo.mask;
			txFifo.count--;
			txBitCount = 0;
		}
		else
		{
			txFlag = 0;
		}
	}
}

接收:
当产生外部中断事件时,置位接收标志rxFlag,并清零接收位计数器rxBitCount,然后在定时器中断事件中采样数据。将采样到的位数据暂存到文件全局变量rxData中,采样结束后将rxData存入接收FIFO中。示意代码如下所示:

if( rxFlag )
{
	if( rxBitCount < 9 ) //接收起始位和数据位
	{
		rxData >>= 1;
		if( PIN_READ( RX ) == SET )
		{
			rxData |= 0x80;
		}
		rxBitCount++;
	}
	else //判断停止位
	{
		if( PIN_READ( RX ) == SET ) //有效停止位
		{
			rxFifo.buf[rxFifo.tail] = rxData;
			rxFifo.tail++;
			rxFifo.tail &= rxFifl.mask;
			rxFifo.count++;
		}
		
		rxFlag = 0;
		rxBitCount = 0;
	}
}

结尾:
经过测试,实现了非阻塞全双工通讯功能,但是接收数据不太稳定,尚需优化。如果对正确率要求不高(如本打字员,仅在生产时使用该串口配置下设备参数,一次不成,可以再来个2345下),那么还是可以凑合使用的。
纯手打,难免手滑,如有错误,您可得海涵。

/**************************************End*************************************/
  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值