用DS8B20做的电子温度计,非常简单。
-
- #include <reg51.h>
- #include"AscLed.h"
- #include <intrins.h>
- #include <stdio.h>
- //********************************************************
- #define Seck (500/TK) //1秒中的主程序的系数
- #define OffLed (Seck*5*60) //自动关机的时间5分钟!
- //********************************************************
- #if (FHz==0)
- #define NOP_2uS_nop_()
- #else
- #define NOP_2uS_nop_();_nop_()
- #endif
- //**************************************
- #define SkipK 0xcc //跳过命令
- #define ConvertK 0x44 //转化命令
- #define RdDs18b20K 0xbe //读温度命令
- //*******************************************
- extern LedOut(void);
- //*************************************************
- sbit PNP1=P3^4;
- sbit PNP2=P3^5;
- sbit BEEP=P3^2;
- //***********************************
- #defineDQ PNP2 //原来的PNP2 BEEP
- //***********************************
- static unsigned char Power=0;
- //************************************
- union{
- unsigned char Temp[2]; //单字节温度
- unsigned int Tt; //2字节温度
- }T;
- //***********************************************
- typedef struct{
- unsigned char Flag; //正数标志 0;1==》负数
- unsigned char WenDu; //温度整数
- unsigned int WenDuDot; //温度小数放大了10000
- }WENDU;
- //***********************************************
- WENDU WenDu;
- unsigned char LedBuf[3];
- //----------------------------------
- //功能:10us 级别延时
- // n=1===> 6Mhz=14uS 12MHz=7uS
- //----------------------------------
- void Delay10us(unsigned char n){
-
- do{
- #if (FHz==1)
- NOP_2uS;NOP_2uS;
- #endif
- }while(--n);
- }
- //-----------------------------------
- //功能:写18B20
- //-----------------------------------
- void Write_18B20(unsigned char n){
- unsigned char i;
- for(i=0;i<8;i++){
- DQ=0;
- Delay10us(1);//延时13us 左右
- DQ=n & 0x01;
- n=n>>1;
- Delay10us(5);//延时50us 以上
- DQ=1;
- }
- }
- //------------------------------------
- //功能:读取18B20
- //------------------------------------
- unsigned char Read_18B20(void){
- unsigned char i;
- unsigned char temp;
- for(i=0;i<8;i++){
- temp=temp>>1;
- DQ=0;
- NOP_2uS;//延时1us
- DQ=1;
- NOP_2uS;NOP_2uS;//延时5us
- if(DQ==0){
- temp=temp&0x7F;
- }else{
- temp=temp|0x80;
- }
- Delay10us(5);//延时40us
- DQ=1;
- }
- return temp;
- }
- //-----------------------------------
- void Init (void){
- DQ=0;
- Delay10us(45);//延时500us
- DQ=1;
- Delay10us(9);//延时90us
- if(DQ){ //0001 1111b=1f
- Power =0; //失败0
- }else{
- Power++;
- DQ=1;
- }
- }
- //----------------------------------
- void Skip(void){
- Write_18B20(SkipK);
- Power++;
- }
- //----------------------------------
- void Convert (void){
- Write_18B20(ConvertK);
- Power++;
- }
- //______________________________________
- void Get_Ds18b20L (void){
- T.Temp[1]=Read_18B20(); //读低位
- Power++;
- }
- //______________________________________
- void Get_Ds18b20H (void){
- T.Temp[0]=Read_18B20(); //读高位
- Power++;
- }
- //------------------------------------
- //规范化成浮点数
- // sssss111;11110000
- // sssss111;1111(0.5,0.25,0.125,0.0625)
- //------------------------------------
- void ReadTemp (void){
- unsigned char i;
- unsigned intF1=0;
- char j=1;
- code int Code_F[]={6250,1250,2500,5000};
- WenDu.Flag=0;
- if (T.Temp[0] >0x80){ //负温度
- T.Tt =~T.Tt+1; //取反+1=源吗 +符号S
- WenDu.Flag=-1;
- }
- T.Tt <<= 4; //左移4位
- WenDu.WenDu=T.Temp[0]; // 温度整数
- //**************************************************
- T.Temp[1]>>=4;
- //---------------------------
- for (i=0;i<4;i++){ //计算小数位
- F1 +=(T.Temp[1] & 0x01)*Code_F;
- T.Temp[1]>>=1;
- }
- WenDu.WenDuDot=F1; //温度的小数
- Power=0;
- }
- //----------------------------------
- void Delay1S (void){
- static unsigned int i=0;
-
- if (++i==Seck) {i=0ower++;}
- }
- //----------------------------------
- void ReadDo (void){
- Write_18B20(RdDs18b20K);
- Power++;
- }
- /**********************************
- 函数指针定义
- ***********************************/
- code void (code *SubTemp[])()={
- Init,Skip,Convert,Delay1S,Init,Skip,ReadDo,Get_Ds18b20L,
- Get_Ds18b20H,ReadTemp
- };
- //**************************************
- void GetTemp(void){
- (*SubTemp[Power])();
- }
- //---------------------------------------------------
- //将温度显示,小数点放大了10000.
- void GetBcd(void){
- LedBuf[0]=WenDu.WenDu / 10;
- LedBuf[1]=WenDu.WenDu % 10 +DotK;
- LedBuf[2]=(WenDu.WenDuDot/1000)%10;
- if(LedBuf[0]==0)LedBuf[0]=Black;
- if(WenDu.Flag==0) return;
- if(LedBuf[0] !=Black){
- LedBuf[2]=LedBuf[1];
- LedBuf[1]=LedBuf[0];
- LedBuf[0]=Led_Pol; //'-'
- }else{
- LedBuf[0]=Led_Pol; //'-'
- }
- }
- /*
- //---------------------------------------------------
- void JbDelay (void){
- static long i;
- if (++i>=OffLed){
- P1=0xff;
- P2=0xff;
- PCON=0x02;
- }
- }
- */
- /*****************************************************
- 主程序开始
- 1:2002_10_1 设计,采用DS18B20测量
- 2:采用函数数组读取DS18B20.LED数码管显示正常!
- 3:改变FHz可以用6,12MHz工作!
- ******************************************************/
- code unsigned char Stop[3] _at_ 0x3b;
- void main (void){
- P1=0xff;
- WenDu.WenDu=0;
- while (1){
- GetTemp();
- GetBcd();
- // JbDelay();
- LedOut();
- }
- }
复制代码 |