|
很早以前淘來的 熱風(fēng)器 自整定 PID 參考程序,現(xiàn)發(fā)布出來給大伙分享,內(nèi)容僅供學(xué)習(xí)參考,包含PCB圖;
Altium Designer畫的原理圖和PCB圖如下:(51hei附件中可下載工程文件)
51hei.png (17.97 KB, 下載次數(shù): 68)
下載附件
2020-2-29 02:13 上傳
51hei.png (47.16 KB, 下載次數(shù): 83)
下載附件
2020-2-29 02:13 上傳
單片機(jī)源程序如下:
- #include<intrins.h>
- #include<stdlib.h>//包含 rand() 這樣的隨機(jī)函數(shù)
- #include "STC12C5A60S2.h"
- #include "zcy.h"
- #include "s_12864.h"
- ////////////////////////////////////////////////////////
- //全局變量
- volatile long time0_temp1 = 0;
- volatile long time0_temp2 = 0;
- volatile long global_sec = 0;
- int key_counter = 0 ;
- int led_flash_mode_index = 2 ;//led閃燈模式 1--8 從1開始 最多8種模式 ssssssssss
- volatile int time0_10ms_flag = 0;
- int time0_10ms_counter = 0;
- int led_active_flag = 0;
- typedef void (*led_fun_str)(void);//定義一個(gè)函數(shù)指針的數(shù)據(jù)類型
- //之后用該數(shù)據(jù)類型定義一個(gè)數(shù)組
- led_fun_str led_fun_bufffer[29+29];
- void (*led_flash_fun_str)(void);
- int led_index = 1;
- int k_off = 0;
- int k_on = 0;
- uchar temp_random = 0;
- uchar now_temp_random = 0;
- uchar last_temp_random = 0;
- uchar temp_diff = 0;
- uchar temp_buffer_random[29];
- int k_extern = 0;
- int loop_temp = 0;
- uchar temp_buffer_16_16_comm[32];//必須設(shè)計(jì)成全局變量才不會(huì)顯示錯(cuò)亂
- uchar temp_buffer_8_16_comm[16];//必須設(shè)計(jì)成全局變量才不會(huì)顯示錯(cuò)亂
- int refer_fun_flag = 0;
- int key_perss_counter = 0;
- int key_once_active_flag = 0;//key動(dòng)作一次
- int key_value = 0 ;
- float now_temp = 0.0;
- long dis_now_temp = 0;
- float wenkong_now_temp = 0.0;//用于溫度控制的當(dāng)前溫度
- volatile int global_sec_flag = 0;
- int temp_zero_below_flag = 1 ;//1說明是0及正溫度 0說明是負(fù)溫度
- char temp_dis_num_buffer[10];//必須定義成全局變量 否則出錯(cuò) 原因不詳
- char *temp_str;
- uint them = 0;
- int ds_18b20_reset_ok_flag = 0;
- //pid
- float SV_value = 50.0; //設(shè)定溫度值
- float PV_value = 0.0; //用于參與計(jì)算的當(dāng)前溫度值
- volatile float P_value = 0.0; //比例帶 比如56.3代表56.3% 0.0--200.0
- int I_value = 0; //積分時(shí)間 秒 0-3600
- int D_value = 0; //微分時(shí)間 秒 0-900
- int comm_dis_once_flag = 1; //初始為1
- volatile int special_dis_once_flag = 1; //初始為1
- int pid_tune_flag = 0;//初始為0 即pid階段 采用默認(rèn)的值 1 為自整定過程
- int three_dot_dis_flag = 0;
- float Proportion = 0.0; // 比例常數(shù) Proportional Const
- float Integral = 0.0; // 積分常數(shù) Integral Const
- float Derivative = 0.0; // 微分常數(shù) Derivative Const
- float LastError = 0.0; // Error[-1]
- float PrevError = 0.0; // Error[-2]
- float SumError = 0.0; // Sums of Errors
- float dError = 0.0;
- float Error = 0.0;
- int pid_result = 0;
- float T_Hight = 0.0;
- float T_LOW = 100.0; //溫度
- long TIME_Hight = 0;
- long TIME_LOW = 0; //具體的秒
- int pid_con_10ms_flag = 0;
- int pid_con_counter = 0;
- float KC = 1.0; //臨界比例系數(shù) 初始默認(rèn)的值
- int TC = 40; //振蕩周期 初始默認(rèn)的值
- int temp_pid = 0;//設(shè)定成全局變量
- volatile int get_now_temp_flag = 0;
- volatile int enable_pid_sec_flag = 0;
- volatile int pid_self_sec_flag = 0;
- //uint pid_self_calc_buffer[200] _at_ 0xF000; //0xffff 對(duì)應(yīng)flash的最頂端
- int zero_across_counter = 0;
- int pid_self_first_status_flag = 0;
- long pid_self_time_sec = 0;
- float max_temp = 0.0 ; //初始溫度等于0
- float min_temp = 100.0 ;//初始溫度等于100
- float sum_temp = 0.0 ; //初始溫度等于0
- float aver_temp = 0.0 ;
- int cool_ack_counter = 0;
- int hot_ack_counter = 0;
- int once_add_1_flag = 0;
- float pid_self_calc_buffer[4];
- int k_pid_self_counter = 0;
- int enable_calc_min_max_flag = 0;
- int k_max_min = 0;
- int dis_tune_once_flag = 1;
- int k_cut_off_flag = 0;//斷k偶標(biāo)志
- long k_reou_value = 0;
- int soft_dis_flag = 1;
- int soft_counter = 0;
- int soft_end_counter = 0;
- int pwm_con_time_flag = 0;
- //qqqqqqqqqqqqqq
- ////////////////////////////////////////////////////////
- //函數(shù)定義
- void SendByte(uchar Dbyte); //發(fā)送字節(jié)數(shù)據(jù)
- void write_cmd(uchar Cbyte);//寫指令
- void write_data(uchar Dbyte);//寫數(shù)據(jù)
- void PUTchar8x8(int row,int col,int count,uchar *put);
- void PUTchar8x16(int row,int col,int count,uchar *put);
- void PUTchar16x16(int row,int col,int count,uchar *put);//32個(gè)字節(jié)表示1個(gè)漢字
- void PUTchar24x24(int row,int col,int count,uchar *put);
- void PUTBMP(void);//圖片
- void PUTREVERSEBMP(void);//圖片反顯
- void LcmClear(void);//清屏
- void LcmSet(void);//顯示所有 即滿屏都是黑色的
- void LcmInit(void);//初始化
- void ohengxian(void);//O橫線程序
- void jihengxian(void);//奇橫線程序
- void oshuxian(void);//O豎線程序
- void jishuxian(void);//奇豎線程序
- void dianxian(void);//點(diǎn)顯示程序 滿屏都是點(diǎn)
- void zifu8x16xian(void);//可以顯示數(shù)字及英文
- void zifu16x16xian(void);//可以顯示特定的漢字
- void lcd_dis_position_16_16(int line,int column,uchar zifu_16_16[2]);// 1行 1列 具體的字符
- void lcd_dis_position_8_16(int line,int column,uchar zifu_8_16);// 1行 1列 具體的字符
- void lcd_s_12864_dis_8_16_str(int dis_line,int start_position,char *dis_str);//顯示一行的8*16的字符
- void ds_18b20_DelayXus(int n);
- void ds_18b20_init(void);//DS18B20的初始化
- uchar ds_18b20_read_date(void); //讀一個(gè)字節(jié)
- void ds_18b20_write_date(uchar date);//寫一個(gè)字節(jié)
- float read_18b20_temp(void);//讀出18b20的溫度值 實(shí)際溫度值返回 同時(shí)改變temp_zero_below_flag的值 如果是0 說明是0度以下
- void key_pro(void);
- void display_pro(void);
- void pid_pro(void);
- void dis_4_line_as_null(void);
- void dis_pid_self_value(void);
- float read_max6675_temper(void);// 利用max6675讀k探頭的溫度 返回最終溫度的1倍
- void PWM_clock(uchar clock);
- void PWM_start(uchar module,uchar mode);
- void set_pwm_value(uchar value);//0--255之間 value越大,占空比越高 輸出電壓也越大 40-->0.8v 237-->4.6v
- //hhhhhhhhhhhhhhhhhhhhhhhhhhh
- ////////////////////////////////////////////////////////
- //中斷函數(shù)ttttttttttttttttttttttttttttt
- void tm0_isr(void) interrupt 1 using 1 //1ms
- {
- TL0 = 0x20; //設(shè)置定時(shí)初值
- TH0 = 0xD1; //設(shè)置定時(shí)初值
-
- time0_temp1++;
- if(time0_temp1 % 2 == 0 )//2ms
- {
-
- pid_con_10ms_flag = 1;
-
- }
- if(time0_temp1 >= 10 )//10ms
- {
- time0_temp1 = 0;
- time0_10ms_flag = 1;
-
- }
- time0_temp2++;
- if(time0_temp2 % 200 == 0)//200ms
- {
- get_now_temp_flag = 1;
- }
- if(time0_temp2 % 200 == 0)//200ms
- {
- //get_now_temp_flag = 1;
-
- pid_self_sec_flag = 1;
-
- pwm_con_time_flag = 1;
- enable_pid_sec_flag = 1;
- special_dis_once_flag = 1;
-
- }
- if(time0_temp2 >= 1000 )//1s 如果要想1000對(duì)應(yīng)1s 那么中間不能有關(guān)中斷的行為發(fā)生
- {
- time0_temp2 = 0;
- global_sec++;
- global_sec_flag = 1;
-
- three_dot_dis_flag ^= 1;
-
- soft_dis_flag = 1;//軟啟動(dòng)
-
- //ssr_con_1;delay_ms(10);ssr_con_0;//test
-
- }
- }
- void PCA_Intrrpt(void) interrupt 7 //pwm 的中斷
- {
- if(CCF0) CCF0=0;
- if(CCF1) CCF1=0; //軟件清零
- if(CF) CF=0; //軟件清零
- }
- ////////////////////////////////////////////////////////
- //函數(shù)
- void Timer0Init(void) //1毫秒@12.000MHz 定時(shí)器0
- {
- AUXR |= 0x80; //定時(shí)器時(shí)鐘1T模式
- TMOD &= 0xF0; //設(shè)置定時(shí)器模式
- TMOD |= 0x01; //設(shè)置定時(shí)器模式
- TL0 = 0x20; //設(shè)置定時(shí)初值
- TH0 = 0xD1; //設(shè)置定時(shí)初值
- TF0 = 0; //清除TF0標(biāo)志
- TR0 = 1; //定時(shí)器0開始計(jì)時(shí)
- ET0 = 1; //enable timer0 interrupt
- }
- void io_init(void)
- {
- P3M0 = 0x00 ; // 0000 0000
- P2M0 = 0xf0 ; // 1111 0000 低四位為按鍵
- P1M0 = 0xff ; // 1111 1111 強(qiáng)推挽輸出 lcd 及 ssr驅(qū)動(dòng)
- P0M0 = 0x00 ; // 0000 0000 強(qiáng)推挽輸出
- key_1_in;
- key_2_in;
- key_3_in;
- key_4_in;
- ssr_con_out;
- lcd_s_12864_cs_out;
- lcd_s_12864_reset_out;
- lcd_s_12864_rs_out;
- lcd_s_12864_sda_out;
- lcd_s_12864_sck_out;
- lcd_s_12864_light_out;
- lcd_s_12864_cs_0;
- lcd_s_12864_reset_0;
- lcd_s_12864_rs_0;
- lcd_s_12864_sda_0;
- lcd_s_12864_sck_0;
- lcd_s_12864_light_0;
- max6675_so_in;
- max6675_sck_out;
- max6675_cs1_out;
- cs1_1;
- pwm_con_out;
- pwm_con_0;
- }
- void power_on_event(void)//eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
- {
- int k;
- for( k = 0; k < 2; k++ )//閃燈2次
- {
- lcd_s_12864_light_0;
- delay_ms(200);
- lcd_s_12864_light_1;
- delay_ms(200);
- }
- //引用一下基本的函數(shù) 否則老是出現(xiàn)警告錯(cuò)誤
- if( refer_fun_flag == 1 )//讓refer_fun_flag永遠(yuǎn)為0 意思就是永遠(yuǎn)不實(shí)際引用這些函數(shù)
- {
- // PUTchar8x8(1,1,5,zifu8x8);
- // PUTchar24x24(1,1,2,zifu24x24);
- // PUTBMP();//圖片
- // PUTREVERSEBMP();//圖片反顯
- // LcmClear();//清屏
- // LcmSet();//顯示所有 即滿屏都是黑色的
- // LcmInit();//初始化
- // ohengxian();//O橫線程序
- // jihengxian();//奇橫線程序
- // oshuxian();//O豎線程序
- // jishuxian();//奇豎線程序
- // dianxian();//點(diǎn)顯示程序 滿屏都是點(diǎn)
- // zifu8x16xian();//可以顯示數(shù)字及英文
- // zifu16x16xian();//可以顯示特定的漢字
- // lcd_dis_position_16_16(1,1,"鄭");
- // lcd_dis_position_8_16(1,1,'8');
- }
- }
- //s_12864 lllllllllllllllllllllllllllllll
- void SendByte(uchar Dbyte) //發(fā)送字節(jié)數(shù)據(jù)
- {
- uchar i,TEMP;
- TEMP = Dbyte;
- for(i=0;i<8;i++)
- {
- lcd_s_12864_sck_0;
- _nop_();
- _nop_();
- if( TEMP & 0x80 )
- {
- lcd_s_12864_sda_1;
- }
- else
- {
- lcd_s_12864_sda_0;
- }
- lcd_s_12864_sck_1;
- _nop_();
- _nop_();
- TEMP = TEMP<<1;
- }
- }
- void write_cmd(uchar Cbyte )//寫指令
- {
- lcd_s_12864_cs_0;
- lcd_s_12864_rs_0;
- SendByte(Cbyte);
- }
- void write_data(uchar Dbyte )//寫數(shù)據(jù)
- {
- lcd_s_12864_cs_0;
- lcd_s_12864_rs_1;
- SendByte(Dbyte);
- }
- void PUTchar8x8(int row,int col,int count,uchar *put)
- {
- uint X=0;
- int j,i;
- write_cmd(0xb0+row);
- write_cmd(0x10+(8*col/16));
- write_cmd(0x00+(8*col%16));
- for(j=0;j<count;j++)
- {
- for(i=0;i<8;i++)
- {
- write_data(put[X++]);
- }
- }
- }
- void PUTchar8x16(int row,int col,int count,uchar *put)//row 0--3代表1--4行 col 0--15 代表1--16個(gè)起始位置 count 1--16 代表寫入了幾個(gè)字符 *put代表字符數(shù)組 16個(gè)字節(jié)代表一個(gè)8*16的字符
- {
- uint X=0;
- int j,i;
- write_cmd(0xb0+row);
- write_cmd(0x10+(8*col/16));
- write_cmd(0x00+(8*col%16));
- for(j=0;j<count;j++)
- {
- for(i=0;i<8;i++)
- {
- write_data(put[X++]);
- }
- write_cmd(0xb1+row);
- write_cmd(0x10+(8*col/16));
- write_cmd(0x00+(8*col%16));
- for(i=0;i<8;i++)
- {
- write_data(put[X++]);
- }
- write_cmd(0xb0+row);
- col=col+1;
- }
- }
- void PUTchar16x16(int row,int col,int count,uchar *put)//32個(gè)字節(jié)表示1個(gè)漢字
- {
- uint X=0;
- int j,i;
- write_cmd(0xb0+row);
- write_cmd(0x10+(8*col/16));
- write_cmd(0x00+(8*col%16));
- for(j=0;j<count;j++)
- {
- for(i=0;i<16;i++)
- {
- write_data(put[X++]);
- }
- write_cmd(0xb1+row);
- write_cmd(0x10+(8*col/16));
- write_cmd(0x00+(8*col%16));
- for(i=0;i<16;i++)
- {
- write_data(put[X++]);
- }
- write_cmd(0xb0+row);
- col=col+2;
- }
- }
- void PUTchar24x24(int row,int col,int count,uchar *put)
- {
- uint X=0;
- int j,i;
- write_cmd(0xb0+row); //縱坐標(biāo)
- write_cmd(0x10+(8*col/16)); //橫坐標(biāo)
- write_cmd(0x00+(8*col%16));
- for(j=0;j<count;j++)
- {
- for(i=0;i<24;i++)
- {
- write_data(put[X++]);
- }
- write_cmd(0xb1+row);
- write_cmd(0x10+(8*col/16));
- write_cmd(0x00+(8*col%16));
- for(i=0;i<24;i++)
- {
- write_data(put[X++]);
- }
- write_cmd(0xb2+row);
- write_cmd(0x10+(8*col/16));
- write_cmd(0x00+(8*col%16));
- for(i=0;i<24;i++)
- {
- write_data(put[X++]);
- }
- write_cmd(0xb0+row);
- col=col+3;
- }
- }
- void PUTBMP(void)//圖片
- {
- uint X=0;
- int j,i;
- for(j=0;j<8;j++)
- {
- write_cmd(0xb0+j);
- write_cmd(0x10);
- write_cmd(0x00);
- for(i=0;i<128;i++)
- {
- write_data(bmp1[X++]);//bmp1為具體的圖片數(shù)組
- }
- }
- }
- void PUTREVERSEBMP(void)//圖片反顯
- {
- uint X=0;
- int j,i;
- for(j=0;j<8;j++)
- {
- write_cmd(0xb0+j);
- write_cmd(0x10);
- write_cmd(0x00);
- for(i=0;i<128;i++)
- {
- write_data(~bmp1[X++]);
- }
- }
- }
- void LcmClear(void)//清屏
- {
- int x,y;
- for(y=0;y<8;y++)
- {
- write_cmd(0xb0+y);
- write_cmd(0x10);
- write_cmd(0x00);
- for(x=0;x<132;x++)
- {
- write_data(0);
- }
- }
- }
- void LcmSet(void)//顯示所有 即滿屏都是黑色的
- {
- int x,y;
- for(y=0;y<8;y++)
- {
- write_cmd(0xb0+y);
- write_cmd(0x10);
- write_cmd(0x00);
- for(x=0;x<132;x++)
- {
- write_data(0xff);
- }
- }
- }
- void LcmInit(void)//初始化
- {
- lcd_s_12864_cs_0;
- lcd_s_12864_reset_0;
- delay_ms(100);
- lcd_s_12864_reset_1;
- delay_ms(100);
- write_cmd(0xe2);//system reset
- delay_ms(10);
- write_cmd(0x24);//SET VLCD RESISTOR RATIO 0x20--0x27 可以調(diào)節(jié)對(duì)比對(duì) 之有 0x23 0x24 這2個(gè)值可以選擇 0x24的對(duì)比度強(qiáng) 粗調(diào)
- write_cmd(0xa2);//BR=1/9
- write_cmd(0xa0);//set seg direction
- write_cmd(0xc8);//set com direction
- write_cmd(0x2f);//set power control
- write_cmd(0x40);//set scroll line
- write_cmd(0x81);//SET ELECTRONIC VOLUME
- write_cmd(0x1c);//set pm: 通過改變這里的數(shù)值來改變電壓 //也可以調(diào)節(jié)對(duì)比度 從0x00 -- 0x3f 值越大對(duì)比度越大 細(xì)調(diào)
- //write_cmd(0xa6);//set inverse display a6 off, a7 on 打開跟不打開沒有任何影響
- //write_cmd(0xa4);//set all pixel on 打開跟不打開沒有任何影響
- write_cmd(0xaf);//set display enable
- LcmClear(); //先清屏
- }
- void ohengxian(void)//O橫線程序
- {
- int x,y;
- for(y=0;y<8;y++)
- {
- write_cmd(0xb0+y);
- write_cmd(0x10);
- write_cmd(0x00);
- for(x=0;x<128;x++)
- {
- write_data(0x55);
- }
- }
- }
- void jihengxian(void)//奇橫線程序
- {
- int x,y;
- for(y=0;y<8;y++)
- {
- write_cmd(0xb0+y);
- write_cmd(0x10);
- write_cmd(0x00);
- for(x=0;x<128;x++)
- {
- write_data(0xAA);
- }
- }
- }
- void oshuxian(void)//O豎線程序
- {
- int x,y;
- for(y=0;y<8;y++)
- {
- write_cmd(0xb0+y);
- write_cmd(0x10);
- write_cmd(0x00);
- for(x=0;x<128;x++)
- {
- if(x%2==0)
- {
- write_data(0xFF);
- }
- else
- {
- write_data(0);
- }
- }
- }
- }
- void jishuxian(void)//奇豎線程序
- {
- int x,y;
- for(y=0;y<8;y++)
- {
- write_cmd(0xb0+y);
- write_cmd(0x10);
- write_cmd(0x00);
- for(x=0;x<128;x++)
- {
- if(x%2==0)
- {
- write_data(0);
- }
- else
- {
- write_data(0xFF);
- }
- }
- }
- }
- void dianxian(void)//點(diǎn)顯示程序 滿屏都是點(diǎn)
- {
- int x,y;
- for(y=0;y<8;y++)
- {
- write_cmd(0xb0+y);
- write_cmd(0x10);
- write_cmd(0x00);
- for(x=0;x<128;x++)
- {
- if(x%2==0)
- {
- write_data(0xAA);
- }
- else
- {
- write_data(0x55);
- }
- }
- }
- }
- void zifu8x16xian(void)//可以顯示數(shù)字及英文
- {
- int k;
- for(k=0;k<4;k++)//代表顯示4行
- {
- PUTchar8x16(2*k,0,16,zifu8x16);
- }
- }
- void zifu16x16xian(void)//可以顯示特定的漢字
- {
- int k;
- for(k=0;k<4;k++)
- {
- PUTchar16x16(2*k,0,16,zifu16x16);
- }
- }
- //zzzzzzzzzzzzzzzzzzz
- void lcd_dis_position_16_16(int line,int column,uchar zifu_16_16[2])// 1行 1列 具體的字符
- {
- uint X=0;
- int i;
- /////////////////////////////////////
- if ( zifu_16_16 == "鄭" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_001[i];}}
- else if( zifu_16_16 == "州" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_002[i];}}
- else if( zifu_16_16 == "迎" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_003[i];}}
- else if( zifu_16_16 == "之" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_004[i];}}
- else if( zifu_16_16 == "勝" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_005[i];}}
- else if( zifu_16_16 == "電" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_006[i];}}
- else if( zifu_16_16 == "子" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_007[i];}}
- else if( zifu_16_16 == "公" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_008[i];}}
- else if( zifu_16_16 == "司" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_009[i];}}
- else if( zifu_16_16 == "當(dāng)" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_010[i];}}
- else if( zifu_16_16 == "前" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_011[i];}}
- else if( zifu_16_16 == "溫" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_012[i];}}
- else if( zifu_16_16 == "度" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_013[i];}}
- else if( zifu_16_16 == "設(shè)" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_014[i];}}
- else if( zifu_16_16 == "定" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_015[i];}}
- else if( zifu_16_16 == "比" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_016[i];}}
- else if( zifu_16_16 == "例" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_017[i];}}
- else if( zifu_16_16 == "積" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_018[i];}}
- else if( zifu_16_16 == "分" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_019[i];}}
- else if( zifu_16_16 == "微" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_020[i];}}
- else if( zifu_16_16 == "自" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_021[i];}}
- else if( zifu_16_16 == "整" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_022[i];}}
- else if( zifu_16_16 == "定" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_023[i];}}
- else if( zifu_16_16 == "中" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_024[i];}}
- else if( zifu_16_16 == "軟" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_025[i];}}
- else if( zifu_16_16 == "啟" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_026[i];}}
- else if( zifu_16_16 == "動(dòng)" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_027[i];}}
- /////////////////////////////////////
- write_cmd(0xb0+((line-1)*2));//第1行
- write_cmd(0x10+(8*(2*(column-1))/16));
- write_cmd(0x00+(8*(2*(column-1))%16));//起始位置
- for(i=0;i<16;i++)
- {
- write_data(temp_buffer_16_16_comm[X++]);
- }
- write_cmd(0xb1+((line-1)*2));
- write_cmd(0x10+(8*(2*(column-1))/16));
- write_cmd(0x00+(8*(2*(column-1))%16));
- for(i=0;i<16;i++)
- {
- write_data(temp_buffer_16_16_comm[X++]);
- }
- write_cmd(0xb0+((line-1)*2));
- }
- void lcd_dis_position_8_16(int line,int column,uchar zifu_8_16)// 1行 1列 具體的字符
- {
- uint X=0;
- int i;
- /////////////////////////////////////
- if ( zifu_8_16 == '0' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_001[i];}}
- else if( zifu_8_16 == '1' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_002[i];}}
- else if( zifu_8_16 == '2' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_003[i];}}
- else if( zifu_8_16 == '3' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_004[i];}}
- else if( zifu_8_16 == '4' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_005[i];}}
- else if( zifu_8_16 == '5' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_006[i];}}
- else if( zifu_8_16 == '6' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_007[i];}}
- else if( zifu_8_16 == '7' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_008[i];}}
- else if( zifu_8_16 == '8' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_009[i];}}
- else if( zifu_8_16 == '9' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_010[i];}}
- else if( zifu_8_16 == ':' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_011[i];}}
- else if( zifu_8_16 == '-' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_012[i];}}
- else if( zifu_8_16 == '.' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_013[i];}}
- else if( zifu_8_16 == '+' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_014[i];}}
- else if( zifu_8_16 == '%' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_015[i];}}
- else if( zifu_8_16 == 'S' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_016[i];}}
- else if( zifu_8_16 == 'C' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_017[i];}}
- else if( zifu_8_16 == 'P' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_018[i];}}
- else if( zifu_8_16 == 'I' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_019[i];}}
- else if( zifu_8_16 == 'D' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_020[i];}}
- else if( zifu_8_16 == ' ' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_021[i];}}
- /////////////////////////////////////
- write_cmd(0xb0+((line-1)*2));//第1行
- write_cmd(0x10+(8*(1*(column-1))/16));
- write_cmd(0x00+(8*(1*(column-1))%16));//起始位置
- for(i=0;i<8;i++)
- {
- write_data(temp_buffer_8_16_comm[X++]);
- }
- write_cmd(0xb1+((line-1)*2));
- write_cmd(0x10+(8*(1*(column-1))/16));
- write_cmd(0x00+(8*(1*(column-1))%16));
- for(i=0;i<8;i++)
- {
- write_data(temp_buffer_8_16_comm[X++]);
- }
- write_cmd(0xb0+((line-1)*2));
- }
- char *convert_num_to_str(long num)//將數(shù)字轉(zhuǎn)成字符串 最大顯示21億 第1位為0的話,則顯示0
- {
- temp_dis_num_buffer[0] = ((num/1000000000)%10) + '0';
- temp_dis_num_buffer[1] = ((num/100000000)%10) + '0';
- temp_dis_num_buffer[2] = ((num/10000000)%10) + '0';
- temp_dis_num_buffer[3] = ((num/1000000)%10) + '0';
- temp_dis_num_buffer[4] = ((num/100000)%10) + '0';
- temp_dis_num_buffer[5] = ((num/10000)%10) + '0';
- temp_dis_num_buffer[6] = ((num/1000)%10) + '0';
- temp_dis_num_buffer[7] = ((num/100)%10) + '0';
- temp_dis_num_buffer[8] = ((num/10)%10) + '0';
- temp_dis_num_buffer[9] = ((num/1)%10) + '0';
- temp_str = temp_dis_num_buffer;
- return temp_str;
- }
- void lcd_s_12864_dis_8_16_str(int dis_line,int start_position,char *dis_str)//顯示一行的8*16的字符
- {
- int temp_1=0;
- int i;
- char *temp_str;
- temp_str = dis_str;
- while(1)//求出長(zhǎng)度
- {
- temp_1++;
- if( *temp_str++ == '\0' )
- {
- break;
- }
- }
- for(i = 0; i < (temp_1 - 1) ; ++i)
- {
- lcd_dis_position_8_16(dis_line,start_position + i , *dis_str++);
- }
- }
- void dis_long_number(int dis_line,long dis_num)
- {
- lcd_dis_position_8_16(dis_line,0,((dis_num/1000000000)%10) + '0');
- lcd_dis_position_8_16(dis_line,1,((dis_num/100000000)%10) + '0');
- lcd_dis_position_8_16(dis_line,2,((dis_num/10000000)%10) + '0');
- lcd_dis_position_8_16(dis_line,3,((dis_num/1000000)%10) + '0');
- lcd_dis_position_8_16(dis_line,4,((dis_num/100000)%10) + '0');
- lcd_dis_position_8_16(dis_line,5,((dis_num/10000)%10) + '0');
- lcd_dis_position_8_16(dis_line,6,((dis_num/1000)%10) + '0');
- lcd_dis_position_8_16(dis_line,7,((dis_num/100)%10) + '0');
- lcd_dis_position_8_16(dis_line,8,((dis_num/10)%10) + '0');
- lcd_dis_position_8_16(dis_line,9,((dis_num/1)%10) + '0');
- }
- //key
- int key_scan(void)
- {
- int key_temp = 0;
- if(!(key_1_status))
- {
- delay_ms(10);
- if(!(key_1_status))
- {
- key_perss_counter++;
- if(( key_perss_counter > key_perss_long_max_num ) && ( key_perss_counter < key_perss_long_long_max_num ))
- {
- //lcd_s_12864_light_0;
- //delay_ms(20);
- //lcd_s_12864_light_1;//報(bào)警
- //delay_ms(20);
- key_temp = 11;//長(zhǎng)按
- }
- else if( key_perss_counter >= key_perss_long_long_max_num )
- {
- lcd_s_12864_light_0;
- delay_ms(50);
- lcd_s_12864_light_1;//報(bào)警
- delay_ms(50);
- key_temp = 111;//超長(zhǎng)按
- }
- else
- {
- if( key_once_active_flag == 1 )
- {
- key_once_active_flag = 0;
- //lcd_s_12864_light_0;
- //delay_ms(10);
- //lcd_s_12864_light_1;//報(bào)警
- key_temp = 1;//短按
- }
- }
- }
- }
- else if(!(key_2_status))
- {
- delay_ms(10);
- if(!(key_2_status))
- {
- key_perss_counter++;
- if(( key_perss_counter > key_perss_long_max_num ) && ( key_perss_counter < key_perss_long_long_max_num ))
- {
- //lcd_s_12864_light_0;
- //delay_ms(20);
- //lcd_s_12864_light_1;
- //delay_ms(20);
- key_temp = 22;//長(zhǎng)按
- }
- else if( key_perss_counter >= key_perss_long_long_max_num )
- {
- lcd_s_12864_light_0;
- delay_ms(50);
- lcd_s_12864_light_1;
- delay_ms(50);
- key_temp = 222;//超長(zhǎng)按
- }
- else
- {
- if( key_once_active_flag == 1 )
- {
- key_once_active_flag = 0;
- //lcd_s_12864_light_0;
- //delay_ms(10);
- //lcd_s_12864_light_1;
- key_temp = 2;//短按
- }
- }
- }
- }
- else if(!(key_3_status))
- {
- delay_ms(10);
- if(!(key_3_status))
- {
- key_perss_counter++;
- if(( key_perss_counter > key_perss_long_max_num ) && ( key_perss_counter < key_perss_long_long_max_num ))
- {
- //lcd_s_12864_light_0;
- //delay_ms(20);
- //lcd_s_12864_light_1;
- //delay_ms(20);
- //key_temp = 33;//長(zhǎng)按
- key_temp = 3;
- }
- else if( key_perss_counter >= key_perss_long_long_max_num )
- {
- lcd_s_12864_light_0;
- delay_ms(50);
- lcd_s_12864_light_1;
- delay_ms(50);
- key_temp = 333;//超長(zhǎng)按
- //key_temp = 3;
- }
- else
- {
- if( key_once_active_flag == 1 )
- {
- key_once_active_flag = 0;
- //lcd_s_12864_light_0;
- //delay_ms(10);
- //lcd_s_12864_light_1;
- key_temp = 3;//短按
- }
- }
- }
- }
- else if(!(key_4_status))
- {
- delay_ms(10);
- if(!(key_4_status))
- {
- key_perss_counter++;
- if(( key_perss_counter > key_perss_long_max_num ) && ( key_perss_counter < key_perss_long_long_max_num ))
- {
- //lcd_s_12864_light_0;
- //delay_ms(20);
- //lcd_s_12864_light_1;
- //delay_ms(20);
- //key_temp = 44;//長(zhǎng)按
- key_temp = 4;
- }
- else if( key_perss_counter >= key_perss_long_long_max_num )
- {
- lcd_s_12864_light_0;
- delay_ms(50);
- lcd_s_12864_light_1;
- delay_ms(50);
- key_temp = 444;//超長(zhǎng)按
- //key_temp = 4;
- }
- else
- {
- if( key_once_active_flag == 1 )
- {
- key_once_active_flag = 0;
- //lcd_s_12864_light_0;
- //delay_ms(10);
- //lcd_s_12864_light_1;
- key_temp = 4;//短按
- }
- }
- }
- }
- else//沒有任何key按動(dòng)的時(shí)候
- {
- key_once_active_flag = 1;//允許再按時(shí)1次動(dòng)作
- key_perss_counter = 0;
- }
- return key_temp;
- }
- //DS18B20
- void ds_18b20_DelayXus(int n)
- {
- while (n--)
- {
- _nop_();
- //_nop_();
- }
- }
- void ds_18b20_init(void)//DS18B20的初始化
- {
- EA = 0;//關(guān)中斷
- DQ=1;
- ds_18b20_DelayXus(1);//1US
- DQ=0;
- ds_18b20_DelayXus(600);//600US
- DQ=1;
- ds_18b20_DelayXus(100); //100US
- if(DQ==0)
- {
- ds_18b20_reset_ok_flag = 1;
- ds_18b20_DelayXus(200);
- DQ=1;
- }
- if(DQ==1)//說明復(fù)位成功
- {
- ds_18b20_reset_ok_flag = 0;
- ds_18b20_DelayXus(200);
- DQ=1;
- }
- EA = 1;//開中斷
- }
- uchar ds_18b20_read_date(void) //讀一個(gè)字節(jié)
- {
- uchar temp,i;
- EA = 0;
- for( i=0;i<8;i++)
- {
- DQ=1;
- ds_18b20_DelayXus(2);
- DQ=0;
- ds_18b20_DelayXus(3);
- DQ=1;
- ds_18b20_DelayXus(2);
- temp>>=1;
- if(DQ)
- {
- temp=temp|0x80;
- }
- ds_18b20_DelayXus(50);
- }
- EA = 1;
- return temp;
- }
- void ds_18b20_write_date(uchar date)//寫一個(gè)字節(jié)
- {
- uchar i;
- //EA = 0;
- for( i=0 ;i<8;i++)
- {
- DQ=0;
- ds_18b20_DelayXus(2);
- DQ = date&0x01;
- ds_18b20_DelayXus(50);//50us
- DQ=1;
- date>>=1;
- }
- EA = 1;
- }
- float read_18b20_temp(void)//讀出18b20的溫度值 實(shí)際溫度值返回 同時(shí)改變temp_zero_below_flag的值 如果是0 說明是0度以下
- {
- uchar themh=0;
- uchar theml=0;
- uint temp_0 = 0;
- float temp_1;
- ds_18b20_init();
- if(ds_18b20_reset_ok_flag == 0)//檢測(cè)傳感器是否存在
- {
- ds_18b20_write_date(0xcc); //跳過ROM匹配
- ds_18b20_write_date(0x44); //發(fā)出溫度轉(zhuǎn)換命令
- ds_18b20_DelayXus(1000);
- }
- ds_18b20_init();
- if(ds_18b20_reset_ok_flag == 0)
- {
- ds_18b20_write_date(0x0cc); //跳過ROM匹配
- ds_18b20_write_date(0x0be); //發(fā)出讀溫度命令
- theml=ds_18b20_read_date() ; //讀出溫度值并存放在 theml,themh
- themh=ds_18b20_read_date() ;
- }
- //temp_0 = themh*256 + theml;
- temp_0 = (themh<<8) | theml; //2句作用一樣
- if( temp_0 & 0xf000 ) //說明是 負(fù)溫度
- {
- temp_0 = (~temp_0)+ 1 ;//等于268 0000 0001 0000 1100 == 按位反 = 1111 1110 1111 0011 = fef3 = 65267 然后加1 = 65267+1 = 65268
- //temp_0 = (65536 - temp_0) ;//負(fù)溫度求補(bǔ)碼 65268 + 268 = 65536 跟用這個(gè)辦法計(jì)算出的值一樣
- temp_zero_below_flag = 0;
- }
- else//為0 ,說明是 正溫度
- {
- temp_zero_below_flag = 1;
- }
- temp_1 = (float)(temp_0)*0.0625;
- return temp_1;
- }
- void dis_now_temp_test(void)//測(cè)試用 顯示當(dāng)前溫度
- {
- if( global_sec_flag == 1 )//1秒1次
- {
- global_sec_flag = 0;
- ssr_con_1;delay_ms(10);ssr_con_0;//test
-
- now_temp = read_18b20_temp();
- wenkong_now_temp = now_temp;
- dis_now_temp = (long)(wenkong_now_temp*10);//*10是為了顯示的需要
-
- //dis_now_temp = 396;//test
- lcd_dis_position_16_16(1,1,"當(dāng)");
- lcd_dis_position_16_16(1,2,"前");
- lcd_dis_position_16_16(1,3,"溫");
- lcd_dis_position_16_16(1,4,"度");
-
- if (temp_zero_below_flag == 1)//正溫度
- {
- lcd_dis_position_8_16(2,1, '+');
- lcd_dis_position_8_16(2,2, (dis_now_temp/100%10) + '0');
- lcd_dis_position_8_16(2,3, (dis_now_temp/10%10) + '0');
- lcd_dis_position_8_16(2,4, '.');
- lcd_dis_position_8_16(2,5, (dis_now_temp/1%10) + '0');
- }
- else if (temp_zero_below_flag == 0)//負(fù)溫度
- {
- lcd_dis_position_8_16(2,1, '-');
- lcd_dis_position_8_16(2,2, (dis_now_temp/100%10) + '0');
- lcd_dis_position_8_16(2,3, (dis_now_temp/10%10) + '0');
- lcd_dis_position_8_16(2,4, '.');
- lcd_dis_position_8_16(2,5, (dis_now_temp/1%10) + '0');
- }
- }
- }
- //kkkkkkkkkkkkkkkkkkkk
- void key_pro(void)
- {
- key_value = key_scan();
- if (key_value == 1)//A 作為 自整定 跟 pid 切換的開關(guān)
- {
- pid_tune_flag ^= 1;
- LcmClear();//清屏
- //清除最后一行的內(nèi)容
- //dis_4_line_as_null();
- if(pid_tune_flag == 1)//自整定階段
- {
-
- //記錄此刻的狀態(tài) 即設(shè)定溫度是否 高于或等于 當(dāng)前溫度
- if( SV_value >= PV_value )//設(shè)定溫度 高于 或者 等于 當(dāng)前溫度 啟動(dòng)加熱
- {
- pid_self_first_status_flag = 1;
- once_add_1_flag = 0;
- }
- else//設(shè)定溫度 低于 當(dāng)前溫度
- {
- pid_self_first_status_flag = 0;
- once_add_1_flag = 1;
- }
-
- dis_tune_once_flag = 1;
- zero_across_counter = 0;
- pid_self_time_sec = 0;
- pid_self_calc_buffer[0]=0.0;
- pid_self_calc_buffer[1]=0.0;
- pid_self_calc_buffer[2]=0.0;
- pid_self_calc_buffer[3]=0.0;
- k_pid_self_counter = 0;
- enable_calc_min_max_flag = 0;
- max_temp = 0.0 ; //初始溫度等于0
- min_temp = 1024.0 ;//初始溫度等于1024
- sum_temp = 0.0 ; //初始溫度等于0
- aver_temp = 0.0 ;
- T_Hight = 0.0;
- T_LOW = 1024.0; //溫度
- TIME_Hight = 0;
- TIME_LOW = 0; //具體的0.2s
-
- }
- else if(pid_tune_flag == 0)//pid階段
- {
- comm_dis_once_flag = 1;
- special_dis_once_flag = 1;
- }
- }
- else if(key_value == 2)//B
- {
-
- }
- else if((key_value == 3) || (key_value == 333)) //- 設(shè)定溫度
- {
- special_dis_once_flag = 1;
- if(key_value == 3)
- {
- SV_value-=1.0;
- }
- else
- {
- SV_value-=10.0;
- }
- if(SV_value < 0.0)
- {
- SV_value = 999.9;
- }
- }
- else if((key_value == 4) || (key_value == 444)) //+
- {
- special_dis_once_flag = 1;
- if(key_value == 4)
- {
- SV_value+=1.0;
- }
- else
- {
- SV_value+=10.0;
- }
- if(SV_value > 999.9)
- {
- SV_value = 0.0;
- }
- }
- }
- //dddddddddddddddddddddd
- void display_pro(void)
- {
- if( pid_tune_flag == 0 )//pid階段
- {
- //第1行 當(dāng)前溫度
- //第2行 設(shè)定溫度
- //第3行 顯示pid 各參數(shù)的名字
- //第4行 顯示pid 各參數(shù)的具體值
- if (comm_dis_once_flag == 1)//基本信息只顯示一次
- {
- comm_dis_once_flag = 0;
-
- lcd_dis_position_16_16(1,1,"當(dāng)");
- lcd_dis_position_16_16(1,2,"前");
- lcd_dis_position_16_16(1,3,"溫");
- lcd_dis_position_16_16(1,4,"度");
-
- lcd_dis_position_16_16(2,1,"設(shè)");
- lcd_dis_position_16_16(2,2,"定");
- lcd_dis_position_16_16(2,3,"溫");
- lcd_dis_position_16_16(2,4,"度");
-
- lcd_dis_position_8_16(1,15,'C');
- lcd_dis_position_8_16(2,15,'C');
-
- lcd_dis_position_16_16(3,1,"比");
- lcd_dis_position_16_16(3,2,"例");
- lcd_dis_position_16_16(3,4,"積");
- lcd_dis_position_16_16(3,5,"分");
- lcd_dis_position_16_16(3,7,"微");
- lcd_dis_position_16_16(3,8,"分");
-
- }
-
- if (special_dis_once_flag == 1)//獨(dú)立信息 0.2秒1次
- {
- special_dis_once_flag = 0;
-
- //lcd_s_12864_light_1;delay_ms(10);lcd_s_12864_light_0;//test
- //當(dāng)前溫度
- lcd_dis_position_8_16(1,9, ((uint)(PV_value*10)/1000)%10 + '0');//百位
- lcd_dis_position_8_16(1,10,((uint)(PV_value*10)/100)%10 + '0');
- lcd_dis_position_8_16(1,11,((uint)(PV_value*10)/10)%10 + '0');
- lcd_dis_position_8_16(1,12,'.');
- lcd_dis_position_8_16(1,13,((uint)(PV_value*10)/1)%10 + '0');
-
- //設(shè)定溫度
- lcd_dis_position_8_16(2,9, ((uint)(SV_value*10)/1000)%10 + '0');
- lcd_dis_position_8_16(2,10,((uint)(SV_value*10)/100)%10 + '0');
- lcd_dis_position_8_16(2,11,((uint)(SV_value*10)/10)%10 + '0');
- lcd_dis_position_8_16(2,12,'.');
- lcd_dis_position_8_16(2,13,((uint)(SV_value*10)/1)%10 + '0');
-
- lcd_dis_position_8_16(4,6,'%');
- lcd_dis_position_8_16(4,11,'S');
- lcd_dis_position_8_16(4,16,'S');
-
- if( pid_tune_flag == 1 )//如果啟動(dòng)了pid自整定 ,則顯示 pid自整定中...
- {
- lcd_dis_position_8_16(4,1,'P');
- lcd_dis_position_8_16(4,2,'I');
- lcd_dis_position_8_16(4,3,'D');
-
- lcd_dis_position_16_16(4,3,"自");
- lcd_dis_position_16_16(4,4,"整");
- lcd_dis_position_16_16(4,5,"定");
- lcd_dis_position_16_16(4,6,"中");
-
- if ( three_dot_dis_flag == 1 )//顯示不斷閃爍的3個(gè)點(diǎn) 表示運(yùn)算中
- {
- lcd_dis_position_8_16(4,14,'.');
- lcd_dis_position_8_16(4,15,'.');
- lcd_dis_position_8_16(4,16,'.');
- }
- else if( three_dot_dis_flag == 0 )
- {
- lcd_dis_position_8_16(4,14,' ');
- lcd_dis_position_8_16(4,15,' ');
- lcd_dis_position_8_16(4,16,' ');
- }
- }
- else if( pid_tune_flag == 0 )//整定ok后 顯示計(jì)算獲得的pid值 正常pid控制的時(shí)候顯示的內(nèi)容
- {
- //比例 積分 微分
- lcd_dis_position_8_16(4,1,((uint)(P_value*10)/1000)%10 + '0');
- lcd_dis_position_8_16(4,2,((uint)(P_value*10)/100)%10 + '0');
- lcd_dis_position_8_16(4,3,((uint)(P_value*10)/10)%10 + '0');
- lcd_dis_position_8_16(4,4,'.');
- lcd_dis_position_8_16(4,5,((uint)(P_value*10)/1)%10 + '0');
-
- lcd_dis_position_8_16(4,7,((I_value*1)/1000)%10 + '0');
- lcd_dis_position_8_16(4,8,((I_value*1)/100)%10 + '0');
- lcd_dis_position_8_16(4,9,((I_value*1)/10)%10 + '0');
- lcd_dis_position_8_16(4,10,((I_value*1)/1)%10 + '0');
-
- lcd_dis_position_8_16(4,13,((D_value*1)/100)%10 + '0');
- lcd_dis_position_8_16(4,14,((D_value*1)/10)%10 + '0');
- lcd_dis_position_8_16(4,15,((D_value*1)/1)%10 + '0');
- }
- }
- }
- else if( pid_tune_flag == 1 )//自整定階段
- {
- if(dis_tune_once_flag == 1)//顯示一次
- {
- dis_tune_once_flag = 0;
- dis_pid_self_value();
- }
- }
- }
- int pid_calc(float set_temp ,float now_temp )// pid計(jì)算 set_temp 為設(shè)定的溫度 now_temp 代表實(shí)際輸入的當(dāng)前溫度值 0 - 100的輸出值
- {
- Error = set_temp - now_temp; // 偏差
- if(( Error < max_value_error ) && ( Error > (min_value_error) ))//只有在一定的溫差范圍內(nèi)才pid計(jì)算
- {
- SumError += Error;
- dError = LastError - PrevError; // 當(dāng)前微分
- PrevError = LastError;
- LastError = Error;
- temp_pid = (int)((Proportion * Error) + (Integral * SumError) + (Derivative * dError));
- //temp_pid = (int)(temp_pid * 0.5) ;//輸出比例控制
- }
- else//只有開關(guān)作用
- {
- if( Error >= max_value_error )//遠(yuǎn)大于當(dāng)前溫度,加熱
- {
- temp_pid = 100;
- //temp_pid = 80;
- }
- else if( Error <= (min_value_error) )//遠(yuǎn)小于當(dāng)前溫度,不加熱
- {
- temp_pid = 0;
- }
- }
- if( temp_pid < 0 )
- {
- temp_pid = 0;
- }
- else if( temp_pid > 100 )
- {
- temp_pid = 100;
- }
- return temp_pid;
- }
- void pid_con(void)//由計(jì)算結(jié)果控制輸出
- {
- //適用于 pwm
- //每200ms根據(jù)結(jié)果改變一次輸出電壓的值
- if( pwm_con_time_flag == 1)
- {
- pwm_con_time_flag = 0;
-
- //lcd_s_12864_light_1;delay_ms(10);lcd_s_12864_light_0;//test
- //set_pwm_value(40 + (uchar)(pid_result * (((float)(237-40))/100.0)) );
- set_pwm_value(40 + (uchar)(pid_result * 1.97) );//跟上面這句話等價(jià)
-
- }
- }
- void pid_pro(void)//pid 自整定及控制輸出 ppppppppppppppppppppppppppppp
- {
- //每200ms獲得一次溫度
- if( get_now_temp_flag == 1)//200ms秒獲得一次溫度
- {
- get_now_temp_flag = 0;
-
- //lcd_s_12864_light_1;delay_ms(10);lcd_s_12864_light_0;//test
- PV_value = read_max6675_temper();
- }
- if ( pid_tune_flag == 1 )//自整定階段 完畢之后轉(zhuǎn)成pid控制
- {
- //自整定ok后自動(dòng)轉(zhuǎn)為pid階段
- //自整定失敗的情況下 讓基本參數(shù)恢復(fù)默認(rèn)值
- if( pid_self_sec_flag == 1 )//自整定過程 0.2秒1次
- {
- pid_self_sec_flag = 0;
- dis_tune_once_flag = 1;//0.2秒顯示1次基本信息
- //lcd_s_12864_light_0;delay_ms(10);lcd_s_12864_light_1;//test
- pid_self_time_sec++;
- if(pid_self_time_sec > (3600*3)) // 如果總的自整定時(shí)間大于了3/5=0.6個(gè)小時(shí),則說明整定失敗
- {
- pid_self_time_sec = 0;
- //lcd_s_12864_light_0;delay_ms(10);lcd_s_12864_light_1;//test
- LcmClear();//清屏
- comm_dis_once_flag = 1;
- special_dis_once_flag = 1;
- pid_tune_flag = 0;//那么將自動(dòng)退出自整定過程 同時(shí)采用默認(rèn)值 進(jìn)入pid階段
- KC = 1.0;//臨界比例系數(shù) 初始默認(rèn)的值
- TC = 40; //振蕩周期 初始默認(rèn)的值
- }
- if(( pid_self_first_status_flag == 1) || ( pid_self_first_status_flag == 0))//0 設(shè)定溫度 低于 當(dāng)前溫度 //1設(shè)定溫度 高于 或者 等于 當(dāng)前溫度 啟動(dòng)加熱
- {
- //lcd_s_12864_light_0;delay_ms(10);lcd_s_12864_light_1;//test
- //基本on/off控制
- if( SV_value >= PV_value )//啟動(dòng)加熱
- {
- cool_ack_counter = 0;
- hot_ack_counter++;
- if(hot_ack_counter > 3)//連續(xù)3次都是一樣的結(jié)果 說明確定 SV_value >= PV_value
- {
-
- ssr_con_1;
- //pwm_con_1;//一旦pwm參與將不能通過操作io的形式控制該口線
- set_pwm_value(237);//全速加熱
- if(once_add_1_flag == 0)
- {
- once_add_1_flag = 1;
- zero_across_counter++;
-
- //lcd_s_12864_light_0;delay_ms(10);lcd_s_12864_light_1;//test
-
- if(zero_across_counter == 3 )
- {
- TIME_LOW = pid_self_time_sec - 3;//此時(shí)的時(shí)間不是最低溫度對(duì)應(yīng)的時(shí)間
- }
- }
- }
- }
- else//當(dāng)前溫度 大于 設(shè)定溫度 停止加熱
- {
-
- //lcd_s_12864_light_0;delay_ms(10);lcd_s_12864_light_1;//test
-
- hot_ack_counter = 0;
- cool_ack_counter++;
- if(cool_ack_counter > 3)
- {
- ssr_con_0;
- set_pwm_value(40);//不加熱
- if(once_add_1_flag == 1)
- {
- once_add_1_flag = 0;
- zero_across_counter++;
- if(zero_across_counter == 3 )
- {
- TIME_LOW = pid_self_time_sec - 3;//此時(shí)的時(shí)間不是最低溫度對(duì)應(yīng)的時(shí)間
- }
- }
- }
- }
- //最低溫度 出現(xiàn)在 zero_across_counter = 3 的階段
- //最高溫度 出現(xiàn)在 zero_across_counter = 4 的階段
- if((zero_across_counter == 3 ) || (zero_across_counter == 4 ))
- {
- pid_self_calc_buffer[k_pid_self_counter] = PV_value;
- k_pid_self_counter++;
- if(k_pid_self_counter > 3)//0--3 共4個(gè)元素
- {
- k_pid_self_counter = 0;
- enable_calc_min_max_flag = 1;
- }
- if(enable_calc_min_max_flag == 1)//只要有4個(gè)值,就可以計(jì)算了 后面來的值覆蓋了前面的值
- {
- //去掉最小值 最大值 取剩下2個(gè)值的平均值
- sum_temp = 0.0; //先清0
- min_temp = 1024.0;
- max_temp = 0.0;
-
- for(k_max_min = 0; k_max_min < 4; k_max_min++ )
- {
- if(pid_self_calc_buffer[k_max_min] <= min_temp)
- {
- min_temp = pid_self_calc_buffer[k_max_min];
- }
- if(pid_self_calc_buffer[k_max_min] >= max_temp)
- {
- max_temp = pid_self_calc_buffer[k_max_min];
- }
- sum_temp = (sum_temp + pid_self_calc_buffer[k_max_min]);
- }
- sum_temp = sum_temp - min_temp - max_temp ;
-
-
- //pid_self_first_status_flag = 1 時(shí) 最低溫度出現(xiàn)在3階段
- //pid_self_first_status_flag = 0 時(shí) 最低溫度出現(xiàn)在4階段
- if(pid_self_first_status_flag == 1)
- {
- if(zero_across_counter == 3 )//最低溫度
- {
- aver_temp = (sum_temp/2.0);
- if( aver_temp <= T_LOW )
- {
- T_LOW = aver_temp;
- }
- }
- else if(zero_across_counter == 4 )//最高溫度
- {
- aver_temp = (sum_temp/2.0);
- if( aver_temp >= T_Hight )
- {
- T_Hight = aver_temp;
- }
- }
- }
- else if(pid_self_first_status_flag == 0)
- {
- if(zero_across_counter == 4 )//最低溫度
- {
- aver_temp = (sum_temp/2.0);
- if( aver_temp <= T_LOW )
- {
- T_LOW = aver_temp;
- }
- }
- else if(zero_across_counter == 3 )//最高溫度
- {
- aver_temp = (sum_temp/2.0);
- if( aver_temp >= T_Hight )
- {
- T_Hight = aver_temp;
- }
- }
- }
- }
- }
- else if(zero_across_counter == 5 )//4次過0 則說明出現(xiàn)了振蕩 整定成功
- {
- zero_across_counter = 0;
- pid_tune_flag = 0;//進(jìn)入pid階段
- //pid_tune_flag = 1;//test
- TIME_Hight = pid_self_time_sec - 3;//此時(shí)的時(shí)間不是最高溫度對(duì)應(yīng)的時(shí)間
- LcmClear();//清屏
- comm_dis_once_flag = 1;
- special_dis_once_flag = 1;
- //dis_4_line_as_null();//清除最后一行的內(nèi)容
- //計(jì)算 T_Hight T_LOW TIME_Hight TIME_LOW 這4個(gè)值
- //根據(jù)以上4個(gè)值 KC 與 TC 的值便會(huì)計(jì)算出來
-
- KC = 12.7/(T_Hight - T_LOW);
- KC = 5.0 * KC;//因?yàn)槭?.2s一次 所以擴(kuò)大5倍
- TC = 1 * (TIME_Hight - TIME_LOW);//如果記錄了 最低溫度 與 最高溫度對(duì)應(yīng)的時(shí)間 那么沿用這個(gè)公式:TC = 2 * (TIME_Hight - TIME_LOW);
- }
- }
- //顯示具體的值 測(cè)試用
- //dis_pid_self_value(); //test
- }
- }
- else if( pid_tune_flag == 0 )//pid 階段 默認(rèn)開機(jī)進(jìn)入此階段
- {
- //0 算出 臨界增益 KC 及 振蕩周期 TC
- // KC = (4*d)/(3.14*A) ---> d = 5(輸出幅值) ; A = 記錄的溫度最高值與最低值的差值的0.5倍 即:(T_Hight - T_LOW)*0.5
- // KC = (4*5)/(3.14*((T_Hight - T_LOW)*0.5)) = 40/3.14/(T_Hight - T_LOW) = 12.7/(T_Hight - T_LOW)
- // KC = 12.7/(T_Hight - T_LOW)
- // TC = 2 * (TIME_Hight - TIME_LOW) ---> 2 * ( 高點(diǎn)溫度對(duì)應(yīng)時(shí)間 - 低點(diǎn)溫度對(duì)應(yīng)時(shí)間 )
- // TC = 2 * (TIME_Hight - TIME_LOW)
- //1 算出 具體的比例系數(shù) 積分秒數(shù) 微分秒數(shù)
- //Proportion = 0.6*KC
- //I_value = 0.5*TC
- //D_value = 0.125*TC
- //2 算出具體的 比例帶 積分系數(shù) 微分系數(shù)
- //P_value = (1/Proportion)*100
- //Integral = Proportion/I_value = (0.6*KC)/(0.5*TC)
- //Derivative = Proportion*D_value = (0.6*KC)*(0.125*TC)
- //3顯示用的3個(gè)變量的值
- //P_value = (1/Proportion)*100 百分比
- //I_value = 0.5*TC 秒
- //D_value = 0.125*TC 秒
- //4pid計(jì)算用的3個(gè)變量的值
- //Proportion = 0.6*KC
- //Integral = Proportion/I_value = (0.6*KC)/(0.5*TC)
- //Derivative = Proportion*D_value = (0.6*KC)*(0.125*TC)
-
- //KC = 21.4;//test
- //TC = 471;//test
-
- if(enable_pid_sec_flag == 1)//進(jìn)入pid時(shí),0.2秒計(jì)算1次
- {
-
- ……………………
- …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼
所有資料51hei提供下載:
熱風(fēng) 自整定 PID 51單片機(jī)程序 + 原理圖 PCB.7z
(162.76 KB, 下載次數(shù): 289)
2024-1-22 02:54 上傳
點(diǎn)擊文件名下載附件
51 下載積分: 黑幣 -5
|
評(píng)分
-
查看全部評(píng)分
|