非阻塞方式实现单片机普通IO模拟串口收发

该博客分享了一种使用定时器和状态机在普通经济型单片机上实现全双工串口通信的方法。作者针对没有内置串口的单片机,通过自定义的软件逻辑,成功地实现了串行数据的接收和发送,解决了阻塞方式的不足,提高了通信效率。
摘要由CSDN通过智能技术生成

一个项目中要用到串口,普通经济型单片机又没有串口,在网上搜索了一下单片机普通IO口模拟串口,基本上搜到的都是采用阻塞方式实现的,根本没有实用价值,自己动手写了一个,使用一个定时器完成模拟串口的收发,并且以全双工方式工作。

程序框架采用定时器加状态机实现:

   	   	switch (Su8RxStatus)
   	   	{
   	   	   	case 0:	   	   	   	   	   	   	   	//接收复位
   	   	   	   	if (HIGH == RX_CUR_SIG)
   	   	   	   	{
       	   	   	   	Su8RxSigTime++;
       	   	   	   	if (Su8RxSigTime >= 4)
       	   	   	   	{
       	   	   	   	   	Su8RxSigTime = 0;
       	   	   	   	   	Su8RxBitCnt = 0;
       	   	   	   	   	Su8RxStatus = 1;
       	   	   	   	}
   	   	   	   	}
   	   	   	   	break;
   	   	   	case 1:	   	   	   	   	   	   	   	//接收起始位
   	   	   	   	if (LOW == RX_CUR_SIG)
   	   	   	   	{
   	   	   	   	   	Su8RxSigTime++;
   	   	   	   	   	if (Su8RxSigTime >= 2)
   	   	   	   	   	{
   	   	   	   	   	   	Su8RxSigTime = 0;
   	   	   	   	   	   	Su8RxBitCnt = 0;
   	   	   	   	   	   	Su8RxStatus = 2;
   	   	   	   	   	}
   	   	   	   	}
   	   	   	   	break;
   	   	   	case 2:	   	   	   	   	   	   	   	//循环完成一个字节的接收
   	   	   	   	Su8RxSigTime++;
   	   	   	   	if (Su8RxSigTime >= 2)
   	   	   	   	{
   	   	   	   	   	Su8RxSigTime = 0;
   	   	   	   	   	Gu8SerialDataBuf >>= 1;
   	   	   	   	   	if (RX_CUR_SIG)
   	   	   	   	   	{
   	   	   	   	   	   	Gu8SerialDataBuf |= 0x80;
   	   	   	   	   	}
   	   	   	   	   	else 
   	   	   	   	   	{
   	   	   	   	   	   	Gu8SerialDataBuf &= 0x7f;
   	   	   	   	   	}
   	   	   	   	   	Su8RxBitCnt++;
       	   	   	   	if (Su8RxBitCnt >= 8)
       	   	   	   	{
       	   	   	   	   	Su8RxStatus = 3;
   	   	   	   	   	   	Gu8SerialData = Gu8SerialDataBuf;
   	   	   	   	   	   	RX_BYTE_OK = OK;
       	   	   	   	}
   	   	   	   	}
   	   	   	   	break;
   	   	   	case 3:	   	   	   	   	   	   	   	//接收停止位
   	   	   	   	if (HIGH == RX_CUR_SIG)
   	   	   	   	{
   	   	   	   	   	Su8RxSigTime++;
   	   	   	   	   	if (Su8RxSigTime >= 2)
   	   	   	   	   	{
   	   	   	   	   	   	Su8RxSigTime = 0;
   	   	   	   	   	   	Su8RxStatus = 1;
   	   	   	   	   	}
   	   	   	   	}
   	   	   	   	break;     	   	   	   	
   	   	}
   	   	
   	   	if (EN == TX_EN)
   	   	{
   	   	   	switch (Su8TxStatus)
   	   	   	{
   	   	   	   	case 0:	   	   	   	   	   	   	   	   	//发送起始位
   	   	   	   	   	IO_TX = 0;
   	   	   	   	   	Su8TxSigTime++;
   	   	   	   	   	if (Su8TxSigTime >= 2)
   	   	   	   	   	{
   	   	   	   	   	   	Su8TxSigTime = 0;
   	   	   	   	   	   	Su8TxStatus = 1;
   	   	   	   	   	}
   	   	   	   	   	break;
   	   	   	   	case 1:
   	   	   	   	   	if (1 == Su8TxBuf.bits.bit0)
   	   	   	   	   	{
   	   	   	   	   	   	IO_TX = 1;
   	   	   	   	   	}
   	   	   	   	   	else 
   	   	   	   	   	{
   	   	   	   	   	   	IO_TX = 0;
   	   	   	   	   	}
   	   	   	   	   	Su8TxBitCnt++;
   	   	   	   	   	Su8TxBuf.byte >>= 1;
   	   	   	   	   	Su8TxStatus = 2;
   	   	   	   	   	break;
   	   	   	   	case 2:
   	   	   	   	   	Su8TxStatus = 1;
   	   	   	   	   	if (Su8TxBitCnt >= 8)
   	   	   	   	   	{
   	   	   	   	   	   	Su8TxBitCnt = 0;   	   	   	   	//一个字节8位发送完成进入停止位发送
   	   	   	   	   	   	Su8TxSigTime = 0;
   	   	   	   	   	   	Su8TxStatus = 3;
   	   	   	   	   	}
   	   	   	   	   	break;
   	   	   	   	case 3:	   	   	   	   	   	   	   	   	//发送停止位
   	   	   	   	   	IO_TX = 1;
   	   	   	   	   	Su8TxSigTime++;
   	   	   	   	   	if (Su8TxSigTime >= 2)
   	   	   	   	   	{
   	   	   	   	   	   	Su8TxSigTime = 0;
   	   	   	   	   	   	TX_EN = DIS;
   	   	   	   	   	   	Su8TxStatus = 0;
   	   	   	   	   	}
   	   	   	   	   	break;
   	   	   	}
   	   	}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值