请问哪位dalao看得懂这个传感器的通信规约?

2019-07-15 08:45发布

QQ截图20180329231245.png QQ截图20180329231258.png
具体是这样子的,UART通信的数据每个字节下面还有一个16进制的数字?这个到底是干什么的,到底是怎么通信的,我需要使用52单片机编写程序提取出其中的浓度值,可是哪个我才需要的返回数据?
c3d87fec4ee1e366d49d29539e9f2372.pdf 下载积分: 积分 -1 分
449.12 KB, 下载次数: 11, 下载积分: 积分 -1 分
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
9条回答
异世界的投影
1楼-- · 2019-07-15 15:19
人中狼 发表于 2018-3-30 09:30
通讯就是标准的串口通讯,资料里有写的,通讯协议里的16进制数是列举的例子

可能是我对串口通讯的了解还不太够,我有以下几个问题:
1.我发的图片中它说表4命令行格式,是不是指的是表4中第一个字节到第八个字节的16进制数就是我需要发送给传感器的命令?可是他不是说默认主动上传了,我为何还要发命令行给他?而且表5和6不就是切换上传方式的命令吗?
2.表7竟然是气体浓度的格式?一个气体浓度发了8个字节?表8的传感器返回值又如何解读?里面不是有气体浓度了吗?
3.到底传感器和52单片机之间是怎么通讯的?是传感器默认每1秒上传一起数据吗?上传的是什么数据?是表8吗?
异世界的投影
2楼-- · 2019-07-15 16:26
 精彩回答 2  元偷偷看……
勇哥-lzu
3楼-- · 2019-07-15 21:45
异世界的投影 发表于 2018-3-30 13:05
可能是我对串口通讯的了解还不太够,我有以下几个问题:
1.我发的图片中它说表4命令行格式,是不是指的是表4中第一个字节到第八个字节的16进制数就是我需要发送给传感器的命令?可是他不是说默认主动上传了,我为何还要发命令行给他?而且表5和6不就是切换上传方式的命令吗?
2.表7竟然是气体浓度的格式?一个气体浓度发 ...

1.表4是传感器发给你的;是在主动模式下才用的
2.表7是你发给传感器的,表8是传感器发给你的,是在问答模式下用的
3.你先接上,用默认的主动模式,只要串口接收数据就行了,按照表4解析数据获得气体浓度;后面的再研究吧
人中狼
4楼-- · 2019-07-16 00:00
楼上正解,通讯协议确定后就是固定的,但是如何应用每一个命令则是活的
异世界的投影
5楼-- · 2019-07-16 04:06
wulinwl 发表于 2018-3-31 09:52
给你按默认主动上传方式写的程序,看懂以后,其它应用方式自然就会了。
程序经TX-1C实验板验证无误。
//按默认主动上传方式的程序

感谢dalao还特意写了程序来讲解,不过这里          V_data=(rec_buf[4]<<8)|rec_buf[5];//恢复16位有效数据(浓度值)   我的意见是把它变成 rec_buf[4]*256+rec_buf[5] ?不然怎么可以算出来
异世界的投影
6楼-- · 2019-07-16 09:48
wulinwl 发表于 2018-3-31 09:52
给你按默认主动上传方式写的程序,看懂以后,其它应用方式自然就会了。
程序经TX-1C实验板验证无误。
//按默认主动上传方式的程序

我自己也根据大佬的程序仿照了一下,用的1602显示屏,但是怎么显示的还是0.00000?我的传感器坏了?



#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int

sbit rs = P0^5;        //1602的数据/指令选择控制线  
sbit rw = P0^6;        //1602的读写控制线  
sbit en = P0^7;        //1602的使能控制线   /*P2口接1602的D0~D7   
sbit led_2=P1^3;
uchar UART_dat[9];
uint ch2o,flag;          

void delay( uint n )                           
{      
        uint x, y;      
        for( x=n; x>0; x-- )         
        for( y=112; y>0; y-- );  
}  
void lcd_wcom( uchar com )  //1602写命令函数                 
{      
        rs=0;            //选择指令寄存器      
        rw=0;            //选择写      
        P2=com;          //把命令字送入P2      
        delay( 5 );      //延时一小会儿,让1602准备接收数据      
        en=1;           //使能线电平变化,命令送入1602的8位数据口      
        en=0;  
}
  
void lcd_wdat( uchar dat )        //1602写数据函数        
{      
        rs=1;        //选择数据寄存器      
        rw=0;        //选择写      
        P2=dat;      //把要显示的数据送入P2      
        delay( 5 );  //延时一小会儿,让1602准备接收数据      
        en=1;        //使能线电平变化,数据送入1602的8位数据口  
        en=0;  
}
                               
void lcd_wbyte(uchar *byte)         //1602写字符串函数
{
    while(*byte!='')
    {
        lcd_wdat(*byte);
        byte++;
    }
}

void lcd_init()         //1602初始化函数        
{  
        delay( 15 );
        lcd_wcom( 0x38 );
        delay( 5 );
        lcd_wcom( 0x38 );
        delay( 5 );
        lcd_wcom( 0x38 );  
        lcd_wcom( 0x38 );    //8位数据,双列,5*7字形   
        lcd_wcom( 0x08 );      
        lcd_wcom( 0x0c );    //开启显示屏,关光标,光标不闪烁      
        lcd_wcom( 0x06 );    //显示地址递增,即写一个数据后,显示位置右移一位     
        lcd_wcom( 0x01 );    //清屏
}      
void init_uart()          //初始化串行口
{
        SCON = 0x50;        //工作方式1,
    TMOD = 0x20;        //定时器T1使用工作方式2
    TH1 = 0xFD;          //256 - (11059200/12/32)/baud;  //计算T1重载值,//波特率9600bit/s
    TL1 = 0xFD;                         //初值等于重载值
    TR1  = 1;           //开始计时
    ES=1;                                 //打开串口中断
        EX0=1;
        EX1=1;                               
    EA = 1;             //开启总中断
}

void show()                        //显示数据
{
        lcd_wcom(0x80);
        lcd_wbyte("CH2O:");  
        lcd_wdat(0x30+ch2o/100000);
        lcd_wbyte(".");
        lcd_wdat(0x30+ch2o%100000/10000);
        lcd_wdat(0x30+ch2o%10000/1000);
        lcd_wdat(0x30+ch2o%1000/100);
        lcd_wdat(0x30+ch2o%100/10);
        lcd_wdat(0x30+ch2o%10);
        lcd_wbyte("mg/m3");
}                                                                                                                                                  
void UARTInterrupt() interrupt 4
{
        static uchar num=0;        //静态计数变量
        RI=0;                                                //接收中断请求标志位清0
        UART_dat[num]=SBUF;        //接收到的数据串保存在缓存数组
        if(UART_dat[0]==0xFF)        //验证数据头(起始位)
        {
                num++;
                if(num>=9)
                {
                        flag=1;                        //接收完成标志置1
                        num=0;                        //计数变量清0
                }
        }
}

/*********校验和计算***********/
uchar FucCheckSum(uchar *i,uchar ln)
{
        uchar j,tempq=0;
        i+=1;
        for(j=0;j<(ln-2);j++)
        {
                tempq+=*i;
                i++;
        }
        tempq=(~tempq)+1;
        return(tempq);
}
/************数据解析程序*************/
void analysis()
{
        uchar j;                 //临时变量
        if(flag==1)                //如果9位数据串接收完成
        {
                ES=0;                        //关串口中断
                flag=0;                //接收完成标志清0
                j=FucCheckSum(UART_dat,9);//校验和计算
                if(UART_dat[8]==j)//验证数据校验和
                {
                        ch2o=UART_dat[4]*256+UART_dat[5];//恢复16位有效数据(浓度值)
                        
                }
                ES=1;                //开串口中断
        }
}
/*主函数*/

void main(){
         lcd_init();
         init_uart();
         led_2=!led_2;
         while(1)
        {
        analysis();
            show();
        }
}


补充内容 (2018-4-1 21:25):
原来是接触不良..........

一周热门 更多>