⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 模拟uart设计.txt

📁 高效的模拟UART程序,不用中断 高效的模拟UART程序,不用中断
💻 TXT
字号:
3.1、数据定义

  定义模拟串口程序所必须的一些资源,如I/O引脚、波特率、数据缓冲区等。
  #define Fosc 22118400 //晶振频率
  #define Baud 38400    //波特率
  #define BaudT (Fosc/Baud/3/12)
  #define BufLong 16    //FIFO长度
  sbit RxD1=P1^7;  //模拟接收RxD
  sbit TxD1=P1^6;  //模拟发送TxD
  bit  Brxd1,Srxd1;//RxD检测电平
  BYTE Rbuf1[BufLong];//FIFO接收区
  BYTE Rptr1,Rnum1;
  BYTE Tbuf1[BufLong];//FIFO发送区
  BYTE Tptr1,Tnum1;
  BYTE TimCnt1A,TimCnt1B; 
  BYTE Mtbuf1,Mrbuf1,TxdCnt1,RxdCnt1;
3.2、数据接收子程序

  数据接收过程中,依次存储RxD的逻辑位形成字节数据,当数据接收完毕且停止位为1时,表示接收到了有效数据,就将结果存储到接收FIFO队列中去。

  void Recv()
  {
    if(RxdCnt1>0)      //存数据位8个
    {
      Mrbuf1>>=1;
      if(RxD1==1) Mrbuf1=Mrbuf1|0x80;
    }
    RxdCnt1--;
    if(RxdCnt1==0&& RxD1==1) //数据接收完毕
    { 
      Rbuf1[Rptr1]=Mrbuf1; //存储到FIFO队列
      if(++Rptr1>BufLong-1) Rptr1=0;
      if(++Rnum1>BufLong) Rnum1=BufLong;
    }
  }
3.3、数据发送子程序

  该程序过程中,当数据发送状态结束时,检测发送FIFO队列是否为空,若非空则取出发送数据,然后启动发送状态;当处于发送状态时,则按照状态机的状态进行起始位、数据位和停止位的发送。

  void Send()
  {
   if(TxdCnt1!=0)  //字节发送状态机
   {
    if(TxdCnt1==11) TxD1=0;//发起始位0
    else if(TxdCnt1>2) //发数据位
     { Mtbuf1>>=1; TxD1=CY;}
    else  TxD1=1;     //发终止位1
    TxdCnt1--;
   }
   else if(Tnum1>0)  //检测FIFO队列
   {
     Tnum1--;
     Mtbuf1=Tbuf1[Tptr1]; //读取FIFO数据
     if(++Tptr1>=BufLong) Tptr1=0;
     TxdCnt1=11;     //启动发送状态机
   }
  }

3.4、中断程序
  中断定时时间为波特率定时的1/3,即以3倍的波特率对RxD进行采样,实现起始位的判别,当起始位到达时启动接收过程状态机。将该定时进行3分频再调用数据的发送和接收过程,进行准确波特率下的串口通信。

  void Uart() interrupt 1 using 1
  {
    if(RxdCnt1==0 )  //接收起始识别
    {
      if(RxD1==0 && Brxd1==0 && Srxd1==1) { RxdCnt1=8; TimCnt1B=0;}
    }
    Srxd1=Brxd1; Brxd1=RxD1;
    if(++TimCnt1B>=3 && RxdCnt1!=0) { TimCnt1B=0;  Recv();}//数据接收 
    if(++TimCnt1A>=3) { TimCnt1A=0; Send();} //数据发送
  }

3.5、串口初始化

  打开定时器的中断,将定时器的设置为自装载模式,依照波特率设置定时中断的定时间隔,启动定时器,并进行UART各变量的初始化。

  void IniUart()
  {
    IE="0x82"; TMOD="0x22"; 
    TH0=-BaudT; TL0=-BaudT; TR0=1;
    Rptr1=0;Rnum1=0;Tptr1=0;Tnum1=0;
  }

  4、结束语
     本文提出的模拟串口设计方法,其独特之处在于:仅仅使用任意2个普通I/O引脚和1个定时中断实现了全双工串口,对硬件的占用较少,具有多可串口扩展能力;在串口接收的起始位判别时采用了连续3次采样的判别方法,该方法实现简单、准确率高;用定时中断实现了串口数据的发送和接收,并实现了FIFO队列,使串口发送和接收工作效率高。
  作者在实际应用中已利用该方法在STC12C1052上实现了5个串口的扩展,用于医疗监护仪多个模块数据接收,效果令人满意。随着单片机处理速度的提高,该方法可以替代串口扩展芯片,大大降低系统的硬件成本,由于采样C语言开发,所以可以很方便地移植到AVR、PIC、C8051等高速单片机。

  参考文献

  [1] 陈曦等.基于51系列单片机的通用的实现[J].微计算机信息,2001,(5):79-80

  [2] 景鑫.51单片机的串行口扩展方法[J]. 微计算机信息,2005,(13):63-64+155

  [3] 徐爱钧,彭秀华.单片机高级语言C51 Windows环境编程与应用[J].北京,电子工业出版社,2001

  [4] STC12C2052AD系列单片机中文指南.http//www.mcu-memory.com,2005

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -