基于AT89C52設計的溫度調節控制直流電機,可以通過4*4按鍵設定經過MAX6675驅動的K型熱電偶轉化的溫度上限與下限,高于上限電機正轉,低于下限電機反轉,處于正常溫度電機停止轉動。文件包含具體論文說明,理論與原理描述。
帶proteus仿真工程文件,附件里面可以下載.
整個溫度控制直流電機正反轉系統的仿真原理圖:
6`(6%Q$E)@`G~F9W`LPLZJ9.png (23.14 KB, 下載次數: 83)
下載附件
仿真圖
2017-4-7 10:38 上傳
51單片機源程序:
- #include <reg51.h>
- #include <Intrins.h>
- #include <LCD1602.H>
- #include <math.H>
- #define C02_write 0xa0 //c02寫地址
- #define C02_read 0xa1 //c02讀地址
- #define uchar unsigned char
- #define uint unsigned int
- sbit MAX6675_CS=P1^2; //MAX6675冷端溫度補償,將K型熱電偶信號轉為數字信號
- sbit MAX6675_SCK=P1^1;
- sbit MAX6675_SO=P1^0;
- sbit normal=P2^3; //LED燈表示溫度正常,過高,過低
- sbit upper=P2^4;
- sbit lower=P2^5;
- sbit direction=P2^6;
- sbit stop=P2^7;
- sbit SCL=P1^3; //EEPROM,256byte
- sbit SDA=P1^4;
- sbit beep=P1^7; //蜂鳴器
- bit ack,flag=0,flag1=0;
- uint tz;
- int sth=0,stl=0,t_zhi=0;
- uchar data temp1[]={'+','1','2','0','0',0},temp2[]={'-' ,'1','0','0','0',0};
- uchar data temp[7];
- char code keytab[]={0xEE,0xDE,0xBE,0x7E,0xED,0xDD,0xBD,0x7D,0xEB,0xDB,0xBB,0x7B,0xE7,0xD7,0xB7,0x77};
- unsigned char code str1[]={"STH STL"}; //system temperature high,low
- unsigned char code str2[]={"PARAMTER STEUP"};
- unsigned char code str3[]={" "};
- unsigned int testD2;
- unsigned char data disdata[5];
- void delay0(uchar x) // 延時函數
- {
- uchar i;
- while(x--)
- {
- for (i=0; i<13; i++);
- }
- }
- void delayms(uchar i)
- {
- uchar j;
- for(; i>0; i--)
- for(j=124; j>0; j--);
- }
- void longdelay(uchar i)
- {
- uint j;
- for(;i>0;i--)
- for(j=10000;j>0;j--);
- }
- void keysound() //按鍵聲音函數
- {
- uchar i;
- for (i=0;i<180;i++)
- {
- delay0(5);
- beep=!beep; //BEEP取反
- }
- }
- void I2C_start(void) //I2C開始信號
- {
- SDA=1; SCL=1;
- _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
- SDA=0;
- _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
- SCL=0; _nop_(); _nop_();
- }
- void I2C_stop(void) //I2C結束
- {
- SDA=0; SCL=1;
- _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
- SDA=1;
- _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
- SCL=0;
- _nop_(); _nop_();
- }
- void I2C_no_ackownledge(void) //發送noack信號
- {
- SDA=1;
- _nop_(); _nop_();
- SCL=1;
- _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
- SCL=0;
- _nop_(); _nop_(); _nop_();
- }
- void I2C_sendB(uchar byte)//發送一字節數據
- {
- uchar counter;
- for(counter=0;counter<8;counter++)
- {
- if(byte&0x80) SDA=1;
- else SDA=0;
- _nop_();
- SCL=1;
- _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
- SCL=0;
- _nop_(); _nop_();
- byte<<=1;
- }
- _nop_(); _nop_();
- SDA=1;
- _nop_(); _nop_(); _nop_();
- SCL=1;
- _nop_(); _nop_(); _nop_();
- if(SDA==0) ack=1;
- else ack=0;
- SCL=0;
- _nop_(); _nop_();
- }
-
- uchar I2C_receiveB(void) //接收一字節數據
- {
- uchar temp;
- uchar counter;
- temp=0;
- SDA=1;
- _nop_(); _nop_();
- for(counter=0;counter<8;counter++)
- {
- _nop_(); _nop_(); _nop_();
- _nop_(); _nop_();
- SCL=1;
- _nop_();
- _nop_();
- if(SDA==1) temp=(temp<<1)|0x01;
- else temp=temp<<1;
- _nop_(); _nop_();
- SCL=0;
- _nop_(); _nop_(); _nop_();
- }
- _nop_(); _nop_();
- return(temp);
- }
- bit I2C_send_string(uchar *string,uchar no,uchar address) //發送8位溫度
- {
- uchar counter;
- for(counter=0;counter<no;counter++)
- {
- I2C_start();
- I2C_sendB(C02_write);
- if(ack==0) return(0);
- I2C_sendB(address+counter);
- if(ack==0) return(0);
- I2C_sendB(string[counter]);
- I2C_stop();
- delayms(20);
- }
- return(1);
- }
- bit I2C_receive_string(uchar *string,uchar no,uchar address) //接收8位溫度
- {
- uchar counter;
- for(counter=0;counter<no;counter++)
- {
- I2C_start();
- I2C_sendB(C02_write);
- if(ack==0) return(0);
- I2C_sendB(address+counter);
- if(ack==0) return(0);
- I2C_start();
- I2C_sendB(C02_read);
- if(ack==0) return(0);
- *(string+counter)=I2C_receiveB();
- I2C_no_ackownledge();
- I2C_stop();
- }
- }
- //溫度值讀取程序
- unsigned int ReadMAX6675() //從MAX6675讀取溫度
- {
- unsigned char count;
- unsigned int Value;
- MAX6675_CS=0; //置低,使能MAX6675
- MAX6675_SCK=0;
- Value=0;
- _nop_() ;_nop_();_nop_();_nop_();
- for(count=0;count<16;count++) //獲取16位MSB
- {
- Value=Value<<1; //左移
- MAX6675_SCK=1; //sck置高
- _nop_() ;_nop_();_nop_();_nop_();
- if(MAX6675_SO==1) //取當前值
- Value|=0x01;
- MAX6675_SCK=0;
- }
- MAX6675_CS=1; //關閉MAX6675
- return Value;
- }
- unsigned int GetCurrentTemp(unsigned int CurrentValue) //獲取當前溫度
- {
- unsigned int TempValue;
- TempValue=CurrentValue;
- if(TempValue&0x8000) //D15=1;標識位錯
- return 0;
- if(TempValue&0x0004) //D2=1;熱電偶開路
- return 1;
- }
- void tempdisp() //溫度值顯示
- { unsigned char i;
- unsigned int TempValue;
- unsigned int testD2;
- int xiaoshu;
- TempValue=ReadMAX6675();
- testD2=GetCurrentTemp(TempValue);
- TempValue=ReadMAX6675();
- TempValue&=0x7ff8; //取D14位到D3的值
- TempValue>>=3; //轉換溫度值
- xiaoshu= (TempValue*1023.75/4095)*10-327;
- t_zhi=xiaoshu/10;
- disdata[0]=xiaoshu/10000+0x30; //千位數
- xiaoshu=xiaoshu%10000;
- disdata[1]=xiaoshu/1000+0x30; //百位數
- xiaoshu=xiaoshu%1000;
- disdata[2]=xiaoshu/100+0x30; //十位數
- xiaoshu=xiaoshu%100;
- disdata[3]=xiaoshu/10+0x30; //個位數
- xiaoshu=xiaoshu%10;
- disdata[4]=xiaoshu/1+0x30; //十分位
- LCD_set_position(68);
- for(i=0;i<4;i++)
- LCD_write_data(disdata[i]); //顯示千百十個位
- LCD_write_data('.'); //顯示小數點
- LCD_write_data(disdata[4]); //顯示十分位
- LCD_write_data(0xDF); //顯示dot
- LCD_write_data(0x43); //顯示C
- if(t_zhi>sth){ normal=0; upper=1;lower=0;stop=1;direction=1;} //高于上限
- else if(t_zhi<stl){ normal=0; upper=0;lower=1;stop=1;direction=0;} //低于下限
- else { normal=1; upper=0;lower=0;stop=0;direction=0;} //正常
- }
- //返回-1表示沒有檢測到按鍵按下
- char getkey(void)
- { unsigned char scancode,tmpcode, key_zhi=0;
- P3 = 0xf0; // 發全0行掃描碼
- if ((P3&0xf0)!=0xf0) // 若有鍵按下
- { delayms(5); // 延時去抖動
- if ((P3&0xf0)!=0xf0) // 延時后再判斷一次,去除抖動影響
- { scancode = 0xfe;
- while((scancode&0x10)!=0) // 逐行掃描
- { P3 = scancode; // 輸出行掃描碼
- if ((P3&0xf0)!=0xf0) // 本行有鍵按下
- { tmpcode = P3; // 返回特征字節碼
- while((P3&0xf0)!=0xf0);
- key_zhi=0;
- while(tmpcode!=keytab[key_zhi])
- key_zhi++;
- return( key_zhi++);
- }
- else scancode = (scancode<<1)|0x01;// 行掃描碼左移一位
- }
- }
- }
- return(-1); // 無鍵按下,返回值為0
- }
- void timer0() interrupt 1 using 0
- {
- TR0=0;
- TH0=(65536-10000)/256;
- TL0=(65536-10000)%256;
- TR0=1;
- tz++;
- }
- void main()
- {
- uchar kcode,count1=3,count2=12,i;
- normal=0;
- upper=0;
- lower=0;
- TMOD=0X01;
- TH0=(65536-10000)/256;
- TL0=(65536-10000)%256;
- ET0=1;
- TR0=0;
- LCD_initial();
- LCD_cls();
- LCD_set_position(0);
- LCD_prints(str1);
- LCD_set_position(3);
-
- I2C_receive_string(temp1,5,0x00);
- I2C_receive_string(temp2,4,0x10);
- //change_data();
- LCD_prints(temp1); //顯示上限
- LCD_set_position(12);
- LCD_prints(temp2); //顯示上限
- sth=0;stl=0;
- for(i=1;i<5;i++)
- sth=sth*10+temp1[i]-'0';
- for(i=1;i<4;i++)
- stl=stl*10+temp2[i]-'0';
-
- MAX6675_CS=1; //復位MAX6675
- while(1)
- {
- if(flag==0)
- {
- tempdisp();
- }
- kcode=getkey();
- if(kcode==12&&flag==0)
- {
- flag=1;sth=0;stl=0;
- keysound();
- LCD_set_position(0x41);
- LCD_prints(str2);
- LCD_set_position(count1);
- LCD_write_instruction(0x0f); //光標閃爍
- }
- if(flag)
- {
- if(kcode>=0&&kcode<=9)
- {
- if(flag1==0&&count1!=3) //設置上限溫度
- {
- LCD_set_position(count1);
- sth=sth*10+kcode;
- LCD_write_data(kcode+0x30);
- keysound();
- temp1[count1-3]=kcode+0x30;
- count1++;
- if(count1==8)
- {
- flag1=1;count1=12,count2=12;
- }
- LCD_set_position(count1);
- }
- if(flag1==1&&count2!=12) //設置下限溫度
- {
- LCD_set_position(count2);
-
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
0.png (67.68 KB, 下載次數: 99)
下載附件
2017-4-7 17:50 上傳
下載:
7-溫度控制直流電機.zip
(845.7 KB, 下載次數: 230)
2017-4-7 10:35 上傳
點擊文件名下載附件
可調溫控電機 下載積分: 黑幣 -5
|