📄 ds18b20._c
字号:
// Target : M8
// Crystal: 8.0000Mhz
/*******************************************************************************
* 不可在RESET时做LCD显示,因为DS18B20的复位回应时间只有80us,显示一个字符的时间
远大于这个值
*
*******************************************************************************/
#include <iom8v.h>
#include <macros.h>
#define LCM_Data PORTB
#define Busy 0x80
#define Set_DQ1 DDRC |= 0x08; PORTC |= 0x08; //总线拉高
#define Set_DQ0 DDRC |= 0x08; PORTC &= 0xf7; //总线置低
#define Read_DQ PINC&0x08 //读总线
#define MatchROM 0xcc //匹配ROM
#define WriteMode 0x4e //写模式
#define TH 0x64 //设置温度上限100
#define TL 0x8a //设置温度下限-10
#define MatchTemp 0x7f //写温度匹配寄存器,12bit
#define ConverTem 0x44 //DS18B20温度转换命令
#define Get_Value 0xbe //读取温度寄存器值
uchar data[5];
void process(long int i,uchar*p)
{
p[0]=i/1000;
i=i%1000;
p[1]=i/100;
i=i%100;
p[2]=i/10;
i=i%10;
p[3]=i;
for(i=0;i<4;i++)
p[i]+=0x30;
p[4]='$';
}
void delayms(uint i)
{
uint j;
for(;i!=0;i--)
for(j=0;j<8000;j++)
;
}
void delayus(uint i)
{
for(;i!=0;i--)
;
}
void port_init(void)
{
DDRD = 0xfe;
PORTD = 0xff;
DDRB = 0xff;
PORTB = 0xff;
DDRC = 0xff;
PORTC = 0xff;
}
/**********************************************************/
//写数据
void WriteDataLCM(unsigned char WDLCM)
{
//ReadStatusLCM(); //检测忙
LCM_Data = WDLCM;
//PORTC=0B00000100;
//PORTC=0B00000100;
delayms(1);
PORTC=0B00000101;
PORTC=0B00000100;
}
//写指令
void WriteCommandLCM(unsigned char WCLCM,unsigned char BuysC) //BuysC为0时忽略忙检测
{
if (BuysC)
;//ReadStatusLCM(); //根据需要检测忙
LCM_Data = WCLCM;
delayms(1);
PORTC=0B00000001;
delayms(1);
PORTC=0B00000000;
}
//读数据
unsigned char ReadDataLCM(void)
{
PORTC=0X00000111;
return(LCM_Data);
}
//读状态
void LCMInit(void) //LCM初始化
{
/* LCM_Data = 0;
WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
delayms(5);
WriteCommandLCM(0x38,0);
delayms(5);
WriteCommandLCM(0x38,0);
delayms(5);
*/
WriteCommandLCM(0x38,0); //显示模式设置,开始要求每次检测忙信号
//WriteCommandLCM(0x08,0); //关闭显示
WriteCommandLCM(0x01,0); //显示清屏
WriteCommandLCM(0x06,0); // 显示光标移动设置
WriteCommandLCM(0x0c,0); // 显示开及光标设置
}
/*****************************************************************************/
//按指定位置显示一个字符
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
Y &= 0x1;
X &= 0xF; //限制X不能大于15,Y不能大于1
if (Y) X += 0x40; //当要显示第二行时地址码+0x40;
X += 0x80; // 算出指令码
WriteCommandLCM(X, 0); //这里不检测忙信号,发送地址码
WriteDataLCM(DData);
}
//按指定位置显示一串字符
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char *DData)
{
unsigned char ListLength;
ListLength = 0;
Y &= 0x1;
X &= 0xF; //限制X不能大于15,Y不能大于1
while (DData[ListLength]!= '$') //若到达字串尾则退出
{
if (X <= 0xF) //X坐标应小于0xF
{
DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
ListLength++;
X++;
}
}
}
/**********************************************************/
/***************************************************************
* 功能:主机向总线写0 *
***************************************************************/
void Writr0(void)
{
Set_DQ1;
Set_DQ0;
delayus(700);
Set_DQ1;
asm("nop");
delayus(15);
}
/***************************************************************
* 功能:主机向总线写1 *
***************************************************************/
void Writr1(void)
{
Set_DQ1;
Set_DQ0;
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
Set_DQ1;
delayus(30);
}
/***************************************************************
* 功能:向总线写一个字节 *
* 输入:需要写的字 *
***************************************************************/
void WriteBits(char Byte)
{
char i = 0;
for (i=0;i<8;i++)
{
if (Byte & 0x01)
{
Writr1();
}
else
{
Writr0();
}
Byte>>=1;
}
}
/***************************************************************
* 功能:DS18B20复位程序 *
* 返回:总线复位成功,返回1 *
***************************************************************/
char Reset1820(void)
{
static char CheckTimes = 0;
static char CheckValue = 1;
delayus(664);
Set_DQ1;
Set_DQ0; //拉低总线480us
delayus(332);
Set_DQ1;
DDRC &= 0xf7; //设置端口为输入状态,读取数据
PORTC |= 0x08;
while(PINC&0x08); //等待,直至确认复位成功
CheckValue = Read_DQ;
delayus(150);
return CheckValue;
}
void Init1820(void)
{
/* if (Reset1820() == 0x08)
{
DisplayListChar(0,0,"1820 Not Detect $");
DisplayListChar(0,1," $");
}
else
{
DisplayListChar(0,0,"Init DS18B20 OK!$");
DisplayListChar(0,1," $");
}
*/
WriteBits(MatchROM);
WriteBits(WriteMode);
WriteBits(TH);
WriteBits(TL);
WriteBits(MatchTemp);
}
/***************************************************************
* 功能:从总线中读取数据位 *
* 返回:读取值 *
***************************************************************/
char ReadBit(void)
{
char i = 0;
char Read_Value = 0;
Set_DQ1;
Set_DQ0;
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
Set_DQ1;
DDRC &= 0xf7; //设置端口为输入状态,读取数据
PORTC |= 0x08;
Read_Value = Read_DQ;
asm("nop");
asm("nop");
delayus(30);
return Read_Value;
}
/***************************************************************
* 功能:从总线读取一个字节 *
* 返回:读取到的字符 *
***************************************************************/
char ReadBits(void)
{
char i = 0;
char b = 0;
char ReadBits_Value = 0;
for (i=8;i>0;i--)
{
ReadBits_Value = ReadBits_Value>>1;
b = ReadBit();
if(b)
{
ReadBits_Value = ReadBits_Value|0x80;
}
}
//DEC_Num_Disp(0,1,ReadBits_Value,5);
return ReadBits_Value;
}
/***************************************************************
* 功能:获得温度值 *
* 返回:温度值--摄氏温度 *
***************************************************************/
void Get_Temperature(void)
{
uint i;
static int TempLow = 0;
static int TempHi = 0;
static char Temp2 = 0;
static long final = 0;
Reset1820();
WriteBits(MatchROM);
WriteBits(ConverTem);
//for(i=0;i<20;i++)
//delayus(66);
Reset1820();
WriteBits(MatchROM);
WriteBits(Get_Value);
//for(i=0;i<20;i++)
delayus(70);
TempLow = ReadBits(); //温度低位
delayus(70);
TempHi = ReadBits();
//温度高位
final = (((TempHi)<<8)|TempLow)*0.0625;
process(final,data);
DisplayListChar(3,1,data);
}
//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
LCMInit(); //清屏
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x04; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
void main(void)
{
uchar i;
init_devices();
/*
delayms(5);
DisplayListChar(0,0,"Reset after sure$");
DisplayListChar(0,1," C $");
Init1820();
delayms(10);
*/
DisplayListChar(0,0,"DS18B20+LCD$");
DisplayListChar(0,1,"Made by zhang_he$");
delayms(80);
DisplayListChar(0,0,"Press the button$");
while(PIND!=0xfe);
DisplayListChar(0,0," Now Temp: $");
DisplayListChar(0,1," C $");
for(i=0;;i++)
{
Get_Temperature();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -