📄 main3.c
字号:
/************************************************************
*DS18B20驱动程序,DQ为数据口,接于P3.4
*11.0592M晶振,上拉10k电阻
* 所用CPU :STC12C54XX
*************************************************************/
#include<STC12C5410AD.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
//定时器0
#define TIMER0_10ms_H 0xDC //延时10ms 参数,CCLK = 11.0592 MHz
#define TIMER0_10ms_L 0x00
sbit P3_7 = P3^7;
sbit WDT = P3^5; //看门狗
sbit DQ = P3^4; //串行数据口
bit Flag;
uint Temperature; //温度值
uchar temp_buff[9]; //存储读取的字节,read scratchpad为9字节,read rom ID为8字节
uchar ID_buff[8]; //DS18B20 ID
uchar *p;
uchar comData;
uchar code CrcTable [256]={ 0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220,
35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98,
190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7,
219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154,
101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36,
248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185,
140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139,
87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53 };
//函数声明
void TempDelay (uchar);
void TempDelay100ms(uchar);
void UART_init(void);
void send(uchar);
void Init18B20 (void);
void WriteByte (uchar);
uchar ReadByte (void);
void read_18B20 (uchar);
uchar CRC (uchar);
void GemTemp (void);
void Config18b20 (void);
void ReadID (void);
void TemperatuerResult(void);
//主函数
main()
{ uchar TMP[10];
uchar temp[9];
uchar i,j;
UART_init();
Flag = 0;
EA = 1; //禁止所有的中断
/*
TemperatuerResult();
temp = (Temperature>>8) & 0x00FF;
send(temp);
temp = Temperature & 0x00FF;
send(temp);
*/
while(1)
{ WDT = !WDT;
if(comData == 0xA0)
{ EA = 0;
comData = 0x00;
/*
Init18B20();
WriteByte(0x33); //read ID
p = ID_buff;
read_18B20(8);
send(0xAA);
for(i=0;i<8;i++)
send(ID_buff[i]);
*/
//for(j=0;j<10;j=j+2)
Init18B20 (); //复位
WriteByte(0xCC); //skip rom
WriteByte(0x44); //开始温度转换
DQ = 1; //延时1S 等待温度转换完成
TempDelay100ms (5);
//TempDelay100ms (5);
Init18B20 (); //复位
WriteByte(0xCC); //skip rom
WriteByte(0xBE); //读取暂存器和CRC 字节
/*
for(k = 0;k<9;k++)
temp[k] = ReadByte();
Init18B20 ();
TMP[j] = ReadByte();
TMP[j+1] = ReadByte();
Init18B20 (); //放弃读取
}
send(0xAA);
for(i=0;i<10;i++)
send(TMP[i]);
for(i = 0;i<9;i++)
TMP[i] = ReadByte();
Init18B20 ();
send(0xEE);
for(i=0;i<9;i++)
send(TMP[i]);
*/
for(i = 0;i<9;i++)
TMP[i] = ReadByte();
send(0xAA);
send(TMP[1]);
send(TMP[0]);
EA = 1;
}
//TempDelay100ms (5);
}
}
/************************************************************
*Function:延时1us处理
*************************************************************/
void TempDelay (uchar us)
{
while(us--);
}
/************************************************************
*Function:延时100ms处理
*************************************************************/
void TempDelay100ms (uchar us)
{ uchar i,j;
for(j=0;j<us;j++)
for(i=0;i<100;i++)
{ TempDelay(250);
TempDelay(250);
TempDelay(250);
TempDelay(250);
}
}
//串行口初始化
void UART_init(void)
{ P1M0 = 0x01; //设置P32,P33,P34,P35,P37为推挽输出状态
P1M1 = 0x01;
P3M0 = 0x10;
P3M1 = 0x10;
//初始化串行口和波特率发生器
SCON = 0x50; //选择串口工作方式1,打开接收允许
TMOD = 0x20; //定时器1工作在方式2,定时器0工作在方式1
TH1 = 0xFD; //当SMOD=0时,其初值计算如下:初值 = 256 -(F/B/32/X)(其中X为分频数) X = 6
TL1 = 0XFD; //实现波特率9600(系统时钟 11.0592 MHZ)
TH0 = TIMER0_10ms_H;
TL0 = TIMER0_10ms_L ;
TR1 = 1; //启动定时器T1
ET1 = 0; //禁止T1中断
AUXR = 0xBF; //此句改为AUXR = 0x40 ,波特率可以加倍12倍
ES = 1; //允许串行口中断
//PS = 1; //设置串行口中断优先级
EA = 0; //禁止所有中断
P3_7 = 0;
}
//串口发送子程序
void send(uchar cmd)
{
P3_7 = 1;
SBUF = cmd;
while(!TI);
TI=0;
P3_7 = 0;
}
/************************************************************
*Function:18B20初始化
*************************************************************/
void Init18B20 (void)
{ DQ = 1;
_nop_();
DQ = 0;
TempDelay(150); //延时 480 uS
TempDelay(200);
TempDelay(200);
//_nop_();
DQ = 1;
TempDelay(60); //延时 60 uS
//_nop_();
if(DQ == 0)
Flag = 1; //检测到总线上有 DS1820
else
Flag = 0; //没有检测到总线上的 DS1820
TempDelay(250); //250
TempDelay(200);
//_nop_();
//_nop_();
DQ = 1; //释放DS18B20总线
}
/************************************************************
*Function:向18B20写入一个字节
*************************************************************/
void WriteByte (uchar WR) //单字节写入
{ uchar i;
for (i = 0;i < 8;i++)
{ DQ = 0; //写时间隙开始
TempDelay(16); //DS18B20总线复位保持16us
DQ = WR & 0x01; //写一个bit
TempDelay(45); //等待 45 uS
//_nop_();
WR >>= 1;
DQ = 1; //释放总线准备写入下一位
_nop_(); //1us 恢复时间
}
DQ = 1; //释放DS18B20总线
}
/************************************************************
*Function:读18B20的一个字节
*************************************************************/
uchar ReadByte (void) //读取单字节
{ uchar i,u = 0;
for(i = 0;i < 8;i++)
{ u >>= 1;
DQ = 0; //读时间隙开始
_nop_();
DQ = 1; //开始读,总线释放
TempDelay(8); //持续 8 uS
if(DQ == 1)
u |= 0x80; //从DS18B20读得一位bit
TempDelay(45); //持续 60 uS
DQ = 1; //释放总线准备读下一位
_nop_(); //1us 恢复时间
}
DQ = 1; //重新释放DS18B20 总线
return(u); //返回从DS18B20总线上获得的数据
}
/************************************************************
*Function:读18B20
*************************************************************/
void read_18B20 (uchar j)
{ uchar i;
for(i = 0;i < j;i++)
{ *p = ReadByte();
p++;
}
}
/************************************************************
*Function:CRC校验
*************************************************************/
uchar CRC (uchar j)
{ uchar i,crc_data = 0;
for(i = 0;i < j;i++) //查表校验
crc_data = CrcTable[crc_data^temp_buff[i]];
return (crc_data);
}
/************************************************************
*Function:读取温度
*************************************************************/
void GemTemp (void)
{ read_18B20 (9);
if (CRC(9) == 0) //校验正确
{ Temperature = temp_buff[1]*0x100 + temp_buff[0];
//Temperature *= 0.0625;
Temperature /= 16;
TempDelay(1);
}
}
/************************************************************
*Function:内部配置
*************************************************************/
void Config18b20 (void) //重新配置报警限定值和分辨率
{ Init18B20();
WriteByte(0xCC); //skip rom
WriteByte(0x4E); //WRite scratchpad
WriteByte(0x19); //上限
WriteByte(0x1A); //下限
WriteByte(0x7F); //set 11 bit (0.125)
Init18B20();
WriteByte(0xCC); //skip rom
WriteByte(0x48); //保存设定值
Init18B20();
WriteByte(0xCC); //skip rom
WriteByte(0xB8); //回调设定值
}
/************************************************************
*Function:读18B20ID
*************************************************************/
void ReadID (void) //读取器件 id
{ Init18B20();
WriteByte(0x33); //read rom
read_18B20(8);
}
/************************************************************
*Function:18B20ID全处理
*************************************************************/
void TemperatuerResult(void)
{ p = ID_buff;
ReadID(); //读取ID
Config18b20(); //内部配置
Init18B20 (); //复位
WriteByte(0xCC); //skip rom
WriteByte(0x44); //开始温度转换
DQ = 1;
TempDelay(200);
TempDelay(200);
TempDelay(200);
Init18B20 (); //复位
WriteByte(0xCC); //skip rom
WriteByte(0xBE); //读取暂存器和CRC 字节
p = temp_buff;
GemTemp();
}
//串口接收中断
void uart_isr() interrupt 4
{
EA = 0;
comData = SBUF; //接收数据
RI = 0;
EA = 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -