Altium Designer畫的原理圖和PCB圖如下:(51hei附件中可下載工程文件)
51hei拼音截圖20210709162540.png (342.28 KB, 下載次數: 58)
下載附件
2021-7-9 16:26 上傳
51hei拼音截圖20210709162601.png (205.86 KB, 下載次數: 51)
下載附件
2021-7-9 16:26 上傳
制作出來的恒溫控制電路實物圖如下:
51hei圖片20210705190509.jpg (4.72 MB, 下載次數: 49)
下載附件
2021-7-9 16:24 上傳
電路原理圖,我加了7805就不需要雙電源了,PCB版沒有
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei.gif (84.05 KB, 下載次數: 54)
下載附件
2021-7-9 18:25 上傳
元件清單:
0.1uF(104)瓷片電容 1 C3
10K 碳膜電阻 4 R2, R9, R10,R5
12.00MHz 晶體振蕩器 1 CRY1
1N4007 二極管 2 D1, D2
0.47uF(1uF) 電解電容 1 CE1
100uF(220uF) 電解電容 1 CE2
22pF 瓷片電容 2 C1, C2
4.7K 碳膜電阻 1 R3
1K 碳膜電阻 4 R4, R6, R7, R8
5K 電位器 1 RP1
5V DC蜂鳴器 1 BZ1
S8550三極管 1 Q1
6x6輕觸按鍵 4 S1,S2,S3,S4
DS18B20 溫度傳感器 1 J1
SRD-05VDC 繼電器 2 RELAY1, RELAY2
LCD1602 液晶屏 1 LCD1
IDC-3P 2.54mm 單排排針 1 J1
IDC-16P 2.54mm 單排排針 1 LCD1
S9014 三極管 2 Q2, Q3
STC89C52 單片機 1 IC1
XH-2P 2.54mm插座 1 J2
KF25-6P-7.62mm 接線座 1 J6
紅色LED 2 LD2,LD3, LD4
綠色LED 1 LD1
萬能板(洞洞板) 1
錫線 1份
連線 1份
單片機源程序如下:
- #include <reg52.h>
- #include <intrins.h>
- #define uint unsigned int
- #define uchar unsigned char
- sbit DQ=P2^3;//ds18b20與單片機連接口
- sbit RS=P2^5;//液晶控制線接口
- sbit RW=P2^6;
- sbit EN=P2^7;
- uchar data disdata[5];
- uint tvalue,CurrentT=0;//溫度值
- uchar tflag;//溫度正負標志
-
- #define LCD_BUS P0
- sbit SetKey = P2^2;//設置按鍵
- sbit UpKey = P2^1; //加按鍵
- sbit DnKey = P2^0;//減按鍵
- sbit BEEP = P2^4;//蜂鳴器
- sbit Heat = P1^0;//加熱繼電器控制
- sbit Cool = P1^1;//降溫繼電器控制
- unsigned char AlarmTempLow=10,AlarmTempTop=40,Set=0;
- void delayms(uint ms) //延時xx毫秒
- {
- uchar i;
- while(ms--)
- {
- for(i=0;i<120;i++);
- }
- }
- void command(uint com) //LCD寫指令
- {
- RS=0; //RS為0
- LCD_BUS=com; //裝載指令
- delayms(5); //延時5ms
- EN=1; //LCD使能
- delayms(5); //延時5ms
- EN=0; //LCD不使能
- }
- void write_dat(uchar dat) //LCD寫數據
- {
- RS=1; //RS為1
- LCD_BUS=dat; //裝載數據
- delayms(5); //延時5ms
- EN=1; //LCD使能
- delayms(5); //延時5ms
- EN=0; //LCD不使能
- }
- void writestring(uchar x,uchar y,uchar *s) //LCD 寫字符串
- {
- if (y == 0) command(0x80 + x); //表示第一行
- else command(0xC0 + x); //表示第二行
-
- while (*s) //判斷是否字符串的結尾
- {
- write_dat( *s); //顯示當前字符
- s ++; //字符串地址加1
- }
- }
- void writeChar(uchar x,uchar y,uchar s) //LCD 寫字符串
- {
- if (y == 0) command(0x80 + x); //表示第一行
- else command(0xC0 + x); //表示第二行
-
- {
- write_dat( s); //顯示當前字符
- }
- }
- void LCD_Initial() //LCD初始化
- {
- EN=0; //LCD不使能
- RW=0; //RW為0
- command(0x38); //發送初始化指令
- command(0x0c); //發送初始化指令
- command(0x06); //發送初始化指令
- command(0x01); //發送初始化指令
- command(0x80+0x02); //發送LCD初始位置
- }
- /*************************DS1820程序****************************/
- void delay_18B20(unsigned int i)//延時1微秒
- {
- while(i--);
- }
- void ds1820rst(void)/*ds1820復位*/
- {
- unsigned char x=0;
- DQ = 1; //DQ復位
- delay_18B20(4); //延時
- DQ = 0; //DQ拉低
- delay_18B20(100); //精確延時大于480us
- DQ = 1; //拉高
- delay_18B20(40);
- }
- uchar ds1820rd(void)/*讀數據*/
- {
- unsigned char i=0;
- unsigned char dat = 0;
- for (i=8;i>0;i--)
- {
- DQ = 0; //給脈沖信號
- dat>>=1;
- DQ = 1; //給脈沖信號
- if(DQ)
- dat|=0x80;
- delay_18B20(10);
- }
- return(dat);
- }
- void ds1820wr(uchar wdata)/*寫數據*/
- {
- unsigned char i=0;
- for (i=8; i>0; i--) //寫一個字節數據到DS18B20
- {
- DQ = 0;
- DQ = wdata&0x01; //寫一位數據
- delay_18B20(10); //延時
- DQ = 1; //拉高數據線
- wdata>>=1;//準備下一位
- }
- }
- unsigned int Read_Temperature(void)/*讀取溫度值并轉換*/
- {
- uchar a,b;
- ds1820rst();
- ds1820wr(0xcc);//*跳過讀序列號*/
- ds1820wr(0x44);//*啟動溫度轉換*/
- ds1820rst();
- ds1820wr(0xcc);//*跳過讀序列號*/
- ds1820wr(0xbe);//*讀取溫度*/
- a=ds1820rd(); //讀取低位數據
- b=ds1820rd(); //讀取高位數據
- tvalue=b;
- tvalue<<=8;
- tvalue=tvalue|a;//取得16位數據
- if(tvalue<0x0fff) tflag=0; //判斷是否正溫度
- else {tvalue=~tvalue+1;tflag=1;} //負溫度,數據取反,溫度標志位為1
- tvalue=tvalue*(0.625);//溫度值擴大10倍,精確到1位小數
- CurrentT=tvalue;//保存當前溫度
- return(tvalue);//返回溫度值
- }
- void Display_Temperature() //顯示溫度
- {
- uchar flagdat;
- disdata[0]=tvalue/1000+0x30;//百位數
- disdata[1]=tvalue%1000/100+0x30;//十位數
- disdata[2]=tvalue%100/10+0x30;//個位數
- disdata[3]=tvalue%10+0x30;//小數位
-
- if(tflag==0) flagdat=0x20;//正溫度不顯示符號
- else flagdat=0x2d;//負溫度顯示負號:-
- if(tflag==1)
- {
- writeChar(10,0,flagdat);//顯示符號位
- writeChar(11,0,disdata[0]);//顯示百位
- writeChar(12,0,disdata[1]);//顯示十位
- writeChar(13,0,disdata[2]);//顯示個位
- writeChar(14,0,0X2E);//顯示小數點
- writeChar(15,0,disdata[3]);//顯示小數位
- }
- else
- {
- writeChar(10,0,disdata[0]);//顯示百位
- writeChar(11,0,disdata[1]);//顯示十位
- writeChar(12,0,disdata[2]);//顯示個位
- writeChar(13,0,0X2e);//顯示小數點
- writeChar(14,0,disdata[3]);//顯示小數位
- writeChar(15,0,' ');//顯示小數位
- }
- }
- void SetFun(void) //進入設置參數子函數
- {
- unsigned char i1=0,i2=0,i3=0,i4=0,i5=0,i6=0;
- if(SetKey==0) //設置按鍵
- {
- delayms(20); //延時防抖
- if(SetKey==0) //設置按鍵
- {
- if(Set<2) Set++; //設置按鍵次數累計
- else Set=0;
- }
- switch(Set) //根據設置按鍵次數,指向對應設置位置
- {
- case 0: writestring(0,1," ");writestring(8,1," ");break;//清除設置符號
- case 1: writestring(0,1,">");writestring(8,1," ");break;//指向設置下限
- case 2: writestring(0,1," ");writestring(8,1,">");break;//指向設置上限
- }
- while(SetKey==0);//等待按鍵松開
- }
-
- if((UpKey==0)&&(Set!=0))//加按鍵按下
- {
- delayms(20);//延時防抖
- if(UpKey==0)//加按鍵按下
- {
- switch(Set)//根據設置按鍵次數,設置上下限
- {
- case 1: if(AlarmTempLow<99) AlarmTempLow++;else AlarmTempLow=99; break;//設置下限
- case 2: if(AlarmTempTop<99) AlarmTempTop++;else AlarmTempTop=99; break;//設置上限
- }
- i1 = AlarmTempLow/100; //獲得下限溫度值的百位
- i2 = AlarmTempLow%100/10; //獲得下限溫度值的十位
- i3 = AlarmTempLow%10; //獲得下限溫度值的個位
-
- i4 = AlarmTempTop/100; //獲得上限溫度值的百位
- i5 = AlarmTempTop%100/10; //獲得上限溫度值的十位
- i6 = AlarmTempTop%10; //獲得上限溫度值的個位
- writestring(5,1," "); //清除之前的內容
- writestring(13,1," ");//清除之前的內容
- if(i1!=0) writeChar(5,1,i1+'0');//在第二行第5位 ,顯示下限溫度值的百位
- if((i1==0)&&(i2!=0)) writeChar(5,1,i2+'0');//在第二行第5位 ,顯示下限溫度值的十位
- if(i1!=0) writeChar(6,1,i2+'0');//在第二行第6位 ,顯示下限溫度值的十位
- if((i1==0)&&(i2==0)) writeChar(5,1,i3+'0');//在第二行第5位 ,顯示下限溫度值的個位
- else if((i1==0)&&(i2!=0)) writeChar(6,1,i3+'0');//在第二行第6位 ,顯示下限溫度值的個位
- if((i1!=0)) writeChar(7,1,i3+'0');//在第二行第7位 ,顯示下限溫度值的個位
-
- if(i4!=0) writeChar(13,1,i4+'0');//在第二行第13位 ,顯示上限溫度值的百位
- if((i4==0)&&(i5!=0)) writeChar(13,1,i5+'0');//在第二行第13位 ,顯示上限溫度值的十位
- if(i4!=0) writeChar(14,1,i5+'0');//在第二行第14位 ,顯示上限溫度值的十位
- if((i4==0)&&(i5==0)) writeChar(13,1,i6+'0');//在第二行第13位 ,顯示上限溫度值的個位
- else if((i4==0)&&(i5!=0)) writeChar(14,1,i6+'0');//在第二行第14位 ,顯示上限溫度值的個位
- if((i4!=0)) writeChar(15,1,i6+'0');//在第二行第15位 ,顯示上限溫度值的個位
- while(UpKey==0);//等待按鍵松開
- }
- }
-
- if((DnKey==0)&&(Set!=0))//減按鍵
- {
- delayms(20);
- if(DnKey==0)//減按鍵
- {
- switch(Set)//根據設置按鍵次數,設置上下限
- {
- case 1: if(AlarmTempLow>0) AlarmTempLow--;else AlarmTempLow=0; break;//設置下限
- case 2: if(AlarmTempTop>0) AlarmTempTop--;else AlarmTempTop=0; break;//設置上限
- }
- i1 = AlarmTempLow/100; //獲得下限溫度值的百位
- i2 = AlarmTempLow%100/10; //獲得下限溫度值的十位
- i3 = AlarmTempLow%10; //獲得下限溫度值的個位
-
- i4 = AlarmTempTop/100; //獲得上限溫度值的百位
- i5 = AlarmTempTop%100/10; //獲得上限溫度值的十位
- i6 = AlarmTempTop%10; //獲得上限溫度值的個位
- writestring(5,1," "); //清除之前的內容
- writestring(13,1," ");//清除之前的內容
- if(i1!=0) writeChar(5,1,i1+'0');//在第二行第5位 ,顯示下限溫度值的百位
- if((i1==0)&&(i2!=0)) writeChar(5,1,i2+'0');//在第二行第5位 ,顯示下限溫度值的十位
- if(i1!=0) writeChar(6,1,i2+'0');//在第二行第6位 ,顯示下限溫度值的十位
- if((i1==0)&&(i2==0)) writeChar(5,1,i3+'0');//在第二行第5位 ,顯示下限溫度值的個位
- else if((i1==0)&&(i2!=0)) writeChar(6,1,i3+'0');//在第二行第6位 ,顯示下限溫度值的個位
- if((i1!=0)) writeChar(7,1,i3+'0');//在第二行第7位 ,顯示下限溫度值的個位
-
- if(i4!=0) writeChar(13,1,i4+'0');//在第二行第13位 ,顯示上限溫度值的百位
- if((i4==0)&&(i5!=0)) writeChar(13,1,i5+'0');//在第二行第13位 ,顯示上限溫度值的十位
- if(i4!=0) writeChar(14,1,i5+'0');//在第二行第14位 ,顯示上限溫度值的十位
- if((i4==0)&&(i5==0)) writeChar(13,1,i6+'0');//在第二行第13位 ,顯示上限溫度值的個位
- else if((i4==0)&&(i5!=0)) writeChar(14,1,i6+'0');//在第二行第14位 ,顯示上限溫度值的個位
- if((i4!=0)) writeChar(15,1,i6+'0');//在第二行第15位 ,顯示上限溫度值的個位
-
- while(DnKey==0);
- }
- }
- }
- void Alarm(void)//報警子函數
- {
- if((CurrentT>=(AlarmTempTop*10))||(CurrentT<=(AlarmTempLow*10))||(tflag==1)) //超出設定范圍
- {
- BEEP=0;//啟動報警
- }
- else //在設定范圍內
- {
- BEEP=1;//取消報警
- }
- }
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
51hei.png (6.09 KB, 下載次數: 67)
下載附件
2021-7-9 18:23 上傳
全部資料51hei下載地址(dsn文件 仿真是用Proteus7.5畫的):
恒溫控制.7z
(3.38 MB, 下載次數: 217)
2021-7-9 18:28 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|