摘要:
本設計中利用STC89C52單片機制作了一個簡單的數字電壓表,主要通過A/D轉換器XPT2046把輸入的模擬信號即電位器的電壓值轉換成數字信號,送到1602液晶進行數據顯示,并預設了一個警報值,當超過警報值時,報警電路發出警報。
硬件電路主要包括單片機最小系統、顯示模塊、按鍵模塊、報警模塊和AD轉換模塊、數據存儲模塊六個部分。軟件采用了模塊化的設計方法,主要分為主程序、A/D轉換子程序、按鍵檢測子程序、液晶顯示子程序、E2PROM存儲程序和中斷程序。
目錄:
1. 概述.............................................................1
1.1課題研究背景與意義...........................................1
1.2課題設計內容.................................................1
2. 設計方案........................................................1
3. 硬件電路設計....................................................2
3.1 器件選擇....................................................2
A.STC89C52..................................................2
B. XPT2046...................................................3
C.AT24C02...................................................4
D.LCD1602...................................................5
3.2 單片機最小系統..............................................6
3.3 A/D轉換模塊.................................................7
3.4 數據顯示模塊................................................7
3.5 數據存儲....................................................8
3.6 按鍵模塊....................................................8
3.7 報警模塊....................................................9
3.8 電路原理圖..................................................9
4.軟件設計.........................................................10
4.1 主程序.....................................................10
4.2 AD轉換程序.................................................11
4.3 數據存儲程序...............................................11
4.4 1602液晶顯示程序...........................................12
4.5 按鍵驅動程序...............................................12
4.6 中斷程序...................................................13
4.7 部分程序代碼...............................................13
5.仿真與調試.......................................................14
5.1軟件仿真....................................................14
5.2硬件調試....................................................16
結束語.............................................................17
附錄1.............................................................18
附錄2.............................................................19
1. 概述
1.1課題研究的背景與意義
隨著電子技術的發展,老式通過人眼估讀的電壓值不能滿足工業甚至是科技的要求,那這就需要我們去追求準確度高,分辨率高,測量速度快的數字電壓表,然后通過LED或者是LCD顯示出來。
在電量的測量中,電壓、電流和頻率是最基本的3個被測量,其中電壓量的測量最為常見,經常需要測量出精度高的多點電壓值,因此多點數字電壓表變得越來越重要。數字電壓表(Digital Voltmeter)簡稱DVM,是采用數字化測量技術,把連續的模擬量(直流或交流輸入電壓)轉換成不連續、離散的數字形式并加以顯示的儀表。由于數字儀器具有讀數準確、精度高、誤差小、靈敏度高、分辨率高、測量速度快等特點而備受青睞。
1.2課題設計的內容
以單片機為控制器,對0—5V的模擬電壓進行循環采集,采集的數據送LED或LCD顯示,并存入內存24WC04。超過界限時指示燈閃爍并報警。
編寫下列控制程序:
1).對0—5V模擬信號輸入實行循環采集,連續采集16次,取平均值并顯示。
2).設定采集的上限值,若采集的平均值超過該界限值,則對應的指示燈閃爍10次后一直亮,指示燈閃爍時喇叭發聲,以示警告。
3)可按鍵查看以往的電壓采集值并顯示。
2. 設計方案
本設計選用A/D芯片XPT2046接收電位器上的電壓信號,轉換后的數字信號輸送到單片機STC89C52,數據經過單片機處理之后通過LCD1602進行數據顯示,同時,將數據寫入AT24C02進行數據存儲,通過按鍵控制可進行數據回顯。按鍵還可以設置報警值,當測得數據大于報警值時,蜂鳴器會發出警報。總體框圖如圖2.1所示。
3. 硬件電路設計
3.1 器件選擇
A.STC89C52
本設計選用單片機STC89C52,是宏晶科技推出的新一代超強抗干擾、高速、低功耗的單片機,基于Intel 標準的8052,指令代碼完全兼容傳統的8051 系列單片機,12 時鐘/機器周期和6 時鐘/機器周期可任意選擇,最新的D 版本內集成MAX810 專用復位電路。
主要特性:
1). 增強型8051單片機,6 時鐘/機器周期和12 時鐘/機器周期可以任意 選擇,指令代碼完全兼容傳統8051.[1]
2). 工作電壓:5.5V~3.3V(5V單片機)/3.8V~2.0V(3V 單片機)
3).工作頻率范圍:0~40MHz,相當于普通8051 的0~80MHz,實際工作 頻率可達48MHz
4). 用戶應用程序空間為8K字節
5). 片上集成512 字節RAM
6). 通用I/O 口(32 個),復位后為:P1/P2/P3是準雙向口/弱上拉, P0 口是漏極開路輸出,作為總線擴展用時,不用加上拉電阻,作為 I/O 口用時,需加上拉電阻。
7). ISP(在系統可編程)/IAP(在應用可編程),無需專用編程器,無 需專用仿真器,可通過串口直接下載用戶程 序,數秒即可完成一片
8). 具有EEPROM 功能
9). 共3 個16 位定時器/計數器。即定時器T0、T1、T2
10).外部中斷4 路,下降沿中斷或低電平觸發電路,Power Down 模式可由外部中斷低電平觸發中斷方式喚醒
11). 通用異步串行口(UART),還可用定時器軟件實現多個UART
12). 工作溫度范圍:-40~+85℃(工業級)/0~75℃(商業級)
B. XPT2046
XPT2046是一種典型的逐次逼近型模數轉換器(SARADC),包含了采樣/保持、模數轉換、串口數據輸出等功能。同時芯片集成有一個2.5V的內部參考電壓源、溫度檢測電路,工作時使用外部時鐘。XPT2046可以單電源供電,電源電壓范圍為2.7V~5.5V。參考電壓值直接決定ADC的輸入范圍,參考電壓可以使用內部參考電壓,也可以從外部直接輸入1V~VCC范圍內的參考電壓(要求外部參考電壓源輸出阻抗低)。X、Y、Z、VBAT、Temp和AUX模擬信號經過片內的控制寄存器選擇后進入ADC,ADC可以配置為單端或差分模式。引腳分布如圖3.1所示。
XPT2046通過SPI接口與主控制器進行通信,其與主控制器的接口包括以下信號:PENIRQ_N:筆觸中斷信號,當設置了筆觸中斷信號有效時,每當觸摸屏被按下,該引腳被拉為低電平。當主控檢測到該信號后,可以通過發控制信號來禁止筆觸中斷,從而避免在轉換過程中誤觸發控制器中斷。該引腳內部連接了一個50K的上拉電阻。
CS_N:芯片選中信號,當CS_N被拉低時,用來控制轉換時序并使能串行輸入/輸出寄存器以移出或移入數據。當該引腳為高電平時,芯片(ADC)進入掉電模式。
DCLK:外部時鐘輸入,該時鐘用來驅動SARADC的轉換進程并驅動數字IO上的串行數據傳輸。
DIN:芯片的數據串行輸入腳,當CS為低電平時,數據在串行時鐘DCLK的上升沿被鎖存到片上的寄存器。
DOUT:串行數據輸出,在串行時鐘DCLK的下降沿數據從此引腳上移出,當CS_N引腳為高電平時,該引腳為高阻態。
BUSY:忙輸出信號,當芯片接收完命令并開始轉換時,該引腳產生一個DCLK周期的高電平。當該引腳由高點平變為低電平的時刻,轉換結果的最高位數據呈現在DOUT引腳上,主控可以讀取DOUT的值。當CS_N引腳為高電平時,BUSY引腳為高阻態。
C. AT24C02
AT24C02支持I2C,總線數據傳送協議I2C,總線協議規定任何將數據傳送到總線的器件作為發送器。任何從總線接收數據的器件為接收器。數據傳送是由產生串行時鐘和所有起始停止信號的主器件控制的。主器件和從器件都可以作為發送器或接收器,但由主器件控制傳送數據(發送或接收)的模式,由于A0、A1和A2可以組成000~111八種情況,即通過器件地址輸入端A0、A1和A2可以實現將最多8個AT24C02器件連接到總線上,通過進行不同的配置進行選擇器件。引腳分布如圖3.2所示
器件操作:
時鐘及數據傳輸:SDA 引腳通常被外圍器件拉高。SDA 引腳的數據應在 SCL 為低時變化;當數據在 SCL 為高時變化,將視為下文所述一個起始或停止命令。
起始命令:當 SCL 為高,SDA 由高到低的變化被視為起始命令,必須以起始命令作為任何一次讀/寫操作命令的開始。
停止命令:當 SCL 為高,SDA 由低到高的變化被視為停止命令,在一個讀操作后,停止命令會使 EEPROM 進入等待態低功耗模式。
應答:所有的地址和數據字節都是以 8 位為一組串行輸入和輸出的。每收到一組 8 位的數據后,EEPROM 都會在第 9 個時鐘周期時返回應答信號。每當主控器件接收到一組 8 位的數據后,應當在第 9 個時鐘周期向EEPROM 返回一個應答信號。收到該應答信號后,EEPROM 會繼續輸出下一組 8 位的數據。若此時沒有得到主控器件的應答信號,EEPROM 會停止讀出數據,直到主控器件返回一個停止命令來結束讀周期。
等待模式:24C01/02/04/08/16 特有一個低功耗的等待模式。可以通過以下方法進入該模式:(a)上電 (2)收到停止位并且結束所有的內部操作后。
器件復位:在協議中斷、下電或系統復位后,器件可通過以下步驟復位:(1)連續輸入 9 個時鐘;(2)在每個時鐘周期中確保當 SCL 為高時 SDA 也為高;(3)建立一個起始條件。
D. LCD1602
1602液晶也叫1602字符型液晶,它是一種專門用來顯示字母、數字、符號等的點陣型液晶模塊。它由若干個5X7或者5X11等點陣字符位組成,每個點陣字符位都可以顯示一個字符,每位之間有一個點距的間隔,每行之間也有間隔,起到了字符間距和行間距的作用。
1602LCD采用標準的14腳(無背光)或16腳(帶背光)接口,各引腳接口說明如表3.1所示:
3.2 單片機最小系統
單片機最小系統,或者稱為最小應用系統,是指用最少的元件組成的單片機可以工作的系統.對51系列單片機來說,最小系統一般應該包括:單片機、晶振電路、復位電路.電路圖如圖3.3所示。
復位電路:由電容串聯電阻構成,由圖并結合"電容電壓不能突變"的性質,可以知道,當系統一上電,RST腳將會出現高電平,并且,這個高電平持續的時間由電路的RC值來決定.典型的51單片機當RST腳的高電平持續兩個機器周期以上就將復位,所以,適當組合RC的取值就可以保證可靠的復位.
晶振電路:典型的晶振取11.0592MHz(因為可以準確地得到9600波特率和19200波特率,用于有串口通訊的場合)/12MHz(產生精確的uS級時歇,方便定時操作)
3.3 A/D轉換模塊
利用XPT2046來采集電位器的得電壓信號,經轉換之后輸送給單片機。電路圖如圖3.4所示。
3.4 數據顯示模塊
1602液晶接收單片機P0口輸出的數據直接進行顯示,在1602的V0引腳接上一個電位器來調整液晶顯示的對比度。由于單片機的P0口進行數據傳輸需接上拉電阻。電路圖如圖3.5所示。
3.5 數據存儲
將芯片 A2、A1、A0 都是接的 GND,也就是說都是 0,因此24C02的 7 位地址實際上是二進制的 0b1010000,也就是 0x50。我們用 I 2 C 的協議來尋址 0x50,利用IIC通信來讀寫數據。電路圖如圖3.6所示。
3.6 按鍵模塊
利用獨立按鍵來進行控制,S0進行數據回顯,S1、S2是對警告值進行加
減,每次加減0.5V。電路圖如圖3.7所示。
3.7 報警模塊
當測得的電壓值大于設定的報警值時,會從P2^3引腳輸出一個1HZ脈沖是小燈閃爍10次,然后輸出一個低電平,小燈常亮。蜂鳴器采用了有源蜂鳴器,需給端口一定頻率的脈沖,蜂鳴器才會發出聲音。電路圖如圖3.8所示。
3.8 電路原理圖
見附錄1。
4. 軟件設計
4.1 主程序
主程序主要調用A/D轉換程序、按鍵驅動程序、1602液晶顯示程序、數據存儲程序和警報程序。首先對系統進行初始化,當被測電壓輸入后,調用A/D轉換子程序,轉換出來的數值經數據存儲程序寫入AT24C02,并通過1602液晶顯示程序進行數據顯示,同時,與報警值進行比較,當大于報警值時,啟用報警程序。主程序流程圖如圖4.1所示。
4.2 A/D轉換程序
A/D轉換程序主要是對電位器產生的模擬信號進行數據轉換,首先啟動AD芯片,輸入指令后,等待數據處理完后,輸出結果,本次轉換完成。子程序流程圖如圖4.2所示。
4.3數據存儲程序
數據存儲程序主要是對A/D轉換后的數值進行數據存儲,當按鍵控制的時候可以數據回顯。AT24C02用IIC進行數據通信,首先選擇芯片地址,然后進行數據讀取,待完成后輸出結果。程序流程圖如圖11所示。
4.4 1602液晶顯示程序
本設計使用1602液晶進行數據顯示,接收從單片機傳輸的字符型數據直接進行顯示。首先初始化液晶,輸入數據顯示的地址,即在液晶屏上顯示的行與列。再輸入字符型的數據,液晶即可進行數據顯示。程序流程圖如圖4.4所示。
4.5按鍵驅動程序
本設計使用3個獨立按鍵,一個按鍵用來控制讀取E2PROM中存儲的數據,然后通過液晶1602進行數據顯示。另外兩個按鍵來進行報警值的調整,S1對報警值加5,S2對數據減5,報警值在1602上立即刷新。按鍵每次按下會有抖動,所以進行按鍵消抖,這樣按鍵使用更加精準。程序流程圖如圖4.5所示。
4.6中斷程序
本程序使用定時器中斷0,中斷優先級為1,定時2ms,中斷中主要產生一個1s和200ms的時間標志位、進行按鍵的掃描和產生蜂鳴器需要的脈沖。
4.7 部分程序代碼
見附錄2.
5.仿真與調試
1).軟件仿真
仿真運行的時候,液晶顯示如圖5.1所示。
當S0按下并調整電位器的值得時候,液晶顯示如圖5.2所示。
2).硬件調試
當接通電源的時候,液晶顯示如圖5.3所示。
當S0按下,并調整電位器,液晶如圖5.4所示。
當按下S2的時候,報警值減掉0.5V,并調整電位器,使其電壓大于報警值,電路發出警報,蜂鳴器器報警,小燈閃爍。如圖5.5所示。
6.結束語
通過這次課程設計有很多收獲,把所學到的知識得到了應用,對所學的知識有了更深的了解,有了新的體會。對于制圖軟件AltiumDesigner、編程軟件keil5掌握的更加熟悉,也發現了不少的問題,經過一系列的努力得以解決,充實了自己。
主程序:
void main()
{
EA = 1;
AUXR &= 0x7F;
TMOD &= 0xF0;
TL0 = 0xCD;
TH0 = 0xF8;
TF0 = 0;
TR0 = 1;
ET0 = 1;
LcdInit();
while(1)
{
KeyDriver();
if (flag_200ms)
{
flag_200ms = 1;
if (flag_s1)
{
Get_AD_buf();
AD_Display();
}
if (flag_s1 == 0)
{
sdat =E2Read(0x00);
buf[0] =sdat/10+'0';
buf[1] = '.';
buf[2] =sdat%10+'0';
buf[3] = '\0';
LcdWriteCom(0x80+0x40);
LcdWriteData(buf[0]);
LcdWriteData(buf[1]);
LcdWriteData(buf[2]);
}
}
if (pdat >warn)
{
BUZZ = buz;
if (n<10)
Led_1s();
else
LED = 0;
}else
{
n = 0;
LED = 1;
BUZZ = 0;
}
}
}
A/D轉換程序:
voidSPI_Write(uchar dat)
{
uchar i;
CLK = 0;
for(i=0; i<8;i++)
{
DIN = dat >>7;
dat <<= 1;
CLK = 0;
CLK = 1;
}
}
uintSPI_Read(void)
{
uint i, dat=0;
CLK = 0;
for(i=0; i<12;i++)
{
dat <<= 1;
CLK = 1;
CLK = 0;
dat |= DOUT;
}
return dat;
}
uintRead_AD_Data(uchar cmd)
{
uchar i;
uint AD_Value;
CLK = 0;
CS = 0;
SPI_Write(cmd);
for(i=6; i>0;i--);
CLK = 1;
_nop_();_nop_();
CLK = 0;
_nop_();_nop_();
AD_Value=SPI_Read();
CS = 1;
return AD_Value;
}
1602液晶顯示程序:
voidLcdWriteCom(uchar com)
{
LCD1602_E = 0;
LCD1602_RS = 0;
LCD1602_RW = 0;
LCD1602_DATAPINS =com;
Lcd1602_Delay1ms(1);
LCD1602_E = 1;
Lcd1602_Delay1ms(5);
LCD1602_E = 0;
}
voidLcdWriteData(uchar dat)
{
LCD1602_E = 0;
LCD1602_RS = 1;
LCD1602_RW = 0;
LCD1602_DATAPINS =dat;
Lcd1602_Delay1ms(1);
LCD1602_E = 1;
Lcd1602_Delay1ms(5);
LCD1602_E = 0;
}
void LcdInit()
{
LcdWriteCom(0x38);
LcdWriteCom(0x0c);
LcdWriteCom(0x06);
LcdWriteCom(0x01);
LcdWriteCom(0x80);
}
E2PROM存儲程序:
voidIIC_Start(void)
{
SDA = 1;
SCL = 1;
somenop;
SDA = 0;
somenop;
SCL = 0;
}
voidIIC_Stop(void)
{
SDA = 0;
SCL = 1;
somenop;
SDA = 1;
}
voidIIC_Ack(unsigned char ackbit)
{
if(ackbit)
SDA = 0;
else
SDA = 1;
somenop;
SCL = 1;
somenop;
SCL = 0;
SDA = 1;
somenop;
}
bitIIC_WaitAck(void)
{
SDA = 1;
somenop;
SCL = 1;
somenop;
if(SDA)
{
SCL = 0;
IIC_Stop();
return 0;
}
else
{
SCL = 0;
return 1;
}
}
voidIIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0;i<8;i++)
{
if(byt&0x80)
{
SDA = 1;
}
else
{
SDA = 0;
}
somenop;
SCL = 1;
byt <<= 1;
somenop;
SCL = 0;
}
}
unsigned charIIC_RecByte(void)
{
unsigned char da;
unsigned char i;
for(i=0;i<8;i++)
{
SCL = 1;
somenop;
da <<= 1;
if(SDA)
da |= 0x01;
SCL = 0;
somenop;
}
return da;
}
unsigned charE2Read(unsigned char addr)
{
unsigned char str;
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0xa1);
IIC_WaitAck();
str =IIC_RecByte();
IIC_WaitAck();
IIC_Stop();
return str;
}
voidE2Write(unsigned char str,unsigned char addr)
{
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_SendByte(str);
IIC_WaitAck();
IIC_Stop();
|