這個是單片機練習,大致需要實現的功能如下:
1.包括一個電源開關,一個設定按鍵,兩個控制設定溫度增減的按鍵
2.通過4位數碼管分別顯示設定溫度和實際溫度,量程為0到99度,開機后設定溫度值初始化為26度(這個地方我用了兩個2位數碼管分別顯示,設定溫度值通過藍色數碼管顯示)
3.用ds18b20對溫度進行轉換并通過數碼管顯示(通過紅色數碼管顯示)
4.單片機要根據設定溫度S和實測溫度P控制繼電器R的動作,精度為2度
(1)當P<=S-1時,繼電器接通加熱回路
(2)當P>S+1時,繼電器斷開加熱回路
(3)當P>S-1且P<=S+1時,繼電器保持原狀態不變
目前原理圖和程序都已經基本完成了,但是只實現了“通過ds18b20讀取溫度并通過數碼管顯示”,和“通過數碼管顯示設定溫度,并通過按鍵增減數值”這兩個模塊的功能,按下設定按鍵后,無論設定溫度和實測溫度值之間關系如何,P3.0口始終保持高電平,繼電器沒有任何動作,目前找不到問題出在什么地方。
此外還很好奇為什么開始仿真時,顯示實測溫度的數碼管會顯示85大約1秒鐘的時間,之后才恢復正常,如果可以解決的話又要如何解決呢?
希望各位大神能夠指導一下。
下面是原理圖:
原理圖,應該也存在需要修改的地方
下面是我自己在參考了一些文章后編寫的代碼,參考的部分主要是控制ds18b20初始化和讀寫數據
- /*預計實現功能:DS18B20讀取溫度通過P3.7口送入單片機,P3.2和P3.3通過外部中斷方式增大或減小設定溫度值*/
- /*P3.1口是設定按鍵,P3.0口通過光耦連接繼電器*/
- /*設定按鍵按下后,當DS18B20讀取到的溫度數值小于設定溫度減1時,繼電器會接通;*/
- /*當讀取到的溫度大于設定溫度加1時,繼電器斷開;*/
- /*當讀取到的溫度大于設定溫度-1且小于等于設定溫度+1時,繼電器不動作*/
- /*目前的問題是程序只能實現顯示當前溫度和設定溫度兩個功能*/
- /*而無論當前溫度和設定溫度數值大小關系如何,P3.0口始終保持高電平,無任何動作,目前找不到問題出在什么地方*/
- /*希望能夠得到解答和幫助*/
- #include<reg51.h>//頭文件
- /*測量部分溫度顯示相關變量定義*/
- sbit DQ=P3^7;//DE18B20總線
- sbit CurTempTP=P2^0;//當前溫度十位,Curent Temperature's Ten Place
- sbit CurTempOP=P2^1;//當前溫度個位,Curent Temperature's One Place
- char CurTemp;//量程限制為0到99攝氏度,故使用有符號字符型變量
- int CurTempTPNum;//當前溫度十位數字
- int CurTempOPNum;//當前溫度個位數字
- /*設定部分溫度顯示相關變量定義*/
- char SetTemp=26;//設定溫度,初始值為26
- sbit SetTempTP=P2^2;//設定溫度的十位,set temperature's one place
- sbit SetTempOP=P2^3;//設定溫度的個位,set temperature's ten place
- int SetTempTPNum;//設定溫度十位數字
- int SetTempOPNum;//設定溫度個位數字
- /*其他設定*/
- sbit SetButton=P3^1;//溫度設定按鍵
- sbit Heater=P3^0;//加熱線圈繼電器控制
- int a,b;
- unsigned char LED[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90};//定義0~9共陽極數碼管字符碼
- void DelayMs(const int ms)//毫秒延時子程序,正常
- {
- int i;
- for(i=0;i<ms;i++)//單次循環約1毫秒,根據輸入的ms值進行延時
- {
- int j;
- for(j=0;j<120;j++);
- }
- }
- void DelayUs(unsigned int k)//微秒延時子程序,正常
- {
- while(k--);//每次數值減1延時約6微秒,設定值為需要延時的時間除以6
- }
- void DS18B20Init()//ds18b20初始化子程序,正常
- {
- unsigned char Flag=0;//DS18B20初始化標志位
- DQ=1;//暫時拉高總線
- DelayUs(5);//稍作延時
- DQ=0;//主機(單片機)發送復位脈沖
- DelayUs(80);//保持480微秒以上
- DQ=1;//然后釋放總線
- DelayUs(14);//若從機(DS18B20)初始化成功,會在15到60微秒后產生低電平信號,信號持續60到240微秒
- Flag=DQ;//若DQFlag=0則初始化成功,DQFlag=1則初始化失敗
- DelayUs(20);
- }
- unsigned char DS18B20ReadData()//ds18b20讀數據子程序,正常
- {
- unsigned char k=0;
- unsigned char dat=0;
- for(k=8;k>0;k--)
- {
- DQ=0;//拉低總線
- dat=dat>>1;//從最高位開始讀取數據,每讀取一位后向右移動一位
- DQ=1;//釋放總線
- if(DQ)
- dat|=0x80;
- DelayUs(4);
- }
- return dat;
- }
- void DS18B20WriteData(unsigned char com)//ds18b20寫數據子程序,com為command,正常
- {
- unsigned char l=0;
- for(l=8;l>0;l--)
- {
- DQ=0;//拉低總線
- DQ=com&0x01;//從最低位開始寫入指令數據,
- DelayUs(5);//延時
- DQ=1;//釋放總線
- com=com>>1;//寫入一位后,指令數據右移一位等待下一位寫入
- }
- }
- unsigned char DS18B20GetTemp()//溫度獲取
- {
- unsigned char TL=0;//溫度低8位
- unsigned char TH=0;//溫度高8位
- unsigned char Temp=0;
- DS18B20Init();//溫度轉換部分,初始化
- DS18B20WriteData(0xcc);//跳過讀rom
- DS18B20WriteData(0x44);//轉換溫度
- DS18B20Init();//溫度讀取部分
- DS18B20WriteData(0xcc);
- DS18B20WriteData(0xbe);//讀取溫度
- TL=DS18B20ReadData();//讀低8位
- TH=DS18B20ReadData();//讀高8位
- Temp=TH<<4;//高8位左移4位后賦值
- Temp=Temp|TL>>4;//低8位左移4位舍棄小數部分后按位或賦值
- return Temp;//返回Temp
- }
- void ShowTemp()//測量溫度數值與設定溫度數值綜合顯示,兩種數值顯示區間均為0到99攝氏度,正常
- {
- //顯示當前測量溫度,數碼管接P0口,數位由P2.0和P2.1口控制
- if(CurTemp>=0&&CurTemp<=99)//當測量值處于0到99攝氏度區間
- {
- CurTempTPNum=CurTemp/10;//取測量值十位
- CurTempOPNum=CurTemp%10;//取測量值個位
- //顯示測量值十位,點亮1毫秒后熄滅
- CurTempTP=1;
- P0=LED[CurTempTPNum];
- DelayMs(10);
- CurTempTP=0;
- //顯示測量值個位,點亮1毫秒后熄滅
- CurTempOP=1;
- P0=LED[CurTempOPNum];
- DelayMs(10);
- CurTempOP=0;
- }
- else if(CurTemp<0)//當測量值低于0攝氏度,則數碼管顯示0
- {
- CurTempTP=1;
- P0=LED[0];
- DelayMs(10);
- CurTempTP=0;
- CurTempOP=1;
- P0=LED[0];
- DelayMs(10);
- CurTempOP=0;
- }
- else if(CurTemp>99)//當測量值高于99攝氏度,則數碼管顯示9
- {
- CurTempTP=1;
- P0=LED[9];
- DelayMs(10);
- CurTempTP=0;
- CurTempOP=1;
- P0=LED[9];
- DelayMs(10);
- CurTempOP=0;
- }
- //顯示當前設定溫度,數碼管連接P1口,數位由P2.2和P2.3控制
- SetTempTPNum=SetTemp/10;//取設定值十位
- SetTempOPNum=SetTemp%10;//取設定值個位
- //顯示設定值十位,點亮1毫秒后熄滅
- SetTempOP=1;
- P1=LED[SetTempOPNum];
- DelayMs(10) ;
- SetTempOP=0;
- //顯示設定值個位,點亮1毫秒后熄滅
- SetTempTP=1;
- P1=LED[SetTempTPNum];
- DelayMs(10);
- SetTempTP=0;
- }
- void Add() interrupt 0//P3.2口接按鈕控制增加設定值,正常
- {
- if(SetTemp<99)//防止數值溢出
- {
- SetTemp++;//設定值加1
- }
- }
- void Sub() interrupt 2//P3.3口接按鈕控制減小設定值,正常
- {
- if(SetTemp>0)//防止數值過小
- {
- SetTemp--;//設定值減1
- }
- }
- void main()//主函數,有問題
- {
- EA=1;//允許總中斷
- EX0=1;//允許外部中斷0
- EX1=1;//允許外部中斷1
- IT0=1;//外部中斷0跳沿觸發
- IT1=1;//外部中斷1跳沿觸發
- Heater=0;
- while(1)
- {
- CurTemp=DS18B20GetTemp();//讀取DS18B20轉換的溫度
- ShowTemp();
- a=SetTemp-1;
- b=SetTemp+1;
- if(SetButton==0)//原本按下按鍵后應該會對當前溫度和設定溫度進行比較然后確定繼電器的動作,但是卻沒有任何反應,也不清楚是哪里出了問題
- {
- DelayMs(10);
- if(SetButton==0)
- {
- if(CurTemp>a&&CurTemp<=b)
- {
- ;
- }
- else if(CurTemp<=a)
- {
- Heater=0;
- }
- else if(CurTemp>b)
- {
- Heater=1;
- }
- }
- }
- }
- }
復制代碼
基于DS18B20的水溫控制器,但是程序有點小問題.zip
(98.88 KB, 下載次數: 162)
2022-6-19 11:52 上傳
點擊文件名下載附件
仿真工程和程序都在這里面
|