📄 temp.c
字号:
#include "reg51.h"
#include "intrins.h"
#include "uart.h"
#include "my_type.h"
#define disdata P1
#define discan P3 //用P3.2-P3.5四个口进行扫描
#define uchar unsigned char
#define uint unsigned int
sbit DQ = P3^7;
sbit DIN = P1^7;
uint h;
uchar code ditab[16]= //小数点集合
{0X00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};
uchar code dis_7[12]= {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};//数码管显示的段数,即显示几段
uchar code scan_con[4]={0xfb,0xf7,0xef,0xdf}; //扫描数码管的片选
uchar data temp_data[2]={0x00, 0x00,}; //温度数据读取
uchar data display[5]={0x00,0x00,0x00,0x00,0x00}; //要显示的数据的集合
//uchar ii,jj; //定义全局变量
void delay(uint t)
{
for(;t>0;t--);
}
scan() //扫描方法是从最右边的数码管开始扫描,逐个扫描显示。
{
char k;
disdata=0xc6;
discan=scan_con[0];delay(90);discan=0xff;
for(k=1;k<4;k++)
{
disdata=dis_7[display[k]]; //一个数字的显示只要用7段,所以只要设置7段为输出。
if(k==2){DIN=0;} //当扫描到个位时,要用到小数点,所以要将P1^7口设置为输出
///*以上控制到底点亮数码管8段中的哪几段*/
discan=scan_con[k];delay(90);discan=0xff; //discan=0xff:将其设置为输入状态,避免总线冲突。因为51是准双向口
//discan=scan_con[k];delay(90);discan=0xff; /*控制到底是点亮哪个数码管*/
}
//disdata=0xc6;
//discan=scan_con[3];delay(90);discan=0xff;
//注意:点亮的段码是用正常的码段的反码来表示的。
//例如:字母C是用0x39表示,但要用反码0xc6来表示
}
ow_reset(void)
{
char presence=1;
while(presence)
{
while(presence)
{
DQ=1;_nop_();_nop_();
DQ=0;
delay(50);
DQ=1;
delay(6);
presence=DQ;
}
delay(45);
presence = ~DQ;
}
DQ=1;
}
void write_byte(uchar val)
{
uchar i;
for(i=8;i>0;i--)
{
DQ=1;_nop_();_nop_(); //_nop_延时时间在us级的用_nop_函数
DQ=0;_nop_();_nop_();_nop_();_nop_();_nop_();
DQ=val&0x01;
delay(6);
val=val/2;
}
DQ=1;
delay(1);
}
uchar read_byte(void)
{
uchar i;
uchar value=0;
for(i=8;i>0;i--)
{
DQ=1;_nop_();_nop_();
value >>=1;
DQ=0;
_nop_();_nop_();_nop_();_nop_();
DQ=1;_nop_();_nop_();_nop_();_nop_();
if (DQ)value|=0x80;
delay(6);
}
DQ=1;
return(value);
}
read_temp()
{
ow_reset();
write_byte(0xcc);
write_byte(0xbe); //读温度值命令,读取温度值
temp_data[0]=read_byte();
temp_data[1]=read_byte();
ow_reset();
write_byte(0xcc);
write_byte(0x44);
//************************************
//ii=temp_data[0];
//jj=temp_data[1];
//************************************
}
calculate_temp()
{
uchar n=0;
if(temp_data[1]>127)
{temp_data[1]=(256-temp_data[1]);
temp_data[0]=(256-temp_data[0]);n=1;}
display[4]=temp_data[0]&0x0f;display[1]=ditab[display[4]];
display[4]=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4) ;
//display[3]=display[4]/100;
display[2]=display[4]%100;
display[3]=display[4]/10;
display[2]=display[4]%10;
if(!display[3]){display[3]=0x0a; //0x0a表示不显示
if(!display[2]){display[2]=0x0a;}}
if(n){display[3]=0x0b;} //若温度为零下,则显示负号
}
void main (void)
{
char k;
InitUART();
Prints("系统启动...............",1);
disdata=0xff; //设置为输入口
discan=0xff; //设置为输入口
for(h=0;h<4;h++){display[h]=8;}
//display[0]=0x0a;
//display[1]=1;
//display[2]=2;
//display[3]=3;
Prints("系统与温度传感器复位...............",1);
ow_reset();
Prints("开始对DS18B20写字节...............",1);
write_byte(0xcc); //跳过ROM命令
write_byte(0x44); //启动所有在线的DS18B20进行温度转换
//write_byte(0x55); 发匹配ROM命令
Prints("开始扫描...............",1);
for(h=0;h<500;h++)
{for(k=0;k<4;k++) //初始化4个8
{
disdata=dis_7[display[k]];
if(k==2){DIN=0;}
discan=scan_con[k];delay(90);discan=0xff;
}
}
Prints("进入无限循环...............",1);
Prints("开始读取温度值.............",1);
while(1)
{
read_temp(); //读取温度
//**********************************
//Prints("开始采样...............",1);
//PrintLongInt(ii);
//Prints(",",0);
//PrintLongInt(jj);
//Prints("",1);
//**********************************
calculate_temp(); //对读取到的温度进行换算
for(h=0;h<500;h++)
{scan();} //将温度显示出来
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -