标题:
求17年电赛简易水情检测系统的完整代码,谢谢
[打印本页]
作者:
君莫笑hhh
时间:
2019-4-12 15:00
标题:
求17年电赛简易水情检测系统的完整代码,谢谢
作者:
zxxlw
时间:
2019-5-1 11:16
基于stc15w的oled显示
作者:
小猫要吃鱼
时间:
2019-5-1 13:40
你好!
把你的硬件清单说一下
1、用的什么单片机
2、显示用什么?
3、PH值传感器型号?
4、水位高度测量超声波吗?
5、具体设计和实物制作,看我头像,请注明来自 51黑
作者:
君莫笑hhh
时间:
2019-5-11 09:58
已经解决啦,谢谢啦
作者:
MC_城洛
时间:
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);
}
}
作者:
zhongzl728
时间:
2019-7-28 17:32
楼去解决了吗?可以分享一下吗?
作者:
QDH
时间:
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);
}
}
作者:
怪脾气
时间:
2020-3-27 13:19
君莫笑hhh 发表于 2019-5-11 09:58
已经解决啦,谢谢啦
楼主能共享下原理图吗
作者:
wengjiamin
时间:
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.
作者:
wengjiamin
时间:
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
}
}
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1