找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3595|回复: 1
收起左侧

STC12 STC15系列单片机串口通信的总结

[复制链接]
ID:285461 发表于 2018-2-25 18:57 | 显示全部楼层 |阅读模式
串口通信:
软件调试,在调试过程中需要使用虚拟串口助手。在编程中注意设计时钟和波特率。注意程序的串口设置和串口调试助手中串口设置相同。
单串口:
mode com2 9600,0,8,1
assign com2 <sin> sout
stime = 0
多串口:
mode com2 9600,0,8,1
assign com2 <s0in> s0out
0表示单片机的串口0
编程:
STC12介绍的方法:
接收一个字节的函数和发送字符串的函数,发送字符串需要知道字符串的长度。对于接收字符串的函数,可以仿照通过调用接收一个字节的函数,写出接收字符串函数。
void WriteUart(uchar *pucData ,ucharucLength)
{
       if(ucLength== 0)
       {
              return;
       }
       if(UartBuzy== 1)
              return;
       ucSendLength=    ucLength;
       pucSendData= pucData;
       SBUF= *pucSendData;
       UartBuzy= 1;
       ucSendedCount= 0;
}
uchar ReadUart(void)
{
       ucharData;
       Data= ucRecData;
       ucRecData= 0;      
       returnData;
}
Unsigned  char RString(unsigned char *s, unsigned intlen)
{
Unsigned int  i;
For(i =0;i<len ;i++)
{
*s++ = ReadUart();
}
}
void UartIRQ(void) interrupt 4
{
      if(RI)
       {
              RI = 0;
              ucRecData = SBUF;
       }
       if(TI)
       {
              TI = 0;
              ucSendedCount++;
              if(ucSendedCount >= ucSendLength)
              {
                     UartBuzy= 0;
                     return;   
              }
              else
              {
                     SBUF= *(pucSendData + ucSendedCount);
              }
       }
}
STC15:
STC15只给出了发送函数,且发送函数有瑕疵,具体见最后分析。
void UART1_ISR(void) interrupt 4 using 1
{
   if (RI)                   //接收数据
    {
       RI = 0;           //清除RI
    }
   if (TI)                   //发送数据
    {
       TI = 0;           //清除TI
       busy = 0; //清忙标志
    }
}
void SendData(unsigned char dat)
{
   while (busy);  //等待前面的数据发送完成
   busy = 1;
    SBUF= dat;          //写数据到UART数据寄存器
}
void SendString(char *s)
{
   while(*s)               //检测字符串结束标志
    {
       SendData(*s++);    //发送当前字符
    }
}
SendString()字符串函数,当遇到发送的字符串里面有0x00就会终止,实用性不强。SendData()函数中三条语句的顺序容易引起死机。
比较好的处理串口接收一个字节数据的方法,不采用中断处理标志位。通过关中断,然后处理串口接收标志,从而减少在处理过程中因为触发中断而造成的死循环。修改好的串口接收一个字节的代码(这是采用的串口2接收一个字节数据的处理函数,其控制寄存器不支持位操作)如下:
void SendData(BYTE dat)
{
     EA = 0;
       S2BUF= dat;        //SBUF=dat
   while (!(S2CON & S2TI));               //等待前面的数据发送完成  whileTI);
       S2CON&= ~S2TI;  //TI = 0
       EA= 1;      
}
Unsigned  char SendString(unsigned char *s, unsignedint len)
{
Unsigned int  i;
For(i =0;i<len ;i++)
{
SendData(*s++);
}
}
一个比较好的接收处理框架(利用通信协议):
void UART1_ISR(void) interrupt 4 using 1
{
        unsigned char sbuffer;   
   if(RI)
    {
       RI = 0;
        sbuffer = SBUF;     
              if(nflag == 0)
                     {
                            REC_MAX     =REC_MAX_NAME ;
                     }
              else
                         REC_MAX     =REC_MAX_DATA;           
       if((sbuffer == CHECK_HEAD) && (Rec_Flag == 0))//如果收到文件头而且当前未接收
       {
           Rec_Flag = 1;
           Rec_Len  = 0;
             uarttext[0]= sbuffer;         // 这里保留了包头
              }  
       else if(Rec_Flag)                       // 开始接收
       {
           if(Rec_Len < (REC_MAX - 1))  
           {     
                            Rec_Len++;               
                uarttext[Rec_Len] = sbuffer; // 当数据送缓冲区                           
           }
           else if(Rec_Len == (REC_MAX - 1)) // 接收完成 
           {
                     /*    if(uarttext[Rec_Len] == CHECK_TAIL) //  表明接收成功未出错
                {
                            //     
                }
                else  //  有误码
                {
                    
                }
                Rec_Flag = 0;// 接收完成,标志清0
           }
       }
       }      
       else  if(TI)
       {            
             TI =0;
              busy=0;
              }     
}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表