1? 系統(tǒng)方案設(shè)計(jì)
1.1 系統(tǒng)整體設(shè)計(jì)
電子智能補(bǔ)光器的設(shè)計(jì)思路:首先通過(guò)單片機(jī)判斷特殊天氣模式是否啟用,如果啟用則直接亮黃燈并在手機(jī)上顯示出來(lái)。確定特殊天氣模式?jīng)]有啟用時(shí),通過(guò)季節(jié)模塊判斷當(dāng)前月份對(duì)應(yīng)的季節(jié)來(lái)確定補(bǔ)光模式。通過(guò)光照傳感器將外界光照強(qiáng)度與對(duì)應(yīng)季節(jié)設(shè)定光照閾值進(jìn)行比較,當(dāng)外界光照強(qiáng)度大于設(shè)定閾值時(shí)進(jìn)行補(bǔ)光操作,并通過(guò)藍(lán)牙連接在手機(jī)上顯示當(dāng)前補(bǔ)光模式以及光照強(qiáng)度。
1.2 設(shè)計(jì)任務(wù)
主要任務(wù)簡(jiǎn)述:以單片機(jī)為核心,設(shè)計(jì)電子智能補(bǔ)光器,以滿足各種不同情境下對(duì)光照需求的差異。
要求簡(jiǎn)述:
(1)在外界光照強(qiáng)度大于所設(shè)定閾值時(shí)補(bǔ)光器保持不工作狀態(tài),光照強(qiáng)度小于設(shè)定閾值時(shí)開始補(bǔ)光;
(2)可選擇春、夏、秋、冬四種模式,分別對(duì)應(yīng)四種不同的閾值電壓;
(3)設(shè)置特殊天氣模式,開啟特殊天氣模式后亮起黃色霧燈;
(4)通過(guò)藍(lán)牙連接手機(jī),顯示當(dāng)前的模式和光照強(qiáng)度。
1.3 模塊方案選型
1.3.1主控方案選型
STC89C52單片機(jī)是宏晶科技推出的高反應(yīng)速度、低功率消耗、有著很強(qiáng)抵的擋外界干擾能力的單片機(jī),而且該單片機(jī)的指令代碼非常切合傳統(tǒng)的8051單片機(jī),并且與傳統(tǒng)51單片機(jī)對(duì)比而言,該單片機(jī)速度更快,是傳統(tǒng)51單片機(jī)的8~12倍。除此之外,該單片機(jī)還有6時(shí)鐘周期和12時(shí)鐘周期可以任意選擇。
主要特性如下:
(1)新一代8051單片機(jī),6時(shí)鐘機(jī)器周期和12時(shí)鐘機(jī)器周期可以任意選擇,指令代碼非常契合傳統(tǒng)8051單片機(jī)。
(2)工作電壓:5.5V~3.3V(5V單片機(jī))。
(3)工作頻率范圍處于0~40MHz之間,相當(dāng)于普通8051單片機(jī)工作頻率的0~80MHz范圍,而且新一代單片機(jī)的實(shí)際工作頻率可達(dá)48MHz。
(4)一共具有3個(gè)16位定時(shí)器,也就是定時(shí)器T0、T1、T2。
(5)外部中斷4路,低電平觸發(fā)或下降沿中斷電路,PowerDown模式可通過(guò)外部中斷低電平觸發(fā)中斷的方式觸發(fā)。
1.3.2光電轉(zhuǎn)換器的選擇
ADC0832是NS(National Semiconductor)公司生產(chǎn)的串行接口8位A/D轉(zhuǎn)換器,通過(guò)三線接口與單片機(jī)連接,功耗低,性能價(jià)格比較高,合適使用在袖珍式的智能儀器儀表中。ADC0832為8位分辨率A/D轉(zhuǎn)換芯片,其最高分辨可達(dá)256級(jí),可以適應(yīng)一般的模擬量轉(zhuǎn)換要求。芯片具有雙數(shù)據(jù)輸出可作為數(shù)據(jù)校驗(yàn),以減少數(shù)據(jù)誤差,轉(zhuǎn)換速度快且穩(wěn)定性能強(qiáng)。獨(dú)立的芯片使能輸入,使多器件連接和處理器控制變得更加方便。通過(guò)DI 數(shù)據(jù)輸入端,可以輕易的實(shí)現(xiàn)通道功能的選擇。其主要特點(diǎn)如下:
(1)8位分辨率,其最高分辨可達(dá)256級(jí);
(2)雙通道A/D轉(zhuǎn)換;
(3)電源供電時(shí)光電轉(zhuǎn)換器的輸入電壓在0~5V之間;
選擇該A/D轉(zhuǎn)換芯片,不僅因?yàn)槠潴w積小、功耗低,而且可以適應(yīng)一般的模擬量轉(zhuǎn)換要求,完全滿足系統(tǒng)的要求。另外,其內(nèi)部電源輸入與參考電壓的復(fù)用,使得轉(zhuǎn)換芯片的模擬電壓輸入在0~5V之間,電源電路供電可以同時(shí)滿足51單片機(jī)和該芯片的共同使用。除此之外該芯片的轉(zhuǎn)換時(shí)間極短,僅為32μS,反應(yīng)非常迅速,另外該芯片具有雙數(shù)據(jù)輸出可作為數(shù)據(jù)校驗(yàn)的工具,以此來(lái)減少實(shí)驗(yàn)數(shù)據(jù)誤差,轉(zhuǎn)換速度快并且穩(wěn)定性能出色。單獨(dú)工作的芯片的使能輸入,可以更輕松地對(duì)多元件進(jìn)行連接,同時(shí)也可以更加方便地控制處理器。通過(guò)DI 數(shù)據(jù)輸入端,使得實(shí)現(xiàn)通道功能的選擇變的易如反掌。除此之外,價(jià)格上的優(yōu)勢(shì)同樣也是選擇它的原因之一。
1.3.3顯示器的選擇
LCD1602液晶顯示器是廣泛使用的一種工業(yè)字符型液晶顯示模塊。由字符型液晶顯示器(LCD)、控制驅(qū)動(dòng)主電路HD44780及其擴(kuò)展驅(qū)動(dòng)電路HD44100,以及少量電阻、電容元件和結(jié)構(gòu)件等裝配在PCB板上而組成,能夠同時(shí)顯示16x02即32個(gè)字符。(16列2行)。但寄存器不止32個(gè),有一些顯示效果,如字符一個(gè)個(gè)顯示、字符從左到右或從右到左顯示等等,顯示效果簡(jiǎn)單。當(dāng)然也有其他更好的選擇,例如12864液晶顯示器,它的顯示模塊是128×64點(diǎn)陣的漢字圖形型液晶顯示模塊,可顯示漢字及圖形,具有多種功能:光標(biāo)顯示、畫面移位、睡眠模式等。
其實(shí)綜合來(lái)說(shuō),二者編程方面的難度差不多,原理方面也差不多,甚至12864液晶顯示器更勝一籌,因?yàn)樵擄@示器顯示更全面,字符也更多,需要進(jìn)行更多操作的話自然是12864液晶顯示器能夠勝任。但是對(duì)比來(lái)說(shuō)的話,1602液晶顯示器也能實(shí)現(xiàn)設(shè)計(jì)的要求,而且相對(duì)來(lái)說(shuō)更重要的原因就是1602液晶顯示器比較廉價(jià),網(wǎng)上購(gòu)買也比較便宜,最低五六塊錢左右。而12864液晶顯示器網(wǎng)上購(gòu)買最便宜的也要在二三十左右。所以從造價(jià)方面以及使用方面考慮,當(dāng)然是價(jià)格低廉而且功能也不欠缺的優(yōu)先。因此選擇1602液晶顯示器作為顯示器件。
2? 硬件設(shè)計(jì)
2.1 單片機(jī)模塊
單片機(jī)的主要特點(diǎn)有:
(1)有出色的性能單價(jià)比,高效能、低電壓,易于制作便攜式產(chǎn)品。
(2)集成度高,體積小,有較高的穩(wěn)定性。而且單片機(jī)把各功能零件組合在一塊芯片上,內(nèi)部結(jié)構(gòu)使用的是總線結(jié)構(gòu),不僅減輕了各芯片彼此之間的連線,還大大增加了單片機(jī)的安全性和抗干擾能力。
(3)控制功能強(qiáng)。為求滿足工業(yè)控制的要求,通常單片機(jī)的指令系統(tǒng)中均有極多樣的轉(zhuǎn)移指令、I/O口的邏輯操作和位處理特性。單片機(jī)的邏輯控制功能及運(yùn)轉(zhuǎn)速度均遠(yuǎn)高于同一等級(jí)的微機(jī)。
(4)外部總線增加了I2C(Inter-Integrated Circuit)及SPI(Serial Peripheral Interface)等串行總線方式,逐步縮小了體積,精簡(jiǎn)了構(gòu)造。單片機(jī)的系統(tǒng)擴(kuò)展、系統(tǒng)配置較典型、規(guī)范,容易構(gòu)成各種規(guī)模的應(yīng)用系統(tǒng)。
PORT0(P0.0~P0.7):端口0是一個(gè)8位寬的開路汲極雙向輸出入端口,共有8個(gè)位,P0.0表示位0,P0.1表示位1,依此類推。其他三個(gè)I/O端口(P1、P2、P3)則不具有此電路組態(tài),而是內(nèi)部有一提升電路,P0在當(dāng)做I/O用時(shí)可以推動(dòng)8個(gè)LS的TTL負(fù)載。
PORT1(P1.0~P1.7):端口1也是具有內(nèi)部提升電路的雙向I/O端口,其輸出緩沖器可以推動(dòng)4個(gè)LSTTL負(fù)載,同樣地若將端口1的輸出設(shè)為高電平,便是由此端口來(lái)輸入數(shù)據(jù)。
PORT2(P2.0~P2.7):端口2是具有內(nèi)部提升電路的雙向I/O端口,每一個(gè)引腳可以推動(dòng)4個(gè)LS的TTL負(fù)載,若將端口2的輸出設(shè)為高電平時(shí),此端口便能當(dāng)成輸入端口來(lái)使用。P2除了當(dāng)做一般I/O端口使用外,若是在STC89C52擴(kuò)充外接程序存儲(chǔ)器或數(shù)據(jù)存儲(chǔ)器時(shí),也提供地址總線的高字節(jié)A8~A15,這個(gè)時(shí)候P2便不能當(dāng)做I/O來(lái)使用了。
PORT3(P3.0~P3.7):端口3也具有內(nèi)部提升電路的雙向I/O端口,其輸出緩沖器可以推動(dòng)4個(gè)TTL負(fù)載,同時(shí)還多工具有其他的額外特殊功能,包括串行通信、外部中斷控制、計(jì)時(shí)計(jì)數(shù)控制及外部數(shù)據(jù)存儲(chǔ)器內(nèi)容的讀取或?qū)懭肟刂频裙δ堋纹瑱C(jī)的引腳圖如圖3-1所示。
#include "51Lib_Configure.h"
#include "51Lib_Declaration.h"
#if _CONFIG_FUNC_LCD1602_ == CH_ENABLE
#define _NOP() _nop_()
#define DataPort P0
#define DataPIN P0
#define CLR_RS (lcd1602_RS=0)
#define SET_RS (lcd1602_RS=1)
#define CLR_RW (lcd1602_RW=0)
#define SET_RW (lcd1602_RW=1)
#define CLR_EN (lcd1602_EN=0)
#define SET_EN (lcd1602_EN=1)
/*
LcdReset(); //LCD1602初始化
DelayMs(10);
sprintf(temp,"1111111111111111");//更新顯示
DispStr(0,0,(unsigned char *)temp);//打印顯示
sprintf(temp,"1111111111111111");//更新顯示
DispStr(0,1,(unsigned char *)temp);//打印顯示
*/
/***********************************************
函數(shù)名稱:DispNum
功 能:讓液晶從某個(gè)位置起連續(xù)顯示一個(gè)數(shù)值,前面不會(huì)補(bǔ)0
參 數(shù):x--位置的列坐標(biāo)
y--位置的行坐標(biāo)
Dis_dat--需要顯示的數(shù)
Dis_Len--需要顯示的寬度
返回值 :無(wú)
***********************************************/
void DispNum(uchar x, uchar y, uint Dis_dat, uchar Dis_Len)
{
uchar i;
uint dat = 1;
Disp1Char(x+Dis_Len-1,y,Dis_dat%10+0x30);
if(Dis_Len == 1)
return;
for(i = 1;i < Dis_Len;i++)
dat*=10;
for(i = 1; i < Dis_Len ; i++)
{
//dat = pow(10, Dis_Len-i);
if(Dis_dat >= dat)
Disp1Char(x+i-1,y,Dis_dat/dat%10+0x30);
else
Disp1Char(x+i-1,y,' ');
dat/=10;
}
}
/***********************************************
函數(shù)名稱:DispStr
功 能:讓液晶從某個(gè)位置起連續(xù)顯示一個(gè)字符串
參 數(shù):x--位置的列坐標(biāo)
y--位置的行坐標(biāo)
ptr--指向字符串存放位置的指針
返回值 :無(wú)
***********************************************/
void DispStr(uchar x,uchar y,uchar *ptr)
{
uchar *temp;
uchar i,n = 0;
temp = ptr;
while(*ptr++ != '?') n++; //計(jì)算字符串有效字符的個(gè)數(shù)
for (i=0;i<n;i++)
{
Disp1Char(x++,y,temp[i]);
if (x == 0x10)
{
break;
}
}
}
/*******************************************
函數(shù)名稱:DispNchar
功 能:讓液晶從某個(gè)位置起連續(xù)顯示N個(gè)字符
參 數(shù):x--位置的列坐標(biāo)
y--位置的行坐標(biāo)
n--字符個(gè)數(shù)
ptr--指向字符存放位置的指針
返回值 :無(wú)
*******************************************
void DispNChar(uchar x,uchar y, uchar n,uchar *ptr)
{
uchar i;
for (i=0;i<n;i++)
{
Disp1Char(x++,y,ptr[i]);
if (x == 0x10)
{
x = 0;
y ^= 1;
}
}
}
*/
/*******************************************
函數(shù)名稱:LocateXY
功 能:向液晶輸入顯示字符位置的坐標(biāo)信息
參 數(shù):x--位置的列坐標(biāo)
y--位置的行坐標(biāo)
返回值 :無(wú)
********************************************/
void LocateXY(uchar x,uchar y)
{
uchar temp;
temp = x&0x0f;
y &= 0x01;
if(y) temp |= 0x40; //如果在第2行
temp |= 0x80;
LcdWriteCommand(temp,1);
}
/*******************************************
函數(shù)名稱:Disp1Char
功 能:在某個(gè)位置顯示一個(gè)字符
參 數(shù):x--位置的列坐標(biāo)
y--位置的行坐標(biāo)
data--顯示的字符數(shù)據(jù)
返回值 :無(wú)
********************************************/
void Disp1Char(uchar x,uchar y,uchar data1)
{
LocateXY( x, y );
LcdWriteData( data1 );
}
/*******************************************
函數(shù)名稱:LcdReset
功 能:對(duì)1602液晶模塊進(jìn)行復(fù)位操作
參 數(shù):無(wú)
返回值 :無(wú)
********************************************/
void LcdReset(void)
{
// DataDir = 0xFF; //數(shù)據(jù)端口設(shè)為輸出狀態(tài)
LcdWriteCommand(0x38, 0); //規(guī)定的復(fù)位操作
DelayMs(5);
LcdWriteCommand(0x38, 0);
DelayMs(5);
LcdWriteCommand(0x38, 0);
DelayMs(5);
LcdWriteCommand(0x38, 1); //顯示模式設(shè)置
LcdWriteCommand(0x08, 1); //顯示關(guān)閉
LcdWriteCommand(0x01, 1); //顯示清屏
LcdWriteCommand(0x06, 1); //寫字符時(shí)整體不移動(dòng)
LcdWriteCommand(0x0c, 1); //顯示開,不開游標(biāo),不閃爍
}
/*------------------------------------------------
清屏函數(shù)
------------------------------------------------*/
void LcdClear(void)
{
LcdWriteCommand(0x01,1);
DelayMs(5);
}
/*******************************************
函數(shù)名稱:LcdWriteCommand
功 能:向液晶模塊寫入命令
參 數(shù):cmd--命令,
chk--是否判忙的標(biāo)志,1:判忙,0:不判
返回值 :無(wú)
********************************************/
void LcdWriteCommand(uchar cmd,uchar chk)
{
if (chk) WaitForEnable(); // 檢測(cè)忙信號(hào)?
CLR_RS;
CLR_RW;
_NOP();
DataPort = cmd; //將命令字寫入數(shù)據(jù)端口
_NOP();
SET_EN; //產(chǎn)生使能脈沖信號(hào)
_NOP();
_NOP();
CLR_EN;
}
/*******************************************
函數(shù)名稱:LcdWriteData
功 能:向液晶顯示的當(dāng)前地址寫入顯示數(shù)據(jù)
參 數(shù):data--顯示字符數(shù)據(jù)
返回值 :無(wú)
********************************************/
void LcdWriteData( uchar data1 )
{
WaitForEnable(); //等待液晶不忙
SET_RS;
CLR_RW;
SET_EN;
_NOP();
DataPort = data1; //將顯示數(shù)據(jù)寫入數(shù)據(jù)端口
_NOP();
//產(chǎn)生使能脈沖信號(hào)
_NOP();
_NOP();
CLR_EN;
}
/*******************************************
函數(shù)名稱:WaitForEnable
功 能:等待1602液晶完成內(nèi)部操作
參 數(shù):無(wú)
返回值 :無(wú)
********************************************/
void WaitForEnable(void)
{
unsigned int later=0;
DataPort=0xff;
CLR_RS;
SET_RW;
_NOP();
SET_EN;
_NOP();
_NOP();
// while((DataPIN&Busy)!=0);
while(((DataPIN&0x80)!=0)&&(later<1000)) //檢測(cè)忙標(biāo)志
{
DelayUs2x(2);
later++;
}
CLR_EN;
// DataDir|=0xFF; //將P4口切換為輸出狀態(tài)
}
#endif