* 采用四位共阴极数码管琒R42056K,P1口接数码管段码。P0.0接第一位 * P0.1接第二位,p0.2接第三位,p0.3接第四位。 * 单片机AR89S52,晶振7.3728M * DS18B20接P2.0。 * ***********************************************************************/ #include#include #define uchar unsigned char #define uint unsigned int /*********************************************************************** * DS18B20 数据口 DQ * 共阴极数码管 *共阴极数码管带小数点 ***********************************************************************/ //#define DQ RC1 //#define DQ_HIGH() TRISC1=1 //#define DQ_LOW() TRISC1=0;DQ=0 //__CONFIG(0x3B31); sbit DQ=P2^0; //const uchar table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, // 0x07,0x7f,0x6f}; unsigned char code table[]={//共阴极0~f数码管编码 0x3f,0x06,0x5b,0x4f, //0~3 0x66,0x6d,0x7d,0x07, //4~7 0x7f,0x6f,0x77,0x7c, //8~b 0x39,0x5e,0x79,0x71 //c~f }; //const uchar table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd, // 0x87,0xff,0xef}; const uchar table1[]={ 0xbf,0x86,0xdb,0xcf,//0-3 0xe6,0xed,0xfd,0x87,//4-7 0xff,0xef//8-9 }; uint temper;//温度值缓存 uchar a1,a2,a3,a4;//数码管每个位上显示的数字 uchar time=0;//延时缓存 uchar TH; //判断负值 void delay(uint x); void delayus(uint,uchar); void init();//初始化 void disp(uchar num1,uchar num2,uchar num3,uchar num4);//正值显示 void disp1(uchar num1,uchar num2,uchar num3);//负值显示 void write_byte(uchar date); void delayms(uchar i); //误差 -0.651041666667us uchar read_byte(); void get_tem();//获取温度 void delay20us(); void delay30us(); void delay45us(); void delay70us(); void delay750us(); void delay500us(); void InitTimer0(void); void delay20us(void) //误差 -0.46875us { unsigned char a,b; for(b=1;b>0;b--) for(a=3;a>0;a--); } void delay30us(void) //误差 -0.703125us { unsigned char a,b; for(b=3;b>0;b--) for(a=1;a>0;a--); } void delay45us(void) //误差 -1.0546875us { unsigned char a; for(a=12;a>0;a--); } void delay70us(void) //误差 -0.013020833333us { unsigned char a; for(a=20;a>0;a--); } void delay750us(void) //误差 -1.302083333333us { unsigned char a,b; for(b=1;b>0;b--) for(a=227;a>0;a--); } void delay500us(void) //误差 -0.325520833333us { unsigned char a; for(a=152;a>0;a--); } void InitTimer0() { TMOD = 0x01; TH0 = 0x88; TL0 = 0x00; EA = 1; ET0 = 1; TR0 = 1; } void main() { init(); InitTimer0(); while(1) { uchar num; for(num=100;num>0;num--) { if(TH<0X7F) disp(a1,a2,a3,a4); else disp1(a1,a2,a3); } } } /*********************************************************************** * 复位18B20 ***********************************************************************/ void reset() { uchar st=1; // DQ_HIGH(); DQ=1; // NOP();NOP(); _nop_(); while(st) { // DQ_LOW(); DQ=0; // delayus(70,30); delay750us(); // DQ_HIGH(); DQ=1; // delayus(4,4); delay70us(); if(DQ==1) st=1; else st=0; //delayus(50,10); delay500us(); } } /*********************************************************************** * 写字节 ***********************************************************************/ void write_byte(uchar date) { uchar i,temp; // DQ_HIGH(); DQ=1; // NOP();NOP(); _nop_(); for(i=8;i>0;i--) { temp=date&0x01;//01010101 // DQ_LOW(); DQ=0; // delayus(0,0); delay20us(); if(temp==1) // DQ_HIGH(); DQ=1; // delayus(2,2); delay45us(); // DQ_HIGH(); DQ=1; date=date>>1;//00101010 } } /*********************************************************************** * 读字节 ***********************************************************************/ uchar read_byte() { uchar i,date; static bit j; for(i=8;i>0;i--) { date=date>>1; // DQ_HIGH(); DQ=1; // NOP();NOP(); _nop_(); // DQ_LOW(); DQ=0; // NOP();NOP();NOP();NOP();NOP();NOP(); _nop_();_nop_(); // DQ_HIGH(); DQ=1; // NOP();NOP();NOP();NOP(); _nop_(); j=DQ; if(j==1) date=date|0x80;//1000 0000 // delayus(1,1); delay30us(); } return (date); }[page] /*********************************************************************** * 温度获取 ***********************************************************************/ void get_tem() { uchar tem1,tem2; float aaa; reset(); //复位 write_byte(0xCC);//跳过ROM write_byte(0x44);//温度转换 reset(); write_byte(0xCC); write_byte(0xBE); tem1=read_byte(); tem2=read_byte(); TH=tem2; if(tem2>0x7f) tem2=~tem2; aaa=(tem2*256+tem1)*6.25; temper=(int)aaa; a1=temper/1000; a2=temper%1000/100; a3=temper%100/10; a4=temper%10; } /*********************************************************************** * 清屏 ***********************************************************************/ void init() { P1=0x00; P0=0xff; } /*********************************************************************** * 正温度时,显示 * ***********************************************************************/ void disp(uchar num1,uchar num2,uchar num3,uchar num4) { P1=table[num1]; P0=0xfe; delayms(2); P1=table1[num2]; P0=0xfd; delayms(2); P1=table[num3]; P0=0xfb; delayms(2); P1=table[num4]; P0=0xf7; delayms(2); } /*********************************************************************** * 负温度时,显示 * ***********************************************************************/ void disp1(uchar num1,uchar num2,uchar num3) { P1=0x40;//显示负号 P0=0xfe; delayms(2); P1=table[num1]; P0=0xfd; delayms(2); P1=table1[num2]; P0=0xfb; delayms(2); P1=table[num3]; P0=0xf7; delayms(2); } /*********************************************************************** * 毫秒级的延时 * 晶振7.3728M ***********************************************************************/ void delayms(uchar i) //误差 -0.651041666667us { uchar a,b; for(;i>0;i--) for(b=47;b>0;b--) for(a=5;a>0;a--); } /*********************************************************************** * 定时器0中断服务程序, 设置20毫秒计时器。每1秒钟采集一次温度值 * ***********************************************************************/ void Timer0Interrupt(void) interrupt 1 { TH0 = 0x88; TL0 = 0x00; //add your code here! time++; if(time==20) { time=0; get_tem(); } }
上一篇:keilc51中如何看堆栈的分配情况
下一篇:单片机驱动H桥电路
推荐阅读最新更新时间:2024-03-16 14:25