你这样问很难解答,给你一个成熟的程序和仿真图参考
- /*-----------------------------------------------
- 名称:DS18b20测温程序 数码管显示(-55~128度)
- ------------------------------------------------*/
- #include <reg51.H>
- #define uchar unsigned char
- #define uint unsigned int
- #define DataPort P0 //定义数据端口
- sbit LATCH1=P2^6;//定义锁存使能端口 段锁存
- sbit LATCH2=P2^7;// 位锁存
- sbit DQ=P2^2; //DS18B20 端口
- /************定义全局变量*************/
- uchar code dofly_DuanMa[]={//共阴数码管段码"0~f-."
- 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,
- 0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40,0x80};
- uchar code dofly_WeiMa[]={//共阴数码管8位位码
- 0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
- uchar TempData[6]; //存储显示值的全局变量
- bit ReadTempFlag; //读时间标志
- /*------------------------------------------------
- 函数声明
- ------------------------------------------------*/
- void WriteOneChar(uchar dat);//写入DS18B20一个字节
- uchar ReadOneChar();//读取DS18B20一个字节
- uint ReadTemperature();//读取DS18B20温度值
- void Init_DS18B20();//初始化DS18B20
- void Display(); //数码管显示函数
- void Init_Timer0(); //定时器初始化
- void delay(uchar i);//1ms延时函数
- /*------------------------------------------------
- 主函数
- ------------------------------------------------*/
- void main()
- {
- uint temp;
- long tempM;
- bit negative;//负数标志
- uchar TempH,TempL,TempK;
- Init_Timer0();
- TempData[5]=0x39; //显示C
- while(1) //主循环
- {
- if(ReadTempFlag==1)//定时标志
- {
- ReadTempFlag=0;
- temp=ReadTemperature();//读取温度
- if(temp&0x8000)
- {
- negative=1; //负号标志
- temp=~temp; //取反加1
- temp +=1;
- }
- else negative=0; //正数
- tempM=temp*0.0625*100; //换算为10进制温度值再放大100倍
- TempH=tempM/100; //分解出整数值
- TempL=tempM%100; //分解出小数值
- TempL=(TempL+TempK)/2+0.5;//小数取两次平均值加四舍五入
- TempK=TempL;
-
- if(negative==1)
- TempData[0]=0x40;//显示负号
- else if(TempH/100==0)//小于100
- TempData[0]=0; //百位消隐
- else
- TempData[0]=dofly_DuanMa[TempH/100]; //显示百位温度
-
- if((TempH/100==0)&&((TempH%100)/10==0))
- TempData[1]=0; //十位消隐
- else
- TempData[1]=dofly_DuanMa[(TempH%100)/10]; //显示十位温度
- TempData[2]=dofly_DuanMa[(TempH%100)%10]|0x80;//显示个位温度,带小数点
- TempData[3]=dofly_DuanMa[TempL/10]; //显示温度小数1位
- TempData[4]=dofly_DuanMa[TempL%10]; //显示温度小数2位
- }
- }
- }
- /**********1ms延时************/
- void delay(uchar i)
- {
- uchar j, k;
- for(j=i;j>0;j--)
- for(k=120;k>0;k--);
- }
- /*****初始化DS18B20*****/
- void Init_DS18B20()
- {
- uint i;
- DQ=0;
- i = 103;
- while(i>0)
- i--;
- DQ=1;
- i = 4;
- while(i>0)
- i--;
- }
- /*****读一个字节*****/
- uchar ReadOneChar()
- {
- uchar i=0;
- uchar dat = 0;
- for (i=8;i>0;i--)
- {
- DQ = 0; // 给脉冲信号
- dat>>=1;
- DQ = 1; // 给脉冲信号
- if(DQ)
- dat|=0x80;
- delay(1);
- }
- return(dat);
- }
- /*****写一个字节*****/
- void WriteOneChar(uchar dat)
- {
- uchar i=0;
- for(i=8; i>0; i--)
- {
- DQ = 0;
- DQ = dat&0x01;
- delay(1);
- DQ = 1;
- dat>>=1;
- }
- delay(1);
- }
- /*****读取温度*****/
- uint ReadTemperature()
- {
- uchar a,b;
- uint tt;
- Init_DS18B20(); //初始化DS18B20
- delay(1); //延时1ms
- WriteOneChar(0xcc); //写入跳过序列号命令字
- WriteOneChar(0x44); //写入温度转换命令字
- delay(1); //延时1ms //@12.000MHz //转换需要一点时间,延时
- Init_DS18B20(); //初始化DS18B20
- delay(1); //延时1ms
- WriteOneChar(0xcc); //写入跳过序列号命令字
- WriteOneChar(0xbe); //写入读取数据令字
- a=ReadOneChar(); //读出温度的低位LSB
- b=ReadOneChar(); //读出温度的高位MSB
- tt=(b<<8)|a;
- return tt;
- }
- /*------------------------------------------------
- 6位动态数码管显示函数
- ------------------------------------------------*/
- void Display()
- {
- static uchar i=0;
- DataPort=0; //清空数据,消隐
- LATCH1=1; //段锁存
- LATCH1=0;
-
- DataPort=dofly_WeiMa[i]; //取位码
- LATCH2=1; //位锁存
- LATCH2=0;
-
- DataPort=TempData[i]; //取显示数据,段码
- LATCH1=1; //段锁存
- LATCH1=0;
-
- i++;
- i%=6;
- }
- /*------------------------------------------------
- 定时器初始化子程序
- ------------------------------------------------*/
- void Init_Timer0(void)
- {
- TMOD |= 0x01; //使用模式1,16位定时器
- TH0=(65536-2000)/256; //给定初值
- TL0=(65536-2000)%256;
- EA=1; //总中断打开
- ET0=1; //定时器中断打开
- TR0=1; //定时器开关打开
- }
- /*------------------------------------------------
- 定时器中断子程序
- ------------------------------------------------*/
- void Timer0_isr(void) interrupt 1
- {
- static uint num;
- TH0=(65536-2000)/256; //重新赋值 2ms
- TL0=(65536-2000)%256;
-
- Display(); // 调用数码管扫描
- num++;
- if(num>=250) //500ms
- {
- num=0;
- ReadTempFlag=1; //读标志位置1
- }
- }
复制代码
|