|
歷經(jīng)千辛萬苦,我的孵化器溫控器終于搞成了。在此感謝51黑網(wǎng)友的大力支持。程序和圖紙奉上,歡迎大家指正,并加以完善。
圖片詳見:http://www.torrancerestoration.com/bbs/dpj-224670-1.html
制作出來的孵化器實(shí)物圖如下:


Altium Designer畫的原理圖和PCB圖如下:(51hei附件中可下載工程文件)
51hei.png (34.53 KB, 下載次數(shù): 61)
下載附件
2022-11-24 00:16 上傳
51hei.png (46.95 KB, 下載次數(shù): 61)
下載附件
2022-11-24 00:16 上傳
單片機(jī)源程序如下:
- /******************************************
- 名稱:aip650的驅(qū)動(dòng)
- 時(shí)間:2022-11-13
- 版本:
- 作者:cjz
- **************************************************/
- //頭文件
- #include <STC89X52RC.H>
- #include <absacc.h>
- #include <intrins.h>
- #include <EEPROM.H>
- /*************************************************
- 常量、變量定義區(qū)
- ***************************************************/
- //常量定義
- #define true 1
- #define false 0
- #define uchar unsigned char
- #define uint unsigned int
- //數(shù)組定義
- uchar Display_Code[13]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x80,0x40,0x00};
- //共陰數(shù)碼管段碼 0, 1, 2, 3, 4 , 5, 6, 7, 8, 9, ., -, 不亮
- //uchar Display_16Code[16]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
- //16進(jìn) 制段碼(用于顯示鍵值)0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f
- uchar Dig_Bit_Code[4]={0x68,0x6a,0x6c,0x6e};//650位碼
- uchar Light_Level_Code[8]={0x11,0x21,0x31,0x41,0x51,0x61,0x71,0x01};//亮度調(diào)節(jié)
- uchar keyvalue;
- uint wendu;//用于存儲(chǔ)溫度值
- uint maxwendu;
- uchar maxwenduH;//最高溫度高8位
- uchar maxwenduL;//最高溫度低8位
- uint minwendu;
- uchar minwenduH;//最低溫度高8位
- uchar minwenduL;
- uchar menu=0, cou;//菜單標(biāo)志,計(jì)數(shù),cou1
- uint h;//溫度計(jì)算使用
- uint temp;//溫度返回值
- //uchar k;
- /***************************溫度小數(shù)部分用查表法*****************/
- uchar ditab[16]=
- {0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};
- uchar temp_data[2]={0x00,0x00};//讀出溫度暫存
- uchar display[5]={0x00,0x00,0x00,0x00,0x00};//顯示單元數(shù)據(jù),共4個(gè)數(shù)據(jù)和一個(gè)運(yùn)算暫用
- //定義IO口
- sbit SDA=P3^7;
- sbit SCL=P3^6;
- //sbit beep=P1^4;
- sbit DQ=P1^1; //ds18b20溫度輸入口
- //sbit DIN=P1^3; //LED小數(shù)點(diǎn)控制
- /**********************************函數(shù)定義區(qū)************************************/
- //I2C相關(guān)
- /*******************************************************************************
- 功能:I2CWait
- 描述:I2C延時(shí)
- 參數(shù):
- 返回:
- *******************************************************************************/
- void I2CWait(void)
- {_nop_();_nop_();_nop_();_nop_();
- }
- /*******************************************************************************
- 功能:I2CStart
- 描述:開啟I2C總線
- 參數(shù):
- 返回:位變量,1=I2C總線可用,0=不可用
- *******************************************************************************/
- bit I2CStart(void)
- {
- SDA=1;
- SCL=1;
- I2CWait();
- if(!SDA)
- return false;//SDA線為低電平則總線忙,退出
- SDA=0;
- I2CWait();
- while(SDA)
- return false;//SDA線為高電平則總線出錯(cuò),退出
- SCL=0;
- I2CWait();
- return true;
- }
- /*******************************************************************************
- 功能:I2CStop(void)
- 描述:關(guān)閉I2C總線
- 參數(shù):
- 返回:
- *******************************************************************************/
- void I2CStop(void)
- {
- SDA=0;
- SCL=0;
- I2CWait();
- SCL=1;
- I2CWait();
- SDA=1;
- }
- /*******************************************************************************
- 功能:I2CSendAck
- 描述:發(fā)送ACK信號(hào)
- 參數(shù):
- 返回:
- *******************************************************************************/
- void I2CSendAck(void)
- {
- SDA=0;
- SCL=0;
- I2CWait();
- SCL=1;
- I2CWait();
- SCL=0;
- }
- /*******************************************************************************
- 功能:I2CSendNoAck
- 描述:發(fā)送 No Ack
- 參數(shù):
- 返回:
- *******************************************************************************/
- /*void I2CSendNoAck(void)
- {
- SDA=1;
- SCL=0;
- I2CWait();
- SCL=1;
- I2CWait();
- SCL=0;
-
- }*/
- /*******************************************************************************
- 功能:I2CWaitAck
- 描述:讀取ACK信號(hào)
- 參數(shù):
- 返回:位變量, 1=有ACK,0=無ACK
- *******************************************************************************/
- bit I2CWaitAck(void)
- {
- uchar errtime=255;
- SCL=0;
- SDA=1;
- I2CWait();
- SCL=1;
- I2CWait();
- while(SDA)
- {
- errtime--;
- if(!errtime)
- SCL=0;
- return false;
- }
- SCL=0;
- return true;
- }
- /*******************************************************************************
- 功能:I2CSendByte
- 描述:向總線發(fā)送一個(gè)字節(jié)
- 參數(shù):待發(fā)送字節(jié)demand,發(fā)送順序指示order
- order=1,從HI-->LO發(fā)送8bit數(shù)
- order=0,從LO-->HI發(fā)送8bit數(shù)
- 返回:
- *******************************************************************************/
- void I2CSendByte(uchar demand,bit order)
- {
- uchar i=8;
- if(order)
- {
- while(i--)
- {
- SCL=0;
- _nop_();
- SDA=(bit)(demand&0x80);
- demand<<=1;
- I2CWait();
- SCL=1;
- I2CWait();
- }
- SCL=0;
- }
- else
- {
- while(i--)
- {
- SCL=0;
- _nop_();
- SDA=(bit)(demand&0x01);
- demand>>=1;
- I2CWait();
- SCL=1;
- I2CWait();
- }
- SCL=0;
- }
- }
- /*******************************************************************************
- 功能:I2CReceiveByte
- 描述:從總線讀一個(gè)字節(jié)
- 參數(shù):
- 返回:
- *******************************************************************************/
- uchar I2CReceiveByte(void)
- {
- uchar i=8;
- uchar ddata=0;
- SDA=1;
- while(i--)
- {
- ddata>>=1;//數(shù)據(jù)從低位開始讀取
- SCL=0;
- I2CWait();
- SCL=1;
- I2CWait();//從低位開始 ddata|=SDA;ddata>>=1
- if(SDA)
- {
- ddata|=0x80;
- }
- }
- SCL=0;
- return ddata;
- }
- /*******************************************************************************
- 功能:從650讀鍵值
- 描述:
- 參數(shù):
- 返回:uchar鍵值
- *******************************************************************************/
- uchar AipReadKey()
- {
- uchar key;
- I2CStart();
- I2CSendByte(0x4f,1);
- if(I2CWaitAck())
- {
- key=I2CReceiveByte();
-
- I2CSendAck();
- }
- I2CStop();
- return key;
- }
- /*******************************************************************************
- 功能:向650發(fā)送地址,和數(shù)據(jù)
- 描述:
- 參數(shù):
- 返回:
- *******************************************************************************/
- void Aip650_Set(uchar add,uchar dat)
- {
- //寫顯存必須從高地址開始寫
- I2CStart();
- I2CSendByte(add,1);
- I2CSendAck();
- I2CSendByte(dat,1);
- I2CSendAck();
- I2CStop();
- }
- /*******************************************************************************
- 功能:驅(qū)動(dòng)數(shù)碼管顯示數(shù)字
- 描述:位碼數(shù)組中選擇對(duì)應(yīng)的位地址,在段碼數(shù)組中選擇對(duì)應(yīng)數(shù)字的段碼發(fā)送給650
- 參數(shù):
- 返回:
- *******************************************************************************/
- void Aip650_DisPlay(uchar Dig_Bit,uchar Display_num)
- {
- Aip650_Set(Dig_Bit_Code[Dig_Bit-1],Display_Code[Display_num]);
- }
- /*******************************************************************************
- 功能:驅(qū)動(dòng)數(shù)碼管顯示16進(jìn)制數(shù)的代碼
- 描述:
- 參數(shù):
- 返回:
- void Aip650_DisPlay16(uchar Dig_Bit16,uchar Display_num16)
- {
- Aip650_Set(Dig_Bit_Code[Dig_Bit16-1],Display_16Code[Display_num16]);
- }
- *******************************************************************************/
- /*******************************************************************************
- 功能:650清屏
- 描述:
- 參數(shù):
- 返回:
- *******************************************************************************/
- void Aip650_CLR()
- {
- uchar i;
- for(i=0;i<4;i++)
- {
- Aip650_Set(Dig_Bit_Code[i],0x00);[/i][i]
- }
- }
- /*******************************************************************************
- 功能:設(shè)置顯示亮度
- 描述:
- 參數(shù):
- 返回:
- *******************************************************************************/
- void Light_Level_Set(uchar level)
- {
- Aip650_Set(0x48,Light_Level_Code[level-1]);
- }
- //溫度用
- /*******************************************************************************
- 功能:delay 延時(shí)程序 11us
- 描述:
- 參數(shù):
- 返回:
- *******************************************************************************/
- void delay(uint t)
- {
- for(;t>0;t--);
- }
- /*******************************************************************************
- 功能:Ds18b20 復(fù)位函數(shù)
- 描述:
- 參數(shù):
- 返回:
- *******************************************************************************/
- void ow_reset(void)
- {
- uchar presence=1;
- while(presence)
- {while(presence)
- {
- DQ=1;
- _nop_();_nop_();//從高拉到低
- DQ=0;
- delay(50);//550us
- DQ=1;
- delay(6);//66us
- presence=DQ;//presence=0復(fù)位成功,繼續(xù)下一步
- }
- delay(45);//延時(shí)500us
- presence=~DQ;
- }
- DQ=1; //拉高電平
- }
- /*******************************************************************************
- 功能:Ds18b20寫命令函數(shù)
- 描述:向總線上寫1個(gè)字節(jié)
- 參數(shù):
- 返回:
- *******************************************************************************/
- void write_byte(uchar val)
- {
- uchar i;
- for(i=8;i>0;i--)
- {DQ=1;_nop_();_nop_();//從高拉低
- DQ=0; _nop_();_nop_();_nop_();_nop_();//5us
- DQ=val&0x01;// 最低位移出
- delay(6);//66us
- val=val/2;//右移一位}
- }
- DQ=1;
- delay(1);
- }
- /*******************************************************************************
- 功能:從18b20總線上讀1字節(jié)
- 描述:
- 參數(shù):
- 返回:value
- *******************************************************************************/
- uchar read_byte(void)
- {
- uchar i;
- uchar value=0;
- for(i=8;i>0;i--)
- {
- DQ=1;_nop_();_nop_();
- value>>=1;
- DQ=0;_nop_();_nop_();_nop_();_nop_();//4us
- DQ=1;_nop_();_nop_();_nop_();_nop_();//4us
- if(DQ)value|=0x80;
- delay(6);
- }
-
- DQ=1;
- return(value);
- }
- /*******************************************************************************
- 功能:讀出溫度
- 描述:
- 參數(shù):
- 返回:
- *******************************************************************************/
- read_temp()
- {
- ow_reset();
- delay(200);//總線復(fù)位
- write_byte(0xcc);//發(fā)命令
- write_byte(0x44);//發(fā)轉(zhuǎn)換命令
- ow_reset();
- delay(1);
- write_byte(0xcc);//發(fā)命令
- write_byte(0xbe);
- temp_data[0]=read_byte();//讀溫度的低字節(jié)
- temp_data[1]=read_byte();//讀溫度的高字節(jié)
- temp=temp_data[1];
- temp<<=8;
- temp=temp|temp_data[0];// 兩字節(jié)合成一個(gè)整型變量
- return temp;
- }
- /*******************************************************************************
- 功能:溫度處理
- 描述:二進(jìn)制數(shù)的高字節(jié)的低半字節(jié)和低字節(jié)的高半字節(jié)組成一個(gè)字,這個(gè)字節(jié)轉(zhuǎn)換為十進(jìn)制后,
- 就是溫度的百、十、個(gè)位值,而剩下的低字節(jié)的低半字節(jié)轉(zhuǎn)化成十進(jìn)制后,就是溫度值的小數(shù)部分。
- 參數(shù):
- 返回:
- *******************************************************************************/
- void work_temp(uint tem)
- {
- uchar n=0;
- if(tem>6348) //溫度正負(fù)判斷
- {tem=65536-tem;n=1;} //負(fù)溫度求補(bǔ)碼,標(biāo)志位置1
- display[4]=tem&0x0f;
- display[0]=ditab[display[4]];//存入小數(shù)部分的顯示值
- display[4]=tem>>4;
- display[3]=display[4]/100;//取百位數(shù)據(jù)暫存
- display[1]=display[4]%100;//取后兩位數(shù)據(jù)暫存
- display[2]=display[1]/10;//取十位數(shù)據(jù)暫存
- display[1]=display[1]%10;
- /***********符號(hào)位顯示判斷*************************/
- if(!display[3])
- {
- display[3]=0x0c; //最高位為0時(shí)不顯示
- if(!display[2])
- {
- display[2]=0x0c; //次高位為0時(shí)不顯示
- }
- if(n)
- {display[3]=0x0b;} //負(fù)溫度時(shí)最高位顯示“-”
- }
- }
- /*******************************************************************************
- 功能:顯示溫度
- 描述:處理溫度數(shù)值,發(fā)送650
- 參數(shù):
- 返回:
- *******************************************************************************/
- void xianshiwendu(uint tem1)
- {
- work_temp(tem1);
- //Aip650_CLR();
- Light_Level_Set(2);
- // Aip650_DisPlay(2,10);//顯示小數(shù)點(diǎn)
- Aip650_DisPlay(3,display[2]);//十位
- Aip650_Set(Dig_Bit_Code[1],Display_Code[display[1]]|0x80);//個(gè)位加小數(shù)點(diǎn)
- //Aip650_DisPlay(2,display[1]);//個(gè)位
- Aip650_DisPlay(1,display[0]);//小數(shù)
- }
- /*******************************************************************************
- 功能:顯示鍵值
- 描述:將按鍵的16進(jìn)制代碼送顯示
- 參數(shù):
- 返回:
- void xianshijianzhi(uchar key1)
- {uchar keyL,keyH;
- keyL=key1&0x0f;
- Light_Level_Set(4);
- Aip650_DisPlay16(1,keyL);
- keyH=key1>>4;
-
- Aip650_DisPlay16(2,keyH);
- }
- *******************************************************************************/
- /*********************************************************************************************
- 函數(shù)名:定時(shí)/計(jì)數(shù)器初始化函數(shù)
- 調(diào) 用:T_C_init();
- /**********************************************************************************************/
- void Timer0_init (void){
- TMOD = 0x11; //高4位控制T/C1 [ GATE,C/T,M1,M0,GATE,C/T,M1,M0 ]
- EA = 1; //中斷總開關(guān)
- TH0 = 0x3c; //16位計(jì)數(shù)寄存器T0高8位(寫入初值)
- TL0 = 0xb0; //16位計(jì)數(shù)寄存器T0低8位
- ET0 = 1; //T/C1中斷開關(guān)
- TR0 = 0; //T/C1關(guān)閉開關(guān)
- }
- /*********************************************************************************************
- 函數(shù)名:定時(shí)/計(jì)數(shù)器1中斷處理函數(shù)
- 調(diào) 用:[T/C1溢出后中斷處理]
- /*****************************/
- void Timer0(void) interrupt 1 using 1{ //切換寄存器組到1
- cou++; // 軟計(jì)數(shù)器加1
- if(cou > 99){// 計(jì)數(shù)值到(5s)
- cou = 0;// 軟計(jì)數(shù)器清零
- eepromEraseSector(0x2000); //擦除整個(gè)扇區(qū)
- eepromWrite(0x2000,maxwenduH );//將 新的溫度上限值高8位寫入 EEPROM
- eepromWrite(0x2001, maxwenduL);//將 新的溫度上限值低8位寫入 EEPROM
- eepromWrite(0x2002,minwenduH );//將 新的溫度下限值高8位寫入 EEPROM
- eepromWrite(0x2003, minwenduL);//將 新的溫度下限值低8位寫入 EEPROM
- TR0 = 0; //T/C1停止計(jì)數(shù)
- menu=0;//返回 主菜單的溫度顯示界面
- }
- TH0 = 0x3c; //16位計(jì)數(shù)寄存器T0高8位(重新寫入初值)
- TL0 = 0xb0; //16位計(jì)數(shù)寄存器T0低8位
- }
- /*******************************************************************************
- 功能:
- 描述:
- 參數(shù):
- 返回:
- *******************************************************************************/
- void Delay1ms (unsigned int a){ // 1ms延時(shí)程序
- unsigned int i;
- while( --a != 0){
- for(i = 0; i < 629; i++);//STC15單片機(jī)在外部晶振為12MHz時(shí)i值上限為629
- }
- }
- /******************************主函數(shù)*****************************************
- 功能:
- 描述:
- 參數(shù):
- 返回:
- *******************************************************************************/
- void main()
- {
- P3=0x00;
- P1=0x00;
- Aip650_CLR();
- Timer0_init();//定時(shí)器初始化
-
-
- //從eeprom讀出開啟和停止溫度
- maxwenduH=eepromRead(0x2000);
- maxwenduL=eepromRead(0x2001);
- maxwendu=maxwenduH*256+maxwenduL;//讀出停止溫度
- minwenduH=eepromRead(0x2002);
- minwenduL=eepromRead(0x2003);
- minwendu=minwenduH*256+minwenduL;//讀出開啟溫度*/
-
-
- while(1)
- {
- keyvalue=AipReadKey();
- /**********************顯示溫度界面******************************/
- if(menu==0){
- // for(k=15;k>0;k--){
- wendu=read_temp();
-
- xianshiwendu(wendu);
-
- /* if(keyvalue==0xfa){//k4按下溫度上限下限值恢復(fù)出廠設(shè)置
- Delay1ms(10);
- if(keyvalue==0xfa){
-
- maxwendu=382;//溫度上限38度
- minwendu=370;//溫度下限37度
- minwenduL=minwendu;
- minwenduH=(minwendu>>8);
- maxwenduL=maxwendu;
- maxwenduH=(maxwendu>>8);
- eepromEraseSector(0x2000); //擦除整個(gè)扇區(qū)
- eepromWrite(0x2000,maxwenduH );//將 新的溫度上限值高8位寫入 EEPROM
- eepromWrite(0x2001, maxwenduL);//將 新的溫度上限值低8位寫入 EEPROM
- eepromWrite(0x2002,minwenduH );//將 新的溫度下限值高8位寫入 EEPROM
- eepromWrite(0x2003, minwenduL);//將 新的溫度下限值低8位寫入 EEPROM
-
- }
- } */
- }
- /*********************進(jìn)入調(diào)溫度上限界面*******************************/
- if(menu==1){
- if(minwendu>maxwendu) //如果下限溫度高于上限溫度,顯示00
- { Aip650_CLR();
- Light_Level_Set(2);
- Aip650_DisPlay(1,0);
- Aip650_DisPlay(2,0);
- }
- else
- {
- xianshiwendu(maxwendu);}
-
- if(keyvalue==0xf2){
- Delay1ms(10);
- if(keyvalue==0xf2){
- maxwendu++; //按下K2鍵則溫度上限加零點(diǎn)一度
- cou=0;//重新計(jì)數(shù)
- TR0 = 1; //T/C1啟動(dòng)開關(guān)
- maxwenduL=maxwendu;
- maxwenduH=(maxwendu>>8);
- while(keyvalue!=0xf2);
-
- }
- }
-
- if(keyvalue==0xe2){
- Delay1ms(10);
- if(keyvalue==0xe2){
- maxwendu--; //按下K1鍵則溫度上限減零點(diǎn)一度
- cou=0;//重新計(jì)數(shù)
- TR0 = 1; //T/C1啟動(dòng)開關(guān)
- maxwenduL=maxwendu;
- maxwenduH=(maxwendu>>8);
- while(keyvalue!=0xe2);
-
- }
- }
-
- }
- /*********************進(jìn)入調(diào)溫度下限界面*******************************/
- if(menu==2){
- if(minwendu>maxwendu) //如果下限溫度高于上限溫度,顯示00
- { Aip650_CLR();
- Light_Level_Set(2);
- Aip650_DisPlay(1,0);
- Aip650_DisPlay(2,0);
- }
- else
- {
- xianshiwendu(minwendu);}
- if(keyvalue==0xf2){
- Delay1ms(10);
- if(keyvalue==0xf2){
- minwendu++; //按下K2鍵則溫度下限加零點(diǎn)一度
- cou=0;//重新計(jì)數(shù)
- TR0 = 1; //T/C1啟動(dòng)開關(guān)
- minwenduL=minwendu;
- minwenduH=(minwendu>>8);
-
- while(keyvalue!=0xf2);
-
- }
- }
-
-
- if(keyvalue==0xe2){
- Delay1ms(10);
- if(keyvalue==0xe2){
- minwendu--; //按下K1鍵則溫度下限減零點(diǎn)一度
- cou=0;//重新計(jì)數(shù)
- TR0 = 1; //T/C1啟動(dòng)開關(guān)
- minwenduL=minwendu;
- minwenduH=(minwendu>>8);
- while(keyvalue!=0xe2);
-
- }
- }
-
- }
- /*************************按下K3鍵進(jìn)入下限菜單設(shè)置界面***************************/
-
- if(keyvalue==0xea){
- cou=0;//重新計(jì)數(shù)
- TR0 = 1; //T/C1啟動(dòng)開關(guān)
- menu=2; //按下K3鍵則菜單加一
- //if(menu>2){menu=0;}
-
- while(keyvalue!=0xea);
- }
- /*************************按下K4鍵進(jìn)入上限菜單設(shè)置界面***************************/
- if(keyvalue==0xfa){
- cou=0;//重新計(jì)數(shù)
- TR0 = 1; //T/C1啟動(dòng)開關(guān)
- menu=1; //按下K3鍵則菜單加一
- // if(menu>2){menu=0;}
-
- while(keyvalue!=0xfa);
- }
-
-
-
-
- }
- }
復(fù)制代碼
下載:
Keil代碼.zip
(65.69 KB, 下載次數(shù): 84)
2022-11-23 23:22 上傳
點(diǎn)擊文件名下載附件
孵化器溫控器PCB文件.7z
(2.64 MB, 下載次數(shù): 61)
2022-11-23 23:22 上傳
點(diǎn)擊文件名下載附件
|
評(píng)分
-
查看全部評(píng)分
|