找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2829|回复: 9
收起左侧

求17年电赛简易水情检测系统的完整代码,谢谢

[复制链接]
ID:375962 发表于 2019-4-12 15:00 | 显示全部楼层 |阅读模式
20黑币

回复

使用道具 举报

ID:525479 发表于 2019-5-1 11:16 | 显示全部楼层
基于stc15w的oled显示
回复

使用道具 举报

ID:497670 发表于 2019-5-1 13:40 | 显示全部楼层
你好!
把你的硬件清单说一下
1、用的什么单片机
2、显示用什么?
3、PH值传感器型号?
4、水位高度测量超声波吗?
5、具体设计和实物制作,看我头像,请注明来自 51黑
回复

使用道具 举报

ID:375962 发表于 2019-5-11 09:58 来自手机 | 显示全部楼层
已经解决啦,谢谢啦
回复

使用道具 举报

ID:375799 发表于 2019-6-15 19:31 | 显示全部楼层
#include <STC15F2K60S2.H>// 包含STC115F2K60S2单片机寄存器定义文件   
#define VCC 5.0   // 存放用万用表实测的单片机供电电压
#include <intrins.h>                                           
#define uchar unsigned char
#define uint  unsigned int
unsigned int ADvalue;            // 存放AD转换返回的结果

sbit ADC_SCK=P2^6 ;//ADC时钟
sbit ADC_DIN= P2^7;//ADC数据入
sbit ADC_DOUT=P2^4;  //ADC数据出
sbit ADC_DBY=P2^5;//ADC准备
unsigned int channal1;

sbit RS=P0^0;            //片选信号        rs        CS
sbit RW=P0^1;                //数据信号        rw          SID
sbit E=P0^2;                //时钟信号   e                 SCLK

sbit RST=P0^6;                //复位信号
sbit PSB = P0^7;                //并行、串行选择信号         psb   CH

sbit c_send   = P3^3;                //超声波发射          t
sbit c_recive = P3^2;                //超声波接收         e
uchar flag_hc_value;        //超声波中间变量

long distance;                //距离
uint set_d;                    //距离
bit flag_csb_juli;      //超声波超出量程
uint  flag_time0;      //用来保存定时器0的时候的
uint time;

/********************************************************************
* 名称 : delay()
* 功能 : 延时,延时时间为 100us * t。这是通过软件延时,有一定误差。
* 输入 : t
* 输出 : 无
***********************************************************************/
void delay(unsigned int t)
{
        unsigned int i,j;
        for(i=0; i<t;  i++)
    for(j=0; j<10; j++);
}
void Delay_ms(unsigned int n)
{
        unsigned int  i,j;
        for(i=0;i<n;i++)
                for(j=0;j<123;j++);
}

void UART_init(void)
{                  
        //下面代码设置定时器1
        TMOD = 0x20;        // 0010 0000 定时器1工作于方式2(8位自动重装方式)
        TH1  = 0xFD;        // 波特率:9600 /11.0592MHZ
        TL1  = 0xFD;        // 波特率:9600 /11.0592MHZ
        TR1  = 1;
        //下面代码设置定串口
        AUXR = 0x00;             // 很关键,使用定时器1作为波特率发生器,S1ST2=0
        SCON = 0x50;         // 0101 0000 SM0.SM1=01(最普遍的8位通信),REN=1(允许接受)
        TI=1;                        // 很关键,使用printf函数时必须有此命令
}

/********************************************************************
* 名称 : sendbyte()
* 功能 : 按照液晶的串口通信协议,发送数据
* 输入 : zdata
* 输出 : 无
***********************************************************************/
void sendbyte(unsigned char zdata)
{
        unsigned int i;
        for(i=0; i<8; i++)
        {
                if((zdata << i) & 0x80)
                {
                        RW = 1;
                }
                else
                {
                        RW = 0;
                }
                E = 0;
                E = 1;
        }
}

/********************************************************************
* 名称 : write_com()
* 功能 : 写串口指令
* 输入 : cmdcode
* 输出 : 无
***********************************************************************/
void write_com(unsigned char cmdcode)
{
        RS = 1;
        sendbyte(0xf8);
        sendbyte(cmdcode & 0xf0);
        sendbyte((cmdcode << 4) & 0xf0);
        delay(2);
}

/********************************************************************
* 名称 : write_data()
* 功能 : 写串口指令
* 输入 : cmdcode
* 输出 : 无
***********************************************************************/
void write_data(unsigned char Dispdata)
{
        RS = 1;
        sendbyte(0xfa);
        sendbyte(Dispdata & 0xf0);
        sendbyte((Dispdata << 4) & 0xf0);
        delay(2);
}

/********************************************************************
* 名称 : lcdinit()
* 功能 : 初始化函数
* 输入 : cmdcode
* 输出 : 无
***********************************************************************/
void lcdinit()
{  
    PSB = 0;
        delay(1);
        RST = 0;
        delay(100);
        RST = 1;
        delay(20000);
        write_com(0x30);
        delay(50);
        write_com(0x0c);
        delay(50);
}

/********************************************************************
* 名称 : hzkdis()
* 功能 : 显示字符串
* 输入 : *s
* 输出 : 无
***********************************************************************/
void hzkdis(unsigned char code *s)
{  
        while(*s > 0)
    {
                write_data(*s);
                s++;
                delay(50);
    }
}
        void time_init()          
{
        EA  = 1;                   //开总中断
        TMOD = 0X01;          //定时器0、定时器1工作方式1
        ET0 = 1;                  //开定时器0中断
        TR0 = 1;                  //允许定时器0定时
}
void send_wave()
{
         c_send=1;     //启动一次检测模块
         delay(20);
         c_send=0; //停止向检测模块Trig端发送高电平
         while(!c_recive);      //无回波时等待
         TR0=1;             //计时开始
         while(c_recive);       //有回波是计数并继续等待
         TR0=0;
         time=TH0*256+TL0;   
         TH0=0;
         TL0=0;
         distance=269.05-time*0.191;//  计算距离,算出来的单位是mm
         if(distance<=0)
          distance=0;
         if(distance>=269.05)
         distance=269.05;
       
}
void  ADC_P11_init()
{
        unsigned int i;                    // 用于软件延时程序
        ADC_CONTR|=0x80;              // 开AD转换电源,第一次使用时要打开内部模拟电源
    for (i=0;i<10000;i++);  // 适当延时等待AD转换供电稳定,一般延时1ms以内即可,为了缩短AD
// 调用时间,可把这2行剪切到主程序中去。
        P1ASF|=0x02;                        // 选择P1.1作为AD转换通道,0x02= 0000 0010       
        ADC_CONTR=0xE1;         // 选择P1.1作为AD转换通道,最高转换速度,清转换完成标志。
        for (i=0;i<200;i++);   // 如果是多通道模拟量进行AD转换,则更换AD转换通道后要适当延时,
// 使输入电压稳定,延时量取20μs~200μs即可,与输入电压源的内阻有关,如果输入电压信号源的内
// 阻在10K以下,可不加延时,如果是单通道模拟量转换,则不需要更换AD转换通道,也不需要加延时。
        ADC_CONTR|=0x08;        // 启动 A/D 转换,ADC_START=1。
        EADC=1;
        EA=1;         
}  
void ADC(void) interrupt 5
{
        unsigned int AD_Dat=0,AD_Dat1=0;    // 10位AD转换值
        unsigned char Tmp=0,Tmp1=0;          // 临时变量用于将AD转换出来的2个字节合成一个字节
        ADC_CONTR&=0xE7;               // 将ADC_FLAG清0, 0xE7=1110 0111B,ADC_FLAG=0,ADC_START=0。       
        AD_Dat = ADC_RES;                  // 默认高字节高8位。
        AD_Dat <<= 2;
        Tmp = ADC_RESL;           // 默认低字节低2位。
        Tmp &= 0x03;              // 屏蔽无关位
        AD_Dat|= Tmp;                  // 高低字节拼接成一个10位数。
        ADvalue=AD_Dat;
        ADC_CONTR|=0x08;          // 重新启动 A/D 转换,ADC_START=1。
}

/******向AD7705写入一个字节******/
void WriteByte7705(unsigned char dat)
{
        unsigned char i;
        for (i=0; i<8; i++)
        {
                 ADC_SCK=0;
                _nop_();
                _nop_();
                _nop_();
                 if(dat & 0x80){ADC_DIN=1;}
                 else
                 ADC_DIN=0;
                _nop_();
                _nop_();
                _nop_();
                 ADC_SCK=1;                        
                _nop_();
                _nop_();
                _nop_();
                 dat=dat<<1;
        }
}

/****** 从AD7705读一个字节 ******/
unsigned long ReadWord7705()
{
        unsigned long read_dat=0;
        unsigned char i;
        for(i=0;i<16;i++)
        {
                 read_dat=read_dat<<1;
                 ADC_SCK=0;
                _nop_();
                _nop_();
                _nop_();
                 if(ADC_DOUT == 1)
                 {read_dat++; }
                _nop_();
                _nop_();
                _nop_();
                  ADC_SCK=1;
                _nop_();
                _nop_();
                _nop_();                         
         }
         return read_dat;
}

/******ad7705通信端口复位******/
void reset7705()
{
         unsigned char i;
          ADC_DIN=1;
         for(i=0;i<36;i++)
         {
         ADC_SCK=0;
        _nop_();
        _nop_();
        _nop_();
         ADC_SCK=1;
        _nop_();
        _nop_();
        _nop_();
   }
}

/******AD7705通道1初始化******/
void ad7705_init1()
{
reset7705();
WriteByte7705(0x20);//写通信寄存器,选择通道1,将下一次操作设为写时钟寄存器
WriteByte7705(0x01);//写时钟寄存器,不分频,更新频率25Hz
WriteByte7705(0x10);//写通信寄存器,选择通道1
WriteByte7705(0x44);//写设置寄存器4,单极性,非缓冲模式,清除滤波器同步,启动对1通道的自校准
}

/******读取AD7705通道1转换数据函数******/
unsigned int ReadData1_7705()
{
          unsigned int value;
          ad7705_init1();
          reset7705();
          while(ADC_DBY);          //等待转换结束
          WriteByte7705(0x38);    //写通信寄存器,下一次操作为读数据寄存器
          value=5000*ReadWord7705()/65535;
          return value;                                   
}

void main(void)
{
        float Vin,N,U;                                   // 存放计算出来的外部输入电压
        uint PH;
        ADC_P11_init();
        UART_init();                                   // 串口初始化9600/11.0592MHz
        time_init();
        send_wave();
        lcdinit();
        delay(10);
        write_com(0x03);
          while(1)
        {
         
                channal1=ReadData1_7705();         //测电池电压
                channal1=channal1*1.618;
                delay(50);     
                send_wave();                           //测距
                delay(50);
                Vin=VCC*ADvalue/1023;      // 注意是1023才正确
                    U=Vin*1010.33;
                N=(4418.5-U)/177.28;       
                PH=N*100;                                          //测PH值
                write_com(0x81);
                hzkdis("水情检测系统");
        write_com(0x90);
        hzkdis("液位高度: ");
                write_data(distance%1000/100 + 0x30);
                write_data(distance%100/10 + 0x30);
                write_data(distance%10 + 0x30);
                hzkdis("mm");
        write_com(0x88);
        hzkdis("当前PH值: ");
                write_data(PH%10000/1000 + 0x30);
                write_data(PH%1000/100 + 0x30);
                hzkdis(".")        ;
                write_data(PH%100/10 + 0x30);
        write_com(0x98);
        hzkdis("电池电压: ");
                write_data(channal1%10000/1000 + 0x30);
                hzkdis(".");
                write_data(channal1%1000/100 + 0x30);
                write_data(channal1%100/10 + 0x30);
                hzkdis("V");
                Delay_ms(10);

        }
   }
回复

使用道具 举报

ID:472844 发表于 2019-7-28 17:32 | 显示全部楼层
楼去解决了吗?可以分享一下吗?
回复

使用道具 举报

ID:563310 发表于 2020-3-19 12:53 | 显示全部楼层
#include <STC15F2K60S2.H>// ????STC115F2K60S2?????????????????   
#define VCC 5.0   // ????????????????????????
#include <intrins.h>                                           
#define uchar unsigned char
#define uint  unsigned int
unsigned int ADvalue;            // ???AD??????????

sbit ADC_SCK=P2^6 ;//ADC???
sbit ADC_DIN= P2^7;//ADC??????
sbit ADC_DOUT=P2^4;  //ADC?????
sbit ADC_DBY=P2^5;//ADC???
unsigned int channal1;

sbit RS=P0^0;            //?????        rs        CS
sbit RW=P0^1;                //???????        rw          SID
sbit E=P0^2;                //??????   e                 SCLK

sbit RST=P0^6;                //??λ???
sbit PSB = P0^7;                //???С???????????         psb   CH

sbit c_send   = P3^3;                //??????????          t
sbit c_recive = P3^2;                //??????????         e
uchar flag_hc_value;        //???????м????

long distance;                //????
uint set_d;                    //????
bit flag_csb_juli;      //??????????????
uint  flag_time0;      //???????涨???0??????
uint time;

/********************************************************************
* ???? : delay()
* ???? : ???,??????? 100us * t????????????????????????䶮
* ???? : t
* ??? : ??
***********************************************************************/
void delay(unsigned int t)
{
        unsigned int i,j;
        for(i=0; i<t;  i++)
    for(j=0; j<10; j++);
}
void Delay_ms(unsigned int n)
{
        unsigned int  i,j;
        for(i=0;i<n;i++)
                for(j=0;j<123;j++);
}

void UART_init(void)
{                  
        //???????????????1
        TMOD = 0x20;        // 0010 0000 ?????1????????2??8λ???????????
        TH1  = 0xFD;        // ???????9600 /11.0592MHZ
        TL1  = 0xFD;        // ???????9600 /11.0592MHZ
        TR1  = 1;
        //????????????????
        AUXR = 0x00;             // ?????????????1????????????????S1ST2=0
        SCON = 0x50;         // 0101 0000 SM0.SM1=01(??????8λ????,REN=1??????????
        TI=1;                        // ?????????printf??????????д?????
}

/********************************************************************
* ???? : sendbyte()
* ???? : ???????????????Э?飬????????
* ???? : zdata
* ??? : ??
***********************************************************************/
void sendbyte(unsigned char zdata)
{
        unsigned int i;
        for(i=0; i<8; i++)
        {
                if((zdata << i) & 0x80)
                {
                        RW = 1;
                }
                else
                {
                        RW = 0;
                }
                E = 0;
                E = 1;
        }
}

/********************************************************************
* ???? : write_com()
* ???? : д???????
* ???? : cmdcode
* ??? : ??
***********************************************************************/
void write_com(unsigned char cmdcode)
{
        RS = 1;
        sendbyte(0xf8);
        sendbyte(cmdcode & 0xf0);
        sendbyte((cmdcode << 4) & 0xf0);
        delay(2);
}

/********************************************************************
* ???? : write_data()
* ???? : д???????
* ???? : cmdcode
* ??? : ??
***********************************************************************/
void write_data(unsigned char Dispdata)
{
        RS = 1;
        sendbyte(0xfa);
        sendbyte(Dispdata & 0xf0);
        sendbyte((Dispdata << 4) & 0xf0);
        delay(2);
}

/********************************************************************
* ???? : lcdinit()
* ???? : ?????????
* ???? : cmdcode
* ??? : ??
***********************************************************************/
void lcdinit()
{  
    PSB = 0;
        delay(1);
        RST = 0;
        delay(100);
        RST = 1;
        delay(20000);
        write_com(0x30);
        delay(50);
        write_com(0x0c);
        delay(50);
}

/********************************************************************
* ???? : hzkdis()
* ???? : ????????
* ???? : *s
* ??? : ??
***********************************************************************/
void hzkdis(unsigned char code *s)
{  
        while(*s > 0)
    {
                write_data(*s);
                s++;
                delay(50);
    }
}
        void time_init()          
{
        EA  = 1;                   //?????ж?
        TMOD = 0X01;          //?????0???????1???????1
        ET0 = 1;                  //???????0?ж?
        TR0 = 1;                  //????????0???
}
void send_wave()
{
         c_send=1;     //?????μ?????
         delay(20);
         c_send=0; //?????????Trig????????
         while(!c_recive);      //????????
         TR0=1;             //??????
         while(c_recive);       //?л????????????????
         TR0=0;
         time=TH0*256+TL0;   
         TH0=0;
         TL0=0;
         distance=269.05-time*0.191;//  ???????????????λ??mm
         if(distance<=0)
          distance=0;
         if(distance>=269.05)
         distance=269.05;
       
}
void  ADC_P11_init()
{
        unsigned int i;                    // ??????????????
        ADC_CONTR|=0x80;              // ??AD??????,????????????????????
    for (i=0;i<10000;i++);  // ?????????AD??????????????????1ms???????????????AD
// ????????????2?м??е????????????
        P1ASF|=0x02;                        // ???P1.1???AD????????0x02= 0000 0010       
        ADC_CONTR=0xE1;         // ???P1.1???AD??????????????????????????????
        for (i=0;i<200;i++);   // ??????????????????AD??????????AD?????????????????
// ??????????????????20??s??200??s?????????????????????й???????????????????
// ????10K???£???????????????????????????????????????AD?????????????????????
        ADC_CONTR|=0x08;        // ??? A/D ?????ADC_START=1??
        EADC=1;
        EA=1;         
}  
void ADC(void) interrupt 5
{
        unsigned int AD_Dat=0,AD_Dat1=0;    // 10λAD????
        unsigned char Tmp=0,Tmp1=0;          // ????????????AD?????????2?????????????
        ADC_CONTR&=0xE7;               // ??ADC_FLAG??0?? 0xE7=1110 0111B??ADC_FLAG=0??ADC_START=0??       
        AD_Dat = ADC_RES;                  // ????????8λ??
        AD_Dat <<= 2;
        Tmp = ADC_RESL;           // ????????2λ??
        Tmp &= 0x03;              // ???????λ
        AD_Dat|= Tmp;                  // ?????????????10λ????
        ADvalue=AD_Dat;
        ADC_CONTR|=0x08;          // ??????? A/D ?????ADC_START=1??
}

/******??AD7705д????????******/
void WriteByte7705(unsigned char dat)
{
        unsigned char i;
        for (i=0; i<8; i++)
        {
                 ADC_SCK=0;
                _nop_();
                _nop_();
                _nop_();
                 if(dat & 0x80){ADC_DIN=1;}
                 else
                 ADC_DIN=0;
                _nop_();
                _nop_();
                _nop_();
                 ADC_SCK=1;                        
                _nop_();
                _nop_();
                _nop_();
                 dat=dat<<1;
        }
}

/****** ??AD7705???????? ******/
unsigned long ReadWord7705()
{
        unsigned long read_dat=0;
        unsigned char i;
        for(i=0;i<16;i++)
        {
                 read_dat=read_dat<<1;
                 ADC_SCK=0;
                _nop_();
                _nop_();
                _nop_();
                 if(ADC_DOUT == 1)
                 {read_dat++; }
                _nop_();
                _nop_();
                _nop_();
                  ADC_SCK=1;
                _nop_();
                _nop_();
                _nop_();                         
         }
         return read_dat;
}

/******ad7705??????λ******/
void reset7705()
{
         unsigned char i;
          ADC_DIN=1;
         for(i=0;i<36;i++)
         {
         ADC_SCK=0;
        _nop_();
        _nop_();
        _nop_();
         ADC_SCK=1;
        _nop_();
        _nop_();
        _nop_();
   }
}

/******AD7705???1?????******/
void ad7705_init1()
{
reset7705();
WriteByte7705(0x20);//д???????,??????1,??????β??????д???????
WriteByte7705(0x01);//д???????,?????,???????25Hz
WriteByte7705(0x10);//д???????,??????1
WriteByte7705(0x44);//д???ü????4,??????,???????,???????????,?????1???????У?
}

/******???AD7705???1??????????******/
unsigned int ReadData1_7705()
{
          unsigned int value;
          ad7705_init1();
          reset7705();
          while(ADC_DBY);          //??????????
          WriteByte7705(0x38);    //д???????,????β??????????????
          value=5000*ReadWord7705()/65535;
          return value;                                   
}

void main(void)
{
        float Vin,N,U;                                   // ???????????????????
        uint PH;
        ADC_P11_init();
        UART_init();                                   // ????????9600/11.0592MHz
        time_init();
        send_wave();
        lcdinit();
        delay(10);
        write_com(0x03);
          while(1)
        {
         
                channal1=ReadData1_7705();         //??????
                channal1=channal1*1.618;
                delay(50);     
                send_wave();                           //???
                delay(50);
                Vin=VCC*ADvalue/1023;      // ?????1023?????
                    U=Vin*1010.33;
                N=(4418.5-U)/177.28;       
                PH=N*100;                                          //??PH?
                write_com(0x81);
                hzkdis("???????");
        write_com(0x90);
        hzkdis("?λ???: ");
                write_data(distance%1000/100 + 0x30);
                write_data(distance%100/10 + 0x30);
                write_data(distance%10 + 0x30);
                hzkdis("mm");
        write_com(0x88);
        hzkdis("???PH?: ");
                write_data(PH%10000/1000 + 0x30);
                write_data(PH%1000/100 + 0x30);
                hzkdis(".")        ;
                write_data(PH%100/10 + 0x30);
        write_com(0x98);
        hzkdis("?????: ");
                write_data(channal1%10000/1000 + 0x30);
                hzkdis(".");
                write_data(channal1%1000/100 + 0x30);
                write_data(channal1%100/10 + 0x30);
                hzkdis("V");
                Delay_ms(10);

        }
   }
回复

使用道具 举报

ID:712010 发表于 2020-3-27 13:19 | 显示全部楼层
君莫笑hhh 发表于 2019-5-11 09:58
已经解决啦,谢谢啦

楼主能共享下原理图吗
回复

使用道具 举报

ID:860602 发表于 2021-1-16 16:30 | 显示全部楼层



2017年全国大学生电子设计竞赛


简易水情检测系统(P 题)










编号:107219


简易水情检测系统

摘要:设计以STC15F2K60S2单片机为核心控制处理器,对PH传感器和液位传感器及蓝牙模块进行采集运算,从而对液体状态实时监测。系统主要由单片机最小系统、电池组、稳压模块电路、PH传感器、液位传感器、电压检测电路、 AD转换电路、12864液晶显示、蓝牙模块和手机APP组成。系统使用PH传感器对液体进行PH检测,测量精度小于0.09;使用压力传感器对水位通过线性关系测量,测量误差小于2mm;通过电阻二分法分压测量电池组端口电压,测量误差小于0.01V。水位测量高度值、PH测量值及电池输出电压值通过LCD12864及手机APP同步显示显示。为降低系统功耗,手机APP可开关液晶背光。通过测试满足了基本和发挥部分的大部分要求。
关键词:蓝牙模块、PH传感器、压力传感器、手机APP、最小系统  
1 系统方案选择
1.1.方案比较
主芯片选型
1)采用STC89C51RC做主控芯片,外部高精度晶体/ 时钟,内部R/C 振荡器。常温下内部R/C 振荡器频率为:5.2MHz ~6.8MHz。
2)采用STC15F2K60S2做为主控芯片,其指令代码完全兼容传统80c51,且速度快8-12倍,内有可设定的晶振,无须外接。
系统使用使用高速、可设晶振频率芯片更便于程序的书写,故采用STC15F2K60S2型号芯片为主芯片。
水位传感器选型
1)水位传感器采用DS1603L,液位≥50mm时,精度可以达到0;50mm以下为盲区不可以测量。
2)水位传感器采用D3B压力传感器,通过液体压力检测水位高度,无盲区,可检测题目要求的200mm以下高度。
水位监测不应有盲区,盲区会影响整体测量结果。且50mm占整个任务要求的1/4,占比太大,故选择D3B压力传感器。
稳压芯片选型
1)稳压芯片采用LM7805,输入电压范围8-12V,压差最低2V,电池组电压与单片机供电电压压差为1V左右,稳压芯片本身有压降,影响输出准确值。
2)稳压芯片采用LM1117,输入电压范围1.25-13.8,压差最低1.2V,电池组电压与单片机供电电压压差为1V左右,稳压芯片本身有压降,影响输出准确值。
3、稳压芯片采用MIC29302,电压压差为0.37V,且输出稳定。
AD监测需用基准电压,应稳定输入电压,且干电池耗电太快,应选择压差最小的稳压芯片,故选择MIC29302稳压芯片。
1.2.方案描述
水情监测系统,以STC15F2K60S2单片机作为控制核心,通过16位AD转换测量供电电池的输出电压、PH值、水位。数据通过串口在12864液晶模块实时显示,同时通过蓝牙模块与手机APP连接实时显示数据且可通过手机APP控制液晶背光的开关。
系统方案框图如图1所示。

图1 系统方案框图
2 系统设计与论证
2.1传感器信号处理方法分析
1)PH检测信号由雷磁E-201-C型号PH传感器采集,由7705型号16位AD模块模数转换,转换结果经处理器分析,通过串口发送至电脑,计算其所呈现的线性关系,得出线性方程。数据结果由公式计算得出并显示。
2)水位监测信号由日本松下旗下压力传感器采集,由7705型号16位AD模块模数转换,转换结果经处理器分析,通过串口发送至电脑,数据计算发现,数据不呈现线性关系,故采集多组数据输入为数组,结果采用查表法计算。
2.2电压检测方法分析
加两个精度为千分之一的10K精密电阻,采用二分法进行分压测量,以提高准确度,通过AD采集、单片机处理计算并显示。
3 电路与程序设计
3.1系统组成
水情监测系统组成包括6V电池组、稳压芯片MIC29302、STC15F2K60S2单片机、PH监测模块、压力传感器水位监测模块、16位AD模块、12864液晶显示模块及蓝牙模块。
3.2硬件电路设计
1)稳压及12864显示模块如图2所示:
图2稳压及12864显示模块
2)AD转换模块如图3所示:
图3  AD转换模块
PH模块、压力传感器模块、蓝牙模块如图3所示:

图3  PH模块、压力传感器模块、蓝牙模块
3.3软件系统设计
根据题目要求,使用12864显示模块进行数据显示;水位测量偏差不大于2mm,PH测量偏差不大于0.1,电压测量偏差不大于0.01。因精度要求高,程序需做滤波处理以提高精度。同时通过蓝牙将数据发送至手机APP实时显示。且为降低系统功耗可通过手机APP进行开关液晶背光。软件设计流程图如图4所示。
图4 软件设计流程图



4、测试结果及分析
4.1测试数据完整性
表1 水位高度测试结果分析表
次数        第一次        第二次        第三次        第四次        第五次
测量水位高度/mm        30        65        99        120        170
实际水位高度/mm        31        64        99        121        170
误差/mm        1        1        0        1        0
表2 PH值测试结果分析表
次数        第一次        第二次        第三次        第四次        第五次
测量PH值        6.86        5.42        5.08        4.56        3.89
实际PH值        6.79        5.39        5.10        4.50        3.85
误差        0.07        0.03        0.02        0.06        0.04
表 3 电池电压值测试结果分析表
次数        第一次        第二次        第三次        第四次        第五次
测量电池电压/V        5.99        5.95        5.85        5.80        5.75
实际电池电压/V        5.99        5.96        5.85        5.81        5.75
误差/V        0.00        0.01        0.00        0.01        0.00
4.2测试结果分析
由水位高度测试结果分析表,发现水位测量结果不没有良好的线性关系,但可使用查表法进行误差调节,以满足任务要求;
由PH值测试结果分析表,发现其呈现良好的线性关系,且误差满足任务要求;
电压值基本无误差,满足任务要求
总结
系统主要用STC15F2K60S2作为核心,检测PH、压力传感器上的电压变化,送给单片机内部,通过16位AD处理信号,整个系统由各个电路模块搭建而成,这样便于了解系统,系统出错时方便找出问题所在,系统带有手机APP,可实时同步LCD12864显示数据且可控制显示背光的开关。软件方面增加滤波,以提高检测精度,整个系统运行稳定,可靠。
参考文献
[1] 瓮嘉民.单片机应用开发技术[M].北京:中国电力出版社,2010:215-223.
[2] 杨钦.电路设计与仿真[M].北京:清华大学出版社,2006:103-111.
[3] 马忠梅,刘滨.单片机C语言Windows环境编程宝典.北京:北京航空航天大学出版社,2002:79-83.
回复

使用道具 举报

ID:860602 发表于 2021-1-16 16:32 | 显示全部楼层
#include "STC15F2K60S2.h"
#include "bsp_tm7705.c"
#include "bsp_tm77052.c"
#include "SerialLcd12864.c"


#define FOSC 11059200L          //Ïμí3ÆμÂê
#define BAUD 9600         
   //′®¿ú2¨ìØÂê

typedef unsigned char BYTE;
typedef unsigned int WORD;


#define u16 unsigned int
#define u8 unsigned char


u16 code WaterDatNum[21]=
{
        1727,  //0
        2005,        //1
        2600,        //2
        3225,        //3
        3945,        //4
        4675,        //5
        5370,        //6
        6100,        //7
        6823,        //8
        7530,        //9
        8337,        //10
        9031,        //11
        9707,        //12
        10393,        //13
        11020,        //14
        11759,        //15
        12457,        //16
        13188,//17
        13822,//18
        14590,//19
        15260 //20

};

unsigned long SysDat;
uint16_t VolDat,PHDat;

uint16_t WaterDat,SendNum;


bit busy;

#define S1_S0 0x40              //P_SW1.6
#define S1_S1 0x80              //P_SW1.7
                       
void SysDelay(u16 ms)
{
   while(ms--);
}


/*----------------------------
UART ÖD¶Ï·tÎñ3ìDò
-----------------------------*/
void Uart() interrupt 4 using 1
{
        u8 Uartdat;
    if (RI)
    {
        RI = 0;                 //Çå3yRIλ
        Uartdat = SBUF;              //Uartdat¸3Öμ′®¿úêy¾Y
                if(Uartdat=='A')
                {
                        P55=0;
                }else if(Uartdat=='B')
                {
                        P55=1;
                }
    }
    if (TI)
    {
        TI = 0;                 //Çå3yTIλ
        busy = 0;               //ÇåÃ|±êÖ¾
    }
}

/*----------------------------
·¢Ëí′®¿úêy¾Y
----------------------------*/
void SendData(BYTE dat)
{
    while (busy);               //μè′yÇ°ÃæμÄêy¾Y·¢Ëííê3é
    busy = 1;
    SBUF = dat;                 //D′êy¾Yμ½UARTêy¾Y¼Ä′æÆ÷
}

/*----------------------------
·¢Ëí×Ö·û′®
----------------------------*/
void SendString(char *s)
{
    while (*s)                  //¼ì2a×Ö·û′®½áêø±êÖ¾
    {
        SendData(*s++);         //·¢Ëíμ±Ç°×Ö·û
    }
}


void ConfigCode(void)          //Ïμí3ó2¼tÅäÖÃ3ìDòμÄ
{
        P0M0=0;        P0M1=0;       
        P1M0=0;        P1M1=0;       
        P2M0=0;        P2M1=0;       
        P5M0=0;        P5M1=0;       
        P55=0;         //LCD12864  ±31a¿ØÖÆIO   μíμçƽμãáá

        ACC = P_SW1;
        ACC &= ~(S1_S0 | S1_S1);    //S1_S0=0 S1_S1=0
        P_SW1 = ACC;                //(P3.0/RxD, P3.1/TxD)
        SCON = 0x50;                //8λ¿é±ä2¨ìØÂê
        AUXR = 0x40;                //¶¨ê±Æ÷1Îa1TÄ£ê½
        TMOD = 0x20;                //¶¨ê±Æ÷1ÎaÄ£ê½2(8λ×Ô¶ˉÖØÔØ)         
        TL1 = (256 - (FOSC/32/BAUD));   //éèÖÃ2¨ìØÂêÖØ×°Öμ           £¨9600£©
        TH1 = (256 - (FOSC/32/BAUD));
        TR1 = 1;                    //¶¨ê±Æ÷1¿aê¼1¤×÷
        ES = 1;                     //ê1Äü′®¿úÖD¶Ï
        EA = 1;
}


void ShowCode()          //  12864òo¾§ÏÔê¾3ìDò
{

        LCD12864_pos(0,1);                 //μúò»DD  μú2áD
        LCD12864_writebyte("Ë®Çé¼ì2aÏμí3");


        LCD12864_pos(1,0);                 //μú2DD  μú1áD
        LCD12864_writebyte("ˮλ¸ß¶è:");
        LCD12864_write(1,WaterDat/100%10+0x30);
        LCD12864_write(1,WaterDat/10%10+0x30);
        LCD12864_write(1,WaterDat%10+0x30);
        LCD12864_writebyte("mm");


        LCD12864_pos(2,0);
        LCD12864_writebyte("PHÖμ:");
        if(PHDat>1400)
        {                                                         
                LCD12864_writebyte("--.--");       
        }
        else
        {
        LCD12864_write(1,PHDat/1000%10+0x30);
        LCD12864_write(1,PHDat/100%10+0x30);
        LCD12864_writebyte(".");
        LCD12864_write(1,PHDat/10%10+0x30);
        LCD12864_write(1,PHDat%10+0x30);
        }
        LCD12864_pos(3,0);
        LCD12864_writebyte("μç3ØμçÑ1:");
        LCD12864_write(1,VolDat/100%10+0x30);
        LCD12864_writebyte(".");
        LCD12864_write(1,VolDat/10%10+0x30);
        LCD12864_write(1,VolDat%10+0x30);
        LCD12864_writebyte("V");
       
       
}
                                        
void main(void)                //Ö÷3ìDò
{
        uint16_t adc1, adc2,adc3;
        float ADNum,WaterNum;
        u8 i;

        ConfigCode();        //Ïμí3ÅäÖÃoˉêy         
        bsp_InitTM7705();                        /* 3õê¼»ˉÅäÖÃTM7705 */
        bsp_InitTM7705_2();                        /* 3õê¼»ˉÅäÖÃTM7705 */

        TM7705_CalibSelf(1);                /* ×ÔD£×¼¡£Ö′DDê±¼ä½Ï3¤£¬Ô¼180ms */               
        adc1 = TM7705_ReadAdc(1);                               
        TM7705_CalibSelf(2);                /* ×ÔD£×¼¡£Ö′DDê±¼ä½Ï3¤£¬Ô¼180ms */
        adc2 = TM7705_ReadAdc(2);       
                                                                                                                                                                                                                                  
        TM7705_2_CalibSelf(1);                /* ×ÔD£×¼¡£Ö′DDê±¼ä½Ï3¤£¬Ô¼180ms */               
        adc3 = TM7705_2_ReadAdc(1);                               

        LCD12864_init();                        //LCD128643õê¼»ˉ
        LCD12864_Qing();                        //Çå3yÆáÄ»ÏÔê¾
        while(1)
        {
                adc1 = TM7705_ReadAdc(1);        /* Ö′DDê±¼ä 80ms */        //ˮλADÖμ       
                adc2 = TM7705_ReadAdc(2);        /* Ö′DDê±¼ä 80ms */        //PH  AD¼ì2a
                adc3 = TM7705_2_ReadAdc(1);        /* Ö′DDê±¼ä 80ms */               

                if(adc2>50000) PHDat=245;
                else PHDat=(50000-adc2)/23.225+246;          



                VolDat=(uint16_t)(adc1*0.01917);                 //μçÑ1¼ÆËã1«ê½y=x£¨yÎaμçÑ1Ö죬xÎaADÖ죩

               
                ADNum=ADNum*0.9+adc3*0.1;
                for(i=0;i<21;i++)
                {
                        if(ADNum<WaterDatNum[i])
                        {
                                break;       
                        }
                }
                if(i==0)
                {
                        WaterDat=0;       
                }else
                {
                        WaterDat=i-1;  //Õûêy2¿·Ö′|àí
                        WaterNum=(float)((ADNum-WaterDatNum[i-1])/(WaterDatNum[i]-WaterDatNum[i-1])*10);//D¡êy2¿·Ö′|àí       
                        WaterDat=(u16)(WaterDat*10+WaterNum-1);
                }


               



                SendNum++;
                if(SendNum>3)
                {
                        SendNum=0;
                        SendString("\r\ndat,");        //à¶Ñà·¢ËíÏμí3êy¾YÏÔê¾
                        if(WaterDat>99)SendData(WaterDat/100%10+0x30);          //ˮλêy¾Y
                        if(WaterDat>9)SendData(WaterDat/10%10+0x30);
                        SendData(WaterDat%10+0x30);
                        SendString(",");

                        if(PHDat>999)SendData(PHDat/1000%10+0x30);         //PH Öμêy¾Y
                        SendData(PHDat/100%10+0x30);
                        SendString(".");
                        SendData(PHDat/10%10+0x30);
                        SendData(PHDat%10+0x30);
                        SendString(",");

                        if(VolDat>999)SendData(VolDat/1000%10+0x30);  //Ïμí31¤×÷μçÑ1êy¾Y
                        SendData(VolDat/100%10+0x30);
                        SendString(".");
                        SendData(VolDat/10%10+0x30);
                        SendData(VolDat%10+0x30);
                        SendString(",ok");

                }
                ShowCode();         //LCD12864  òo¾§ÏÔê¾oˉêy
        }
}
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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