標(biāo)題:
求17年電賽簡易水情檢測系統(tǒng)的完整代碼,謝謝
[打印本頁]
作者:
君莫笑hhh
時(shí)間:
2019-4-12 15:00
標(biāo)題:
求17年電賽簡易水情檢測系統(tǒng)的完整代碼,謝謝
作者:
zxxlw
時(shí)間:
2019-5-1 11:16
基于stc15w的oled顯示
作者:
小貓要吃魚
時(shí)間:
2019-5-1 13:40
你好!
把你的硬件清單說一下
1、用的什么單片機(jī)
2、顯示用什么?
3、PH值傳感器型號?
4、水位高度測量超聲波嗎?
5、具體設(shè)計(jì)和實(shí)物制作,看我頭像,請注明來自 51黑
作者:
君莫笑hhh
時(shí)間:
2019-5-11 09:58
已經(jīng)解決啦,謝謝啦
作者:
MC_城洛
時(shí)間:
2019-6-15 19:31
#include <STC15F2K60S2.H>// 包含STC115F2K60S2單片機(jī)寄存器定義文件
#define VCC 5.0 // 存放用萬用表實(shí)測的單片機(jī)供電電壓
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
unsigned int ADvalue; // 存放AD轉(zhuǎn)換返回的結(jié)果
sbit ADC_SCK=P2^6 ;//ADC時(shí)鐘
sbit ADC_DIN= P2^7;//ADC數(shù)據(jù)入
sbit ADC_DOUT=P2^4; //ADC數(shù)據(jù)出
sbit ADC_DBY=P2^5;//ADC準(zhǔn)備
unsigned int channal1;
sbit RS=P0^0; //片選信號 rs CS
sbit RW=P0^1; //數(shù)據(jù)信號 rw SID
sbit E=P0^2; //時(shí)鐘信號 e SCLK
sbit RST=P0^6; //復(fù)位信號
sbit PSB = P0^7; //并行、串行選擇信號 psb CH
sbit c_send = P3^3; //超聲波發(fā)射 t
sbit c_recive = P3^2; //超聲波接收 e
uchar flag_hc_value; //超聲波中間變量
long distance; //距離
uint set_d; //距離
bit flag_csb_juli; //超聲波超出量程
uint flag_time0; //用來保存定時(shí)器0的時(shí)候的
uint time;
/********************************************************************
* 名稱 : delay()
* 功能 : 延時(shí),延時(shí)時(shí)間為 100us * t。這是通過軟件延時(shí),有一定誤差。
* 輸入 : 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)
{
//下面代碼設(shè)置定時(shí)器1
TMOD = 0x20; // 0010 0000 定時(shí)器1工作于方式2(8位自動(dòng)重裝方式)
TH1 = 0xFD; // 波特率:9600 /11.0592MHZ
TL1 = 0xFD; // 波特率:9600 /11.0592MHZ
TR1 = 1;
//下面代碼設(shè)置定串口
AUXR = 0x00; // 很關(guān)鍵,使用定時(shí)器1作為波特率發(fā)生器,S1ST2=0
SCON = 0x50; // 0101 0000 SM0.SM1=01(最普遍的8位通信),REN=1(允許接受)
TI=1; // 很關(guān)鍵,使用printf函數(shù)時(shí)必須有此命令
}
/********************************************************************
* 名稱 : sendbyte()
* 功能 : 按照液晶的串口通信協(xié)議,發(fā)送數(shù)據(jù)
* 輸入 : 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()
* 功能 : 初始化函數(shù)
* 輸入 : 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; //定時(shí)器0、定時(shí)器1工作方式1
ET0 = 1; //開定時(shí)器0中斷
TR0 = 1; //允許定時(shí)器0定時(shí)
}
void send_wave()
{
c_send=1; //啟動(dòng)一次檢測模塊
delay(20);
c_send=0; //停止向檢測模塊Trig端發(fā)送高電平
while(!c_recive); //無回波時(shí)等待
TR0=1; //計(jì)時(shí)開始
while(c_recive); //有回波是計(jì)數(shù)并繼續(xù)等待
TR0=0;
time=TH0*256+TL0;
TH0=0;
TL0=0;
distance=269.05-time*0.191;// 計(jì)算距離,算出來的單位是mm
if(distance<=0)
distance=0;
if(distance>=269.05)
distance=269.05;
}
void ADC_P11_init()
{
unsigned int i; // 用于軟件延時(shí)程序
ADC_CONTR|=0x80; // 開AD轉(zhuǎn)換電源,第一次使用時(shí)要打開內(nèi)部模擬電源
for (i=0;i<10000;i++); // 適當(dāng)延時(shí)等待AD轉(zhuǎn)換供電穩(wěn)定,一般延時(shí)1ms以內(nèi)即可,為了縮短AD
// 調(diào)用時(shí)間,可把這2行剪切到主程序中去。
P1ASF|=0x02; // 選擇P1.1作為AD轉(zhuǎn)換通道,0x02= 0000 0010
ADC_CONTR=0xE1; // 選擇P1.1作為AD轉(zhuǎn)換通道,最高轉(zhuǎn)換速度,清轉(zhuǎn)換完成標(biāo)志。
for (i=0;i<200;i++); // 如果是多通道模擬量進(jìn)行AD轉(zhuǎn)換,則更換AD轉(zhuǎn)換通道后要適當(dāng)延時(shí),
// 使輸入電壓穩(wěn)定,延時(shí)量取20μs~200μs即可,與輸入電壓源的內(nèi)阻有關(guān),如果輸入電壓信號源的內(nèi)
// 阻在10K以下,可不加延時(shí),如果是單通道模擬量轉(zhuǎn)換,則不需要更換AD轉(zhuǎn)換通道,也不需要加延時(shí)。
ADC_CONTR|=0x08; // 啟動(dòng) A/D 轉(zhuǎn)換,ADC_START=1。
EADC=1;
EA=1;
}
void ADC(void) interrupt 5
{
unsigned int AD_Dat=0,AD_Dat1=0; // 10位AD轉(zhuǎn)換值
unsigned char Tmp=0,Tmp1=0; // 臨時(shí)變量用于將AD轉(zhuǎn)換出來的2個(gè)字節(jié)合成一個(gè)字節(jié)
ADC_CONTR&=0xE7; // 將ADC_FLAG清0, 0xE7=1110 0111B,ADC_FLAG=0,ADC_START=0。
AD_Dat = ADC_RES; // 默認(rèn)高字節(jié)高8位。
AD_Dat <<= 2;
Tmp = ADC_RESL; // 默認(rèn)低字節(jié)低2位。
Tmp &= 0x03; // 屏蔽無關(guān)位
AD_Dat|= Tmp; // 高低字節(jié)拼接成一個(gè)10位數(shù)。
ADvalue=AD_Dat;
ADC_CONTR|=0x08; // 重新啟動(dòng) A/D 轉(zhuǎn)換,ADC_START=1。
}
/******向AD7705寫入一個(gè)字節(jié)******/
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讀一個(gè)字節(jié) ******/
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通信端口復(fù)位******/
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,將下一次操作設(shè)為寫時(shí)鐘寄存器
WriteByte7705(0x01);//寫時(shí)鐘寄存器,不分頻,更新頻率25Hz
WriteByte7705(0x10);//寫通信寄存器,選擇通道1
WriteByte7705(0x44);//寫設(shè)置寄存器4,單極性,非緩沖模式,清除濾波器同步,啟動(dòng)對1通道的自校準(zhǔn)
}
/******讀取AD7705通道1轉(zhuǎn)換數(shù)據(jù)函數(shù)******/
unsigned int ReadData1_7705()
{
unsigned int value;
ad7705_init1();
reset7705();
while(ADC_DBY); //等待轉(zhuǎn)換結(jié)束
WriteByte7705(0x38); //寫通信寄存器,下一次操作為讀數(shù)據(jù)寄存器
value=5000*ReadWord7705()/65535;
return value;
}
void main(void)
{
float Vin,N,U; // 存放計(jì)算出來的外部輸入電壓
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("水情檢測系統(tǒng)");
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("當(dāng)前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
時(shí)間:
2019-7-28 17:32
樓去解決了嗎?可以分享一下嗎?
作者:
QDH
時(shí)間:
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);
}
}
作者:
怪脾氣
時(shí)間:
2020-3-27 13:19
君莫笑hhh 發(fā)表于 2019-5-11 09:58
已經(jīng)解決啦,謝謝啦
樓主能共享下原理圖嗎
作者:
wengjiamin
時(shí)間:
2021-1-16 16:30
2017年全國大學(xué)生電子設(shè)計(jì)競賽
簡易水情檢測系統(tǒng)(P 題)
編號:107219
簡易水情檢測系統(tǒng)
摘要:設(shè)計(jì)以STC15F2K60S2單片機(jī)為核心控制處理器,對PH傳感器和液位傳感器及藍(lán)牙模塊進(jìn)行采集運(yùn)算,從而對液體狀態(tài)實(shí)時(shí)監(jiān)測。系統(tǒng)主要由單片機(jī)最小系統(tǒng)、電池組、穩(wěn)壓模塊電路、PH傳感器、液位傳感器、電壓檢測電路、 AD轉(zhuǎn)換電路、12864液晶顯示、藍(lán)牙模塊和手機(jī)APP組成。系統(tǒng)使用PH傳感器對液體進(jìn)行PH檢測,測量精度小于0.09;使用壓力傳感器對水位通過線性關(guān)系測量,測量誤差小于2mm;通過電阻二分法分壓測量電池組端口電壓,測量誤差小于0.01V。水位測量高度值、PH測量值及電池輸出電壓值通過LCD12864及手機(jī)APP同步顯示顯示。為降低系統(tǒng)功耗,手機(jī)APP可開關(guān)液晶背光。通過測試滿足了基本和發(fā)揮部分的大部分要求。
關(guān)鍵詞:藍(lán)牙模塊、PH傳感器、壓力傳感器、手機(jī)APP、最小系統(tǒng)
1 系統(tǒng)方案選擇
1.1.方案比較
主芯片選型
1)采用STC89C51RC做主控芯片,外部高精度晶體/ 時(shí)鐘,內(nèi)部R/C 振蕩器。常溫下內(nèi)部R/C 振蕩器頻率為:5.2MHz ~6.8MHz。
2)采用STC15F2K60S2做為主控芯片,其指令代碼完全兼容傳統(tǒng)80c51,且速度快8-12倍,內(nèi)有可設(shè)定的晶振,無須外接。
系統(tǒng)使用使用高速、可設(shè)晶振頻率芯片更便于程序的書寫,故采用STC15F2K60S2型號芯片為主芯片。
水位傳感器選型
1)水位傳感器采用DS1603L,液位≥50mm時(shí),精度可以達(dá)到0;50mm以下為盲區(qū)不可以測量。
2)水位傳感器采用D3B壓力傳感器,通過液體壓力檢測水位高度,無盲區(qū),可檢測題目要求的200mm以下高度。
水位監(jiān)測不應(yīng)有盲區(qū),盲區(qū)會(huì)影響整體測量結(jié)果。且50mm占整個(gè)任務(wù)要求的1/4,占比太大,故選擇D3B壓力傳感器。
穩(wěn)壓芯片選型
1)穩(wěn)壓芯片采用LM7805,輸入電壓范圍8-12V,壓差最低2V,電池組電壓與單片機(jī)供電電壓壓差為1V左右,穩(wěn)壓芯片本身有壓降,影響輸出準(zhǔn)確值。
2)穩(wěn)壓芯片采用LM1117,輸入電壓范圍1.25-13.8,壓差最低1.2V,電池組電壓與單片機(jī)供電電壓壓差為1V左右,穩(wěn)壓芯片本身有壓降,影響輸出準(zhǔn)確值。
3、穩(wěn)壓芯片采用MIC29302,電壓壓差為0.37V,且輸出穩(wěn)定。
AD監(jiān)測需用基準(zhǔn)電壓,應(yīng)穩(wěn)定輸入電壓,且干電池耗電太快,應(yīng)選擇壓差最小的穩(wěn)壓芯片,故選擇MIC29302穩(wěn)壓芯片。
1.2.方案描述
水情監(jiān)測系統(tǒng),以STC15F2K60S2單片機(jī)作為控制核心,通過16位AD轉(zhuǎn)換測量供電電池的輸出電壓、PH值、水位。數(shù)據(jù)通過串口在12864液晶模塊實(shí)時(shí)顯示,同時(shí)通過藍(lán)牙模塊與手機(jī)APP連接實(shí)時(shí)顯示數(shù)據(jù)且可通過手機(jī)APP控制液晶背光的開關(guān)。
系統(tǒng)方案框圖如圖1所示。
圖1 系統(tǒng)方案框圖
2 系統(tǒng)設(shè)計(jì)與論證
2.1傳感器信號處理方法分析
1)PH檢測信號由雷磁E-201-C型號PH傳感器采集,由7705型號16位AD模塊模數(shù)轉(zhuǎn)換,轉(zhuǎn)換結(jié)果經(jīng)處理器分析,通過串口發(fā)送至電腦,計(jì)算其所呈現(xiàn)的線性關(guān)系,得出線性方程。數(shù)據(jù)結(jié)果由公式計(jì)算得出并顯示。
2)水位監(jiān)測信號由日本松下旗下壓力傳感器采集,由7705型號16位AD模塊模數(shù)轉(zhuǎn)換,轉(zhuǎn)換結(jié)果經(jīng)處理器分析,通過串口發(fā)送至電腦,數(shù)據(jù)計(jì)算發(fā)現(xiàn),數(shù)據(jù)不呈現(xiàn)線性關(guān)系,故采集多組數(shù)據(jù)輸入為數(shù)組,結(jié)果采用查表法計(jì)算。
2.2電壓檢測方法分析
加兩個(gè)精度為千分之一的10K精密電阻,采用二分法進(jìn)行分壓測量,以提高準(zhǔn)確度,通過AD采集、單片機(jī)處理計(jì)算并顯示。
3 電路與程序設(shè)計(jì)
3.1系統(tǒng)組成
水情監(jiān)測系統(tǒng)組成包括6V電池組、穩(wěn)壓芯片MIC29302、STC15F2K60S2單片機(jī)、PH監(jiān)測模塊、壓力傳感器水位監(jiān)測模塊、16位AD模塊、12864液晶顯示模塊及藍(lán)牙模塊。
3.2硬件電路設(shè)計(jì)
1)穩(wěn)壓及12864顯示模塊如圖2所示:
圖2穩(wěn)壓及12864顯示模塊
2)AD轉(zhuǎn)換模塊如圖3所示:
圖3 AD轉(zhuǎn)換模塊
PH模塊、壓力傳感器模塊、藍(lán)牙模塊如圖3所示:
圖3 PH模塊、壓力傳感器模塊、藍(lán)牙模塊
3.3軟件系統(tǒng)設(shè)計(jì)
根據(jù)題目要求,使用12864顯示模塊進(jìn)行數(shù)據(jù)顯示;水位測量偏差不大于2mm,PH測量偏差不大于0.1,電壓測量偏差不大于0.01。因精度要求高,程序需做濾波處理以提高精度。同時(shí)通過藍(lán)牙將數(shù)據(jù)發(fā)送至手機(jī)APP實(shí)時(shí)顯示。且為降低系統(tǒng)功耗可通過手機(jī)APP進(jìn)行開關(guān)液晶背光。軟件設(shè)計(jì)流程圖如圖4所示。
圖4 軟件設(shè)計(jì)流程圖
4、測試結(jié)果及分析
4.1測試數(shù)據(jù)完整性
表1 水位高度測試結(jié)果分析表
次數(shù) 第一次 第二次 第三次 第四次 第五次
測量水位高度/mm 30 65 99 120 170
實(shí)際水位高度/mm 31 64 99 121 170
誤差/mm 1 1 0 1 0
表2 PH值測試結(jié)果分析表
次數(shù) 第一次 第二次 第三次 第四次 第五次
測量PH值 6.86 5.42 5.08 4.56 3.89
實(shí)際PH值 6.79 5.39 5.10 4.50 3.85
誤差 0.07 0.03 0.02 0.06 0.04
表 3 電池電壓值測試結(jié)果分析表
次數(shù) 第一次 第二次 第三次 第四次 第五次
測量電池電壓/V 5.99 5.95 5.85 5.80 5.75
實(shí)際電池電壓/V 5.99 5.96 5.85 5.81 5.75
誤差/V 0.00 0.01 0.00 0.01 0.00
4.2測試結(jié)果分析
由水位高度測試結(jié)果分析表,發(fā)現(xiàn)水位測量結(jié)果不沒有良好的線性關(guān)系,但可使用查表法進(jìn)行誤差調(diào)節(jié),以滿足任務(wù)要求;
由PH值測試結(jié)果分析表,發(fā)現(xiàn)其呈現(xiàn)良好的線性關(guān)系,且誤差滿足任務(wù)要求;
電壓值基本無誤差,滿足任務(wù)要求
總結(jié)
系統(tǒng)主要用STC15F2K60S2作為核心,檢測PH、壓力傳感器上的電壓變化,送給單片機(jī)內(nèi)部,通過16位AD處理信號,整個(gè)系統(tǒng)由各個(gè)電路模塊搭建而成,這樣便于了解系統(tǒng),系統(tǒng)出錯(cuò)時(shí)方便找出問題所在,系統(tǒng)帶有手機(jī)APP,可實(shí)時(shí)同步LCD12864顯示數(shù)據(jù)且可控制顯示背光的開關(guān)。軟件方面增加濾波,以提高檢測精度,整個(gè)系統(tǒng)運(yùn)行穩(wěn)定,可靠。
參考文獻(xiàn)
[1] 甕嘉民.單片機(jī)應(yīng)用開發(fā)技術(shù)[M].北京:中國電力出版社,2010:215-223.
[2] 楊欽.電路設(shè)計(jì)與仿真[M].北京:清華大學(xué)出版社,2006:103-111.
[3] 馬忠梅,劉濱.單片機(jī)C語言Windows環(huán)境編程寶典.北京:北京航空航天大學(xué)出版社,2002:79-83.
作者:
wengjiamin
時(shí)間:
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.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1