本篇为DS18B20搭配数码管动态显示
段码表:
u8 code t_display[]={ //标准字库 // 0 1 2 3 4 5 6 7 8 9 A B C D E F 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71, //black - H J K L N o P U t G Q r M y 0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e, 0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46}; //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1 u8 code T_COM[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //位码
可在stc-isp中找到,不用记
具体步骤可以再数码管那篇公众号看,这里发个截图。
DS18B20文件处理:
STEP1:将onewire复制到当前目录下并加入文件到工程
STEP2:修改onewire.h文件,把所有函数复制黏贴进去
STEP3:修改onewire.c文件,修改其中如下函数
//单总线延时函数
void Delay_OneWire(unsigned int t) //STC89C52RC
{
unsigned char i;
while(t--)
{
for(i=0;i<12;i++);
}
}
其中,增加了for这一行和函数内部首行的unsigned char i;
原因是频率不同,不赘述,记住即可。
DS18B20读取温度步骤:
1、初始化
2、写0xcc
3、写0x44
4、delay
5、初始化
6、写0xcc
7、写0xbe
8、读数据(先读出低字节的,再读出的是高字节的)
9、处理读出的数据,先将高字节的存入变量;左移八位;或上低字节数据;右移四位。由此能得到整数部分。省赛多半不涉及小数部分。
Tips.记不住的无所谓,记代码。
void ds18b20()
{
unsigned char MSE,LSE;
init_ds18b20();
Write_DS18B20(0xCC);
Write_DS18B20(0x44);
Delay1(1000,temp);
init_ds18b20();
Write_DS18B20(0xCC);
Write_DS18B20(0xBE);
LSE=Read_DS18B20();
MSE=Read_DS18B20();
temp=MSE;
temp=temp<<8;
temp=temp|LSE;
temp=temp>>4;
}
总体代码展示:(main.c)
#include "reg52.h"
#include "intrins.h"
#include "onewire.h"
/************* 本地常量声明 **************/
unsigned char code t_display[]={ //标准字库
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
//black - H J K L N o P U t G Q r M y
0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46}; //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1
unsigned int temp; #!!!!!!!!!!!!!!!!!!!!!!!!
void Delay1(unsigned char t,unsigned char dat);
void InitSys();
void SelectHC138(unsigned char channel,unsigned char dat);
void SMG_bit(unsigned pos,unsigned char num);
void SMG_1(unsigned char dat);
void Delay1ms(); //@11.0592MHz
void ds18b20();
void main()
{
InitSys();
while(1)
{
ds18b20();
SMG_1(temp);
}
}
void Delay1(unsigned char t,unsigned char dat)
{
while(t--)
{
SMG_1(dat);
}
}
void SelectHC138(unsigned char channel,unsigned char dat)
{
P0=dat;
switch(channel)
{
case 0:
P2=P2&0x1f|0x00;
break;
case 4:
P2=P2&0x1f|0x80;
break;
case 5:
P2=P2&0x1f|0xa0;
break;
case 6:
P2=P2&0x1f|0xc0;
break;
case 7:
P2=P2&0x1f|0xe0;
break;
}
P2=P2&0x1f|0x00;
}
void InitSys()
{
SelectHC138(4,0xff);
SelectHC138(5,0x00);
SelectHC138(6,0xff);
SelectHC138(7,0xff);
}
void ds18b20()
{
unsigned char MSE,LSE;
init_ds18b20();
Write_DS18B20(0xCC);
Write_DS18B20(0x44);
Delay1(1000,temp);
init_ds18b20();
Write_DS18B20(0xCC);
Write_DS18B20(0xBE);
LSE=Read_DS18B20();
MSE=Read_DS18B20();
temp=MSE;
temp=temp<<8;
temp=temp|LSE;
temp=temp>>4;
}
void SMG_bit(unsigned pos,unsigned char num)
{
SelectHC138(6,0x01<<pos);
SelectHC138(7,~t_display[num]);
Delay1ms();
SelectHC138(7,0xff);
}
void SMG_1(unsigned char dat)
{
SMG_bit(7,dat%10);
SMG_bit(6,dat/10);
}
void Delay1ms() //@11.0592MHz
{
unsigned char i, j;
_nop_();
_nop_();
_nop_();
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
}
易错点:(个人)
1.1将onewire.c中的delay_onewire函数改成
unsigned char i;
while(t--)
{
for(i=0;i<12;i++);
}
1.2 temp不能定义成unsigned char,必须定义成unsigned int,不然结果不对
1.3 漏掉了一个init_ds18b20();
应该有两个,在写入0x44后还有一个init,之后再写0xcc和0xbe
1.4 在主程序中,ds18b20的子函数内的delay函数用的不是onewire中的那个delay,是自己写的延时函数,并且数码管要在其内部进行显示。
作者的话:
本系列不是教学篇,为速通版。因此涉及打破砂锅问到底的逻辑部分较少。
C语言教程可移步曾经发过的C语言速通教程。
有建议欢迎指出,也欢迎友好交流!
另也欢迎关注其他平台上本人的账号 如下:
知乎:youzuos
微信公众号:知识薪火站
感谢支持!