- 樓主的程序:
- /*****************************************************************
- *程序名稱:DS18B20 4位數(shù)碼管 上位機(jī)
- *程序功能:讀寫DS18B20,數(shù)碼管顯示溫度值,上位機(jī)顯示。
- *開發(fā)工具:谷雨電子 多功能51開發(fā)板
- *MCU型號(hào):STC89C52RC
- *時(shí)鐘頻率:11.0592MHZ
- *程序作者:LCG
- *版權(quán)說明:
- *****************************************************************/
- #include <reg52.h>
- #define uint unsigned int
- #define uchar unsigned char
- //定義DS18B20通信端口,修改硬件時(shí)要修改的部分
- sbit DQ = P2 ^ 0;
- //0-9的8位共陽數(shù)碼管位碼 其中負(fù)號(hào)0xbf
- uchar const LEDNumber[] = { 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf };
- //0-9的8位共陽數(shù)碼管位碼 帶小數(shù)點(diǎn)
- uchar const LEDNumberDot[] ={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
- //LCG
- uchar const LCGData[]={0xC7,0xC6,0xC2};
- //溫度是否是負(fù)
- uchar tempSign;
- //傳感器的溫度的高位低位
- uchar tH=0x00;tL=0x00;
- //當(dāng)前溫度
- float tt=0;//臨時(shí)
- int CurrentT=0;
- int t=0;//臨時(shí)
- //數(shù)位
- uchar bw,sw,gw,sfw;//百位,十位,個(gè)位,十分位
- //***********************以下為函數(shù)聲明部分*****************
- void DispLCG(int pos, int Data);
- void LCGDisp(void);
- void delay(uint us);
- void Init_DS18B20(void);
- uchar ReadOneChar(void);
- void WriteOneChar(uchar dat);
- void ReadTemperature(void);
- void LedDispDig(int Pos, int Dig, uchar isDot);
- void DisplayTemp(void);
- void init_serial(void);
- void Tranfer(char Data);
- //char Temp_lower, Temp_upper; //溫度的上限和下限
- //=================================================================
- // 函數(shù)名稱 :void delay (uint us)
- // 函數(shù)功能 :延時(shí)
- // 入口參數(shù) :us 延時(shí)時(shí)間的長(zhǎng)短
- // 出口參數(shù) :無
- //=================================================================
- void delay(uint us)
- {
- //此函數(shù)精確計(jì)算[12MHz晶振]:18+6*(t-1)=延時(shí)時(shí)間(us)
- while (us--);
- }
- //=================================================================
- // 函數(shù)名稱 :void Init_DS18B20(void)
- // 函數(shù)功能 :DS18B20初始化函數(shù)
- // 入口參數(shù) :無
- // 出口參數(shù) :無
- //=================================================================
- void Init_DS18B20(void)
- {
- uchar x = 0;
- DQ = 1; //DQ復(fù)位
- delay(8); //稍做延時(shí)
- DQ = 0; //單片機(jī)將DQ拉低
- delay(80); //精確延時(shí) 大于 480us
- DQ = 1; //拉高總線
- delay(14);
- x = DQ; //稍做延時(shí)后 如果x=0則初始化成功 x=1則初始化失敗
- delay(20);
- }
- //=================================================================
- // 函數(shù)名稱 :uchar ReadOneChar(void)
- // 函數(shù)功能 :DS18B20讀字節(jié)函數(shù)
- // 入口參數(shù) :無
- // 出口參數(shù) :dat 讀回的字節(jié)數(shù)據(jù)
- //=================================================================
- uchar ReadOneChar(void)
- {
- uchar i = 0;
- uchar dat = 0;
- for (i = 0; i < 8; i++)
- {
- DQ = 0; // 給脈沖信號(hào)
- dat >>= 1;
- DQ = 1; // 給脈沖信號(hào)
- if (DQ)
- dat |= 0x80;
- delay(4);
- }
- return dat;
- }
- //=================================================================
- // 函數(shù)名稱 :void WriteOneChar(uchar dat)
- // 函數(shù)功能 :DS18B20寫字節(jié)函數(shù)
- // 入口參數(shù) :dat 要寫入的字節(jié)數(shù)據(jù)
- // 出口參數(shù) :無
- //=================================================================
- void WriteOneChar(uchar dat)
- {
- uchar i = 0;
- for (i = 0; i <8; i++)
- {
- DQ = 0;
- DQ = dat & 0x01;
- delay(5);
- DQ = 1;
- dat >>= 1;
- }
- }
- //=================================================================
- // 函數(shù)名稱 :float ReadTemperature(void)
- // 函數(shù)功能 :DS18B20讀取溫度值函數(shù)
- // 入口參數(shù) :無
- // 出口參數(shù) :讀取的溫度值,為float型的數(shù)據(jù)
- //=================================================================
- void ReadTemperature(void)
- {
- Init_DS18B20();
- WriteOneChar(0xcc); // 跳過讀序號(hào)列號(hào)的操作
- WriteOneChar(0x44); // 啟動(dòng)溫度轉(zhuǎn)換
- Init_DS18B20();
- WriteOneChar(0xcc); //跳過讀序號(hào)列號(hào)的操作
- WriteOneChar(0xbe); //讀取溫度寄存器等(共可讀9個(gè)寄存器) 前兩個(gè)就是溫度
- tL = ReadOneChar();
- tH = ReadOneChar();
-
- //合并為字
- t = tH;
- t <<= 8;
- t = t | tL;
-
- if((tH & 0xf8)==0xf8) //負(fù)溫度
- {
- tt=(~t+1)*0.0625;
- tempSign = 1;
- }
- else //正溫度
- {
- tt=t*0.0625;
- tempSign=0;
- }
- CurrentT=(int)(tt*10); //tt*10保留一位小數(shù)并對(duì)float型強(qiáng)制取整
-
- bw=CurrentT/1000; //百位
- sw=CurrentT%1000/100; //十位
- gw=CurrentT%100/10; //個(gè)位
- sfw=CurrentT%10; //小數(shù)十分位
- }
- //=================================================================
- // 函數(shù)名稱 :void DispLCG(int pos, int Data)
- // 函數(shù)功能 :顯示LCG
- // 入口參數(shù) :Pos 數(shù)碼管的位置
- // Data 要顯示的數(shù)字
- // 出口參數(shù) :無
- //=================================================================
- void DispLCG(int Pos, int Data)
- {
- P0 = LCGData[Data];
- P1 |= 0x0f;
- P1 &= 0xff - (0x01 << Pos);
- }
- void LCGDisp(void)
- {
- int i,j;
- for(j=0;j<500;j++) //大約2秒
- {
- for(i=0;i<3;++i)
- {
- DispLCG(i,i);
- delay(300);
- }
- }
- }
- //=================================================================
- // 函數(shù)名稱 :void LedDispDig(int Pos,int Dig)
- // 函數(shù)功能 :在指定的數(shù)碼管上顯示數(shù)字
- // 入口參數(shù) :Pos 數(shù)碼管的位置
- // Dig 要顯示的數(shù)字
- // isDot 是否是個(gè)位數(shù),個(gè)位數(shù)帶小數(shù)點(diǎn)
- // 出口參數(shù) :無
- //=================================================================
- void LedDispDig(int Pos, int Dig, uchar isDot)
- {
- if (isDot==1)
- {
- P0=LEDNumberDot[Dig]; //帶小數(shù)點(diǎn)
- }
- else
- {
- P0 = LEDNumber[Dig]; //不帶小數(shù)點(diǎn)
- }
- P1 |= 0x0f;
- P1 &= 0xff - (0x01 << Pos);
- }
- //=================================================================
- // 函數(shù)名稱 :void scan(float Temp)
- // 函數(shù)功能 :數(shù)碼管動(dòng)態(tài)掃描顯示溫度
- // 入口參數(shù) :Temp 數(shù)碼管上要顯示的溫度值
- // 出口參數(shù) :無
- //=================================================================
- void DisplayTemp(void)
- {
- //針對(duì)4位數(shù)碼管
- if(tempSign==1) //負(fù)溫度,不會(huì)超過 -100,百位總是0,所以只判斷十位來確定在哪個(gè)位顯示負(fù)號(hào)
- {
- if(sw==0)
- {
- LedDispDig(1,10,0);//十位顯示負(fù)號(hào),LEDNumber中第11個(gè)元素
- delay(300);
- LedDispDig(2,gw,1); //個(gè)位,1顯示小數(shù)點(diǎn)
- delay(300);
- LedDispDig(3,sfw,0); //小數(shù)十分位
- }
- else
- {
- LedDispDig(0,10,0);//百位顯示負(fù)號(hào),LEDNumber中第11個(gè)元素
- delay(300);
- LedDispDig(1,sw,0); //十位
- delay(300);
- LedDispDig(2,gw,1); //個(gè)位,1顯示小數(shù)點(diǎn)
- delay(300);
- LedDispDig(3,sfw,0); //小數(shù)十分位
- }
- }
- else //正溫度
- {
- if(bw!=0)
- {
- LedDispDig(0,bw,0); //百位
- delay(300);
- LedDispDig(1,sw,0); //十位
- delay(300);
- }
- else if(sw!=0) //十位
- {
- LedDispDig(1,sw,0);
- delay(300);
- }
- LedDispDig(2,gw,1); //個(gè)位,1顯示小數(shù)點(diǎn)
- delay(300);
- LedDispDig(3,sfw,0); //小數(shù)十分位
- }
- //P1 |= 0x0f; //顯示小數(shù)點(diǎn)
- //P1 &= 0xfb;
- //P0=0x7f;
- //delay(300);
- }
- //====================================================================================
- //函數(shù)名稱:void init_serial(void)
- //函數(shù)功能:初始化串口
- //入口參數(shù):無
- //出口參數(shù):無
- //====================================================================================
- void init_serial(void)
- {
- TMOD = 0x22; //定時(shí)器T1使用工作方式2
- TH1 = 250; //設(shè)置初值
- TL1 = 250;
- TR1 = 1; //開始計(jì)時(shí)
- PCON = 0x80; //SMOD=1;
- SCON = 0x50; //工作方式1,波特率9600bit/s,允許接收
- TI = 1;
- }
- //====================================================================================
- //函數(shù)名稱:void Tranfer(char Data)
- //函數(shù)功能:發(fā)送數(shù)據(jù)程序
- //入口參數(shù):Data 要發(fā)送的數(shù)據(jù)
- //出口參數(shù):無
- //====================================================================================
- void Tranfer(char Data)
- {
- while (TI == 0);
- SBUF = Data;
- TI = 0;
- }
- //====================================================================================
- //函數(shù)名稱:int main(void)
- //函數(shù)功能:主函數(shù),主要用于上位機(jī)發(fā)送
- //入口參數(shù):無
- //出口參數(shù):無
- //====================================================================================
- int main(void)
- {
- float Temp;
- //顯示LCG
- LCGDisp();
-
- tempSign = 0;
- IT1 = 1; //負(fù)跳變方式產(chǎn)生中斷
- EX1 = 1; //開外部中斷1
- EA = 1; //開總中斷
- Init_DS18B20();
- init_serial();
- while (1)
- {
- ReadTemperature();
- DisplayTemp();
-
- Tranfer('a');
- //針對(duì)4位數(shù)碼管
- if(tempSign==1) //負(fù)溫度不會(huì)超過 -100,百位總是0
- {
- Tranfer('-');//發(fā)送負(fù)號(hào)
- if(sw==0) //十位為零,不發(fā)送百位和十位
- {
- Tranfer(gw+0x30); //個(gè)位
- Tranfer(sfw+0x30); //小數(shù)十分位
- }
- else
- {
- Tranfer(sw+0x30); //十位
- Tranfer(gw+0x30); //個(gè)位
- Tranfer(sfw+0x30); //小數(shù)十分位
- }
- }
- else //第一位百位
- {
- if(bw!=0)
- {
- Tranfer(bw+0x30); //百位
- Tranfer(sw+0x30); //十位
- }
- else if(sw!=0) Tranfer(sw+0x30); //十位
- Tranfer(gw+0x30); //個(gè)位
- Tranfer(sfw+0x30); //小數(shù)十分位
- }
- Tranfer('b');
- }
- }
復(fù)制代碼 |