×
单片机 > 单片机程序设计 > 详情

代码调试之串口调试2

发布时间:2020-06-10 发布时间:
|

串口调试这个东西真的太经典了,虽然我对51的串口通信方式还是一知半解,但是这几天调试程序,又通过看郭天祥的书,对51的串口有了进一步的认识,串口调试的程序需要多多收集,开始德飞来板子上的串口程序感觉起来就是个渣渣,一点都不好用,在调试程序的时候老是出问题,上一篇调试串口的程序就是移植德飞来板子上的程序,不仅波特率不能自己更改,比较死板,要注意的东西很多,不适合,今天调试温度传感器那个程序,突然间发现一个比较又用的串口调试程序,就晒在园子里,供大家参考

//****************************************************************//

//           AM系列读单总线使用范例 

//单片机 :AT89S52 或 STC89C52RC 

// 功能  :串口发送温湿度数据  波特率 9600 

// 晶振  :12M (用户系统时钟如不是12M 请更改相关宏定义及注释的延时时间)

// 编译环境:  Keil3

// 公司  :奥松电子    

//****************************************************************//


#include "reg52.h"

#include


//用户根据自己的晶振修改相应值

#define FOSC  11059200

               

#define BAUD  9600 


//读传感器 端口位定义,可修改

sbit Sensor_SDA = P0^0;

sbit Sensor_SCL = P0^1;


// 变量定义

unsigned char Sensor_Data[5]={0x00,0x00,0x00,0x00,0x00};

unsigned char Sensor_Check;          //校验和


unsigned char Sensor_AnswerFlag;  //收到起始标志位

unsigned char Sensor_ErrorFlag;   //读取传感器错误标志

unsigned int  Sys_CNT;

unsigned int  Tmp;


unsigned char *String;


//字符串定义

#define S_Temp "Temp:"

#define S_RH   "RH:"

#define S_CRCT "Check: True"

#define S_CRCF "Check: Wrong"

#define S_Data "Data: "

#define S_NotS "Sensor Not Connected"


/********************************************\

|* 功能: 延时    晶振为12M时                    *|

|*  t = 1 为 20us  然后成倍增加10us左右        *|

\********************************************/

void Delay_N10us(unsigned char t)

{

    while(t--)

   {

        _nop_();

   }

}

/********************************************\

|* 功能: 延时    晶振为12M时                    *|

|* 延时大约 1ms                                *|

\********************************************/ 

void Delay_N1ms(unsigned int t)

{

  unsigned int i;

  unsigned int j;

  for(j=t;j>0;j--)

     for(i=124;i>0;i--);  //延时大约 1ms

}

/********************************************\

|* 功能: 初始化串口                        *|

\********************************************/

void InitUART(void)

  {

    unsigned int iTmpBaud;

    unsigned long lTmpBaud;

    iTmpBaud = 0;

    //首先选定定时器2作为波特率发生器,16位定时器,自动装载

    SCON = 0x50;    //SM0 SM1 SM2 REN TB8 RB8 TI RI        //0   1   0   1   0   0   0  0    

      PCON = 0x00;    //PCON的地址是87H,这里SMOD =0


      T2CON = 0x30;    //TF2 EXF2 RCLK TCLK EXEN2 TR2 C(/T2) CP(/RL2) //0 0 1 1 0 0 0 0 

      T2MOD = 0x00;    // /    /    /    /        /    /    T2OE    DCEN   //0 0 0 0 0 0 0 0


      lTmpBaud = FOSC/BAUD;

      lTmpBaud /= 32;                        //12T-mode

      iTmpBaud = lTmpBaud & 0xFFFF;        

      iTmpBaud = 65536 - iTmpBaud;

      RCAP2H = (iTmpBaud>>8) & 0x0FF;

      RCAP2L = iTmpBaud & 0x0FF;


      RI = 0;            //清除接收中断标志

      REN = 1;        //允许串行接收

      ES = 1;            //允许串行中断

      TR2 = 1;        //启动定时器1


      EA=1;//开总中断

  }  


/********************************************\

|* 功能: 串口发送函数                         *|

\********************************************/

void UARTSend(char UCHAR)

  {

    SBUF=UCHAR;

    while(TI==0);

    TI=0;

  }

/********************************************\

|* 功能: 串口中断函数                         *|

\********************************************/

void UARTRead(void) interrupt 4

  {

    char temp; 

    if(RI)

    {

      RI=0;

      temp = SBUF;

    }

  }

 /********************************************\

|* 功能: 串口发送子函数                     *|

\********************************************/

void UART_PutString(unsigned char *buf)

  {

    while(*buf)

      UARTSend(*buf++);

  }

void UART_PutStringAndNum(unsigned char *buf ,unsigned int num)

  {

    unsigned char a[3],i;

    a[3] = '0'+num%10;

    a[2] = '.';

    a[1] = '0'+num/10%10;

    a[0] = '0'+num/100%10;

    while(*buf)

      UARTSend(*buf++);

    UARTSend(' ');

     for(i=0;i<4;i++)

    {

        UARTSend(a[i]);

    } 

  }

void UART_PutStringAnd_Data(unsigned char *buf ,unsigned char *bufdata)

  {

    unsigned char a[2],i,j;

    while(*buf)

      UARTSend(*buf++);

    UARTSend(' ');

    for(i=0;i<5;i++)

    {

        a[0] = bufdata[i]/16; 

        a[1] = bufdata[i]%16;

        for(j=0;j<2;j++)

        {

          if(a[j]>9)

          {

            a[j] = (a[j]-10)+'A';

          }

          else

          {

            a[j] = a[j]+'0';

          }

          UARTSend(a[j]);

        }

        UARTSend(' ');

    } 

  }

/********************************************\

|* 功能: 串口发送传感器数据函数             *|

\********************************************/

void UARTSend_Nbyte(void)

  {

       if(Sensor_AnswerFlag == 1)

       {

          Sensor_Check = Sensor_Data[0]+Sensor_Data[1]+Sensor_Data[2]+Sensor_Data[3];

          //校验成功

          if(Sensor_Check ==Sensor_Data[4])    

          {

             String = S_RH;//"RH:";       

             Tmp = Sensor_Data[0]*256+Sensor_Data[1];       

             UART_PutStringAndNum(String,Tmp); 

                UARTSend(' ');

             UARTSend(' ');

             

             String = S_Temp;// "Temp:";       

                Tmp = Sensor_Data[2]*256+Sensor_Data[3];       

             UART_PutStringAndNum(String,Tmp);

                UARTSend(' ');

             UARTSend(' ');


             String = S_CRCT;//"Check: True";

             UART_PutString(String);

          }else    //校验失败 送上读到数据

          {

             String = S_Data;//"Data: ";

             UART_PutStringAnd_Data(String,Sensor_Data);

             UARTSend(' ');    

             UARTSend(' ');

             String = S_CRCF;//"Check: Wrong";

             UART_PutString(String); 

          }

        }// 传感器未连接

        else

        {

           String = S_NotS; //"Sensor Not Connected";

            UART_PutString(String);

        }        

        UARTSend(0x0A); 


  }  

void Clear_Data (void)

  {

    int i;

    for(i=0;i<5;i++)

    {

       Sensor_Data[i] = 0x00;

     }//接收数据清零

  }



/********************************************\

|* 功能: 读传感器发送的单个字节            *|

\********************************************/

unsigned char Read_SensorData(void)

  {

    unsigned char i,cnt;

    unsigned char buffer,tmp;

    buffer = 0;

    for(i=0;i<8;i++)

    {

        cnt=0;

        while(!Sensor_SDA)    //检测上次低电平是否结束

        {

          if(++cnt >= 300)

           {

              break;

           }

        }

        //延时Min=26us Max50us 跳过数据"0" 的高电平

        Delay_N10us(2);     //延时30us   

        

        //判断传感器发送数据位

        tmp =0;

        if(Sensor_SDA)     

        {

          tmp = 1;

        }  

        cnt =0;

        while(Sensor_SDA)        //等待高电平 结束

        {

               if(++cnt >= 200)

            {

              break;

            }

        }

        buffer <<=1;

        buffer |= tmp;    

    }

    return buffer;

  }


/********************************************\

|* 功能: 读传感器                          *|

\********************************************/

unsigned char Read_Sensor(void)

  {

    unsigned char i;

    //主机拉低(Min=800US Max=20Ms) 

    Sensor_SDA = 0;

    Delay_N1ms(2);  //延时2Ms

      

    //释放总线 延时(Min=30us Max=50us)

    Sensor_SDA = 1;     

    Delay_N10us(1);//延时30us

    //主机设为输入 判断传感器响应信号 

    Sensor_SDA = 1; 

           

    Sensor_AnswerFlag = 0;  // 传感器响应标志     


    //判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行      

    if(Sensor_SDA ==0)

    {

       Sensor_AnswerFlag = 1;//收到起始信号

       Sys_CNT = 0;

       //判断从机是否发出 80us 的低电平响应信号是否结束     

       while((!Sensor_SDA))

       {

         if(++Sys_CNT>300) //防止进入死循环

         {

           Sensor_ErrorFlag = 1;

           return 0;

          } 

        }

        Sys_CNT = 0;

        //判断从机是否发出 80us 的高电平,如发出则进入数据接收状态

        while((Sensor_SDA))

        {

           if(++Sys_CNT>300) //防止进入死循环

           {

             Sensor_ErrorFlag = 1;

             return 0;

           } 

        }          

        // 数据接收    传感器共发送40位数据 

        // 即5个字节 高位先送  5个字节分别为湿度高位 湿度低位 温度高位 温度低位 校验和

        // 校验和为:湿度高位+湿度低位+温度高位+温度低位

        for(i=0;i<5;i++)

        {

          Sensor_Data[i] = Read_SensorData();

        }

      }

      else

      {

        Sensor_AnswerFlag = 0;      // 未收到传感器响应    

      }

      return 1;

  }    


void main(void)

{

  Sensor_SCL = 0;

  InitUART();  //初始串口发送函数

  while(1)

  {

    Clear_Data();         // 清除收到数据

    Read_Sensor();          // 读取传感器数据

    UARTSend_Nbyte();      // 串口发送读到传感器数据

    Delay_N1ms(2000);      // 延时 2S(两次读取间隔至少2S) 

  }

}

代码是可以调整波特率的,虽然还没有仔细的看,但是改一下晶振晶振的宏定义就可以用了,比较万能



关键字:代码调试  串口调试 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
基于ARM控制器和GPRS技术网络实现配变监控系统的设计