|
- /*一、主要功能:
- (1)1路溫度采集電路.
- (2)采集測溫范圍為-55~+120 ℃.
- (3)溫度精度在0.1 ℃;誤差±0.2℃以內.
- (4)顯示模塊,采用4個LED數碼管顯示.
- (5)按鍵3個,設置、加、減.
- (6)報警設置1-99度.低于下限報警,高于上限報警。
- */
- #include<reg51.h>
- #include<intrins.h>
- #define uint unsigned int
- #define uchar unsigned char
- //-----------------------
- sbit S1=P1^0; //設置 上下限
- sbit S2=P1^1; //加
- sbit S3=P1^2; //減
- sbit SEG1=P2^0; //段碼位1
- sbit SEG2=P2^2; //段碼位2
- sbit SEG3=P2^4; //段碼位3
- sbit SEG4=P2^6; //段碼位4
- sbit DQ1=P1^7; //傳感器1
- sbit LED1=P3^0; //報警顯示燈
- sbit BUZ=P3^1; //蜂鳴器
- uchar DQ1_SET[2]; //DQ1上下限設置 DQ1_SET[0] 下限 DQ1_SET[1] 上限;
- uchar Temp; //溫度報警
- uchar count; //蜂鳴器定時用
- uchar mode; //mode=1正常顯示 mode=2 設置下限模式 mode=3設置上限
- //////////////////////////////DS18B20////////////////////////////////////////////////
- uchar ng; //負號標志
- uchar code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x58,0x00};//共陰數碼碼表
- /* 0 1 2 3 4 5 6 7 8 9 C 無*/
- uchar code df_Table[]=
- {
- 0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9
- }; //溫度小數位對照表
- uchar CurrentT = 0; //當前讀取的溫度整數部分
- uchar Temp_Value[]={0x00,0x00}; //從DS18B20讀取的溫度值
- uchar Display_Digit[]={0,0,0,0};//待顯示的各溫度數位
- bit DS18B20_IS_OK = 1; //傳感器正常
- ////////////////////////////////DS18B20///////////////////////////////////////////////
- //************************************************************************/
- // 函數: LCD_Delay()
- // 描述: 延時t ms函數
- // 參數: t
- // 返回: 無
- // 備注: 12MHZ t=1延時時間約1ms
- //************************************************************************/
- void Delay_ms(unsigned int t)
- {
- unsigned int i,j;
- for(i=0;i<t;i++)
- for(j=0;j<120;j++)
- ;
- }
- //************************************************************************/
- // 函數: LCD_Delay()
- // 描述: 延時x us函數
- // 參數: t
- // 返回: 無
- // 備注: 12MHZ 延時時間約us
- //************************************************************************/
- void Delay(uint x)
- {
- while(--x);
- }
- //************************************************************************/
- // 函數: Init_DS18B20()
- // 描述: 初始化DS18B20
- // 參數: t
- // 返回: 無
- // 備注: 12MHZ
- //************************************************************************/
- //初始化DS18B20
- /*DS18B20的復位脈沖 主機通過拉低單總線至少480us以產生復位脈沖
- 然后主機釋放單總線并進入接收模式 此時單總線電平被拉高
- DS18B20檢測到上升沿后 延時15~60us,拉低總線60~240us產生應答脈沖 */
- uchar Init_DS18B20(void)
- {
- uchar status;
- DQ1 = 1; //DS18B20置高電平
- Delay(8); //延時
- DQ1 = 0; //DS18B20置低電平
- Delay(90); //延時480us以上
- DQ1 = 1; //DS18B20置高電平
- Delay(8); //延時
- status = DQ1;//讀狀態
- Delay(100); //延時
- DQ1 = 1; //DS18B20置高電平
- return status;//返回狀態
- }
- //************************************************************************/
- // 函數: Init_DS18B20()
- // 描述: 讀一個字節
- // 參數: t
- // 返回: 無
- // 備注: 12MHZ
- //************************************************************************/
- /*寫時隙 主機在寫1時隙向DS18B20寫入1,在寫0時隙向DS18B20寫入0
- 所有寫時隙至少需要60us,且在兩次寫時隙之間至少需要1us的恢復時間
- 兩種寫時隙均以主機拉低總線開始
- 產生寫1時隙:主機拉低總線后,必須在15us內釋放總線,由上拉電阻拉回至高電平
- 產生寫0時隙:主機拉低總線后,必須整個時隙保持低電平 */
- uchar ReadOneByte()
- {
- uchar i,dat=0;
- DQ1 = 1;//DS18B20置高電平
- _nop_();//延時
- for(i=0;i<8;i++)
- {
- DQ1 = 0;//DS18B20置低電平
- dat >>= 1;//右移數據
- DQ1 = 1;//DS18B20置高電平
- _nop_();//延時
- _nop_();//延時
- if(DQ1)
- dat |= 0X80;
- Delay(30);//延時
- DQ1 = 1;//DS18B20置高電平
- }
- return (dat);
- }
- //************************************************************************/
- // 函數: WriteOneByte(uchar dat)
- // 描述: 寫一個字節
- // 參數: t
- // 返回: 無
- // 備注: 12MHZ
- //************************************************************************/
- /*所有讀時隙至少60us 且兩次獨立的讀時隙之間至少需要1us的恢復時間
- 每次讀時隙由主機發起,拉低總線至少1us。
- 若傳1,則保持總線高電平;若發送0,則拉低總線
- 傳0時DS18B20在該時隙結束時釋放總線,再拉回高電平狀態,主機必須在讀時隙開始后的15us內釋放總線,并保持采樣總線狀態 */
- void WriteOneByte(uchar dat)
- {
- uchar i;
- for(i=0;i<8;i++)
- { DQ1 = 0; //DS18B20置低電平
- DQ1 = dat& 0x01;
- Delay(5); //延時
- DQ1 = 1; //DS18B20置高電平
- dat >>= 1; //右移數據
- }
- }
- //************************************************************************/
- // 函數: Read_Temperature()
- // 描述: 讀溫度值
- // 參數: t
- // 返回: 無
- // 備注: 12MHZ
- //************************************************************************/
- void Read_Temperature()
- { EA=0; //關中斷
- if(Init_DS18B20()==1)
- DS18B20_IS_OK=0;
- else
- {
- WriteOneByte(0xcc); //跳過序列號
- WriteOneByte(0x44); //啟動溫度轉換
- Init_DS18B20();
- WriteOneByte(0xcc);//跳過序列號
- WriteOneByte(0xbe);//讀取溫度寄存器
- Temp_Value[0] = ReadOneByte(); //溫度低8位
- Temp_Value[1] = ReadOneByte();//溫度高8位
- DS18B20_IS_OK=1;
- }
- EA=1; // 開中斷
- }
- //************************************************************************/
- // 函數: Display_Temperature()
- // 描述: 處理溫度值
- // 參數: t
- // 返回: 無
- // 備注: 12MHZ
- //************************************************************************/
- void Display_Temperature()
- {
- uchar t = 150; //,延時
- ng = 0; //與負值標志
- if((Temp_Value[1]&0xf8)==0xf8) //溫度為負?
- {
- Temp_Value[1] = ~Temp_Value[1];
- Temp_Value[0] = ~Temp_Value[0]+1;
- if(Temp_Value[0]==0x00)
- Temp_Value[1]++;
- ng = 1; //負溫度標志
- }
- else{ng = 0;}
- Display_Digit[0] = df_Table[Temp_Value[0]&0x0f]; //查表得溫度小數部分
- CurrentT = ((Temp_Value[0]&0xf0)>>4) | ((Temp_Value[1]&0x07)<<4); //溫度整數部分
- Display_Digit[3] = CurrentT/100; //百
- Display_Digit[2] = CurrentT%100/10; //十
- Display_Digit[1] = CurrentT%10; //個
- Temp=CurrentT ; //報警溫度
- if(ng == 1){Temp=0;}//當溫度為負時,報警判斷溫度寄存器為0
- }
- //************************************************************************/
- // 函數: DIS_SEG(void)
- // 描述: 在LED上顯示數據
- // 參數: t
- // 返回: 無
- // 備注: 12MHZ
- //************************************************************************/
- void DIS_SEG(void)
- {
- if(ng==1){P0=0x40;}else{P0=tab[Display_Digit[3]];} // 數碼管顯示負數 或正的百位
- SEG1=0; //片選數碼管
- Delay_ms(3); //延時2ms
- SEG1=1; //關閉數碼管
- P0=tab[Display_Digit[2]]; //溫度十位
- SEG2=0; //片選數碼管
- Delay_ms(3); //延時2ms
- SEG2=1; //關閉數碼管
- P0=(tab[Display_Digit[1]]+0x80); //溫度個位和小數點
- SEG3=0; //片選數碼管
- Delay_ms(3); //延時2ms
- SEG3=1; //關閉數碼管
- P0=tab[Display_Digit[0]]; //小數位
- SEG4=0; //片選數碼管
- Delay_ms(3); //延時2ms
- SEG4=1; //關閉數碼管
- }
- //************************************************************************/
- // 函數: DIS_SET_SEG(void)
- // 描述: 在LED上顯示數據
- // 參數: t
- // 返回: 無
- // 備注: 12MHZ
- //************************************************************************/
- void DIS_SET_SEG(void)
- {
- P0=tab[Display_Digit[3]];// 數碼管顯示負數 或正的百位
- SEG1=0; //片選數碼管
- Delay_ms(3); //延時2ms
- SEG1=1; //關閉數碼管
- P0=tab[Display_Digit[2]];//溫度十位
- SEG2=0; //片選數碼管
- Delay_ms(3); //延時2ms
- SEG2=1; //關閉數碼管
- P0=tab[Display_Digit[1]];//溫度個位
- SEG3=0; //片選數碼管
- Delay_ms(3); //延時2ms
- SEG3=1; //關閉數碼管
- P0=tab[Display_Digit[0]];//小數位
- SEG4=0; //片選數碼管
- Delay_ms(3); //延時2ms
- SEG4=1; //關閉數碼管
- }
- //************************************************************************/
- // 函數: DIS_UP(void)
- // 描述: 下限設置顯示
- // 參數: t
- // 返回: 無
- // 備注: 12MHZ
- //************************************************************************/
- void DIS_UP(void)
- {
- Display_Digit[3]=DQ1_SET[0]%100/10; //處理顯示溫度
- Display_Digit[2]=DQ1_SET[0]%10;
- Display_Digit[1] =11; //顯示空白
- Display_Digit[0] =11; //顯示空白
- }
- //************************************************************************/
- // 函數: DIS_DOWN(void)
- // 描述: 上限設置顯示
- // 參數: t
- // 返回: 無
- // 備注: 12MHZ
- //************************************************************************/
- void DIS_DOWN(void)
- {
- Display_Digit[3] = 11; //顯示空白
- Display_Digit[2] = 11; //顯示空白
- Display_Digit[1]=DQ1_SET[1]%100/10; //處理顯示溫度
- Display_Digit[0]=DQ1_SET[1]%10;
- }
- //----------------------------鍵盤掃描-------------------------------------------
- //************************************************************************/
- // 函數: void S2_ADD(void)
- // 描述: 加按鍵操作函數
- // 參數: t
- // 返回: 無
- // 備注: 12MHZ
- //************************************************************************/
- void S2_ADD(void)
- { if(mode==2) //下限模式
- {
- DQ1_SET[0]++; if(DQ1_SET[0]>99){DQ1_SET[0]=99;} //加下限 和限值下限最大值
- }
- if(mode==3)//上限模式
- {
- DQ1_SET[1]++; if(DQ1_SET[1]>99){DQ1_SET[1]=99;} //加上限 和限值下限最大值
- }
- }
- //************************************************************************/
- // 函數: S3_SUB(void)
- // 描述: 減按鍵操作
- // 參數: t
- // 返回: 無
- // 備注: 12MHZ
- //************************************************************************/
- void S3_SUB(void)
- { if(mode==2) //下限模式
- {
- DQ1_SET[0]--; if(DQ1_SET[0]<1){DQ1_SET[0]=1;} //加下限 和限值下限最大值
- }
- if(mode==3)//上限模式
- {
- DQ1_SET[1]--; if(DQ1_SET[1]<1){DQ1_SET[1]=1;} //加上限 和限值下限最大值
- }
- }
- //************************************************************************/
- // 函數: KEY_SCAN(void)
- // 描述: 鍵盤掃描
- // 參數: t
- // 返回: 無
- // 備注: 12MHZ
- //************************************************************************/
- void KEY_SCAN(void)
- { if(S1==0)
- {
- Delay_ms(10); //延時去抖動
- mode++;
- if(mode>3){mode=1;} //在1 2 3中切換
- while(!S1){;} //等待按鍵釋放
- }
- if(S2==0)
- {
- Delay_ms(10); //延時去抖動
- S2_ADD();
- while(!S2){;} //等待按鍵釋放
- }
- if(S3==0)
- {
- Delay_ms(10); //延時去抖動
- S3_SUB();
- while(!S3){;} //等待按鍵釋放
- }
- // 通道切換
- }
- //----------------------------鍵盤掃描-------------------------------------------
- //************************************************************************/
- // 函數: init(void)
- // 描述: 初始化定時器蜂鳴器報警用
- // 參數: t
- // 返回: 無
- // 備注: 12MHZ
- //************************************************************************/
- void init(void) //定時器初始化
- {
- TMOD=0x01;
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- EA=1; //開中斷
- ET0=1; //
- TR0=0; //
- BUZ=1; //關蜂鳴器
- }
- //************************************************************************/
- // 函數: main(void)
- // 描述: 主程序
- // 參數: t
- // 返回: 無
- // 備注:
- //************************************************************************/
- void main(void)
- { uchar i;
- //--------超溫初始---------------
- DQ1_SET[0]=10; //DQ1下限10
- DQ1_SET[1]=90; //DQ1上限90
- //-----------------------
- init(); //初始化蜂鳴器
-
- Read_Temperature(); //初始化DQ1
- Delay_ms(1000); //延時1s
- Read_Temperature(); //讀溫度
- //------------------------------------
- Read_Temperature(); //讀溫度
- if(DS18B20_IS_OK)
- Display_Temperature(); //顯示溫度處理
- //------------------------------------
- mode=1; //mode=1 正常模式
- while(1)
- { if(mode==1){//模式1
- //--------------鍵盤掃描-------------------------
- KEY_SCAN();
- //------------在SEG上顯示溫度--------------------
- DIS_SEG();
- //--------------------溫度-----------------------
- i++;
- if(i>88) //避免頻繁采集溫度
- { Read_Temperature(); //讀溫度
- if(DS18B20_IS_OK){Display_Temperature();} //溫度數據處理
- i=0;
- }
- //-----------------------超溫報警-----------------------------
- while(1)
- {
- if(Temp<DQ1_SET[0]){LED1=0;TR0=1;break;}else{ if(Temp>DQ1_SET[1]){LED1=0;TR0=1;break;}else{LED1=1;BUZ=1;TR0=0;}}
- break; //下限報警 //上限報警
- }
-
- //-----------------------超溫報警-----------------------------
- }
- if(mode==2) //下限設置
- {
- KEY_SCAN(); //鍵盤掃描
- DIS_UP(); //顯示數據處理
- DIS_SET_SEG(); //設置模式下SEG顯示方式
- }
- if(mode==3) //上限設置
- {
- KEY_SCAN(); //鍵盤掃描
- DIS_DOWN(); //顯示數據處理
- DIS_SET_SEG(); //設置模式下SEG顯示方式
- //--------------------通道顯示------------------------
- }
- }
- }
- void timer0() interrupt 1 using 1 //蜂鳴器報警聲音
- {
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- count++;
- if(count==10) //約10*50000us 取反1次0.5s
- {
- count=0; //清除計數
- BUZ=~BUZ; //蜂鳴器取反
- }
- }
復制代碼
|
評分
-
查看全部評分
|