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