|
转载自互联网!!!
STC12C5406AD 晶振频率为12MHz
本程序已调试完成:
功能说明:采用廉价的NTC热敏电阻设计高精度温度计的方案,
根据NTC热敏电阻的温度特性,采用了较具新意程序算法;摆脱了传统的查表显示温度的方法,
特点:程序中无须查表,打破了常规的查表显示温度的方法。
- //NTC敏电阻温度显示。
- //DS18B20温度显示。
- #include "stc12c5410ad.h"//头文件
- #include "intrins.h"
- #define uchar unsigned char//宏定义
- #define uint unsigned int//宏定义
- sbit RS=P3^4;//定义I/O的硬件接口
- sbit E=P3^7;
- sbit A_B=P3^2;
- sbit CP=P3^3;
- sbit RT=P1^3;//外接NTC
- sbit R_100K=P1^4;//
- sbit D_J=P1^6;//检测
- sbit DQ=P1^5;////定义I/O的硬件接口--温度
- uint Temperature;//温度暂存单元
- uint Negative_Temperature;//负温度暂存单元
- bit Negative_sign=1;//负温度标志
- unsigned long TEMP_1;//长整形单元
- float Time_RT,Time_R;
- uchar aa,CC,ee;
- uint bb[11];
- float dd,temp5;
- uchar code DispTab_1[]={’0’,’1’,’2’,’3’,’4’,’5’,’6’,’7’,’8’,’9’,’A’,’B’,’C’,’D’,’E’,’F’};//1602:0-9 数字
- uchar code DispTab_2[]={0x10,0x06,0x09,0x08,0x08,0x09,0x06,0x00};//温度符号
- uchar DispBuf[6]; //6字节的显示缓冲区
- void delay(uint z)//1ms延时
- {
- uchar x,x1;
- for(;z>0;z--)
- {
- for(x=0;x<114;x++)
- {
- for(x1=0;x1<1;x1++);
- }
- }
- }
- void delay1(uchar x2)//经精准计算,该段程序1次延时时间为 19.53us;多次调用需要重新计算。
- {
- while(x2>0)
- {
- x2--;
- }
- }
- void write_Directive(uchar a)//写指令
- {
- uchar i,temp;
- for(i=0;i<8;i++)
- {
- temp=a;
- temp&=0x80;
- if(temp==0x80)
- A_B=1;
- else
- A_B=0;
- a=a<<1;
- delay1(1);
- CP=0;
- delay1(1);
- CP=1;
- delay1(1);
- CP=0;
- }
- RS=0;
- delay(3);
- E=0;
- delay(3);
- E=1;
- delay(3);
- E=0;
- delay(3);
- }
- void write_Data(uchar a)//写数据
- {
- uchar i,temp;
- for(i=0;i<8;i++)
- {
- temp=a;
- temp&=0x80;
- if(temp==0x80)
- A_B=1;
- else
- A_B=0;
- a=a<<1;
- delay1(1);
- CP=0;
- delay1(1);
- CP=1;
- delay1(1);
- }
- RS=1;
- delay(3);
- E=0;
- delay(3);
- E=1;
- delay(3);
- E=0;
- delay(3);
- }
- void init()//初始化
- {
- TMOD=0x10;//定时器T1工作于方式1,16位计数器
- TH1=0x00;
- TL1=0x00;
- EA=1;//开总中断允许
- ET1=1;//开定时器T1允许控制
- //PT1=1;//开定时器T1中断为最高优先级
- TR1=0;//T1开始运行
- P1M1=0x80;
- P1M0=0x80;
- //aa=TH1;
- //aa=aa<<8;
- //aa|=TL1;
- //Time_RT=aa;
- //Time_RT=Time_RT|TL1;
- _nop_();
- delay(15);
- write_Directive(0x38);
- delay(5);
- write_Directive(0x38);
- delay(5);
- write_Directive(0x38);
- write_Directive(0x01);
- write_Directive(0x02);///初始化后数据地址为0x80;即第一行,第一个位置
- write_Directive(0x0c);
- }
- void Temperature_symbol()//温度符号
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- write_Directive(0x40+i);//写入温度符号
- write_Data(DispTab_2[i]);
- }
- }
- void write_Data_String()//显示时间函数
- {
- uchar i;
- uint mm,mb;
- mb=temp5;
- // DispBuf[0]=temp/10000;//显示百位
- // mm=temp%10000;
- // DispBuf[1]=mm/1000;//显示十位
- // mm=mm%1000;
- // DispBuf[2]=mm/100;//显示个位
- // mm=mm%100;
- DispBuf[1]=mb/100;//显示小数点:0.001
- mm=mb%100;//显示小数点:0.0001
- DispBuf[2]=mm/10;//显示小数点:0.001
- DispBuf[3]=mm%10;//显示小数点:0.0001
- //i=DispBuf[0];//百位判断,如果为0,则消隐
- //if(i==0)
- // i=10;
- //DispBuf[0]=DispTab_1[i];//查表,取字符
- i=DispBuf[1];
- DispBuf[1]=DispTab_1[i];
- i=DispBuf[2];
- DispBuf[2]=DispTab_1[i];
- i=DispBuf[3];
- DispBuf[3]=DispTab_1[i];
- //i=DispBuf[4];
- //DispBuf[4]=DispTab_1[i];
- write_Directive(0x80+0x00);//第一行,第五个位置地址
- write_Data(’N’);
- write_Data(’T’);
- write_Data(’C’);
- //write_Data(’5’);
- //write_Data(’D’);
- //write_Data(’Z’);
- //write_Data(’ ’);
- write_Data(’:’);
- //write_Data(DispBuf[0]);//第一行,第五个位置
- write_Data(DispBuf[1]);//第一行,第七个位置
- write_Data(DispBuf[2]);//第一行,第八个位置
- write_Data(’.’);//第一行,第六个位置
- write_Data(DispBuf[3]);//第一行,第九个位置
- //write_Data(DispBuf[4]);//第一行,第十个位置
- //write_Data(0x00);//第一行,第十三个位置显示温度符号
- }
- void DB18B20_init()//DB18B20复位
- {
- DQ=1;
- delay1(1);//程序1次延时时间为 19.53us
- DQ=0;
- delay1(250);//程序110次延时时间为 965.71us
- DQ=1;
- delay1(10);//程序1次延时时间为 19.53us
- while(DQ==1);
- //if(DQ==0)
- _nop_();
- // LED_7=~led_7;//led检测复位正常否,如果DB18B20存在,且正常;led闪烁。
- while(DQ==0);
- delay1(40);//程序20次延时时间为 197.32us
- }
- void write_DB18B20(uchar m1)//写DB18B20
- {
- uchar i,m2;
- for(i=0;i<8;i++)
- {
- m2=m1;
- m2=m2&0x01;
- DQ=0;
- _nop_();
- DQ=1;
- if(m2==0x01)
- DQ=1;
- else
- DQ=0;
- delay1(50);//程序5次延时时间为 54.25us
- m1=m1>>1;
- DQ=1;
- }
- }
- read_DB18B20()//读DB18B20
- {
- uint temp_1;
- uchar i;
- for(i=0;i<16;i++)
- {
- temp_1=temp_1>>1;
- DQ=1;
- _nop_();
- DQ=0;
- _nop_();
- DQ=1;
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- if(DQ==1)
- temp_1=temp_1|0x8000;
- //else
- // temp_1=temp_1|0x0000;
- delay1(50);//程序5次延时时间为 54.25us
- }
- return temp_1;//返回温度值
- }
- void Negative()//温度为零度以下时,将变换温度
- {
- Negative_Temperature=Temperature;
- Negative_Temperature=Negative_Temperature&0xf800;
- if(Negative_Temperature==0xf800)
- {
- Temperature=~Temperature;
- Temperature=Temperature+1;
- Negative_sign=0;
- }
- }
- void write_Data_String1()//显示时间函数
- {
- uchar i;
- unsigned long mm;
- DispBuf[0]=TEMP_1/1000000;//显示百位
- mm=TEMP_1%1000000;
- DispBuf[1]=mm/100000;//显示十位
- mm=mm%100000;
- DispBuf[2]=mm/10000;//显示个位
- mm=mm%10000;
- DispBuf[3]=mm/1000;//显示小数点:0.1
- mm=mm%1000;
- DispBuf[4]=mm/100;//显示小数点:0.01
- mm=mm%100;
- DispBuf[5]=mm/10;//显示小数点:0.001
- DispBuf[6]=mm%10;//显示小数点:0.0001
- i=DispBuf[0];//百位判断,如果为0,则消隐
- if(i==0)
- i=10;
- else if(Negative_sign==0)//负温度判断,如果为0,则温度为负的,显示负号
- i=11;
- DispBuf[0]=DispTab_1[i];//查表,取字符
- i=DispBuf[1];
- DispBuf[1]=DispTab_1[i];
- i=DispBuf[2];
- DispBuf[2]=DispTab_1[i];
- i=DispBuf[3];
- DispBuf[3]=DispTab_1[i];
- i=DispBuf[4];
- DispBuf[4]=DispTab_1[i];
- i=DispBuf[5];
- DispBuf[5]=DispTab_1[i];
- i=DispBuf[6];
- DispBuf[6]=DispTab_1[i];
- write_Directive(0x80+0x40);//第一行,第五个位置地址
- write_Data(’D’);
- write_Data(’S’);
- write_Data(’1’);
- write_Data(’8’);
- write_Data(’B’);
- write_Data(’2’);
- write_Data(’0’);
- write_Data(’:’);
- //write_Data(DispBuf[0]);//第一行,第五个位置
- //
- write_Data(DispBuf[1]);//第一行,第六个位置
- write_Data(DispBuf[2]);//第一行,第八个位置
- write_Data(’.’);//第一行,第七个位置
- write_Data(DispBuf[3]);//第一行,第九个位置
- write_Data(DispBuf[4]);//第一行,第十个位置
- //write_Data(DispBuf[5]);//第一行,第十一个位置
- //write_Data(DispBuf[6]);//第一行,第十二个位置
- write_Data(0x00);//第一行,第十三个位置显示温度符号
- }
- void Timer1() interrupt 3//TR1
- {
- //TR1=0;
- }
- //P1M0=0x08;//P1.3高阻
- /*
- void RT_DJ()
- {
- D_J=0;
- R_100K=0;
- P1M0=0x18;//P1.3,P1.4高阻
- P1M1=0x18;//P1.3,P1.4高阻
- TH1=0x00;
- TL1=0x00;
- P1M0=0x48;//P1.3,P1.6高阻
- P1M1=0x48;//P1.3,P1.6高阻
- R_100K=1;
- TR1=1;
- while(!D_J);
- TR1=0;
- aa=TH1;
- aa=aa<<8;
- aa|=TL1;
- Time_R=aa;
- temp=aa;
- }*/
- void ADC_Conversion()//ADC开始转
- {
- ADC_CONTR=0x87;
- delay(1);
- ADC_CONTR=0x8f;
- delay(1);
- //while((ADC_CONTR==0x8f));
- ADC_CONTR=0x87;
- delay(1);
- //temp=ADC_DATA;//高8位
- }
- void main()
- {
- //delay1(5);//程序1次延时时间为 19.53us
- //P1M1=0x80;
- //P1M0=0x80;
- ///sbit RT=P1^3;//外接NTC
- //sbit R_100K=P1^4;//
- //sbit D_J=P1^6;//检测
- uchar i;
- cc=0x3d;
- dd=30;
- //goto lk;
- init();
- Temperature_symbol();//写入温度符号
- while(1)
- {
- DB18B20_init();//DB18B20复位
- write_DB18B20(0xcc);//写DB18B20;0xcc 跳过 ROM 指令
- write_DB18B20(0x44);//写DB18B20;0x44 启动温度转换指令
- delay(1000);//延时1秒
- DB18B20_init();//DB18B20复位
- write_DB18B20(0xcc);//写DB18B20;0xcc 跳过 ROM 指令
- write_DB18B20(0xbe);//写DB18B20;0xbe 读温度指令
- Temperature=read_DB18B20();//读 DB18B20 温度,读出的温度在 Temperature
- Negative();//温度为零度以下时,将变换温度,否则不变
- TEMP_1=Temperature*0.0625*10000;//转换成 十进制(*10000,表示,显示到小数点后4位:0.0000)
- write_Data_String1();//显示温度
- //RT_DJ();
- for(i=0;i<10;i++)
- {
- ADC_Conversion();
- bb[i]=ADC_DATA;//高8位;
- }
- Time_RT=bb[0]+bb[1]+bb[2]+bb[3]+bb[4]+bb[5]+bb[6]+bb[7]+bb[8]+bb[9];
- ee=Time_RT/10;
- //lk: temp=0x46;
- //if(ee==cc)
- //{
- // temp5=30;
- //}
- if(ee>cc)
- {
- for(i=0;i<94;i++)
- {
- cc=cc+1;
- dd=dd+0.5;
- if(ee==cc)
- {
- temp5=dd*10;
- i=93;
- }
- }
- }
- if(ee<cc)
- {
- for(i=0;i<30;i++)
- {
- cc=cc-1;
- dd=dd-0.5;
- if(ee==cc)
- {
- temp5=dd*10;
- i=29;
- }
- }
- }
- write_Data_String();
- delay(100);
- }
- }
复制代码
|
|