- #include <main.h>
- int PWM_I,PWM_P;
- unsigned char count , high_time=0; //占空比調節
- bit flag;
- uint temp_m1=0;
- int temp_m=0; //溫度放大100倍后的中轉值
- int set_temp=0; //設置溫度*100
- void InitTimer0(void) //
- {
- TMOD = 0x01;
- TH0 = 0x28;
- TL0 = 0x00;
- EA = 1;
- ET0 = 1;
- TR0 = 1;
- }
- void pid_control () //PID控制
- {
- if(set_temp>temp_m)
- {
- if(set_temp-temp_m>250) //如果設定溫度大于實際溫度2.5度
- high_time=100; //全力加熱
- else //否則
- {
- PWM_I=pid_calc(&temp_PID,temp_m); // 高電平輸出PID計算值
- if(high_time<=100)
- high_time= PWM_I; //限制高電平最大100
- else
- high_time=100;
- }
- }
- else
- high_time=0; //實際大于設定時輸出低電平
- }
- void Timer0Interrupt(void) interrupt 1 //PWM波輸出
- {
- if(++count<=(high_time)) //
- PWM=0;
- else if(count<=100)
- PWM=1;
- else
- count=0;
- TH0 = 0x28;
- TL0 = 0x00;
- }
- void main()//主函數
- {
- InitTimer0(); //定時器初始化
- init();//初始化函數
- pid_init (&temp_PID); //PID初始化
- temp_PID.Proportion =60; //設置PID比例系數
- temp_PID.Integral =5; //設置PID積分系數
- temp_PID.Derivative =2; //設置PID微分系數
-
- while(1)
- {
- temp_control();//控制按鍵函數
-
- temp_m1=get_temp(Ds18b20ReadTemp()); //提取計算溫度值
- display_real_tenp(temp_m1); //顯示函數 刷新溫度
- temp_m=unnormal_proccessing(temp_m1); //計數值=60 賦值溫度放大100倍溫度轉換函數*100
-
- pid_control();
- PWM_P=high_time;
- LcdWriteCom(0x80+0X40+0x0C);
- LcdWriteData('0'+PWM_P/100);
- LcdWriteCom(0x80+0X40+0x0D);
- LcdWriteData('0'+PWM_P%100/10);
- LcdWriteCom(0x80+0X40+0x0E);
- LcdWriteData('0'+PWM_P%10);
- }
- }
- void init()//初始化函數
- {
- uint i,j;
- //函數初始化
- LcdInit();//LCD初始化函數
- Ds18b20Init(); //18b20初始化
-
- //I/O口初始化
- PWM=0;//不制熱
-
- //LCD初始化顯示
- LcdWriteCom(0x80);//第一行顯示
- j=strlen(num1);
- for(i=0; i<j; i++)
- {
- LcdWriteData(num1[i]); [/i][i]
- delay_ms(1);
- }
- LcdWriteCom(0x80+0x40);//第二行顯示
- j=strlen(num2);
- for(i=0; i<j; i++)
- {
- LcdWriteData(num2[i]); [/i][i]
- delay_ms(1);
- }
- LcdWriteCom(0x04); //關閉寫一個指針加1
- }
- uint get_temp(uint temp)//計算溫度函數
- {
- float tp;
-
- tp=temp;//因為數據處理有小數點所以將溫度賦給一個浮點型變量
- //如果溫度是正的那么,那么正數的原碼就是補碼它本身
- temp=tp*0.0625*100+0.5;
- //留兩個小數點就*100,+0.5是四舍五入,因為C語言浮點數轉換為整型的時候把小數點
- //后面的數自動去掉,不管是否大于0.5,而+0.5之后大于0.5的就是進1了,小于0.5的就
- //算加上0.5,還是在小數點后面。
- return temp;
- }
- void display_real_tenp(uint temp)//實時溫度顯示函數
- {
- uchar datas[] = {0, 0, 0, 0}; //定義數組
- datas[0] = temp % 10000 / 1000;
- datas[1] = temp % 1000 / 100;
- datas[2] = temp % 100 / 10;
- datas[3] = temp % 10;
-
- LcdWriteCom(0x80+0x0a); //寫地址 80表示初始地址
- LcdWriteData('0'+datas[0]); //十位
- LcdWriteCom(0x80+0x0b); //寫地址 80表示初始地址
- LcdWriteData('0'+datas[1]); //個位
-
- LcdWriteCom(0x80+0x0d); //寫地址 80表示初始地址
- LcdWriteData('0'+datas[2]); //顯示小數點
-
- LcdWriteCom(0x80+0x0e); //寫地址 80表示初始地址
- LcdWriteData('0'+datas[3]); //顯示小數點
-
- }
- void temp_control()//控制溫度上下限函數
- {
- if(limit_choise==0)//選擇按鍵
- {
- delay_ms(5);
- if(limit_choise==0)
- {
- while(!limit_choise);
- limit_choise_num++;
- if(limit_choise_num>=2)
- {
- limit_choise_num=0;
- }
- }
- }
- if(limit_choise_num==0)//正常顯示
- {
- LcdWriteCom(0x0c);//關閉光標
-
- }
-
- if(limit_choise_num==1)//調節上限溫度
- {
- LcdWriteCom(0x80+0X40+2);
- LcdWriteCom(0x0f);//開啟光標
- if(increase_temperature==0)//增加溫度
- {
- delay_ms(5);
- if(increase_temperature==0)
- {
- while(!increase_temperature);
- up_limit_temp++;
- if(up_limit_temp>=100)
- {
- up_limit_temp=0;
- }
- //寫入新數據
- LcdWriteCom(0x80+0X40+0x03);
- LcdWriteData('0'+up_limit_temp/10);
- LcdWriteCom(0x80+0X40+0x04);
- LcdWriteData('0'+up_limit_temp%10);
- LcdWriteCom(0x80+0X40+2);//光標回寫
- }
- }
- if(reduce_temperature==0)//減少溫度
- {
- delay_ms(5);
- if(reduce_temperature==0)
- {
- while(!reduce_temperature);
- up_limit_temp--;
- if(up_limit_temp<0)
- {
- up_limit_temp=99;
- }
- //寫入新數據
- LcdWriteCom(0x80+0X40+0x03);
- LcdWriteData('0'+up_limit_temp/10);
- LcdWriteCom(0x80+0X40+0x04);
- LcdWriteData('0'+up_limit_temp%10);
- LcdWriteCom(0x80+0X40+2);//光標回寫
- }
- }
- }
- set_temp=up_limit_temp*100; //放大100倍計算
- temp_PID.SetPoint =set_temp;
-
- }
- int unnormal_proccessing(uint temp)//溫度轉換函數
- {
- uchar datas[] = {0, 0, 0, 0}; //定義數組
- int temp1=0;
- datas[0] = temp % 10000 / 1000;
- datas[1] = temp % 1000 / 100;
- datas[2] = temp % 100 / 10;
- datas[3] = temp % 10;
- temp1=datas[0]*1000+datas[1]*100+datas[2]*10+datas[3];//實際的溫度乘以100
- return temp1;
- }
復制代碼 |