• 代码调试之串口调试2


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

    //****************************************************************//
    //           AM系列读单总线使用范例 
    //单片机 :AT89S52 或 STC89C52RC 
    // 功能  :串口发送温湿度数据  波特率 9600 
    // 晶振  :12M (用户系统时钟如不是12M 请更改相关宏定义及注释的延时时间)
    // 编译环境:  Keil3
    // 公司  :奥松电子    
    //****************************************************************//
    
    #include "reg52.h"
    #include <intrins.h>
    
    //用户根据自己的晶振修改相应值
    #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) 
      }
    }
    View Code

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

  • 相关阅读:
    使用非ServiceDependency方法获得模块中已注册的服务
    一个比较有效的存储过程命名规则
    SQL重复记录查询
    Redis命令行启动,修改密码
    springboot+dubbo后端打包成jar并运行
    开发问题:NOAUTH Authentication required
    @Api报错
    String的indexof使用
    开发报错:init datasource error, url: jdbc:mysql://localhost:3306/book(初始化数据库错误)
    开发问题:异常Required request body is missing
  • 原文地址:https://www.cnblogs.com/fengdashen/p/3525652.html
Copyright © 2020-2023  润新知