0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何制作一個基于單片機的自動澆花系統(tǒng)

h1654155282.3538 ? 來源:電子報 ? 作者:h1654155268.1688 ? 2021-06-12 17:54 ? 次閱讀

生活中,人工澆灌花木要耗費大量時間,而且土壤濕度不好控制,有時候由于主人長時間外出,家里的花木會因無人澆水而枯死。為了解決上述問題,本文利用單片機,設(shè)計了自動和手動澆花系統(tǒng)(如圖1所示)。

圖1 自動澆花系統(tǒng)

一、功能描述

系統(tǒng)有自動和手動兩種工作模式,兩種工作模式由手自動切換按鍵切換。系統(tǒng)開機進(jìn)行自檢,如果系統(tǒng)有故障則報警,若系統(tǒng)工作正常則進(jìn)入自動狀態(tài),初始設(shè)定值為25%。當(dāng)土壤濕度小于設(shè)定值時水泵工作澆水,當(dāng)高于設(shè)定值加上偏移量(偏移量可根據(jù)實際確定,本文設(shè)為2)時系統(tǒng)停止加水。在自動工作模式下,如果由于缺水、加水不能停止或是測量信號不正常,則系統(tǒng)報警,水泵停止加水。在手動工作模式下,可按加水鍵和停止鍵實現(xiàn)手動加水和停止。背光按鍵控制液晶背光的開關(guān)。電路成品如圖2所示。

圖2 自動澆花系統(tǒng)電路板

二、硬件系統(tǒng)設(shè)計

(一)硬件系統(tǒng)構(gòu)成

系統(tǒng)選擇的各種元器件都是目前市面上常見的,系統(tǒng)核心控制器件采用應(yīng)用廣泛的STC公司的STC89C52RC單片機。除了單片機外,還包括土壤濕度傳感器、AD轉(zhuǎn)化器、LCD1602液晶顯示器、按鍵、指示燈、蜂鳴器、繼電器及水泵等。

(二)電路工作原理

pYYBAGC97QWAQZvXAAEGhu4PQpM462.png

電路原理圖見圖3,包括電源電路、晶振和復(fù)位電路、檢測電路、按鍵和顯示電路、報警電路、輸出控制電路

1.電源電路

系統(tǒng)所需5V電源由外部直接提供,可由常見的各種手機充電器提供,留有USB電源端子和圓形端子跟外部電源連接,使用時連接其中之一,另外一個可以向外提供5V電源,方便系統(tǒng)電源連接。

2.晶振和復(fù)位電路

電容器C6、C7和晶振Y1構(gòu)成振蕩電路,給單片機提供所需的時鐘。C8、R13和按鍵RST1構(gòu)成單片機復(fù)位電路,實現(xiàn)上電復(fù)位和手動復(fù)位。

3.檢測電路

檢測電路由土壤濕度傳感器和AD轉(zhuǎn)換器組成,選擇價格便宜且使用方便的土壤濕度傳感器模塊和AD轉(zhuǎn)換器PCF8591模塊(見圖4)。該模塊有4路輸入、1路輸出,可滿足系統(tǒng)擴展需要。此電路把土壤濕度轉(zhuǎn)換成模擬量,經(jīng)AD轉(zhuǎn)換后轉(zhuǎn)換成單片機可以識別的對應(yīng)數(shù)字量。

圖4 土壤濕度傳感器和AD轉(zhuǎn)換模塊

4.按鍵和顯示電路

按鍵和顯示電路由四個獨立按鍵、LED指示燈和LCD1602構(gòu)成,用于人機操作和系統(tǒng)各種工作狀態(tài)的信息顯示。

5.報警電路

報警電路由蜂鳴器和LED指示燈構(gòu)成,實現(xiàn)聲光報警。聲音報警15次后停止,LED指示燈一直閃爍報警。

6.輸出控制電路

單片機引腳輸出信號通過驅(qū)動電路驅(qū)動繼電器,控制繼電器的通斷,用以驅(qū)動執(zhí)行元件(文中為5V直流水泵)的通斷,LED指示燈顯示輸出狀態(tài)。

三、軟件系統(tǒng)設(shè)計

(一)系統(tǒng)流程圖(見圖5)

poYBAGC97RaAYVysAADAIBDWEKA547.png

(二)系統(tǒng)軟件設(shè)計

系統(tǒng)采用項目化多文件,模塊化編程,便于程序編寫和程序移植。由main.c,I2C.c,KEYBOARD.C,Lcd1602.c文件和對應(yīng)頭文件以及配置文件config.h組成。Lcd1602.c主要負(fù)責(zé)液晶的底層顯示驅(qū)動。I2C.c主要負(fù)責(zé)AD轉(zhuǎn)化器的底層功能驅(qū)動。KEYBOARD.C責(zé)按鍵處理,main.c負(fù)責(zé)系統(tǒng)初始化,自檢,土壤濕度檢測,中值濾波和信號線性化處理,手動自動程序運行。中斷程序負(fù)責(zé),系統(tǒng)運行時的故障處理和報警,程序較短,也放在main.c中。整個項目,軟件按流程圖編寫,結(jié)構(gòu)清晰,流程也比較清楚。為方便讀者學(xué)習(xí)和參考,把所有文件和程序都列了出來,并做了詳細(xì)的注釋。

整個項目的軟件按流程圖編寫即可,程序代碼如下(注意報紙因為版面原因,無法全部刊登,這里可以看到完整的代碼)。

參考程序

/***************************************

config.h

**************************************/

#ifndef _CONFIG_H

#define _CONFIG_H

/*通用頭文件*/

#include《reg52.h》

#include《intrins.h》

#define ON 0

#define OFF 1

#define OFFSET 2 //上下限偏差

/*數(shù)據(jù)類型定義*/

typedef unsigned char uchar ;//8位無符號數(shù)

typedef unsigned int uint ;//8位無符號數(shù)

/*IO引腳分配定義*/

sbit AK_KEY=P1^0;//背光控制

sbit UP_KEY=P1^1; //增加_啟動

sbit DN_KEY=P1^2;//減小_停止

sbit MA_KEY=P1^3;//手動_自動

sbit ALARM_LED=P1^4;//故障指示

sbit PUMP_LED=P1^5;//抽水指示

sbit MANUAL_LED=P1^6;//手動指示

sbit AUTO_LED=P1^7;//自動指示

sbit PUMP=P2^2;//水泵控制

sbit BUZZER=P2^3;//蜂鳴器報警

#define LCD1602_DB P0 //1602液晶數(shù)據(jù)口

sbit LCD1602_RS=P2^7; //1602液晶數(shù)據(jù)_指令選擇

sbit LCD1602_RW=P2^6; //1602液晶讀寫選擇

sbit LCD1602_E=P2^5; //1602液晶使能信號

sbit LCD1602_AK=P2^4; //1602液晶背光信號

sbit I2C_SCL=P2^1;//AD轉(zhuǎn)換器

sbit I2C_SDA=P2^0;

#endif

/***************************************

MAIN.H

***************************************/

#ifndef _MAIN_H

#define _MAIN_H

enum eStaSystem //系統(tǒng)運行狀態(tài)枚舉

{

E_AUTO,E_MANUAL,E_ALARM

}; //設(shè)置,自動,手動,故障報警

#ifndef _MAIN_C

extern enum eStaSystem staSystem;

#endif

void delayms(unsigned int t);//延時函數(shù)

void SysInit();//系統(tǒng)初始化

void SelfCheck();//系統(tǒng)自檢

void AutoWork();//系統(tǒng)自動運行

void ShowLcd1602();//測量、狀態(tài)顯示

void Humidity();//土壤濕度檢測

unsigned char GetADCValue(unsigned char chn); //AD轉(zhuǎn)換

void ConfigTimer0(unsigned int ms); //T0 配置函數(shù)

#endif

/***************************************

main.c

***************************************/

#define _MAIN_C

#include“config.h”

#include “main.h”

#include “Keyboard.h”

#include “I2C.h”

#include “Lcd1602.h”

#define N 3 //AD采樣次數(shù)

#define OFFSET 2//上限偏移量

enum eStaSystem staSystem=E_AUTO;//初始為自動狀態(tài)

unsigned char T0RH=0; //定時器T0載值

unsigned char T0RL=0;

unsigned char TestVal;//測量值

unsigned char cnt; //蜂鳴器報警15次

//----------------------------------------------------------------------------------

void main ()

{

SysInit();

SelfCheck();

while(1)

{

KeyAction();

AutoWork();

}

}

/****************************************

函數(shù)功能:系統(tǒng)初始化

入口參數(shù):無

*****************************************/

void SysInit()

{

AK_KEY=OFF;//按鍵IO口初始化

UP_KEY=OFF;//

DN_KEY=OFF;

MA_KEY=OFF;

ALARM_LED=OFF;//指示燈熄滅

PUMP_LED=OFF;

MANUAL_LED=OFF;

AUTO_LED=OFF;

BUZZER=OFF;//關(guān)蜂鳴器

PUMP=OFF;//關(guān)水泵

LcdInit(); // 初始化液晶

LcdShowStr(0,0, “-Auto watering- ”); // 顯示系統(tǒng)自檢

LcdShowStr(1,1, “system testing”); //

ConfigTimer0(10); // 配置T0 定時10ms

EA=0;// 關(guān)中斷

}

/****************************************

函數(shù)功能:系統(tǒng)自動運行,故障報警

入口參數(shù):無

*****************************************/

void AutoWork()

{

if(staSystem==E_AUTO)

{

Humidity();

AUTO_LED=ON;

MANUAL_LED=OFF;

if(TestVal》96||TestVal《5)

{

staSystem=E_ALARM;

cnt=30;

EA=1;

}//故障

elseif(TestVal《SetVal)

{

PUMP=ON;

PUMP_LED=ON;

}

elseif(TestVal》(SetVal+OFFSET))

{

PUMP=OFF;PUMP_LED=OFF;

}

}

ShowLcd1602();//更新顯示

}

/****************************************

函數(shù)功能:系統(tǒng)自檢,故障報警

入口參數(shù):無

*****************************************/

void SelfCheck()

{

unsignedchar i,k,n;

unsignedchar temp;

for(i=0;i《3;i++)

{

ALARM_LED=ON;

PUMP_LED=ON;//抽水指示

MANUAL_LED=ON;//手動指示

AUTO_LED=ON;//自動指示

delayms(500);

ALARM_LED=OFF;

PUMP_LED=OFF;//抽水指示

MANUAL_LED=OFF;//手動指示

AUTO_LED=OFF;//自動指示

delayms(500);

}

BUZZER=ON;

delayms(500);

BUZZER=OFF;

LcdClearScreen();

LcdShowStr(0,0,“Test Results:”);

for(i=0;i《4;i++)//讀取3次測量結(jié)果,過高故障報警

{

temp=GetADCValue(3);//直接讀取0通道

if(temp》240||temp《10)k++;

}

if(k》2)//自檢故障

{

EA=0;//關(guān)中斷

while(1)

{

ALARM_LED=ON;

LcdShowStr(1,10,“ERROR!”);

delayms(550);

LcdShowStr(1,10,“ ”);

ALARM_LED=OFF;

delayms(250);

if(n++《3)BUZZER=!BUZZER;

elseBUZZER=OFF;

}

}

LcdClearScreen();

}

/****************************************

函數(shù)功能:測量、狀態(tài)顯示

入口參數(shù):無

*****************************************/

void ShowLcd1602()

{

LcdShowStr(0,0,“PV:”);

ShowNum(0,3,TestVal);//顯示實測值

LcdShowStr(0,6,“%RH”);

LcdShowStr(0,10,“State:”);

LcdShowStr(1,0,“SV:”);

ShowNum(1,3,SetVal);//顯示設(shè)定值

LcdShowStr(1,6,“%RH”);

if(staSystem==E_AUTO)LcdShowStr(1,10,“ Auto ”);

elseif(staSystem==E_MANUAL) LcdShowStr(1,10,“Manual”);

}

/**********************************************

函數(shù)功能:讀取當(dāng)前的ADC 轉(zhuǎn)換值

入口參數(shù):chn,AD通道號0-3

**********************************************/

unsigned char GetADCValue(unsigned charchn)

{

ucharval;

I2CStart();

if(!I2CWrite(0x48《《1)) // 尋址PCF8591 PCF8591,如未應(yīng)答,則停止操作并返回,00

{

I2CStop();

return0;

}

I2CWrite(0x40|chn);// 寫入控制字節(jié),選擇轉(zhuǎn)換通道

I2CStart();

I2CWrite((0x48《《1)|0x01);// 尋址PCF8591 PCF8591,指定后續(xù)為讀操作

I2CReadACK();// 先空讀一個字節(jié),提供采樣轉(zhuǎn)換時間

val= I2CReadNAK(); // 讀取剛剛轉(zhuǎn)換完的值

I2CStop();

returnval;

}

/****************************************

函數(shù)功能:按升序排列數(shù)組元素

入口參數(shù):數(shù)組及數(shù)組長度

*****************************************/

void SortArray(unsigned char a[],unsignedchar a_len)

{

unsignedchar i,temp;

for(i=1;i《a_len;i++)

{

if(a[i-1]》a[i])

{

temp=a[i-1];

a[i-1]=a[i];

a[i]=temp;

i=0;

}

}

}

/****************************************

函數(shù)功能:中值濾波,線性轉(zhuǎn)換后,獲得土

壤濕度0-100%

入口參數(shù):無

*****************************************/

void Humidity()

{

unsigned char i, tmp;

unsigned char adBuf[N];

for(i=0;i《N;i++)adBuf[i]=GetADCValue(1);//讀取濕度

SortArray(adBuf,sizeof(adBuf));

tmp=adBuf[N/2];

tmp=GetADCValue(3);

TestVal=100-100.*tmp/255;

}

/****************************************

函數(shù)功能:配置定時器0,定時時間

壤濕度0-100

入口參數(shù):ms,定時時間(毫秒)

****************************************/

void ConfigTimer0(unsigned int ms)

{

unsigned long tmp;

tmp = 11059200 /12; // 定時器計數(shù)頻率

tmp = (tmp * ms) /1000; // 計算所需的計數(shù)值

tmp = 65536 - tmp; // 計算定時器重載值

tmp = tmp + 12; // 修正中斷響應(yīng)延時造成的誤差

T0RH = (unsigned char)(tmp 》》 8); // 定時器重載值拆分為高低字節(jié)

T0RL = (unsigned char)tmp;

TMOD &= 0xF0; // 清零T0 的控制位

TMOD |= 0x01; // 配置T0 為模式11

TH0 = T0RH; // 加載T0 重載值

TL0 = T0RL;

ET0 = 1; // 使能T0 中斷

TR0 = 1; // 啟動T0

}

/****************************************

函數(shù)功能:延時函數(shù)

入口參數(shù):t,延時約t毫秒

****************************************/

//---------延時----------------

void delayms(uint t)

{

uchari;

while(t--)

for(i=0;i《123;i++);

}

/****************************************

函數(shù)功能:T0 中斷服務(wù)函數(shù)

入口參數(shù):無

****************************************/

void InterruptTimer0() interrupt 1

{

static unsigned char tmrms=0;

static unsigned char tmr=0;

TH0 = T0RH; // 定時器重新加載重載值

TL0 = T0RL;

tmrms++;

tmr=(tmr+1)%100;

if(staSystem==E_ALARM) //故障液晶報警顯示

{

if(tmr《50)LcdShowStr(1,11, “ALARM ”);

elseLcdShowStr(1,11, “ ”);

if(tmrms》=50) // 定時0.5s

{

tmrms=0;

ALARM_LED=!ALARM_LED;

if(cnt》0){cnt--;BUZZER=!BUZZER;}

else{BUZZER=OFF;}

}

}

else

{

ALARM_LED=OFF;

BUZZER=OFF;

}

}

/***************************************

Lcd1602.h

***************************************/

#ifndef _LCD1602_H

#define _LCD1602_H

#ifndef _LCD1602_C

#endif

void LcdWaitReady(); //讀取“忙”表示,等待液晶準(zhǔn)備好

void LcdWriteCmd(unsigned char cmd);//給液晶發(fā)送命令cmd

void LcdWriteDat(unsigned char dat); //寫入數(shù)據(jù)函數(shù)

void LcdClearScreen();//液晶清屏

void LcdInit(); //液晶初始化函數(shù)

void CursorPos(unsigned char row,unsignedchar col);//光標(biāo)定位

void ShowNum(unsigned char row,unsignedchar col,unsigned char Num);//顯示3位數(shù)

void LcdShowStr(unsigned char row, unsignedchar col,unsigned char code *str); //顯示字符串

#endif

/***************************************

Lcd1602.c

***************************************/

#define _LCD1602_C

#include“config.h”

#include“Lcd1602.h”

/********************************************

函數(shù)功能:判斷液晶模塊忙碌狀態(tài)。忙,等待。

入口參數(shù):無。

********************************************/

void LcdWaitReady() //讀取“忙”表示,等待液晶準(zhǔn)備好

{

unsigned char sta;

LCD1602_DB = 0xFF;

LCD1602_RS = 0;

LCD1602_RW = 1;

do// do.。.while 循環(huán)語句

{

LCD1602_E= 1;

sta= LCD1602_DB; //讀取狀態(tài)字

LCD1602_E= 0; //讀完了要關(guān)閉使能,防止液晶輸出數(shù)據(jù)干擾總線

}while (sta & 0x80); //bit7 等于1 表示液晶正忙,重復(fù)檢測直到其等于0 為止

}

/************************************************

函數(shù)功能:給液晶發(fā)送命令

入口參數(shù):cmd

**************************************************/

void LcdWriteCmd(unsigned char cmd)

{

LcdWaitReady();

LCD1602_RS = 0;

LCD1602_RW = 0;

LCD1602_DB = cmd;

LCD1602_E = 1;

LCD1602_E = 0;

}

/************************************************

函數(shù)功能:給液晶發(fā)送數(shù)據(jù)

入口參數(shù):dat

**************************************************/

void LcdWriteDat(unsigned char dat) //寫入數(shù)據(jù)函數(shù)

{

LcdWaitReady();

LCD1602_RS = 1;

LCD1602_RW = 0;

LCD1602_DB = dat;

LCD1602_E = 1;

LCD1602_E = 0;

}

/************************************************

函數(shù)功能:清屏

入口參數(shù):無

**************************************************/

void LcdClearScreen()

{

LcdWriteCmd(0x01);

}

/************************************************

函數(shù)功能:液晶初始化

入口參數(shù):無

**************************************************/

void LcdInit() //液晶初始化函數(shù)

{

LcdWriteCmd(0x38); //16*2 顯示,5*7 點陣,8 位數(shù)據(jù)接口

LcdWriteCmd(0x0C); //顯示器開,光標(biāo)關(guān)閉

LcdWriteCmd(0x06); //文字不動,地址自動加1

LcdWriteCmd(0x01); //清屏

}

/************************************************

函數(shù)功能:定位光標(biāo)

入口參數(shù):row行位置,col列位置

**************************************************/

void CursorPos(unsigned char row,unsignedchar col)

{

row%=2; col%=40; //防止越界

if(row)LcdWriteCmd(0xC0+col); //第2行

elseLcdWriteCmd(0x80+col); //第1行

}

/************************************************

函數(shù)功能:顯示3位數(shù)

入口參數(shù):row行位置,col列位置,Num顯示數(shù)據(jù)

**************************************************/

void ShowNum(unsigned char row,unsignedchar col,unsigned char Num)

{

row%=2; col%=40; //防止越界

LcdWriteCmd(0x80+row*0x40+col);//光標(biāo)定位

if(Num《10)

{

LcdWriteDat(‘’); //百位

LcdWriteDat(‘’);//十位

LcdWriteDat(Num%10+‘0’);//個位

}

elseif(Num《100)

{

LcdWriteDat(‘’); //百位

LcdWriteDat(Num/10%10+‘0’); //十位

LcdWriteDat(Num%10+‘0’); //個位

}

else

{

LcdWriteDat(Num/100+‘0’); //百位

LcdWriteDat(Num/10%10+‘0’); //十位

LcdWriteDat(Num%10+‘0’); //個位

}

}

/************************************************

函數(shù)功能:在給定位置顯示字符串

入口參數(shù):row行位置,col列位置,str字符串

**************************************************/

void LcdShowStr(unsigned char row, unsignedchar col, unsigned char code *str) //顯示字符

{

uchari=0;

row%=2;col%=40; //防止越界

LcdWriteCmd(0x80+row*0x40+col);//光標(biāo)定位

for(;col《40&&str[i]!=0;i++,col++){LcdWriteDat(str[i]);}

}

/***************************************

I2C.h

***************************************/

#ifndef _I2C_H

#define _I2C_H

#ifndef _I2C_C

#endif

void I2CStart(); // 產(chǎn)生總線起始信號

void I2CStop(); // 產(chǎn)生總線停止信號

bit I2CWrite(unsigned char dat); //I2C 總線寫操作,待寫入字節(jié)dat dat,返回值為應(yīng)答狀態(tài)

bit I2CWrite(unsigned char dat); //I2C 總線寫操作,待寫入字節(jié)dat dat,返回值為應(yīng)答狀態(tài)

unsigned char I2CReadACK(); //I2C 總線讀操作,并發(fā)送應(yīng)答信號,返回值為讀到的字節(jié)

unsigned char I2CReadNAK();

#endif

/***************************************

I2C.c

***************************************/

#define _I2C_C

#include “config.h”

#include “I2C.h”

#define I2CDelay(){_nop_();_nop_();_nop_();_nop_();}

/********************************************

函數(shù)功能:產(chǎn)生總線起始信號。

入口參數(shù):無。

********************************************/

void I2CStart()

{

I2C_SDA = 1; //首先確保SDA、SCL 都是高電平

I2C_SCL = 1;

I2CDelay();

I2C_SDA = 0; //先拉低SDA

I2CDelay();

I2C_SCL = 0; //再拉低SCL

}

/********************************************

函數(shù)功能:產(chǎn)生總線停止信號。

入口參數(shù):無。

********************************************/

voidI2CStop()

{

I2C_SCL = 0; //首先確保SDA、SCL 都是低電平

I2C_SDA = 0;

I2CDelay();

I2C_SCL = 1; //先拉高SCL

I2CDelay();

I2C_SDA = 1; //再拉高SDA

I2CDelay();

}

/********************************************

函數(shù)功能:I2C 總線寫操作,返回值為應(yīng)答狀態(tài)。

入口參數(shù):待寫入字節(jié)dat。

********************************************/

bit I2CWrite(unsigned char dat)

{

bit ack; //用于暫存應(yīng)答位的值

unsigned char mask; //用于探測字節(jié)內(nèi)某一位值的掩碼變量

for (mask=0x80; mask!=0; mask》》=1) //從高位到低位依次進(jìn)行

{

if ((mask&dat) == 0) //該位的值輸出到SDA 上

I2C_SDA = 0;

else

I2C_SDA = 1;

I2CDelay();

I2C_SCL = 1; //拉高SCL

I2CDelay();

I2C_SCL = 0; //再拉低SCL,完成一個位周期

}

I2C_SDA = 1; //8 位數(shù)據(jù)發(fā)送完后,主機釋放SDA,以檢測從機應(yīng)答

I2CDelay();

I2C_SCL = 1; //拉高SCL

ack = I2C_SDA; //讀取此時的SDA 值,即為從機的應(yīng)答值

I2CDelay();

I2C_SCL = 0; //再拉低SCL 完成應(yīng)答位,并保持住總線

return (~ack); //應(yīng)答值取反以符合通常的邏輯:0=不存在或忙或?qū)懭胧。?=存在且空閑或?qū)懭氤晒?/p>

}

/********************************************

函數(shù)功能:I2C 總線讀操作,并發(fā)送非應(yīng)答信號,

返回值為讀到的字節(jié)。

入口參數(shù):無。

********************************************/

unsigned char I2CReadNAK()

{

unsigned char mask;

unsigned char dat;

I2C_SDA = 1; //首先確保主機釋放SDA

for (mask=0x80; mask!=0; mask》》=1) //從高位到低位依次進(jìn)行

{

I2CDelay();

I2C_SCL = 1; //拉高SCL

if(I2C_SDA == 0) //讀取SDA 的值

dat &= ~mask; //為0 時,dat 中對應(yīng)位清零

else

dat |= mask; //為1 時,dat 中對應(yīng)位置1

I2CDelay();

I2C_SCL = 0; //再拉低SCL,以使從機發(fā)送出下一位

}

I2C_SDA = 1; //8 位數(shù)據(jù)發(fā)送完后,拉高SDA,發(fā)送非應(yīng)答信號

I2CDelay();

I2C_SCL = 1; //拉高SCL

I2CDelay();

I2C_SCL = 0; //再拉低SCL 完成非應(yīng)答位,并保持住總線

return dat;

}

/********************************************

函數(shù)功能:I2C 總線讀操作,并發(fā)送應(yīng)答信號,

返回值為讀到的字節(jié)。

入口參數(shù):無。

********************************************/

unsigned char I2CReadACK()

{

unsigned char mask;

unsigned char dat;

I2C_SDA = 1; //首先確保主機釋放SDA

for (mask=0x80; mask!=0; mask》》=1) //從高位到低位依次進(jìn)行

{

I2CDelay();

I2C_SCL = 1; //拉高SCL

if(I2C_SDA == 0) //讀取SDA 的值

dat &= ~mask; //為0 時,dat 中對應(yīng)位清零

else

dat |= mask; //為1 時,dat 中對應(yīng)位置1

I2CDelay();

I2C_SCL = 0; //再拉低SCL,以使從機發(fā)送出下一位

}

I2C_SDA = 0; //8 位數(shù)據(jù)發(fā)送完后,拉低SDA,發(fā)送應(yīng)答信號

I2CDelay();

I2C_SCL = 1; //拉高SCL

I2CDelay();

I2C_SCL = 0; //再拉低SCL 完成應(yīng)答位,并保持住總線

return dat;

}/***************************************

Keyboard.h

***************************************/

#ifndef _KEY_BOARD_H

#define _KEY_BOARD_H

#ifndef _KEY_BOARD_C

extern unsigned char SetVal;

#endif

void KeyAction();//按鍵處理,手動運行

#endif

/***************************************

KEYBOARD.C

***************************************/

#define _KEY_BOARD_C

#include “config.h”

#include “keyboard.h”

#include “Lcd1602.h”

#include “main.h”

unsigned char SetVal=25;//設(shè)定初始值

/****************************************

函數(shù)功能:按鍵處理,手動運行

入口參數(shù):無

*****************************************/

void KeyAction()

{

if(AK_KEY==0)//LCD1602背光控制

{

delayms(10);

if(AK_KEY==0)

{

LCD1602_AK=!LCD1602_AK;

while(!AK_KEY);

}

}

if(MA_KEY==0)

{

delayms(10);

if(MA_KEY==0)

{

if(staSystem==E_AUTO)

{

staSystem=E_MANUAL;

AUTO_LED=OFF;

MANUAL_LED=ON;

}

elseif(staSystem==E_MANUAL)

{

staSystem=E_AUTO;

AUTO_LED=ON;

MANUAL_LED=OFF;

}

while(!MA_KEY);

}

}

if(staSystem==E_MANUAL)//手動工作狀態(tài)

{

if(UP_KEY==0){PUMP=ON;PUMP_LED=ON;}//手動開

elseif(DN_KEY==0){PUMP=OFF;PUMP_LED=OFF;}//手動關(guān)}

}

elseif(staSystem==E_AUTO)//自動狀態(tài)

{

if(UP_KEY==0)

{

delayms(10);

if(UP_KEY==0)

{

if(SetVal《100) SetVal++; //設(shè)置+

while(!UP_KEY);

}

}

if(DN_KEY==0)

{

delayms(10);

if(DN_KEY==0)

{

if(SetVal》0) SetVal--; //設(shè)置-

while(!DN_KEY);

}

}

}

}
責(zé)任編輯人:CC

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 單片機
    +關(guān)注

    關(guān)注

    6040

    文章

    44594

    瀏覽量

    636941
收藏 人收藏

    評論

    相關(guān)推薦

    怎樣去設(shè)計種基于單片機的士壤濕度檢測自動澆花系統(tǒng)

    單片機土壤濕度檢測自動澆花系統(tǒng)是由哪些部分組成的?單片機土壤濕度檢測自動
    發(fā)表于 07-01 07:05

    怎么實現(xiàn)基于51單片機的智能大棚澆花系統(tǒng)的設(shè)計?

    怎么實現(xiàn)基于51單片機的智能大棚澆花系統(tǒng)的設(shè)計?
    發(fā)表于 10-13 08:50

    基于51單片機自動澆花系統(tǒng)設(shè)計

    51單片機自動澆水系統(tǒng)/51單片機自動澆花系統(tǒng)整個設(shè)
    發(fā)表于 11-18 08:27

    如何去實現(xiàn)基于單片機的智能澆花系統(tǒng)設(shè)計

    智能澆花系統(tǒng)選擇AT89C51單片機最小系統(tǒng)作為整體控制芯片。該系統(tǒng)功能為對土壤溫度值與濕度值進(jìn)行實時監(jiān)測,并及時控制土壤中溫度值與濕度值。
    發(fā)表于 11-19 06:33

    如何去實現(xiàn)基于單片機自動澆花灌溉系統(tǒng)設(shè)計

    文章目錄1 簡介2 主要器件3 實現(xiàn)效果4 設(shè)計原理5 最后1 簡介Hi,大家好,這里是丹成學(xué)長,今天向大家介紹學(xué)長做的單片機項目基于單片機
    發(fā)表于 11-19 06:52

    如何去實現(xiàn)基于單片機自動澆花灌溉系統(tǒng)設(shè)計

    社會在不斷進(jìn)步,上班、出差、旅游也成了人們生活的部分,這就會導(dǎo)致人們沒有時間去看護(hù)這些花草。對此問題,我們不禁會想到:如果有人能幫我們澆灌那該有多好!對于這樣的想法,我們能聯(lián)想的就是“自動澆花
    發(fā)表于 11-25 06:42

    如何使用單片機進(jìn)行智能澆花系統(tǒng)的設(shè)計與實現(xiàn)的資料說明

    本文基于 STC12C5A60S2 單片機和傳感器技術(shù)設(shè)計實現(xiàn)了款智能澆花系統(tǒng),它的主要功能是為植物定時定量地澆水,通過濕度傳感器實時監(jiān)控土壤濕度,基于
    發(fā)表于 04-29 08:00 ?15次下載
    如何使用<b class='flag-5'>單片機</b>進(jìn)行智能<b class='flag-5'>澆花</b><b class='flag-5'>系統(tǒng)</b>的設(shè)計與實現(xiàn)的資料說明

    使用單片機設(shè)計士壤濕度檢測自動澆花系統(tǒng)的資料說明

    基于51單片機澆花系統(tǒng),可進(jìn)行濕度顯示,按鍵設(shè)置濕度上下限從而自動澆水,包含原理圖,程序代碼,pcb圖以及論文
    發(fā)表于 04-24 08:00 ?14次下載
    使用<b class='flag-5'>單片機</b>設(shè)計士壤濕度檢測<b class='flag-5'>自動</b><b class='flag-5'>澆花</b><b class='flag-5'>系統(tǒng)</b>的資料說明

    使用51單片機控制自動澆花器的源程序和PCB及電路圖合集免費下載

    本文檔的主要內(nèi)容詳細(xì)介紹的是使用51單片機控制自動澆花器的源程序和PCB及電路圖合集免費下載。
    發(fā)表于 05-24 17:33 ?90次下載
    使用51<b class='flag-5'>單片機</b>控制<b class='flag-5'>自動</b><b class='flag-5'>澆花</b>器的源程序和PCB及電路圖合集免費下載

    使用51單片機實現(xiàn)智能澆花系統(tǒng)灌溉土壤濕度檢測設(shè)計的源代碼

    本文檔的主要內(nèi)容詳細(xì)介紹的是使用51單片機實現(xiàn)智能澆花系統(tǒng)灌溉土壤濕度檢測設(shè)計的源代碼。
    發(fā)表于 05-26 17:32 ?93次下載
    使用51<b class='flag-5'>單片機</b>實現(xiàn)智能<b class='flag-5'>澆花</b>水<b class='flag-5'>系統(tǒng)</b>灌溉土壤濕度檢測設(shè)計的源代碼

    設(shè)計并制作單片機最小系統(tǒng)

    設(shè)計并制作單片機最小系統(tǒng)方法。
    發(fā)表于 03-25 09:47 ?37次下載
    設(shè)計并<b class='flag-5'>制作</b><b class='flag-5'>一</b><b class='flag-5'>個</b><b class='flag-5'>單片機</b>最小<b class='flag-5'>系統(tǒng)</b>

    51單片機自動澆水系統(tǒng)/51單片機自動澆花系統(tǒng)/智能澆水系統(tǒng)

    51單片機自動澆水系統(tǒng)/51單片機自動澆花系統(tǒng)整個設(shè)
    發(fā)表于 11-12 09:36 ?58次下載
    51<b class='flag-5'>單片機</b><b class='flag-5'>自動</b>澆水<b class='flag-5'>系統(tǒng)</b>/51<b class='flag-5'>單片機</b><b class='flag-5'>自動</b><b class='flag-5'>澆花</b><b class='flag-5'>系統(tǒng)</b>/智能澆水<b class='flag-5'>系統(tǒng)</b>

    基于單片機的智能澆花(灌溉)系統(tǒng)設(shè)計

    智能澆花系統(tǒng)選擇AT89C51單片機最小系統(tǒng)作為整體控制芯片。該系統(tǒng)功能為對土壤溫度值與濕度值進(jìn)行實時監(jiān)測,并及時控制土壤中溫度值與濕度值。
    發(fā)表于 11-12 17:21 ?17次下載
    基于<b class='flag-5'>單片機</b>的智能<b class='flag-5'>澆花</b>(灌溉)<b class='flag-5'>系統(tǒng)</b>設(shè)計

    685【畢設(shè)課設(shè)】基于單片機士壤濕度檢測及自動澆花系統(tǒng)

    685【畢設(shè)課設(shè)】基于單片機士壤濕度檢測及自動澆花系統(tǒng)
    發(fā)表于 11-12 21:06 ?68次下載
    685【畢設(shè)課設(shè)】基于<b class='flag-5'>單片機</b>士壤濕度檢測及<b class='flag-5'>自動</b><b class='flag-5'>澆花</b><b class='flag-5'>系統(tǒng)</b>

    基于單片機的盆栽自動澆花系統(tǒng)-畢設(shè)課設(shè)protues仿真全套資料

    百度網(wǎng)盤下載地址(996):點擊下載功能介紹:單片機土壤濕度檢測自動澆花系統(tǒng)系統(tǒng)采用STC89C52單片
    發(fā)表于 11-23 17:36 ?27次下載
    基于<b class='flag-5'>單片機</b>的盆栽<b class='flag-5'>自動</b><b class='flag-5'>澆花</b><b class='flag-5'>系統(tǒng)</b>-畢設(shè)課設(shè)protues仿真全套資料