|
前兩天做了一個(gè)ds18b20+lcm1602溫度顯示報(bào)警系統(tǒng),將報(bào)告及源代碼分享給大家學(xué)習(xí),有什么問(wèn)題還請(qǐng)指正
一、單片機(jī)簡(jiǎn)介
二、項(xiàng)目任務(wù)和要求
三、項(xiàng)目設(shè)計(jì)方案的總體設(shè)計(jì)框圖
3.1硬件電路框圖
3.2硬件電路概述
3.3主控電路
3.4顯示電路
3.5報(bào)警溫度調(diào)節(jié)電路
1、蜂鳴器
2、跑馬燈
3.6溫度傳感器及DS18B20測(cè)溫基本原理
3.7單片機(jī)硬件連接實(shí)物圖
四、系統(tǒng)軟件算法設(shè)計(jì)
五、總結(jié)與體會(huì)
附錄
參考文獻(xiàn)
單片機(jī)簡(jiǎn)介
1.實(shí)驗(yàn)系統(tǒng)簡(jiǎn)介
本次課設(shè)單片機(jī)實(shí)驗(yàn)系統(tǒng)采用nKDE-51 單片機(jī)實(shí)驗(yàn)系統(tǒng),nKDE-51 單片機(jī)實(shí)驗(yàn)教學(xué)系統(tǒng)采用模塊化設(shè)計(jì),以方便學(xué)生自由組合功能,設(shè)計(jì)實(shí)驗(yàn)。整個(gè)實(shí)驗(yàn)系統(tǒng)包括六個(gè)功能模塊,分別為CPU板、基本IO板、模擬總線接口IO口、擴(kuò)展總線接口IO板,字符點(diǎn)陣LCD/大容量 flash/GPRS 模塊板和uart/以太網(wǎng)及電話接口拓展板。本次課設(shè)需要CPU板,lcm1602模塊,溫度傳感器模塊,流水燈模塊、蜂鳴器模塊以及數(shù)碼管模塊,所以該實(shí)驗(yàn)板完全滿足課設(shè)的需要,具體用的各部分圖如下:
CPU板部分如圖:
IO口板部分和模擬總線部分板如下圖
2.系統(tǒng)資源及功能簡(jiǎn)介
(1) 單片機(jī)端口的引出
MCS-51 系列單片機(jī)共有 4 個(gè)獨(dú)立的 8 位并行 I/O 端口分別為 P0、P1、P2 和 P3在 CPU板上各通過(guò)兩個(gè)8 芯單排插針引出,可通過(guò)杜邦插座連接到其它模塊或器件。
(2) CPU 工作頻率的選擇
nKDE-51 系統(tǒng)提供了四種常用的晶振頻率分別是 11.0592MHz、12MHz、18.432MHz 和
22.1184MHz。用戶可通過(guò)跳線JP1 和 JP2來(lái)選擇系統(tǒng)晶振的頻率。如果用戶還需要其它的晶振頻率,本系統(tǒng)預(yù)留了一個(gè)焊接晶振的位置X5可供使用。
(3) CPU 工作模式的選擇
MCS-51 單片機(jī)的工作方式可分為端口工作方式不擴(kuò)展總線和擴(kuò)展總線模式。在擴(kuò)展總線模式單片機(jī)的P0口通過(guò)ALE信號(hào)控制外部地址鎖存器復(fù)用為地址總線低8位地址和數(shù)據(jù) 總線,P2口提供高8位地址,同時(shí)P3.6和P3.7作為W R和R D信號(hào)。而當(dāng)單片機(jī)工作在端口方式下時(shí)P0~P3的每一位都可以作為獨(dú)立的端口引腳使用。 在 nKDE-51 系統(tǒng)中當(dāng)實(shí)驗(yàn)中不使用擴(kuò)展總線時(shí),單片機(jī)的端口可通過(guò)表 1-1 所列出的插座引出。如果單片機(jī)實(shí)驗(yàn)需要使用擴(kuò)展總線用戶可使用系統(tǒng)提供的 40 芯連接電纜將J9和JX1連接起來(lái)。此時(shí) P0、P2 和 P3.6、P3.7 等引腳已作為系統(tǒng)總線使用,不要再將它們用作普通的 I/O。JX2 和 JX3 的各引腳和 JX1 的對(duì)應(yīng)引腳相連可以通過(guò)它們將總線連接到其它模塊上。
單片機(jī)的ISP及串行口
電路連接nKDE-51系統(tǒng)使用 STC 公司的STC 12C5A60S2 作為 CPU。該 CPU 兼容標(biāo)準(zhǔn)51內(nèi)核自帶 64K字節(jié)的 Flash 程序存儲(chǔ)器支持通過(guò)串行口進(jìn)行在系統(tǒng)編程ISP以及程序調(diào)試單片機(jī)的串行口通過(guò)雙向自鎖開(kāi)關(guān) SW2 選擇連接到 9 芯孔型插座 COM1 RS232 接口用于和 計(jì)算機(jī)通信進(jìn)行 ISP 或程序調(diào)試或者連接到 J4、J8 及 J9用于進(jìn)行 I/O 端口及 RS485 通信等實(shí)驗(yàn).計(jì)算機(jī)必須通過(guò)實(shí)驗(yàn)系統(tǒng)提供的9 芯串口延長(zhǎng)電纜和 COM1 相連。 當(dāng)SW2 彈起時(shí)單片機(jī)的串行口連接到 COM1 , 當(dāng) SW2 按下時(shí)單片機(jī)串行口連接到 J4、J8 及J9。
項(xiàng)目任務(wù)及要求
1. 單片機(jī)P0.0和DS18B20的數(shù)據(jù)端相連;(實(shí)驗(yàn)八)
2. 編寫單片機(jī)通過(guò)IO端口模擬單總線時(shí)序控制DS18B20的程序,讀出溫度;(實(shí)驗(yàn)八)
3. 在1602字符點(diǎn)陣液晶顯示模塊上顯示實(shí)測(cè)溫度(實(shí)驗(yàn)七)
4.蜂鳴器報(bào)警功能;(+5)
5.串口顯示功能;(+5)
6.發(fā)光二極管流水燈報(bào)警功能,隨著溫度超過(guò)警戒值范圍改變,流水燈的速率進(jìn)行改變。(+5)
7.計(jì)數(shù)器功能記錄超過(guò)警戒值的次數(shù),單個(gè)或者八位數(shù)碼管顯示 計(jì)數(shù)。(+5)
1-3為基本功能部分,4-6為增加功能部分
創(chuàng)新部分: 比如:音樂(lè)播放實(shí)現(xiàn)聲音報(bào)警等。
三、項(xiàng)目設(shè)計(jì)方案的總體設(shè)計(jì)框圖
3.1硬件電路框圖
3.2硬件電路概述
單片機(jī)P0.0和DS18B20的數(shù)據(jù)端相連,在1602字符點(diǎn)陣液晶顯示模塊上顯示實(shí)測(cè)溫度,P0.7和蜂鳴器相連,P0其余口接LED1-6。
3.3主控電路
主控電路主要使用 STC 公司的STC 12C5A60S2作為 CPU,控制整個(gè)系統(tǒng)的工作。
3.4顯示電路
LCD顯示器是一種用液晶材料制成的液晶顯示器,它具有體積小、功耗低、字跡清晰、無(wú)電磁輻射、壽命長(zhǎng)等優(yōu)點(diǎn),1602 字符點(diǎn)陣式LCM共有兩個(gè)顯示行,每行可顯示16個(gè)字符,為最常用的一種字符式LCM,顯示控制器為HD44780,通過(guò)HD44100進(jìn)行規(guī)模的擴(kuò)展。
3.5報(bào)警溫度調(diào)節(jié)電路
1、蜂鳴器
當(dāng)溫度超過(guò)30度時(shí),蜂鳴器會(huì)發(fā)出間隔的報(bào)警聲響。
2、跑馬燈
在30度以上時(shí),跑馬燈會(huì)常亮,28-30度時(shí)會(huì)隨著溫度的升高而加快。
3.6溫度傳感器及DS18B20測(cè)溫基本原理
DS18B20 數(shù)字溫度傳感器提供9位(二進(jìn)制)溫度讀數(shù)指示器件的溫度數(shù)據(jù)經(jīng)單線接口和CPU交互,因此CPU和DS18B20之間只需一條信號(hào)線和地址線即可進(jìn)行通信。
原理圖如下:
3.7單片機(jī)硬件連接實(shí)物圖
四、系統(tǒng)軟件算法設(shè)計(jì)
主程序 main.c
#include <reg51.h>
#include <intrins.h>
#include <stdio.h>
#include "lcm16x2p.h"
#include "DS18B20.h"
#define OSC 11059200 //晶振頻率
#define BAUDRATE 9600 //波特率
#define LCM_DB P2
sbit BUZ_CON = P0^7;
sbit LED =P0;
sbit LCM_BLC=P1^3;
void main(void)
{
unsigned char ucTH,ucTL,Ticks; //中斷程序
unsigned int i;
unsigned char tmph,tmpl;
Temp t;
unsigned char strTemp[8]; //顯示到屏幕的溫度數(shù)據(jù)
LCM_BLC = 0; //開(kāi)背光
TMOD = 0x21; //選擇方式2作為波特率發(fā)生
SCON = 0x50; //串口方式1,允許中斷
PCON |= 0x80; //SMOD=1
TL1 = 256 -(OSC/12/16/BAUDRATE);
TH1 = 256 -(OSC/12/16/BAUDRATE);
TR1 = 1; //啟動(dòng)定時(shí)器
TI = 1; //TI有效
//檢測(cè)DS18B20溫度傳感器是否存在并復(fù)位傳感器
if(DSReset())
printf("\r\Temp sensor ResetOK!");
else printf("\r\Temp Sensor Notready!");
while(1){
DSReset(); //復(fù)位傳感器
Delay(12);
DSWriteByte(SkipROM); //跳讀 省時(shí)
DSWriteByte(StartConvert); //溫度轉(zhuǎn)換
for(i=0;i<40000;i++);
DSReset();
Delay(12);
DSWriteByte(SkipROM);
DSWriteByte(ReadMemory); //讀RAM程序
tmpl = DSReadByte();
tmph = DSReadByte();
printf("\r\nTemperature code HI=%02bX,LO=%02bX ",tmph,tmpl);
DSReadTemp(&t);
//準(zhǔn)備輸出到顯示屏的數(shù)據(jù)
strTemp[0]=t.z/10+0x30; //十位
strTemp[1]=t.z%10+0x30; //個(gè)位
strTemp[2]='.'; //小數(shù)點(diǎn)
strTemp[3]=t.x/1000+0x30; //十分位
strTemp[4]=(t.x/100)%10+0x30; //百分位
strTemp[5]=(t.x/10)%10+0x30;//千分位
strTemp[6]=t.x%10+0x30; //萬(wàn)分位
strTemp[7]='C';
if(t.z>=30)
printf("\nWarning!!!Temperature= %d.%04d ",t.z,t.x) ; //大于30度溫度警告
else
printf("\r\nTemperature = %d.%04d",t.z,t.x);
//小于26度LED燈全亮
if(t.z<26)
{
P0=0x00;
}
else
{
P0=0xff; //燈滅
}
//大于28度流水燈循環(huán)(慢)
if(t.z>=28)
{
BUZ_CON=1;
P0=0xfd;
LCMDelay(60);
P0=0xfb;
LCMDelay(60);
P0=0xf7;
LCMDelay(60);
P0=0xdf;
LCMDelay(60);
//大于29度流水燈循環(huán)(快)
if(t.z>=29)
{
P0=0xfd;
LCMDelay(10);
P0=0xfb;
LCMDelay(10);
P0=0xf7;
LCMDelay(10);
P0=0xdf;
LCMDelay(10);
P0=0xbf;
LCMDelay(10);
}
//大于30度燈全亮。蜂鳴器響
if(t.z>=30)
{
BUZ_CON=0;
LCMDelay(100);
P0=0x00;
}
}
else{
BUZ_CON=1;
}
//初始化
EA = 0; // 停止所有中斷
Ticks = 0;
ucTH =(65536-OSC/12/20)/256; // 計(jì)算 50ms 定時(shí)的時(shí)間常數(shù)
ucTL =(65536-OSC/12/20)%256;
TMOD = 0x21; // T0:模式 1,16 位定時(shí)器
TH0 = ucTH;
TL0 = ucTL;
ET0 = 1; // T0 允許中斷
TR0 = 1; // 啟動(dòng)定時(shí)器
EA = 1; // 打開(kāi)總中斷允許
//輸出數(shù)據(jù)到顯示屏
LCMInit(); //初始化LCM顯示器
LCMClear(); //清屏
if(t.z>=30){
LCMDisplayString(0,0,"TempWarning!!!"); //大于29度警告
LCMDisplayString(1,0,"Temp:");
LCMDisplayString(1,6,strTemp);
}
else{
LCMDisplayString(0,0,"Temperature:");
LCMDisplayString(1,0,strTemp);
}
//閃爍(刷新)
for(i = 0; i < 16;i++)
LCMBlink(0,i,BLINK);
for(i = 0; i < 16;i++)
LCMBlink(1,i,BLINK);
}
}
子程序ds18b20.h文件
#ifndef __DS18B20H__
#define __DS18B20H__
#define ReadROM 0x33
#define MatchROM 0x55
#define ReadMemory 0xBE
#define SkipROM 0xCC
#define SearchROM 0xF0
#define StartConvert 0x44 //變換指令
typedef struct{
int z; //整數(shù)部分
int x; //小數(shù)部分
}Temp;
extern unsigned char ucTH,ucTL,Ticks; //外部引用
void Delay(unsigned int);
bit DSReset(void);
void DSWriteByte(char);
unsigned char DSReadByte(void);
void DSReadTemp(Temp *t);
#endif
ds18b20.c文件
#include "DS18B20.h"
#include <reg51.h>
#include <intrins.h>
sbit DQ = P0^0;
/*
Delay
通過(guò)循環(huán)計(jì)時(shí)
參數(shù):int,表示要延時(shí)的 毫秒 數(shù)
*/
void Delay(unsigned int i)
{ i=i*12;
while(i--);
}
/*
DSReset
復(fù)位DS18B20并返回是否存在
*/
bit DSReset(void)
{
bit x;
DQ = 1;
Delay(8);
DQ = 0; // 主機(jī)拉低總線
Delay(80); // 延時(shí)約 500 個(gè)機(jī)器周期
DQ = 1; // 主機(jī)釋放總線
Delay(8); // 延時(shí) 60 個(gè)機(jī)器周期
x = DQ;
Delay(20);
if(x == 0)
return 1;
else return 0;
}
/*
DSWriteByte
向 DS18820 寫入一個(gè)字節(jié)
*/
void DSWriteByte(unsigned char c)
{
unsigned char ic;
for( ic = 0; ic < 8;ic++ )
{
DQ = 0; //主機(jī)拉低總線,開(kāi)始寫位
DQ = c&0x01;
Delay(5); //延時(shí)60個(gè)機(jī)器周期
DQ = 1; //釋放總線
c >>= 1;
}
}
/*
DSReadByte
從溫度傳感器讀出一個(gè)字節(jié)
返回:讀出的字節(jié)
*/
unsigned char DSReadByte(void)
{
unsigned char c,ic;
c = 0;
for(ic = 0; ic < 8;ic++)
{
DQ = 0;
c >>= 1; //右移
DQ = 1;
if(DQ )
c |= 0x80;
Delay(4);
}
return c;
}
/*
DSReadTemp
讀出溫度
參數(shù):溫度(由整數(shù)和小數(shù)部分構(gòu)成)
*/
void DSReadTemp(Temp *t)
{
unsigned char tmpl,tmph;
DSReset();
Delay(12);
DSWriteByte(SkipROM);
DSWriteByte(StartConvert);
DSReset();
Delay(12);
DSWriteByte(SkipROM);
DSWriteByte(ReadMemory);
tmpl = DSReadByte();
tmph = DSReadByte();
t->z =(int)((tmph&0x07)<<4 | (tmpl&0xf0)>>4);
t->x =(int)((tmpl&0x0f)*625);
}
/*
T0ISR
50ms中斷服務(wù)程序
*/
void T0ISR(void) interrupt 1
{
unsigned char ucTH,ucTL,Ticks;
TH0 = ucTH;
TL0 = ucTL;
TR0 = 1;
Ticks ++;
if(Ticks == 20)
{
Ticks = 0;
}
}
lcm16x2p.h文件
#ifndef LCM16X2_H
#define LCM16X2_H
#define BUSYFLAG 0x80
#define BLINK 0X01
#define NOBLINE 0X00
unsigned char LCMReadState(void);
void LCMDelay(int);
void LCMWriteData(unsigned char);
void LCMWriteCmd(unsigned char);
void LCMClear(void);
void LCMInit(void);
void LCMGotoXY(unsigned char,unsigned char);
void LCMDisplay(unsigned char,unsigned char,unsigned char);
void LCMDisplayString(unsigned char,unsigned char,unsigned char*);
void LCMBlink(unsigned char,unsigned char,unsigned char);
#endif
llcm16x2p.c文件
#include <reg51.h>
#include <intrins.h>
#include "LCM16X2P.H"
#define LCM_DB P2
sbit LCM_RS = P1^0;
sbit LCM_RW = P1^1;
sbit LCM_E = P1^2;
sbit LCM_BLC = P1^3;
unsigned int data DelayConst = 140;
// 延時(shí)程序
void LCMDelay (int ms)
{
unsigned int i,cnt;
cnt = DelayConst * ms*12;
for(i=0;i<cnt;i++);
}
//查詢LCM忙的標(biāo)志
unsigned char LCMReadState(void)
{
unsigned char state;
LCM_E = 0;
LCM_RS = 0;
LCM_RW = 1;
LCM_E = 1;
_nop_();
_nop_();
state = LCM_DB;
LCM_E = 0;
return state;
}
//clear qingpin
void LCMClear(void)
{
LCMDelay(12);
LCM_E = 0;
LCM_RS = 0;
LCM_RW = 0;
LCM_DB = 0x01;
LCM_E = 1;
_nop_();
_nop_();
LCM_E = 0;
LCMDelay(12);
}
//writecmd xierukongzhizi
void LCMWriteCmd(unsigned char cmd)
{
LCMDelay(1);
LCM_E = 0;
LCM_RS = 0;
LCM_RW = 0;
LCM_DB = cmd;
LCM_E = 1;
_nop_();
_nop_();
LCM_E = 0;
}
//write data xierushuju
void LCMWriteData(unsigned char dc)
{
while (LCMReadState()&BUSYFLAG);
LCM_RS = 1;
LCM_RW = 0;
LCM_DB = dc;
LCM_E = 1;
_nop_();
_nop_();
LCM_E = 0;
}
// init chushihua
void LCMInit(void)
{
LCMDelay(720);
LCMWriteCmd(0x38);
LCMDelay(60);
LCMWriteCmd(0x38);
LCMDelay(12);
LCMWriteCmd(0x38);
while(LCMReadState()&BUSYFLAG);
LCMWriteCmd(0x08);
while(LCMReadState()&BUSYFLAG);
LCMWriteCmd(0x01);
while(LCMReadState()&BUSYFLAG);
LCMWriteCmd(0x06);
while(LCMReadState()&BUSYFLAG);
LCMWriteCmd(0x0e);
while(LCMReadState()&BUSYFLAG);
}
//gotoxy yidongguangbiaodao x hang y lie
void LCMGotoXY(unsigned char x, unsigned char y)
{
unsigned char cmd;
if(x==0)
{
cmd = 0x80|y;
}
else
{
cmd =0x80 | 0x40 |y ;
}
LCMWriteCmd(cmd);
while(LCMReadState() & BUSYFLAG);
}
//LCMDISPLAYchar zhidingweizhixianshizifu
void LCMDisplayChar(unsigned char x, unsigned char y,unsigned char ch)
{
LCMGotoXY(x,y);
LCMWriteData(ch);
}
//xianshizifuchan
void LCMDisplayString(unsigned char x,unsigned char y,unsigned char* str)
{
unsigned char ptr;
ptr=0;
while (*(str+ptr)!=0)
{
LCMDisplayChar(x,(y+ptr),*(str+ptr));
ptr++;
}
}
//LCMBLINK zifushanshuo
void LCMBlink(unsigned char x,unsigned char y, unsigned char cmd)
{
LCMGotoXY(x,y);
if(cmd == BLINK)
{
LCMWriteCmd(0x0d);
}
else
{
LCMWriteCmd(0x0c);
}
}
五、總結(jié)與體會(huì)
經(jīng)過(guò)一周的學(xué)習(xí)與努力,溫度顯示系統(tǒng)的設(shè)計(jì)終于完成了,真正的學(xué)到了東西。學(xué)習(xí)了單片機(jī)這門,感覺(jué)是有點(diǎn)難。也不明白整個(gè)學(xué)習(xí)過(guò)程是怎樣過(guò)來(lái)得,但是時(shí)間不等人。但是在學(xué)習(xí)中,我才發(fā)現(xiàn)學(xué)習(xí)單片機(jī)不僅僅僅需要軟件的知識(shí),還需要硬件的知識(shí)。沒(méi)有相應(yīng)的硬件知識(shí),我連單片機(jī)怎樣和電腦相連都不明白,我為我當(dāng)初的想法感到羞愧。單片機(jī)是一門很好的學(xué)問(wèn),需要我去鉆研它。一轉(zhuǎn)眼,一個(gè)學(xué)期又進(jìn)尾聲了,本學(xué)期的單片機(jī)綜合設(shè)計(jì)也在一周內(nèi)完成了。
說(shuō)起設(shè)計(jì),我認(rèn)為最重要的就是做好設(shè)計(jì)的預(yù)習(xí),認(rèn)真的研究老師給的題目,其次,老師對(duì)實(shí)驗(yàn)的講解要一絲不茍的去聽(tīng)去想,因?yàn)橹挥卸济靼琢,做起設(shè)計(jì)就會(huì)事半功倍,如果沒(méi)弄明白,就迷迷糊糊的去做設(shè)計(jì),到頭來(lái)一點(diǎn)收獲也沒(méi)有。最后,要重視程序的模塊化,修改的方便,也要注重程序的調(diào)試,掌握其方法。在享受我們成果之時(shí),不得不感慨單片機(jī)的重要性與高難度性,所以為期一周的單片機(jī)設(shè)計(jì)沒(méi)有浪費(fèi)我我們學(xué)到了很多知識(shí),也讓我對(duì)單片機(jī)有了更深一步的了解,雖然最后結(jié)果是出來(lái)了,可這與老師的精心指導(dǎo)是分不開(kāi)的她引導(dǎo)我們的思路,本來(lái)一竅不通的我經(jīng)過(guò)老師的點(diǎn)撥基本上通了,所以老師是功不可沒(méi)的。總而言之,單片機(jī)設(shè)計(jì)對(duì)于我有很大的幫忙,我從中受益匪淺。
|
-
18b20及實(shí)物圖
-
顯示模塊
-
硬件框圖
-
io口及拓展
-
-
-
溫度顯示報(bào)警代碼及報(bào)告.zip
2019-6-25 08:28 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
3.52 MB, 下載次數(shù): 28, 下載積分: 黑幣 -5
|