能夠同時檢測10個DS18B20的溫度結果。在LCD1620上輪流顯示。也可以通過串口向上位機發送10個溫度的值,但需要上位機向單片機提出請求;具體看程序嘛。
單片機源程序如下:
#include <reg51.h>
#include <Intrins.h>
//DS18B20 相關定義開始
//存儲器操作命令
#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 //寫暫存存儲器
//引腳定義
sbit DQ = P3^7; //溫度數據線端口
//DS18B20序列號,通過調用GetROMSequence()函數在P0口讀出(讀10次)
const unsigned char code ROMData1[8] = {0x28, 0xFF, 0x4D, 0x29, 0x22, 0x17, 0x03, 0x15};
const unsigned char code ROMData2[8] = {0x28, 0xFF, 0xEC, 0xEA, 0x21, 0x17, 0x04, 0x3D};
const unsigned char code ROMData3[8] = {0x28, 0x2B, 0x88, 0x77, 0x91, 0x08, 0x02, 0xC2};
const unsigned char code ROMData4[8] = {0x28, 0x32, 0x07, 0x77, 0x91, 0x04, 0x02, 0xE6};
const unsigned char code ROMData5[8] = {0x28, 0x22, 0x04, 0x77, 0x91, 0x12, 0x02, 0xB5};
const unsigned char code ROMData6[8] = {0x28, 0xD5, 0xF0, 0x16, 0xA8, 0x01, 0x3C, 0xAC};
const unsigned char code ROMData7[8] = {0x28, 0x75, 0x68, 0x16, 0xA8, 0x01, 0x3C, 0x79};
const unsigned char code ROMData8[8] = {0x28, 0x69, 0x5B, 0x16, 0xA8, 0x01, 0x3C, 0x95};
const unsigned char code ROMData9[8] = {0x28, 0xA3, 0x21, 0x16, 0xA8, 0x01, 0x3C, 0x15};
const unsigned char code ROMData10[8] = {0x28, 0xBA, 0x04, 0x16, 0xA8, 0x01, 0x3C, 0xF2};
//數據存儲結構
typedef struct tagTempData
{
unsigned char btThird; //百位數據
unsigned char btSecond; //十位數據
unsigned char btFirst; //個位數據
unsigned char btDecimal; //小數點后一位數據
unsigned char btNegative; //是否為負數
}TEMPDATA;
TEMPDATA m_TempData;
unsigned char RomI=0;
//DS18B20 相關定義結束
//LCD1602 相關定義開始
#define DATA P0 //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 //告警搜索
//控制端口定義
sbit RS= P2^6;
sbit RW= P2^5;
sbit E= P2^7;
//LCD1602 相關定義結束
//RS232 相關定義開始
unsigned char ReData,SenData;
bit flag=0; //串口標志位
//RS232 相關定義結束
void DisplayOne(bit bRow, unsigned char btColumn, unsigned char btData, bit bIsNumber);
unsigned char SendData[8]={' ',' ',' ',' ',' ','.',' ','@'};
//Delay 延時函數
/**************************
函數:Delay16us()
功能:延時16us
參數:無
返回:無
**************************/
void Delay16us()
{
unsigned char a;
for (a = 0; a < 4; a++);
}
/**************************
函數:Delay60us()
功能:延時60us
參數:無
返回:無
**************************/
void Delay60us()
{
unsigned char a;
for (a = 0; a < 18; a++);
}
/**************************
函數:Delay480us()
功能:延時480us
參數:無
返回:無
**************************/
void Delay480us()
{
unsigned char a;
for (a = 0; a < 158; a++);
}
/**************************
函數:Delay240us()
功能:延時240us
參數:無
返回:無
**************************/
void Delay240us()
{
unsigned char a;
for (a = 0; a < 78; a++);
}
/**************************
函數:Delay240us()
功能:延時240us
參數:無
返回:無
**************************/
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++);
}
//延時函數結束
//********************DS18B20
/**************************
函數:Initialization()
功能:DS18B20初始化程序
參數:無
返回:無
**************************/
void Initialization()
{
while(1)
{
DQ = 0;
Delay480us(); //延時480us
DQ = 1;
Delay60us(); //延時60us
if(!DQ) //收到ds18b20的應答信號
{
DQ = 1;
Delay240us(); //延時240us
break;
}
}
}
/**************************
函數:WriteByte(unsigned char btData)
功能:DS18B20從低位開始寫一個字節
參數:無
返回:無
**************************/
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;
}
}
}
/**************************
函數:ReadByte()
功能:DS18B20從低位開始讀一個字節
參數:無
返回:無
**************************/
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;
}
/**************************
函數:MatchROM(const unsigned char *pMatchData)
功能:DS18B20序列號匹配
參數:無
返回:無
**************************/
void MatchROM(const unsigned char *pMatchData)
{
unsigned char i;
Initialization();
WriteByte(MATCH_ROM);
for (i = 0; i < 8; i++) WriteByte(*(pMatchData + i));
}
/**************************
函數:GetROMSequence()
功能:DS18B20Rom序列獲取,在P0口顯示
參數:無
返回:無
**************************
void GetROMSequence()
{
unsigned char i;
Initialization();
WriteByte(READ_ROM);
for (i = 0; i < 10; i++)
P0 = ReadByte();
}
*/
/**************************
函數:ReadTemperature()
功能:DS18B20讀取溫度值多點
參數:無
返回:TempData
**************************/
TEMPDATA ReadTemperature()
{
TEMPDATA TempData;
unsigned int iTempDataH;
unsigned char btDot, iTempDataL;
//static unsigned char i = 0;
TempData.btNegative = 0; //為0溫度為正
RomI++;
if (RomI == 11) RomI = 1;
Initialization();
WriteByte(SKIP_ROM); //跳過ROM匹配
WriteByte(TEMP_SWITCH); //啟動轉換
Delay500ms(); //調用一次就行
Delay500ms();
Initialization();
//多個芯片的時候用MatchROM(ROMData)換掉WriteByte(SKIP_ROM)
switch (RomI)
{
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
case 9 : MatchROM(ROMData9); break; //匹配8
case 10 : MatchROM(ROMData10); 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;
//數據處理
TempData.btThird = (unsigned char)iTempDataH / 100;
TempData.btSecond = (unsigned char)iTempDataH % 100 / 10;
TempData.btFirst = (unsigned char)iTempDataH % 10;
TempData.btDecimal = btDot;
return TempData;
}
/**************************
函數:ReadOneTemperature()
功能:DS18B20讀取單個溫度值
參數:無
返回:TempData
**************************
TEMPDATA ReadOneTemperature()
{
TEMPDATA TempData;
unsigned int iTempDataH;
unsigned char btDot, iTempDataL;
static unsigned char i = 0;
TempData.btNegative = 0; //為0溫度為正
i++;
if (i == 11) i = 1;
Initialization();
WriteByte(SKIP_ROM); //跳過ROM匹配
WriteByte(TEMP_SWITCH); //啟動轉換
Delay500ms(); //調用一次就行
Delay500ms();
Initialization();
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;
//數據處理
TempData.btThird = (unsigned char)iTempDataH / 100;
TempData.btSecond = (unsigned char)iTempDataH % 100 / 10;
TempData.btFirst = (unsigned char)iTempDataH % 10;
TempData.btDecimal = btDot;
return TempData;
}
*/
/**************************
函數:DataProcess()
功能:LCD1602顯示溫度數據處理
參數:無
返回:無
**************************/
void DataProcess()
{
m_TempData = ReadTemperature();
if (m_TempData.btNegative)
{
DisplayOne(1, 6, '-', 0);
SendData[1]='-';
}
else
DisplayOne(1, 6, m_TempData.btThird, 1);
DisplayOne(1, 7, m_TempData.btSecond, 1);
DisplayOne(1, 8, m_TempData.btFirst, 1);
DisplayOne(1, 10, m_TempData.btDecimal, 1);
SendData[1]=' ';
}
//DS18B20 程序結束
//LCD1602 程序開始
/**************************
函數:Busy()
功能:判斷LCD忙指令
參數:無
返回:無
**************************/
void Busy()
{
DATA = 0xff;
RS = 0;
RW = 1;
while(DATA & 0x80)
{
E = 0;
E = 1;
}
E = 0;
}
/**************************
函數:WriteCommand()
功能:寫LCD指令程序
參數:btCommand
返回:無
**************************/
void WriteCommand(unsigned char btCommand)
{
Busy();
RS = 0;
RW = 0;
E = 1;
DATA = btCommand;
E = 0;
}
/**************************
函數:WriteData()
功能:寫LCD數據程序
參數:btData
返回:無
**************************/
void WriteData(unsigned char btData)
{
Busy();
RS = 1;
RW = 0;
E = 1;
DATA = btData;
E = 0;
}
/**************************
函數:Clear()
功能:LCD清屏
參數:無
返回:無
**************************/
void Clear()
{
WriteCommand(1);
}
/**************************
函數:Init()
功能:初始化LCD
參數:無
返回:無
**************************/
void Init()
{
WriteCommand(0x0c); //開顯示,無光標顯示
WriteCommand(0x06); //文字不動,光標自動右移
WriteCommand(0x38); //設置顯示模式:8位2行5x7點陣
}
/**************************
函數:DisplayOne()
功能:顯示單個字符
參數:bRow,btColum,btData,bIsNumber
返回:無
**************************/
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);
}
/**************************
函數:DisplayString()
功能:顯示字符串
參數:bRow,btColum,*pData
返回:無
**************************/
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++; //列數加一
}
}
//LCD1602 程序結束
//RS232 程序開始
/**************************
函數:RS232_Init()
功能:串口通信初始化程序,T1端口
參數:無
返回:無
**************************/
void RS232_Init()
{
TMOD|= 0x20; //定時器工作方式2
SCON = 0x50; //REN=1允許串行接受狀態,串口工作模式1
TH1 = 0xF3; //2400,12m
TL1 = TH1;
PCON|= 0x80;
TR1 = 1;
EA = 1;
ES = 1;
}
/**************************
函數:SendOneByte(unsigned char c)
功能:串口發送程序
參數:c
返回:無
**************************/
void SendOneByte(unsigned char c)
{
SBUF = c;
while(!TI);
TI = 0;
}
/**************************
函數:ser_int (void) interrupt 4 using 1
功能:串口接收程序中斷
參數:無
返回:無
**************************/
void ser_int (void) interrupt 4 using 1
{
if(RI) //RI接受中斷標志
{
RI = 0; //清除RI接受中斷標志
ReData = SBUF; //SUBF接受/發送緩沖器
flag=1;
}
}
//RS232 程序結束
void main(void)
{
unsigned char Nu[10][2]={"1 ","2 ","3 ","4 ","5 ","6 ","7 ","8 ","9 ","10"};
unsigned char Nui[10]={'A','B','C','D','E','F','G','H','I','J'};
// unsigned char c;
int i=0,j;
Init();
RS232_Init();
Clear();
DisplayString(0, 0, "10 POI.TEMP.DET.");
DisplayOne(1, 9, '.', 0);
while (1)
{
//while(!flag);
//ReData=SBUF;
if(ReData=='K')
{
ReData=' ';
RomI=0;
i=0;
for(;i<10;)
{
DataProcess();
DisplayOne(1, 1, Nu[ i][0], 0);
DisplayOne(1, 2, Nu[ i][1], 0);
SendData[0]=Nui[ i];
SendData[2]=m_TempData.btThird+0X30;
SendData[3]=m_TempData.btSecond+0X30;
SendData[4]=m_TempData.btFirst+0X30;
SendData[6]=m_TempData.btDecimal+0X30;
for(j=0;j<8;j++)
SendOneByte(SendData[j]);
i++;
}
if(i==10)
SendOneByte('*');//*表示10個數據發送完成
}
else
{
DataProcess();
DisplayOne(1, 1, Nu[ i][0], 0);
DisplayOne(1, 2, Nu[ i][1], 0);
i++;
}
if(i==10)
{
i=0;
}
}
}
全部資料51hei下載地址:
DS18B20-10-pots.zip
(3.71 KB, 下載次數: 42)
2020-5-17 14:44 上傳
點擊文件名下載附件
C文件 下載積分: 黑幣 -5
|