📄 w012.c
字号:
/*******************************************************************************
* 实验名称: 数字温度表(DS18B20)数码管显示 *
********************************************************************************
* 实验描述: 四位数码管显示测量的温度 *
* 实验说明: 数码管从左到右依次显示温度的百位十位个位小数部分 *
* DS18B20没有安装时,数码管显示FFF.F *
* 实验前要在J7上安装DS18B20 *
* 1:接DS18B20的GND端 *
* 2:接DS18B20的DQ端 *
* 3:接DS18B20的VDD端 *
*******************************************************************************/
#include <reg52.h>
#include <intrins.h>
sbit DQ = P3^7; //定义DS18B20端口DQ
bit presence; //DS18B20初始化成功标志位
unsigned char digit=0; //数码管显示位
/* 段码表 */
unsigned char code seg_code[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, // 0-9
0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x00}; // A, b, C, d, E, F, off
/*温度小数部分查表*/
unsigned char code ditab[16] = {0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,
0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};
unsigned char data temp_data[2] = {0x00,0x00}; //温度数据缓存
unsigned char data dis_data[5]={0,0,0,0,0}; //温度值百十个小数位及一个数据缓存
void Delay( int num) //us级延时函数
{
while( --num );
}
void WriteSegData(unsigned char seg) //写段码数据函数
{
if(seg > 16)
seg = 16;
seg = seg_code[seg];
if(digit == 2)
seg = seg+0x80; //小数点的位置
P0 = seg;
_nop_();
_nop_();
P2 &= 0x1F;
_nop_();
_nop_();
P2 |= 0xE0;
}
void WriteDigitData(unsigned char dig) //写位选数据函数
{
dig &= 0x0F;
P0 = ~dig;
_nop_();
_nop_();
P2 &= 0x3F;
_nop_();
_nop_();
P2 |= 0xE0;
}
DS18B20_Init(void) //DS18B20初始化函数
{
DQ = 1;
Delay(8);
DQ = 0; //将DQ拉低
Delay(95); //延时 大于480us
DQ = 1; //拉高总线
Delay(8);
presence = DQ; //如果 presence=0则初始化成功 presence=1则初始化失败
Delay(100);
DQ = 1;
return(presence); //返回presence
}
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(4);
DQ = 1;
dat>>=1;
}
}
void ReadTemperature(void) //读取温度函数
{
presence = 1;
while(presence == 1)
DS18B20_Init();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0x44); //启动温度转换
presence = 1;
while(presence == 1)
DS18B20_Init();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器
temp_data[0] = ReadOneChar(); //读温度低8位
temp_data[1] = ReadOneChar(); //读温度高8位
}
void TemperatureConvert() //温度数据转换函数
{
dis_data[4]=temp_data[0]&0x0f; //temp_data[0]低4为有效
dis_data[3]=ditab[dis_data[4]]; //查表得小数位的值
dis_data[4]=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4);
dis_data[0]=(dis_data[4])/100; //百位
dis_data[1]=(dis_data[4]%100)/10; //十位
dis_data[2]=(dis_data[4])%10; //个位
if(dis_data[0]==0) //百位为0,不显示
{
dis_data[0]=16;
if(dis_data[1]==0) //十位为0,不显示
dis_data[1]=16 ;
}
}
void Timer0_Init(void) //T0初始化函数
{
TMOD = 0x01;
TH0 = 0xEE;
TL0 = 0x00;
EA = 1;
ET0 = 1;
}
void main() //主函数
{
P0 = 0xFF;
P2 = 0xFF;
Timer0_Init();
TR0 = 1;
while(1)
{
DS18B20_Init();
if(presence==0)
{
ReadTemperature();
TemperatureConvert();
}
if(presence==1)
{
DS18B20_Init();
dis_data[0]=dis_data[1]=dis_data[2]=dis_data[3]=15 ;
dis_data[4]=0 ;
}
}
}
void timer0() interrupt 1 using 1 //中断程序
{
TH0 = 0xEE;
TL0 = 0x00;
if(digit > 3)
digit = 0;
else
digit++;
WriteSegData(dis_data[digit]);
WriteDigitData(1<<digit);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -