• 方案介紹
    • 1.? 簡介
    • 2.? 主要功能
    • 3.? 源程序(Keil5)
    • 4.? 仿真proteus8.6
    • 5.? 設(shè)計(jì)報(bào)告
    • 6.? 資料清單
  • 附件下載
  • 相關(guān)推薦
申請入駐 產(chǎn)業(yè)圖譜

基于51單片機(jī)的溫度補(bǔ)償?shù)某暡y距系統(tǒng)設(shè)計(jì)(二)

04/11 08:37
547
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

單片機(jī)仿真設(shè)計(jì)合集資料獲取.pdf

共1個(gè)文件

資料清單:C程序+仿真+設(shè)計(jì)報(bào)告+使用說明+元件清單+操作視頻

仿真版本:Proteus8.6及以上版本

程序編譯:Keil5 C51

編程語言:C語言

設(shè)計(jì)編號:【H04】

1.? 簡介

? 本文提出了一種基于51單片機(jī)的帶溫度補(bǔ)償?shù)?a class="article-link" target="_blank" href="/tag/%E8%B6%85%E5%A3%B0%E6%B3%A2%E6%B5%8B%E8%B7%9D/">超聲波測距系統(tǒng)。該設(shè)計(jì)使用AT89C51單片機(jī)、DS18B20溫度傳感器模塊、HC_SR04超聲波測距模塊LCD1602顯示模塊以及聲光報(bào)警模塊。用戶可設(shè)置報(bào)警閾值,當(dāng)實(shí)際距離小于設(shè)定閾值時(shí)啟動聲光報(bào)警。

2.? 主要功能

a.通過LCD1602顯示實(shí)際距離、報(bào)警閾值、當(dāng)前溫度。

b.通過獨(dú)立按鍵設(shè)置報(bào)警閾值。

c.當(dāng)實(shí)際距離小于設(shè)定閾值時(shí)啟動聲光報(bào)警,并且報(bào)警頻率隨著距離減小而增加。

3.? 源程序(Keil5)

本設(shè)計(jì)采用keil5 C51軟件(內(nèi)附安裝包)實(shí)現(xiàn)程序設(shè)計(jì)。如需用keil4打開程序,可自行通過.c和.h文件新建工程即可。

#include <reg52.h>
#include <intrins.h>

#define uchar unsigned char	// 以后unsigned char就可以用uchar代替
#define uint  unsigned int	// 以后unsigned int 就可以用uint 代替

sfr ISP_DATA  = 0xe2;			// 數(shù)據(jù)寄存器
sfr ISP_ADDRH = 0xe3;			// 地址寄存器高八位
sfr ISP_ADDRL = 0xe4;			// 地址寄存器低八位
sfr ISP_CMD   = 0xe5;			// 命令寄存器
sfr ISP_TRIG  = 0xe6;			// 命令觸發(fā)寄存器
sfr ISP_CONTR = 0xe7;			// 命令寄存器


sbit LcdRs_P   = P2^7;		// 1602液晶的RS管腳       
//sbit LcdRw_P   = P2^6;		// 1602液晶的RW管腳 
sbit LcdEn_P   = P2^6;		// 1602液晶的EN管腳
sbit Trig_P    = P2^0;		// 超聲波模塊的Trig管腳
sbit Echo_P    = P2^1;		// 超聲波模塊的Echo管腳
sbit KeySet_P  = P1^1;		// “設(shè)置”按鍵的管腳
sbit KeyDown_P = P1^3;		// “減”按鍵的管腳
sbit KeyUp_P   = P1^2;		// “加”按鍵的管腳
sbit Buzzer_P  = P1^0;		// 蜂鳴器的管腳
sbit Led_P     = P1^0;		// LED報(bào)警燈的管腳
sbit DQ        = P1^4;		// 溫度傳感器的引腳定義


uint  gAlarm;							// 報(bào)警距離變量
float gSpeed;							// 保存超聲波的速度值



/*********************************************************/
// 單片機(jī)內(nèi)部EEPROM不使能
/*********************************************************/
void ISP_Disable()
{
	ISP_CONTR = 0;
	ISP_ADDRH = 0;
	ISP_ADDRL = 0;
}


/*********************************************************/
// 從單片機(jī)內(nèi)部EEPROM讀一個(gè)字節(jié),從0x2000地址開始
/*********************************************************/
unsigned char EEPROM_Read(unsigned int add)
{
	ISP_DATA  = 0x00;
	ISP_CONTR = 0x83;
	ISP_CMD   = 0x01;
	ISP_ADDRH = (unsigned char)(add>>8);
	ISP_ADDRL = (unsigned char)(add&0xff);
	// 對STC89C51系列來說,每次要寫入0x46,再寫入0xB9,ISP/IAP才會生效
	ISP_TRIG  = 0x46;	   
	ISP_TRIG  = 0xB9;
	_nop_();
	ISP_Disable();
	return (ISP_DATA);
}


/*********************************************************/
// 往單片機(jī)內(nèi)部EEPROM寫一個(gè)字節(jié),從0x2000地址開始
/*********************************************************/
void EEPROM_Write(unsigned int add,unsigned char ch)
{
	ISP_CONTR = 0x83;
	ISP_CMD   = 0x02;
	ISP_ADDRH = (unsigned char)(add>>8);
	ISP_ADDRL = (unsigned char)(add&0xff);
	ISP_DATA  = ch;
	ISP_TRIG  = 0x46;
	ISP_TRIG  = 0xB9;
	_nop_();
	ISP_Disable();
}


/*********************************************************/
// 擦除單片機(jī)內(nèi)部EEPROM的一個(gè)扇區(qū)
// 寫8個(gè)扇區(qū)中隨便一個(gè)的地址,便擦除該扇區(qū),寫入前要先擦除
/*********************************************************/
void Sector_Erase(unsigned int add)	  
{
	ISP_CONTR = 0x83;
	ISP_CMD   = 0x03;
	ISP_ADDRH = (unsigned char)(add>>8);
	ISP_ADDRL = (unsigned char)(add&0xff);
	ISP_TRIG  = 0x46;
	ISP_TRIG  = 0xB9;
	_nop_();
	ISP_Disable();
}



/*********************************************************/
// 毫秒級的延時(shí)函數(shù),time是要延時(shí)的毫秒數(shù)
/*********************************************************/
void DelayMs(uint time)
{
	uint i,j;
	for(i=0;i<time;i++)
		for(j=0;j<112;j++);
}


/*********************************************************/
// 延時(shí)15微秒
/*********************************************************/
void Delay15us(void)
{
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
}


/*********************************************************/
// 1602液晶寫命令函數(shù),cmd就是要寫入的命令
/*********************************************************/
void LcdWriteCmd(uchar cmd)
{ 
	LcdRs_P = 0;
//	LcdRw_P = 0;
	LcdEn_P = 0;
	P0=cmd;
	DelayMs(2);
	LcdEn_P = 1;    
	DelayMs(2);
	LcdEn_P = 0;	
}


/*********************************************************/
// 1602液晶寫數(shù)據(jù)函數(shù),dat就是要寫入的數(shù)據(jù)
/*********************************************************/
void LcdWriteData(uchar dat)
{
	LcdRs_P = 1; 
	//LcdRw_P = 0;
	LcdEn_P = 0;
	P0=dat;
	DelayMs(2);
	LcdEn_P = 1;    
	DelayMs(2);
	LcdEn_P = 0;
}


/*********************************************************/
// 1602液晶初始化函數(shù)
/*********************************************************/
void LcdInit()
{
	LcdWriteCmd(0x38);        // 16*2顯示,5*7點(diǎn)陣,8位數(shù)據(jù)口
	LcdWriteCmd(0x0C);        // 開顯示,不顯示光標(biāo)
	LcdWriteCmd(0x06);        // 地址加1,當(dāng)寫入數(shù)據(jù)后光標(biāo)右移
	LcdWriteCmd(0x01);        // 清屏
}


/*********************************************************/
// 液晶光標(biāo)定位函數(shù)
/*********************************************************/
void LcdGotoXY(uchar line,uchar column)
{
	// 第一行
	if(line==0)        
		LcdWriteCmd(0x80+column); 
	// 第二行
	if(line==1)        
		LcdWriteCmd(0x80+0x40+column); 
}



/*********************************************************/
// 液晶輸出字符串函數(shù)
/*********************************************************/
void LcdPrintStr(uchar *str)
{
	while(*str!='