用软件模拟单片机串口程序(2)

 接(1)
 //-------------------------------------------------------------------------------------
    //中断服务程序
 //--------------------------------------------------------------------------------------
 void PCA_ISR(void) interrupt 9
 {
  static char SUTXST=0;           //SW_UART TX状态变量
  static char SURXST=0;           //SW_UART RX状态变量
  static unsigned char RXSHIFT;   //SW_UART RX移位寄存器
  static int PCA_TEMP;            //临时储存变量,用于处理PCA模块的搞和低字节
//首先检查接受中断变量,如果CCF0置位则对其服务 
  if(CCF0){
     CCF0=0;                      //清除中断标志
     switch(SURXST){
//状态:0 收到起始位
//在该状态,是SW_TX上的负边沿触发中断,表示检测到起始位,同时PCA0CP0寄存器捕捉PCA0的值
//检查接受允许和起始位
//将PCA模块0切换到软件定时方式
//加3/2位时间到模块0捕捉寄存器以采样LSB
//TX状态变量加1
            case 0:
                 if(SREN&~SW_RX){  //检查接收允许和起始位
                    PCA_TEMP=(PCA0CPH0<<8);//将模块0的内容读到PCA_TEMP
                    PCA_TEMP|=PCA0CPL0;
                    PCA_TEMP+=TH_TIME_COUNT;//加3/2位时间到PCA_TEMP
                    PCA0CPL0=PCA_TEMP;     //更新PCA0CPL0和PCA0CPH0
                    PCA0CPH0=(PCA_TEMP>>8);
                    PCA0CPM0=0x49;         //将模块0切换到软件定时器方式,允许中断
                    SURXST++;   }           //更新RX状态变量     
                    break;
//状态1-8:收到数据位
//采样SW_RX引脚
//将新数据移入RXSHIFT
//加1个位时间变量到模块0捕捉寄存器
//RX状态变量加1
             case 1:
               
             case 2:
                
             case 3:
               
             case 4:
            
             case 5:
 
             case 6:
 
             case 7:
     
             case 8:
                 RXSHIFT=RXSHIFT >> 1; //右移一位
                 if(SW_RX)             //如果SW_RX=1;将1移入RXSHIFT的MSB
                    RXSHIFT |= 0x80;
                   
                    PCA_TEMP = (PCA0CPH0<<8);//将模块0内容读到PCA_TEMP
                    PCA_TEMP |= PCA0CPL0;
                    PCA_TEMP += TIME_COUNT;//加1个位时间到PCA_TEMP
                    PCA0CPL0 = PCA_TEMP;   //更新PCA0CPL0和PCA0CPH0
                    PCA0CPH0 = (PCA_TEMP>>8);
                    SURXST++;              //更新RX状态变量
                    break;
//状态9:已收到8个数据位,捕捉停止位
//将RXSHIFT传到RDR
//置位SRI(表示接收完成)
//设置模块0,为下一次传输做准备
//复位RX状态变量
 
            case 9:
                 RDR = RXSHIFT;
                 SRI = 1;
                 PCA0CPM0 = 0x11;
                 SURXST = 0;
                 break;
             }
 }
 
                
                  
              
 
 //检查发送中断,如果CCF1置位则对其服务
     else if(CCF1){
          CCF1=0;              //清除中断标志
          switch(SUTXST){
//状态0:发送过程以启动
//在此,用户已将要发送的字节装入到TDR,强制模块1中断以启动发送
//发送起始位(使SW_TX变低电平)
//读PCA0,加一个位时间后存到模块1捕捉寄存器
//TX状态变量加1
          case 0:
               SW_TX=0;
               PCA_TEMP=PCA0L;
               PCA_TEMP|=(PCA0H<<8);
               PCA_TEMP+=TIME_COUNT;
               PCA0CPL1=PCA_TEMP;;
               PCA0CPH1=(PCA_TEMP>>8);
               PCA0CPM1|=0x48;
               SUTXST++;
               break;
//状态1-9:发送数据位
//将TDR的LSB输入到TX
//将TDR右移一位
//将一个1移入TDR的MSB作为状态9的停止位
//加一个时间到模块1捕捉寄存器
          case 1:
          case 2:
          case 3:
          case 4:
          case 5:
          case 6:
          case 7:
          case 8:
          case 9:
               SW_TX=(TDR&0x01);
               TDR>>=1;
               TDR|=0x80;
               PCA_TEMP=(PCA0H<<8);
               PCA_TEMP|=PCA0L;
               PCA_TEMP+=TIME_COUNT;
               PCA0CPL1=PCA_TEMP;;
               PCA0CPH1=(PCA_TEMP>>8);
    
               SUTXST++;
               break;
//状态10:最后一位数据已发送完。发送停止位并结束传输过程
//发送停止位
//置1发送结束标志,清除忙标志
//复位TX状态
//设置模块1,为下一次传输做准备
        case 10:
              STI=1;
              SUTXST=0;
              SW_TX=1;
              PCA0CPM1=0x01;
              break;
            }
        }
   
 }
 //==========================================================================================
    //硬件UART中断服务程序
    //发送字符1-15,并接收15个字符
    //检查接收中断并服务
    //检查发送中断并服务
 void HW_UART_ISR(void) interrupt 4
 {
   static char i=0;             //发送数据变量
   static char j=0;             //接收数据的下标
   static idata char HW_BUF[20];//接收数据缓冲区
   if(RI){                     //如果接收完成
      RI=0;                     //清除接收标志
      HW_BUF[j++]=SBUF;        //读接收缓冲区
      if(j==15)                //如果已收到15个字符禁止HW_UART接收器
          REN=0;
          }
      else if(TI){              //如果发送完成
                 TI=0;             //清除发送标志
                 if(i<15)          //如果还有发送的字符变量+1
                    SBUF=i++;
                 else
                    HW_DONE=1;    //如果15个字符发送完毕,指示HW_TX结束
                     }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值