i1mcu 发表于 2024-6-21 19:57

普通IO口模拟串口功能

要模拟串口首先要清楚串口数据传输过程中的原理。
所以最简单的串口传输一个字节总共有10个电平变化,每个电平的宽度由波特率决定的。
下面看一个通过波特率如何计算每个位的电平宽度。
可以计算出传输1位所需要的时间 T1 = 1/9600 约为104us。
上图中就是一个字节的完整波形,起始位为低电平,结束位为高电平,中间8位为数据位,无校验位。数据位是低位在前,高位在后。也就是和起始位挨着的是最低位,和结束位挨着的是最高位。通过这个波形就可以分析出,发送的数据是0x00。
起始位为低电平,结束位为高电平,中间数据位有一个高电平,其余都是低电平,按照低位在前,高位在后规律,数据位就是0000 0001 刚好是16进制的0x01。
//输出1{}void Send_0( void )    SIM_TXD = 0;//发送一个字节{    unsigned char i;    //发送起始位    delay_us( 100 );    for( i = 0; i < 8; i++ )      value = ( sdata & 0x01 ); //先传低位      {      }      {      }      sdata = sdata >> 1;    //停止位    delay_us( 100 );         首先发送起始位,将IO口电平拉低,延时104us,下来发送8位数据位,低位在前,高位在后,每发送一位就延时104us。最后发送结束位,将IO口电平置高,在延时104us。这样一个字节就发送结束了。
下面再看接收程序
void ReadByte( void )    unsigned char i, value = 0;    {      delay_us( 100 );      for( i = 0; i < 8; i++ )            value >>= 1;            {            }      }      //delay_us(100);//一次性接收大量数据时,防止程序执行代码时浪费时间,在结束符时可以不用等待      RecBuf = value;    }接收数据就更好理解了,读取IO口的电平,如果出现低电平就开始接收数据,然后读取8个数据位的电平,在等待结束位结束。这样一个字节的数据就接收完成了。
有两种方式去实现,一种是在死循环中用查询方式去判断,一直读取IO的的电平,如果出现低电平就认为串口有数据发送进来了。
//查询方式接收数据{    unsigned char recstr = {0};    while( 1 )      if( !RecFlag )            //未收到数据时扫描            ReadByte();          //扫描数据      }      {            RecFlag = 0;            RecBuf = 0;      }      {            WriteString( recstr );//发送接收到的数据            i = 0;                  //清除接收数据数组下标            {            }      }      {            return;    }这种方式实现起来比较简单,但是对于程序编写比较麻烦,因为要一直监视者IO口,所以程序干其他事情时,很有可能错过数据的接收。可以用第二种方式,IO口中断来判断什么时候要开始接收数据,将IO口设置为下降沿中断,当有下降沿出现时,说明串口有数据进来了,然后再去读取串口数据。没有中断发生时,程序就可以干其他事情了。
//通道PC3口的下降沿中断检测数据#pragma vector = 7                  // IAR中的中断号,要在STVD中的中断号上加2{    ReadByte();    {      {            recCNT = 0;    }    {      {            RecBuf = 0;      else if( RecBuf == 0x0d )   //收到0x0d 标记结束符开始            recEnd |= 0x01;    }}
当出现下降沿之后进入中断程序,这时候要关闭外部中断,开始读取IO口电平状态。若不关闭中断,在读取IO电平的过程中中断还会不停的进入,这样就会影响读取数据的准确性。所以进入中断会首先要关闭中断,接收完一个字节之后,在打开中断,接收下一个字节。直到收到了回车换行符(也就是0x0D 0x0A),就认为数据发送已经结束。就退出接收过程,然后主程序就可以去处理接收到的数据了。

OKAKAKO 发表于 2024-6-21 20:07

模拟IO能够说明原理性的文件

中国龙芯CDX 发表于 2024-6-26 16:51

计算出传输1位所需要的时间 T1 = 1/9600 约为104us

jf101 发表于 2024-6-27 16:36

一个字节的完整波形,起始位为低电平,结束位为高电平,中间8位为数据位,无校验位
页: [1]
查看完整版本: 普通IO口模拟串口功能