📄 wu01.asm
字号:
#include <reg51.h>
#include <intrins.h>
#define TEST_TIME
#undef TEST_TIME
sbit DQ =P3^3; //定义通信端口
unsigned char data dis_digit;
unsigned char code dis_code[11]={0xc0,0xf9,0xa4,0xb0, // 0, 1, 2, 3
0x99,0x92,0x82,0xf8,0x80,0x90, 0xff};// 4, 5, 6, 7, 8, 9, off
//shixr ,共阳极接法,1表示暗的。
unsigned char data dis_buf[8];
unsigned char data dis_index;
//延时函数
void delay(unsigned int i) //经验表明,这里i=1时约等于6.9us
{
while(i--);
}
//初始化函数
void Init_DS18B20(void)
{
unsigned char x=0;
unsigned int time = 0;
DQ = 1; //DQ复位
delay(8); //稍做延时
DQ = 0; //单片机将DQ拉低
#ifdef TEST_TIME
/* TR0 = 0;
TH0 = 0;
TL0 = 0;
TR0 = 1;
*/
#endif
delay(80); //精确延时 大于 480us
#ifdef TEST_TIME
/*
TR0 = 0;
time = (TH0<<8) + TL0 -2;
*/
/*here time = 0x202 ,that means
514 * 12/11.0592 = 557.73 us.
that means every delay() is 6.9us.
*/
#endif
DQ = 1; //拉高总线
delay(14);
x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
delay(20);
}
//读一个字节
unsigned char ReadOneChar(void)
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 给脉冲信号
dat>>=1;
DQ = 1; // 给脉冲信号
if(DQ)
dat|=0x80;
delay(4);
}
return(dat);
}
//写一个字节
void WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
delay(5);
DQ = 1;
dat>>=1;
}
}
//读取温度
unsigned int ReadTemperature(void)
{
unsigned char a=0;
unsigned char b=0;
unsigned int t=0;
float tt=0;
Init_DS18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
a = ReadOneChar();
b = ReadOneChar();
t=b;
t<<=8;
t=t|a;
tt=t *0.625; //将温度的高位与低位合并
t= tt*10+0.5; //对结果进行4舍5入
return(t);
}
void Delay_ms (unsigned int Nms )
{
unsigned char i;
while(Nms--)
for(i=0; i<125; i++) ;
}
void main()
{
unsigned int t = 0;
P0 = 0xff;
P2 = 0xff;
//以下为定时器初始化。
TMOD = 0x01; // M1,M0 = 0,1 工作在方式1,为16位定时器
TH0 = 0xFC;
TL0 = 0x17; // TH和TL各提供8位。
IE = 0x82; //开cpu中断 和 源中断 即EA = 1, ET0 = 1
dis_buf[0] = 0xff;
dis_buf[1] = 0xff;
dis_buf[2] = 0xff;
dis_buf[3] = 0xff;
dis_buf[4] = 0x0;
dis_buf[5] = 0x0;
dis_buf[6] = 0x0;
dis_buf[7] = 0x0;
dis_digit = 0xfe;
dis_index = 0;
TR0 = 1; //在 TCON 中,启动定时器0。启动工作需要放置在初始化之后,这是一个好的习惯。
do{
t = ReadTemperature();
if (t>0 && t < 9999)
{
dis_buf[4] = dis_code[t/1000];
dis_buf[5] = dis_code[(t%1000)/100] & 0x7f;
dis_buf[6] = dis_code[(t%100)/10];
dis_buf[7] = dis_code[t%10];
}
Delay_ms(300);
}
while(1);
}
void timer0() interrupt 1 using 1 //函数名字可以任意取, interrupt 1中的"1"表示定时器0的中断号为1。
// 定时器0中断服务程序, 用于数码管的动态扫描
// dis_index --- 显示索引, 用于标识当前显示的数码管和缓冲区的偏移量
// dis_digit --- 位选通值, 传送到P2口用于选通当前数码管的数值, 如等于0xfe时,
// 选通P2.0口数码管
// dis_buf --- 显于缓冲区基地址
{
TH0 = 0xFC;
TL0 = 0x17; //在定时器中断中重新赋初始值。可以计算这里的时钟周期为
// (0x10000- 0xfc17) * (1/(11.0592 * 10^6 / 12)) = 1.085ms
P1 = 0xff; // 先关闭所有数码管
//P0 = dis_buf[dis_index]; // 显示代码传送到P0口
P2 = dis_buf[dis_index]; // 显示代码传送到P2口
P1 = dis_digit; //
dis_digit = _crol_(dis_digit,1); // 位选通值左移, 下次中断时选通下一位数码管
dis_index++; //
if (dis_index >= 8)
dis_index = 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -