多點溫度采集系統,仿真+程序 LCD自動切換顯示多點溫度
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
搜狗截圖20181102221701.png (117.46 KB, 下載次數: 62)
下載附件
仿真
2018-11-2 22:19 上傳
#include <AT89X52.h>
#include <Intrins.h>
#define DATA P1 //1602驅動端口
//ROM操作命令
#define READ_ROM 0x33 //讀ROM
#define SKIP_ROM 0xCC //跳過ROM
#define MATCH_ROM 0x55 //匹配ROM
#define SEARCH_ROM 0xF0 //搜索ROM
#define ALARM_SEARCH 0xEC //告警搜索
//存儲器操作命令
#define ANEW_MOVE 0xB8 //重新調出E^2數據
#define READ_POWER 0xB4 //讀電源
#define TEMP_SWITCH 0x44 //啟動溫度變換
#define READ_MEMORY 0xBE //讀暫存存儲器
#define COPY_MEMORY 0x48 //復制暫存存儲器
#define WRITE_MEMORY 0x4E //寫暫存存儲器
//數據存儲結構
typedef struct tagTempData
{
unsigned char btThird; //百位數據
unsigned char btSecond; //十位數據
unsigned char btFirst; //個位數據
unsigned char btDecimal; //小數點后一位數據
unsigned char btNegative; //是否為負數
}TEMPDATA;
TEMPDATA m_TempData;
//引腳定義
sbit DQ = P2^7; //數據線端口
sbit RS= P2^0;
sbit RW= P2^1;
sbit E= P2^2;
//DS18B20序列號,通過調用GetROMSequence()函數在P1口讀出(讀8次)
const unsigned char code ROMData1[8] = {0x28, 0x33, 0xC5, 0xB8, 0x00, 0x00, 0x00, 0xD7}; //U1
const unsigned char code ROMData2[8] = {0x28, 0x30, 0xC5, 0xB8, 0x00, 0x00, 0x00, 0x8E}; //U2
const unsigned char code ROMData3[8] = {0x28, 0x31, 0xC5, 0xB8, 0x00, 0x00, 0x00, 0xB9}; //U3
const unsigned char code ROMData4[8] = {0x28, 0x32, 0xC5, 0xB8, 0x00, 0x00, 0x00, 0xE0}; //U4
const unsigned char code ROMData5[8] = {0x28, 0x34, 0xC5, 0xB8, 0x00, 0x00, 0x00, 0x52}; //U5
const unsigned char code ROMData6[8] = {0x28, 0x35, 0xC5, 0xB8, 0x00, 0x00, 0x00, 0x65}; //U6
const unsigned char code ROMData7[8] = {0x28, 0x36, 0xC5, 0xB8, 0x00, 0x00, 0x00, 0x3C}; //U7
const unsigned char code ROMData8[8] = {0x28, 0x37, 0xC5, 0xB8, 0x00, 0x00, 0x00, 0x0B}; //U8
//判斷忙指令
void Busy()
{
DATA = 0xff;
RS = 0;
RW = 1;
while(DATA & 0x80)
{
E = 0;
E = 1;
}
E = 0;
}
//寫指令程序
void WriteCommand(unsigned char btCommand)
{
Busy();
RS = 0;
RW = 0;
E = 1;
DATA = btCommand;
E = 0;
}
//寫數據程序
void WriteData(unsigned char btData)
{
Busy();
RS = 1;
RW = 0;
E = 1;
DATA = btData;
E = 0;
}
//清屏顯示
void Clear()
{
WriteCommand(1);
}
//初始化
void Init()
{
WriteCommand(0x0c); //開顯示,無光標顯示
WriteCommand(0x06); //文字不動,光標自動右移
WriteCommand(0x38); //設置顯示模式:8位2行5x7點陣
}
//顯示單個字符
void DisplayOne(bit bRow, unsigned char btColumn, unsigned char btData, bit bIsNumber)
{
if (bRow) WriteCommand(0xc0 + btColumn);
else WriteCommand(0x80 + btColumn);
if (bIsNumber) WriteData(btData + 0x30);
else WriteData(btData);
}
//顯示字符串函數
void DisplayString(bit bRow, unsigned char btColumn, unsigned char *pData)
{
while (*pData != '\0')
{
if (bRow) WriteCommand(0xc0 + btColumn); //顯示在第1行
else WriteCommand(0x80 + btColumn); //顯示在第0行
WriteData(*(pData++)); //要顯示的數據
btColumn++; //列數加一
}
}
//延時16us子函數
void Delay16us()
{
unsigned char a;
for (a = 0; a < 4; a++);
}
//延時60us子函數
void Delay60us()
{
unsigned char a;
for (a = 0; a < 18; a++);
}
//延時480us子函數
void Delay480us()
{
unsigned char a;
for (a = 0; a < 158; a++);
}
//延時240us子函數
void Delay240us()
{
unsigned char a;
for (a = 0; a < 78; a++);
}
//延時500ms子函數
void Delay500ms()
{
unsigned char a, b, c;
for (a = 0; a < 250; a++)
for (b = 0; b < 3; b++)
for (c = 0; c < 220; c++);
}
//芯片初始化
void Initialization()
{
while(1)
{
DQ = 0;
Delay480us(); //延時480us
DQ = 1;
Delay60us(); //延時60us
if(!DQ) //收到ds18b20的應答信號
{
DQ = 1;
Delay240us(); //延時240us
break;
}
}
}
//寫一個字節(從低位開始寫)
void WriteByte(unsigned char btData)
{
unsigned char i, btBuffer;
for (i = 0; i < 8; i++)
{
btBuffer = btData >> i;
if (btBuffer & 1)
{
DQ = 0;
_nop_();
_nop_();
DQ = 1;
Delay60us();
}
else
{
DQ = 0;
Delay60us();
DQ = 1;
}
}
}
//讀一個字節(從低位開始讀)
unsigned char ReadByte()
{
unsigned char i, btDest;
for (i = 0; i < 8; i++)
{
btDest >>= 1;
DQ = 0;
_nop_();
_nop_();
DQ = 1;
Delay16us();
if (DQ) btDest |= 0x80;
Delay60us();
}
return btDest;
}
//序列號匹配
void MatchROM(const unsigned char *pMatchData)
{
unsigned char i;
Initialization();
WriteByte(MATCH_ROM);
for (i = 0; i < 8; i++) WriteByte(*(pMatchData + i));
}
//得到64位ROM序列(在P1口顯示,必須與Proteus聯調且在單步調試下才能得到)
/*void GetROMSequence()
{
unsigned char i;
Initialization();
WriteByte(READ_ROM);
for (i = 0; i < 8; i++)
P1 = ReadByte();
}*/
//讀取溫度值
TEMPDATA ReadTemperature()
{
TEMPDATA TempData;
unsigned int iTempDataH;
unsigned char btDot, iTempDataL;
static unsigned char i = 0;
TempData.btNegative = 0; //為0溫度為正
i++;
if (i == 9) i = 1;
Initialization();
WriteByte(SKIP_ROM); //跳過ROM匹配
WriteByte(TEMP_SWITCH); //啟動轉換
Delay500ms(); //調用一次就行
Delay500ms();
Initialization();
//多個芯片的時候用MatchROM(ROMData)換掉WriteByte(SKIP_ROM)
switch (i)
{
case 1 : MatchROM(ROMData1); break; //匹配1
case 2 : MatchROM(ROMData2); break; //匹配2
case 3 : MatchROM(ROMData3); break; //匹配3
case 4 : MatchROM(ROMData4); break; //匹配4
case 5 : MatchROM(ROMData5); break; //匹配5
case 6 : MatchROM(ROMData6); break; //匹配6
case 7 : MatchROM(ROMData7); break; //匹配7
case 8 : MatchROM(ROMData8); break; //匹配8
}
//WriteByte(SKIP_ROM); //跳過ROM匹配(單個芯片時用這句換掉上面的switch)
WriteByte(READ_MEMORY); //讀數據
iTempDataL = ReadByte();
iTempDataH = ReadByte();
iTempDataH <<= 8;
iTempDataH |= iTempDataL;
if (iTempDataH & 0x8000)
{
TempData.btNegative = 1;
iTempDataH = ~iTempDataH + 1; //負數求補
}
//為了省去浮點運算帶來的開銷,而采用整數和小數部分分開處理的方法(沒有四舍五入)
btDot = (unsigned char)(iTempDataH & 0x000F); //得到小數部分
iTempDataH >>= 4; //得到整數部分
btDot *= 5; //btDot*10/16得到轉換后的小數數據
btDot >>= 3;
......部分下載解壓包可看全部
全部資料51hei下載地址:
多點溫度采集系統LCD1602 仿真 程序.rar
(75.72 KB, 下載次數: 217)
2018-11-2 22:20 上傳
點擊文件名下載附件
多點溫度采集系統LCD1602+仿真+程序 下載積分: 黑幣 -5
|