找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 8116|回復(fù): 11
打印 上一主題 下一主題
收起左側(cè)

非原創(chuàng) 單片機(jī)熱風(fēng)器控制 自整定PID程序+PCB文件原理圖

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
很早以前淘來的 熱風(fēng)器 自整定 PID 參考程序,現(xiàn)發(fā)布出來給大伙分享,內(nèi)容僅供學(xué)習(xí)參考,包含PCB圖;
Altium Designer畫的原理圖和PCB圖如下:(51hei附件中可下載工程文件)


單片機(jī)源程序如下:
  1. #include<intrins.h>
  2. #include<stdlib.h>//包含 rand() 這樣的隨機(jī)函數(shù)

  3. #include "STC12C5A60S2.h"
  4. #include "zcy.h"
  5. #include "s_12864.h"



  6. ////////////////////////////////////////////////////////
  7. //全局變量

  8. volatile long time0_temp1 = 0;
  9. volatile long time0_temp2 = 0;

  10. volatile long global_sec = 0;

  11. int key_counter = 0 ;
  12. int led_flash_mode_index = 2 ;//led閃燈模式 1--8 從1開始 最多8種模式   ssssssssss

  13. volatile int time0_10ms_flag = 0;
  14. int time0_10ms_counter = 0;
  15. int led_active_flag = 0;

  16. typedef void (*led_fun_str)(void);//定義一個(gè)函數(shù)指針的數(shù)據(jù)類型
  17. //之后用該數(shù)據(jù)類型定義一個(gè)數(shù)組
  18. led_fun_str led_fun_bufffer[29+29];

  19. void (*led_flash_fun_str)(void);

  20. int led_index = 1;

  21. int k_off = 0;
  22. int k_on  = 0;

  23. uchar temp_random = 0;
  24. uchar now_temp_random = 0;
  25. uchar last_temp_random = 0;
  26. uchar temp_diff        = 0;

  27. uchar temp_buffer_random[29];

  28. int k_extern = 0;
  29. int loop_temp = 0;

  30. uchar temp_buffer_16_16_comm[32];//必須設(shè)計(jì)成全局變量才不會(huì)顯示錯(cuò)亂
  31. uchar temp_buffer_8_16_comm[16];//必須設(shè)計(jì)成全局變量才不會(huì)顯示錯(cuò)亂

  32. int refer_fun_flag = 0;
  33. int key_perss_counter  = 0;
  34. int key_once_active_flag = 0;//key動(dòng)作一次
  35. int key_value = 0 ;

  36. float now_temp              = 0.0;
  37. long dis_now_temp           = 0;
  38. float wenkong_now_temp      = 0.0;//用于溫度控制的當(dāng)前溫度

  39. volatile int global_sec_flag = 0;
  40. int temp_zero_below_flag = 1 ;//1說明是0及正溫度  0說明是負(fù)溫度

  41. char temp_dis_num_buffer[10];//必須定義成全局變量 否則出錯(cuò) 原因不詳
  42. char *temp_str;

  43. uint them = 0;
  44. int  ds_18b20_reset_ok_flag = 0;

  45. //pid
  46. float           SV_value           = 50.0; //設(shè)定溫度值
  47. float           PV_value           = 0.0;  //用于參與計(jì)算的當(dāng)前溫度值
  48. volatile float  P_value            = 0.0;  //比例帶 比如56.3代表56.3%  0.0--200.0
  49. int             I_value            = 0;  //積分時(shí)間  秒  0-3600
  50. int             D_value            = 0;   //微分時(shí)間  秒  0-900

  51. int comm_dis_once_flag    = 1; //初始為1
  52. volatile int special_dis_once_flag = 1; //初始為1
  53. int pid_tune_flag         = 0;//初始為0 即pid階段 采用默認(rèn)的值    1 為自整定過程

  54. int three_dot_dis_flag    = 0;

  55. float  Proportion  = 0.0;           //  比例常數(shù) Proportional Const
  56. float  Integral    = 0.0;           //  積分常數(shù) Integral Const        
  57. float  Derivative  = 0.0;           //  微分常數(shù) Derivative Const
  58. float  LastError   = 0.0;           //  Error[-1]
  59. float  PrevError   = 0.0;           //  Error[-2]
  60. float  SumError    = 0.0;           //  Sums of Errors
  61. float  dError      = 0.0;
  62. float  Error       = 0.0;

  63. int   pid_result = 0;
  64. float T_Hight = 0.0;
  65. float T_LOW   = 100.0; //溫度
  66. long TIME_Hight = 0;
  67. long TIME_LOW   = 0;        //具體的秒
  68. int pid_con_10ms_flag = 0;
  69. int pid_con_counter        = 0;

  70. float  KC = 1.0;  //臨界比例系數(shù)  初始默認(rèn)的值
  71. int    TC = 40;   //振蕩周期      初始默認(rèn)的值

  72. int temp_pid  =  0;//設(shè)定成全局變量  

  73. volatile int get_now_temp_flag   = 0;
  74. volatile int enable_pid_sec_flag = 0;
  75. volatile int pid_self_sec_flag   = 0;

  76. //uint pid_self_calc_buffer[200] _at_ 0xF000;        //0xffff 對(duì)應(yīng)flash的最頂端

  77. int zero_across_counter = 0;
  78. int pid_self_first_status_flag = 0;

  79. long pid_self_time_sec = 0;

  80. float max_temp  = 0.0 ;  //初始溫度等于0
  81. float min_temp  = 100.0 ;//初始溫度等于100
  82. float sum_temp  = 0.0 ;  //初始溫度等于0
  83. float aver_temp        = 0.0 ;

  84. int cool_ack_counter    = 0;
  85. int hot_ack_counter     = 0;
  86. int once_add_1_flag     = 0;

  87. float pid_self_calc_buffer[4];
  88. int k_pid_self_counter = 0;

  89. int enable_calc_min_max_flag = 0;
  90. int k_max_min = 0;
  91. int dis_tune_once_flag = 1;

  92. int k_cut_off_flag = 0;//斷k偶標(biāo)志
  93. long k_reou_value = 0;

  94. int soft_dis_flag = 1;
  95. int soft_counter  = 0;
  96. int soft_end_counter = 0;

  97. int pwm_con_time_flag = 0;

  98. //qqqqqqqqqqqqqq
  99. ////////////////////////////////////////////////////////
  100. //函數(shù)定義
  101. void SendByte(uchar Dbyte); //發(fā)送字節(jié)數(shù)據(jù)
  102. void write_cmd(uchar Cbyte);//寫指令
  103. void write_data(uchar Dbyte);//寫數(shù)據(jù)
  104. void PUTchar8x8(int row,int col,int count,uchar *put);
  105. void PUTchar8x16(int row,int col,int count,uchar *put);
  106. void PUTchar16x16(int row,int col,int count,uchar *put);//32個(gè)字節(jié)表示1個(gè)漢字
  107. void PUTchar24x24(int row,int col,int count,uchar *put);
  108. void PUTBMP(void);//圖片
  109. void PUTREVERSEBMP(void);//圖片反顯
  110. void LcmClear(void);//清屏
  111. void LcmSet(void);//顯示所有  即滿屏都是黑色的
  112. void LcmInit(void);//初始化
  113. void ohengxian(void);//O橫線程序
  114. void jihengxian(void);//奇橫線程序
  115. void oshuxian(void);//O豎線程序
  116. void jishuxian(void);//奇豎線程序
  117. void dianxian(void);//點(diǎn)顯示程序 滿屏都是點(diǎn)
  118. void zifu8x16xian(void);//可以顯示數(shù)字及英文
  119. void zifu16x16xian(void);//可以顯示特定的漢字
  120. void lcd_dis_position_16_16(int line,int column,uchar zifu_16_16[2]);// 1行 1列 具體的字符
  121. void lcd_dis_position_8_16(int line,int column,uchar zifu_8_16);// 1行 1列 具體的字符
  122. void lcd_s_12864_dis_8_16_str(int dis_line,int start_position,char *dis_str);//顯示一行的8*16的字符
  123. void ds_18b20_DelayXus(int n);
  124. void ds_18b20_init(void);//DS18B20的初始化
  125. uchar ds_18b20_read_date(void);  //讀一個(gè)字節(jié)
  126. void ds_18b20_write_date(uchar date);//寫一個(gè)字節(jié)
  127. float read_18b20_temp(void);//讀出18b20的溫度值 實(shí)際溫度值返回 同時(shí)改變temp_zero_below_flag的值 如果是0 說明是0度以下
  128. void key_pro(void);
  129. void display_pro(void);
  130. void pid_pro(void);
  131. void dis_4_line_as_null(void);
  132. void dis_pid_self_value(void);
  133. float read_max6675_temper(void);// 利用max6675讀k探頭的溫度 返回最終溫度的1倍
  134. void PWM_clock(uchar clock);
  135. void PWM_start(uchar module,uchar mode);
  136. void set_pwm_value(uchar value);//0--255之間         value越大,占空比越高 輸出電壓也越大 40-->0.8v 237-->4.6v



  137. //hhhhhhhhhhhhhhhhhhhhhhhhhhh
  138. ////////////////////////////////////////////////////////
  139. //中斷函數(shù)ttttttttttttttttttttttttttttt
  140. void tm0_isr(void) interrupt 1 using 1  //1ms
  141. {

  142. TL0 = 0x20;                //設(shè)置定時(shí)初值
  143. TH0 = 0xD1;                //設(shè)置定時(shí)初值
  144.         
  145. time0_temp1++;
  146. if(time0_temp1 % 2 == 0 )//2ms
  147.         {
  148.         
  149.         pid_con_10ms_flag = 1;
  150.         
  151.         }
  152. if(time0_temp1 >= 10 )//10ms
  153.         {
  154.         time0_temp1 = 0;
  155.         time0_10ms_flag = 1;
  156.         
  157.         }

  158. time0_temp2++;

  159. if(time0_temp2 % 200  == 0)//200ms
  160.         {
  161.         get_now_temp_flag   = 1;
  162.         }

  163. if(time0_temp2 % 200  == 0)//200ms
  164.         {
  165.         //get_now_temp_flag   = 1;
  166.         
  167.         pid_self_sec_flag   = 1;
  168.         
  169.         pwm_con_time_flag   = 1;
  170.         enable_pid_sec_flag = 1;
  171.         special_dis_once_flag = 1;
  172.         
  173.         }

  174. if(time0_temp2 >= 1000 )//1s         如果要想1000對(duì)應(yīng)1s 那么中間不能有關(guān)中斷的行為發(fā)生
  175.         {
  176.         time0_temp2 = 0;
  177.         global_sec++;
  178.         global_sec_flag = 1;
  179.         
  180.         three_dot_dis_flag  ^= 1;
  181.    
  182.         soft_dis_flag = 1;//軟啟動(dòng)
  183.         
  184.         //ssr_con_1;delay_ms(10);ssr_con_0;//test
  185.         
  186.         }

  187. }


  188. void PCA_Intrrpt(void) interrupt 7 //pwm 的中斷
  189. {
  190. if(CCF0) CCF0=0;
  191. if(CCF1) CCF1=0;   //軟件清零
  192. if(CF)   CF=0;     //軟件清零
  193. }



  194. ////////////////////////////////////////////////////////
  195. //函數(shù)

  196. void Timer0Init(void)                //1毫秒@12.000MHz  定時(shí)器0
  197. {
  198.         AUXR |= 0x80;        //定時(shí)器時(shí)鐘1T模式
  199.         TMOD &= 0xF0;        //設(shè)置定時(shí)器模式
  200.         TMOD |= 0x01;        //設(shè)置定時(shí)器模式
  201.         TL0 = 0x20;                //設(shè)置定時(shí)初值
  202.         TH0 = 0xD1;                //設(shè)置定時(shí)初值
  203.         TF0 = 0;                //清除TF0標(biāo)志
  204.         TR0 = 1;                //定時(shí)器0開始計(jì)時(shí)
  205.         ET0 = 1;        //enable timer0 interrupt   
  206. }


  207. void io_init(void)
  208. {

  209. P3M0 = 0x00 ;   //  0000  0000  
  210. P2M0 = 0xf0 ;   //  1111  0000  低四位為按鍵
  211. P1M0 = 0xff ;   //  1111  1111  強(qiáng)推挽輸出          lcd 及 ssr驅(qū)動(dòng)
  212. P0M0 = 0x00 ;   //  0000  0000  強(qiáng)推挽輸出

  213. key_1_in;
  214. key_2_in;
  215. key_3_in;
  216. key_4_in;

  217. ssr_con_out;

  218. lcd_s_12864_cs_out;
  219. lcd_s_12864_reset_out;
  220. lcd_s_12864_rs_out;
  221. lcd_s_12864_sda_out;
  222. lcd_s_12864_sck_out;
  223. lcd_s_12864_light_out;

  224. lcd_s_12864_cs_0;
  225. lcd_s_12864_reset_0;
  226. lcd_s_12864_rs_0;
  227. lcd_s_12864_sda_0;
  228. lcd_s_12864_sck_0;
  229. lcd_s_12864_light_0;

  230. max6675_so_in;
  231. max6675_sck_out;
  232. max6675_cs1_out;
  233. cs1_1;

  234. pwm_con_out;
  235. pwm_con_0;

  236. }



  237. void power_on_event(void)//eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
  238. {
  239. int k;
  240. for( k = 0; k < 2; k++ )//閃燈2次
  241.         {
  242.         lcd_s_12864_light_0;
  243.         delay_ms(200);
  244.         lcd_s_12864_light_1;
  245.         delay_ms(200);
  246.         }

  247. //引用一下基本的函數(shù) 否則老是出現(xiàn)警告錯(cuò)誤
  248. if( refer_fun_flag == 1 )//讓refer_fun_flag永遠(yuǎn)為0 意思就是永遠(yuǎn)不實(shí)際引用這些函數(shù)
  249.         {
  250. //        PUTchar8x8(1,1,5,zifu8x8);
  251. //        PUTchar24x24(1,1,2,zifu24x24);
  252. //        PUTBMP();//圖片
  253. //        PUTREVERSEBMP();//圖片反顯
  254. //        LcmClear();//清屏
  255. //        LcmSet();//顯示所有  即滿屏都是黑色的
  256. //        LcmInit();//初始化
  257. //        ohengxian();//O橫線程序
  258. //        jihengxian();//奇橫線程序
  259. //        oshuxian();//O豎線程序
  260. //        jishuxian();//奇豎線程序
  261. //        dianxian();//點(diǎn)顯示程序 滿屏都是點(diǎn)
  262. //        zifu8x16xian();//可以顯示數(shù)字及英文
  263. //        zifu16x16xian();//可以顯示特定的漢字
  264. //        lcd_dis_position_16_16(1,1,"鄭");
  265. //        lcd_dis_position_8_16(1,1,'8');

  266.         }                                                               

  267. }


  268. //s_12864    lllllllllllllllllllllllllllllll
  269. void SendByte(uchar Dbyte) //發(fā)送字節(jié)數(shù)據(jù)
  270. {
  271. uchar i,TEMP;
  272. TEMP = Dbyte;
  273. for(i=0;i<8;i++)
  274.     {
  275.     lcd_s_12864_sck_0;
  276.     _nop_();        
  277.         _nop_();
  278.     if( TEMP & 0x80 )
  279.         {
  280.         lcd_s_12864_sda_1;
  281.         }
  282.     else
  283.         {
  284.         lcd_s_12864_sda_0;
  285.         }
  286.     lcd_s_12864_sck_1;
  287.     _nop_();        
  288.     _nop_();     
  289.     TEMP = TEMP<<1;
  290.     }
  291. }


  292. void write_cmd(uchar Cbyte )//寫指令
  293. {
  294. lcd_s_12864_cs_0;
  295. lcd_s_12864_rs_0;
  296. SendByte(Cbyte);
  297. }


  298. void write_data(uchar Dbyte )//寫數(shù)據(jù)
  299. {
  300. lcd_s_12864_cs_0;
  301. lcd_s_12864_rs_1;
  302. SendByte(Dbyte);
  303. }


  304. void PUTchar8x8(int row,int col,int count,uchar *put)
  305. {               
  306. uint X=0;
  307. int  j,i;
  308. write_cmd(0xb0+row);
  309. write_cmd(0x10+(8*col/16));               
  310. write_cmd(0x00+(8*col%16));
  311. for(j=0;j<count;j++)
  312.     {
  313.     for(i=0;i<8;i++)
  314.         {
  315.         write_data(put[X++]);
  316.         }
  317.     }        
  318. }


  319. 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的字符
  320. {               
  321. uint X=0;
  322. int j,i;
  323. write_cmd(0xb0+row);
  324. write_cmd(0x10+(8*col/16));               
  325. write_cmd(0x00+(8*col%16));
  326. for(j=0;j<count;j++)
  327.     {
  328.     for(i=0;i<8;i++)
  329.         {
  330.         write_data(put[X++]);
  331.         }
  332.     write_cmd(0xb1+row);        
  333.     write_cmd(0x10+(8*col/16));               
  334.     write_cmd(0x00+(8*col%16));
  335.     for(i=0;i<8;i++)
  336.         {
  337.         write_data(put[X++]);
  338.         }
  339.     write_cmd(0xb0+row);
  340.     col=col+1;
  341.     }
  342. }


  343. void PUTchar16x16(int row,int col,int count,uchar *put)//32個(gè)字節(jié)表示1個(gè)漢字
  344. {               
  345. uint X=0;
  346. int j,i;
  347. write_cmd(0xb0+row);
  348. write_cmd(0x10+(8*col/16));               
  349. write_cmd(0x00+(8*col%16));
  350. for(j=0;j<count;j++)
  351.     {
  352.     for(i=0;i<16;i++)
  353.         {
  354.         write_data(put[X++]);
  355.         }
  356.     write_cmd(0xb1+row);        
  357.     write_cmd(0x10+(8*col/16));               
  358.     write_cmd(0x00+(8*col%16));
  359.     for(i=0;i<16;i++)
  360.         {
  361.         write_data(put[X++]);
  362.         }
  363.     write_cmd(0xb0+row);         
  364.     col=col+2;
  365.     }
  366. }


  367. void PUTchar24x24(int row,int col,int count,uchar *put)
  368. {               
  369. uint X=0;
  370. int j,i;
  371. write_cmd(0xb0+row);           //縱坐標(biāo)
  372. write_cmd(0x10+(8*col/16));                 //橫坐標(biāo)
  373. write_cmd(0x00+(8*col%16));
  374. for(j=0;j<count;j++)
  375.     {
  376.     for(i=0;i<24;i++)
  377.         {
  378.         write_data(put[X++]);
  379.         }
  380.     write_cmd(0xb1+row);        
  381.     write_cmd(0x10+(8*col/16));               
  382.     write_cmd(0x00+(8*col%16));
  383.     for(i=0;i<24;i++)
  384.         {
  385.         write_data(put[X++]);
  386.         }
  387.     write_cmd(0xb2+row);        
  388.     write_cmd(0x10+(8*col/16));               
  389.     write_cmd(0x00+(8*col%16));
  390.     for(i=0;i<24;i++)
  391.         {
  392.         write_data(put[X++]);
  393.         }
  394.     write_cmd(0xb0+row);
  395.     col=col+3;
  396.     }
  397. }


  398. void PUTBMP(void)//圖片
  399. {               
  400. uint X=0;
  401. int j,i;
  402. for(j=0;j<8;j++)
  403.     {
  404.     write_cmd(0xb0+j);
  405.     write_cmd(0x10);               
  406.     write_cmd(0x00);
  407.     for(i=0;i<128;i++)
  408.         {
  409.         write_data(bmp1[X++]);//bmp1為具體的圖片數(shù)組
  410.         }
  411.     }        
  412. }


  413. void PUTREVERSEBMP(void)//圖片反顯
  414. {        
  415. uint X=0;
  416. int j,i;
  417. for(j=0;j<8;j++)
  418.     {
  419.     write_cmd(0xb0+j);
  420.     write_cmd(0x10);               
  421.     write_cmd(0x00);
  422.     for(i=0;i<128;i++)
  423.         {
  424.         write_data(~bmp1[X++]);
  425.         }
  426.     }        
  427. }


  428. void LcmClear(void)//清屏
  429. {         
  430. int x,y;
  431. for(y=0;y<8;y++)
  432.     {   
  433.     write_cmd(0xb0+y);
  434.     write_cmd(0x10);               
  435.     write_cmd(0x00);
  436.     for(x=0;x<132;x++)
  437.         {
  438.         write_data(0);
  439.         }
  440.     }        
  441. }


  442. void LcmSet(void)//顯示所有  即滿屏都是黑色的
  443. {         
  444. int x,y;
  445. for(y=0;y<8;y++)
  446.     {   
  447.     write_cmd(0xb0+y);
  448.     write_cmd(0x10);               
  449.     write_cmd(0x00);
  450.     for(x=0;x<132;x++)
  451.         {
  452.         write_data(0xff);
  453.         }
  454.     }        
  455. }


  456. void LcmInit(void)//初始化
  457. {        
  458. lcd_s_12864_cs_0;
  459. lcd_s_12864_reset_0;
  460. delay_ms(100);
  461. lcd_s_12864_reset_1;
  462. delay_ms(100);
  463. write_cmd(0xe2);//system reset
  464. delay_ms(10);
  465. write_cmd(0x24);//SET VLCD RESISTOR RATIO  0x20--0x27  可以調(diào)節(jié)對(duì)比對(duì) 之有 0x23 0x24 這2個(gè)值可以選擇 0x24的對(duì)比度強(qiáng)  粗調(diào)
  466. write_cmd(0xa2);//BR=1/9
  467. write_cmd(0xa0);//set seg direction
  468. write_cmd(0xc8);//set com direction
  469. write_cmd(0x2f);//set power control
  470. write_cmd(0x40);//set scroll line
  471. write_cmd(0x81);//SET ELECTRONIC VOLUME
  472. write_cmd(0x1c);//set pm: 通過改變這里的數(shù)值來改變電壓 //也可以調(diào)節(jié)對(duì)比度 從0x00 -- 0x3f 值越大對(duì)比度越大 細(xì)調(diào)

  473. //write_cmd(0xa6);//set inverse display           a6 off, a7 on  打開跟不打開沒有任何影響
  474. //write_cmd(0xa4);//set all pixel on                      打開跟不打開沒有任何影響
  475. write_cmd(0xaf);//set display enable
  476. LcmClear();     //先清屏
  477. }


  478. void ohengxian(void)//O橫線程序
  479. {
  480. int x,y;
  481. for(y=0;y<8;y++)
  482.     {   
  483.     write_cmd(0xb0+y);
  484.     write_cmd(0x10);               
  485.     write_cmd(0x00);
  486.     for(x=0;x<128;x++)
  487.         {
  488.         write_data(0x55);
  489.         }
  490.     }         
  491. }


  492. void jihengxian(void)//奇橫線程序
  493. {
  494. int x,y;
  495. for(y=0;y<8;y++)
  496.     {
  497.     write_cmd(0xb0+y);
  498.     write_cmd(0x10);               
  499.     write_cmd(0x00);
  500.     for(x=0;x<128;x++)
  501.         {
  502.         write_data(0xAA);
  503.         }
  504.     }         
  505. }


  506. void oshuxian(void)//O豎線程序
  507. {
  508. int x,y;
  509. for(y=0;y<8;y++)
  510.     {   
  511.     write_cmd(0xb0+y);
  512.     write_cmd(0x10);               
  513.     write_cmd(0x00);
  514.     for(x=0;x<128;x++)
  515.         {
  516.         if(x%2==0)
  517.             {
  518.             write_data(0xFF);
  519.             }
  520.         else
  521.             {
  522.             write_data(0);
  523.             }   
  524.         }
  525.     }         
  526. }


  527. void jishuxian(void)//奇豎線程序
  528. {
  529. int x,y;
  530. for(y=0;y<8;y++)
  531.     {   
  532.     write_cmd(0xb0+y);
  533.     write_cmd(0x10);               
  534.     write_cmd(0x00);
  535.     for(x=0;x<128;x++)
  536.         {
  537.         if(x%2==0)
  538.             {
  539.             write_data(0);
  540.             }
  541.         else
  542.             {
  543.             write_data(0xFF);
  544.             }
  545.         }
  546.     }         
  547. }


  548. void dianxian(void)//點(diǎn)顯示程序 滿屏都是點(diǎn)
  549. {
  550. int x,y;
  551. for(y=0;y<8;y++)
  552.     {   
  553.     write_cmd(0xb0+y);
  554.     write_cmd(0x10);               
  555.     write_cmd(0x00);
  556.     for(x=0;x<128;x++)
  557.         {
  558.         if(x%2==0)
  559.             {
  560.             write_data(0xAA);
  561.             }
  562.         else
  563.             {
  564.             write_data(0x55);
  565.             }
  566.         }
  567.     }         
  568. }


  569. void zifu8x16xian(void)//可以顯示數(shù)字及英文
  570. {
  571. int k;
  572. for(k=0;k<4;k++)//代表顯示4行
  573.     {
  574.     PUTchar8x16(2*k,0,16,zifu8x16);
  575.     }
  576. }


  577. void zifu16x16xian(void)//可以顯示特定的漢字
  578. {
  579. int k;
  580. for(k=0;k<4;k++)
  581.     {
  582.     PUTchar16x16(2*k,0,16,zifu16x16);
  583.     }
  584. }


  585. //zzzzzzzzzzzzzzzzzzz
  586. void lcd_dis_position_16_16(int line,int column,uchar zifu_16_16[2])// 1行 1列 具體的字符
  587. {               
  588. uint X=0;
  589. int i;
  590. /////////////////////////////////////
  591. if     ( zifu_16_16 == "鄭" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_001[i];}}
  592. else if( zifu_16_16 == "州" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_002[i];}}
  593. else if( zifu_16_16 == "迎" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_003[i];}}
  594. else if( zifu_16_16 == "之" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_004[i];}}
  595. else if( zifu_16_16 == "勝" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_005[i];}}
  596. else if( zifu_16_16 == "電" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_006[i];}}
  597. else if( zifu_16_16 == "子" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_007[i];}}
  598. else if( zifu_16_16 == "公" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_008[i];}}
  599. else if( zifu_16_16 == "司" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_009[i];}}

  600. else if( zifu_16_16 == "當(dāng)" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_010[i];}}
  601. else if( zifu_16_16 == "前" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_011[i];}}
  602. else if( zifu_16_16 == "溫" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_012[i];}}
  603. else if( zifu_16_16 == "度" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_013[i];}}

  604. else if( zifu_16_16 == "設(shè)" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_014[i];}}
  605. else if( zifu_16_16 == "定" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_015[i];}}

  606. else if( zifu_16_16 == "比" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_016[i];}}
  607. else if( zifu_16_16 == "例" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_017[i];}}
  608. else if( zifu_16_16 == "積" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_018[i];}}
  609. else if( zifu_16_16 == "分" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_019[i];}}
  610. else if( zifu_16_16 == "微" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_020[i];}}

  611. else if( zifu_16_16 == "自" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_021[i];}}
  612. else if( zifu_16_16 == "整" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_022[i];}}
  613. else if( zifu_16_16 == "定" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_023[i];}}
  614. else if( zifu_16_16 == "中" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_024[i];}}

  615. else if( zifu_16_16 == "軟" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_025[i];}}
  616. else if( zifu_16_16 == "啟" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_026[i];}}
  617. else if( zifu_16_16 == "動(dòng)" ){for(i = 0; i < 32; ++i){temp_buffer_16_16_comm[i] = hanzi_16_16_027[i];}}

  618. /////////////////////////////////////
  619. write_cmd(0xb0+((line-1)*2));//第1行
  620. write_cmd(0x10+(8*(2*(column-1))/16));
  621. write_cmd(0x00+(8*(2*(column-1))%16));//起始位置
  622. for(i=0;i<16;i++)
  623.     {   
  624.     write_data(temp_buffer_16_16_comm[X++]);
  625.     }
  626. write_cmd(0xb1+((line-1)*2));        
  627. write_cmd(0x10+(8*(2*(column-1))/16));        
  628. write_cmd(0x00+(8*(2*(column-1))%16));
  629. for(i=0;i<16;i++)
  630.     {
  631.     write_data(temp_buffer_16_16_comm[X++]);
  632.     }
  633. write_cmd(0xb0+((line-1)*2));
  634. }


  635. void lcd_dis_position_8_16(int line,int column,uchar zifu_8_16)// 1行 1列 具體的字符
  636. {               
  637. uint X=0;
  638. int i;
  639. /////////////////////////////////////
  640. if     ( zifu_8_16 == '0' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_001[i];}}
  641. else if( zifu_8_16 == '1' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_002[i];}}
  642. else if( zifu_8_16 == '2' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_003[i];}}
  643. else if( zifu_8_16 == '3' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_004[i];}}
  644. else if( zifu_8_16 == '4' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_005[i];}}
  645. else if( zifu_8_16 == '5' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_006[i];}}
  646. else if( zifu_8_16 == '6' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_007[i];}}
  647. else if( zifu_8_16 == '7' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_008[i];}}
  648. else if( zifu_8_16 == '8' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_009[i];}}
  649. else if( zifu_8_16 == '9' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_010[i];}}
  650. else if( zifu_8_16 == ':' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_011[i];}}
  651. else if( zifu_8_16 == '-' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_012[i];}}
  652. else if( zifu_8_16 == '.' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_013[i];}}
  653. else if( zifu_8_16 == '+' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_014[i];}}

  654. else if( zifu_8_16 == '%' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_015[i];}}
  655. else if( zifu_8_16 == 'S' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_016[i];}}
  656. else if( zifu_8_16 == 'C' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_017[i];}}

  657. else if( zifu_8_16 == 'P' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_018[i];}}
  658. else if( zifu_8_16 == 'I' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_019[i];}}
  659. else if( zifu_8_16 == 'D' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_020[i];}}

  660. else if( zifu_8_16 == ' ' ){for(i = 0; i < 16; ++i){temp_buffer_8_16_comm[i] = zifu_8_16_021[i];}}

  661. /////////////////////////////////////
  662. write_cmd(0xb0+((line-1)*2));//第1行
  663. write_cmd(0x10+(8*(1*(column-1))/16));
  664. write_cmd(0x00+(8*(1*(column-1))%16));//起始位置
  665. for(i=0;i<8;i++)
  666.     {   
  667.     write_data(temp_buffer_8_16_comm[X++]);
  668.     }
  669. write_cmd(0xb1+((line-1)*2));        
  670. write_cmd(0x10+(8*(1*(column-1))/16));        
  671. write_cmd(0x00+(8*(1*(column-1))%16));
  672. for(i=0;i<8;i++)
  673.     {
  674.     write_data(temp_buffer_8_16_comm[X++]);
  675.     }
  676. write_cmd(0xb0+((line-1)*2));
  677. }


  678. char *convert_num_to_str(long num)//將數(shù)字轉(zhuǎn)成字符串 最大顯示21億 第1位為0的話,則顯示0
  679. {

  680. temp_dis_num_buffer[0] = ((num/1000000000)%10) + '0';
  681. temp_dis_num_buffer[1] = ((num/100000000)%10) + '0';
  682. temp_dis_num_buffer[2] = ((num/10000000)%10) + '0';
  683. temp_dis_num_buffer[3] = ((num/1000000)%10) + '0';
  684. temp_dis_num_buffer[4] = ((num/100000)%10) + '0';
  685. temp_dis_num_buffer[5] = ((num/10000)%10) + '0';
  686. temp_dis_num_buffer[6] = ((num/1000)%10) + '0';
  687. temp_dis_num_buffer[7] = ((num/100)%10) + '0';
  688. temp_dis_num_buffer[8] = ((num/10)%10) + '0';
  689. temp_dis_num_buffer[9] = ((num/1)%10) + '0';

  690. temp_str = temp_dis_num_buffer;

  691. return temp_str;
  692. }


  693. void lcd_s_12864_dis_8_16_str(int dis_line,int start_position,char *dis_str)//顯示一行的8*16的字符
  694. {
  695. int temp_1=0;
  696. int i;
  697. char *temp_str;
  698. temp_str = dis_str;
  699. while(1)//求出長(zhǎng)度
  700.     {
  701.     temp_1++;
  702.     if( *temp_str++ == '\0'  )
  703.         {
  704.         break;
  705.         }
  706.     }
  707. for(i = 0; i < (temp_1 - 1) ; ++i)
  708.     {
  709.     lcd_dis_position_8_16(dis_line,start_position + i , *dis_str++);
  710.     }
  711. }


  712. void dis_long_number(int dis_line,long dis_num)
  713. {

  714. lcd_dis_position_8_16(dis_line,0,((dis_num/1000000000)%10) + '0');
  715. lcd_dis_position_8_16(dis_line,1,((dis_num/100000000)%10) + '0');
  716. lcd_dis_position_8_16(dis_line,2,((dis_num/10000000)%10) + '0');
  717. lcd_dis_position_8_16(dis_line,3,((dis_num/1000000)%10) + '0');
  718. lcd_dis_position_8_16(dis_line,4,((dis_num/100000)%10) + '0');
  719. lcd_dis_position_8_16(dis_line,5,((dis_num/10000)%10) + '0');
  720. lcd_dis_position_8_16(dis_line,6,((dis_num/1000)%10) + '0');
  721. lcd_dis_position_8_16(dis_line,7,((dis_num/100)%10) + '0');
  722. lcd_dis_position_8_16(dis_line,8,((dis_num/10)%10) + '0');
  723. lcd_dis_position_8_16(dis_line,9,((dis_num/1)%10) + '0');

  724. }


  725. //key
  726. int key_scan(void)
  727. {
  728. int key_temp = 0;
  729. if(!(key_1_status))
  730.     {
  731.     delay_ms(10);
  732.     if(!(key_1_status))
  733.         {
  734.         key_perss_counter++;
  735.         if(( key_perss_counter > key_perss_long_max_num ) && ( key_perss_counter < key_perss_long_long_max_num ))
  736.             {
  737.             //lcd_s_12864_light_0;
  738.             //delay_ms(20);
  739.             //lcd_s_12864_light_1;//報(bào)警            
  740.             //delay_ms(20);
  741.             key_temp = 11;//長(zhǎng)按
  742.             }
  743.         else if( key_perss_counter >= key_perss_long_long_max_num )
  744.             {
  745.             lcd_s_12864_light_0;
  746.             delay_ms(50);
  747.             lcd_s_12864_light_1;//報(bào)警            
  748.             delay_ms(50);
  749.             key_temp = 111;//超長(zhǎng)按
  750.             }
  751.         else
  752.             {
  753.             if( key_once_active_flag == 1 )
  754.                 {
  755.                 key_once_active_flag = 0;
  756.                 //lcd_s_12864_light_0;
  757.                 //delay_ms(10);
  758.                 //lcd_s_12864_light_1;//報(bào)警
  759.                 key_temp = 1;//短按
  760.                 }               
  761.             }
  762.         }
  763.     }
  764. else if(!(key_2_status))
  765.     {
  766.     delay_ms(10);
  767.     if(!(key_2_status))
  768.         {
  769.         key_perss_counter++;
  770.         if(( key_perss_counter > key_perss_long_max_num ) && ( key_perss_counter < key_perss_long_long_max_num ))
  771.             {
  772.             //lcd_s_12864_light_0;
  773.             //delay_ms(20);
  774.             //lcd_s_12864_light_1;
  775.             //delay_ms(20);
  776.             key_temp = 22;//長(zhǎng)按
  777.             }
  778.         else if( key_perss_counter >= key_perss_long_long_max_num )
  779.             {
  780.             lcd_s_12864_light_0;
  781.             delay_ms(50);
  782.             lcd_s_12864_light_1;
  783.             delay_ms(50);
  784.             key_temp = 222;//超長(zhǎng)按
  785.             }
  786.         else
  787.             {
  788.             if( key_once_active_flag == 1 )
  789.                 {
  790.                 key_once_active_flag = 0;
  791.                 //lcd_s_12864_light_0;
  792.                 //delay_ms(10);
  793.                 //lcd_s_12864_light_1;
  794.                 key_temp = 2;//短按
  795.                 }               
  796.             }
  797.         }
  798.     }
  799. else if(!(key_3_status))
  800.     {
  801.     delay_ms(10);
  802.     if(!(key_3_status))
  803.         {
  804.         key_perss_counter++;
  805.         if(( key_perss_counter > key_perss_long_max_num ) && ( key_perss_counter < key_perss_long_long_max_num ))
  806.             {
  807.             //lcd_s_12864_light_0;
  808.             //delay_ms(20);
  809.             //lcd_s_12864_light_1;
  810.             //delay_ms(20);
  811.             //key_temp = 33;//長(zhǎng)按
  812.             key_temp = 3;            
  813.                         }
  814.         else if( key_perss_counter >= key_perss_long_long_max_num )
  815.             {
  816.             lcd_s_12864_light_0;
  817.             delay_ms(50);
  818.             lcd_s_12864_light_1;
  819.             delay_ms(50);
  820.             key_temp = 333;//超長(zhǎng)按
  821.             //key_temp = 3;            
  822.                         }
  823.         else
  824.             {
  825.             if( key_once_active_flag == 1 )
  826.                 {
  827.                 key_once_active_flag = 0;
  828.                 //lcd_s_12864_light_0;
  829.                 //delay_ms(10);
  830.                 //lcd_s_12864_light_1;
  831.                 key_temp = 3;//短按
  832.                 }               
  833.             }
  834.         }
  835.     }
  836. else if(!(key_4_status))
  837.     {
  838.     delay_ms(10);
  839.     if(!(key_4_status))
  840.         {
  841.         key_perss_counter++;
  842.         if(( key_perss_counter > key_perss_long_max_num ) && ( key_perss_counter < key_perss_long_long_max_num ))
  843.             {
  844.             //lcd_s_12864_light_0;
  845.             //delay_ms(20);
  846.             //lcd_s_12864_light_1;
  847.             //delay_ms(20);
  848.             //key_temp = 44;//長(zhǎng)按
  849.             key_temp = 4;            
  850.                         }
  851.         else if( key_perss_counter >= key_perss_long_long_max_num )
  852.             {
  853.             lcd_s_12864_light_0;
  854.             delay_ms(50);
  855.             lcd_s_12864_light_1;
  856.             delay_ms(50);
  857.             key_temp = 444;//超長(zhǎng)按
  858.             //key_temp = 4;
  859.                         }
  860.         else
  861.             {
  862.             if( key_once_active_flag == 1 )
  863.                 {
  864.                 key_once_active_flag = 0;
  865.                 //lcd_s_12864_light_0;
  866.                 //delay_ms(10);
  867.                 //lcd_s_12864_light_1;
  868.                 key_temp = 4;//短按
  869.                 }               
  870.             }
  871.         }
  872.     }
  873. else//沒有任何key按動(dòng)的時(shí)候
  874.     {
  875.     key_once_active_flag = 1;//允許再按時(shí)1次動(dòng)作
  876.     key_perss_counter    = 0;
  877.     }
  878. return key_temp;
  879. }


  880. //DS18B20
  881. void ds_18b20_DelayXus(int n)
  882. {
  883. while (n--)
  884.         {
  885.         _nop_();
  886.         //_nop_();
  887.         }
  888. }


  889. void ds_18b20_init(void)//DS18B20的初始化
  890. {  
  891. EA = 0;//關(guān)中斷
  892. DQ=1;
  893. ds_18b20_DelayXus(1);//1US
  894. DQ=0;
  895. ds_18b20_DelayXus(600);//600US
  896. DQ=1;
  897. ds_18b20_DelayXus(100);         //100US
  898. if(DQ==0)
  899.         {
  900.         ds_18b20_reset_ok_flag = 1;
  901.         ds_18b20_DelayXus(200);
  902.         DQ=1;
  903.         }
  904. if(DQ==1)//說明復(fù)位成功
  905.         {
  906.         ds_18b20_reset_ok_flag = 0;
  907.         ds_18b20_DelayXus(200);
  908.         DQ=1;
  909.         }
  910. EA = 1;//開中斷
  911. }


  912. uchar ds_18b20_read_date(void)  //讀一個(gè)字節(jié)
  913. {
  914. uchar temp,i;
  915. EA = 0;
  916. for( i=0;i<8;i++)
  917.         {
  918.         DQ=1;
  919.         ds_18b20_DelayXus(2);
  920.         DQ=0;
  921.         ds_18b20_DelayXus(3);
  922.         DQ=1;
  923.         ds_18b20_DelayXus(2);
  924.         temp>>=1;
  925.         if(DQ)
  926.                 {
  927.                 temp=temp|0x80;
  928.                 }
  929.         ds_18b20_DelayXus(50);
  930.         }
  931. EA = 1;
  932. return temp;
  933. }


  934. void ds_18b20_write_date(uchar date)//寫一個(gè)字節(jié)
  935. {
  936. uchar i;
  937. //EA = 0;
  938. for( i=0 ;i<8;i++)
  939.         {
  940.         DQ=0;
  941.         ds_18b20_DelayXus(2);
  942.         DQ = date&0x01;
  943.         ds_18b20_DelayXus(50);//50us
  944.         DQ=1;
  945.         date>>=1;
  946.         }
  947. EA = 1;
  948. }


  949. float read_18b20_temp(void)//讀出18b20的溫度值 實(shí)際溫度值返回 同時(shí)改變temp_zero_below_flag的值 如果是0 說明是0度以下
  950. {
  951. uchar themh=0;   
  952. uchar theml=0;
  953. uint temp_0 = 0;
  954. float temp_1;

  955. ds_18b20_init();
  956. if(ds_18b20_reset_ok_flag == 0)//檢測(cè)傳感器是否存在
  957.         {   
  958.         ds_18b20_write_date(0xcc);          //跳過ROM匹配
  959.         ds_18b20_write_date(0x44);          //發(fā)出溫度轉(zhuǎn)換命令
  960.         ds_18b20_DelayXus(1000);
  961.         }
  962. ds_18b20_init();
  963. if(ds_18b20_reset_ok_flag == 0)
  964.         {
  965.         ds_18b20_write_date(0x0cc);         //跳過ROM匹配
  966.         ds_18b20_write_date(0x0be);         //發(fā)出讀溫度命令
  967.         theml=ds_18b20_read_date() ;        //讀出溫度值并存放在 theml,themh
  968.         themh=ds_18b20_read_date() ;
  969.         }

  970. //temp_0 = themh*256 + theml;
  971. temp_0 = (themh<<8) | theml;  //2句作用一樣

  972. if( temp_0 & 0xf000 ) //說明是 負(fù)溫度
  973.     {
  974.     temp_0 =  (~temp_0)+ 1 ;//等于268  0000 0001 0000 1100 == 按位反 = 1111 1110 1111 0011 = fef3 = 65267 然后加1 = 65267+1 = 65268
  975.     //temp_0 = (65536 - temp_0) ;//負(fù)溫度求補(bǔ)碼  65268 + 268 = 65536  跟用這個(gè)辦法計(jì)算出的值一樣
  976.         temp_zero_below_flag = 0;
  977.         }
  978. else//為0 ,說明是 正溫度
  979.     {
  980.     temp_zero_below_flag = 1;
  981.         }

  982. temp_1 = (float)(temp_0)*0.0625;

  983. return temp_1;
  984. }


  985. void dis_now_temp_test(void)//測(cè)試用 顯示當(dāng)前溫度
  986. {
  987. if( global_sec_flag == 1 )//1秒1次
  988.         {
  989.         global_sec_flag = 0;
  990.         ssr_con_1;delay_ms(10);ssr_con_0;//test               
  991.         
  992.         now_temp = read_18b20_temp();
  993.         wenkong_now_temp = now_temp;
  994.     dis_now_temp = (long)(wenkong_now_temp*10);//*10是為了顯示的需要
  995.         
  996.         //dis_now_temp = 396;//test
  997.         lcd_dis_position_16_16(1,1,"當(dāng)");
  998.     lcd_dis_position_16_16(1,2,"前");
  999.     lcd_dis_position_16_16(1,3,"溫");
  1000.     lcd_dis_position_16_16(1,4,"度");
  1001.    
  1002.         if (temp_zero_below_flag == 1)//正溫度
  1003.                 {
  1004.                 lcd_dis_position_8_16(2,1, '+');
  1005.             lcd_dis_position_8_16(2,2, (dis_now_temp/100%10) + '0');
  1006.             lcd_dis_position_8_16(2,3, (dis_now_temp/10%10) + '0');
  1007.             lcd_dis_position_8_16(2,4, '.');
  1008.             lcd_dis_position_8_16(2,5, (dis_now_temp/1%10) + '0');
  1009.                 }
  1010.         else if (temp_zero_below_flag == 0)//負(fù)溫度
  1011.                 {
  1012.                 lcd_dis_position_8_16(2,1, '-');
  1013.             lcd_dis_position_8_16(2,2, (dis_now_temp/100%10) + '0');
  1014.             lcd_dis_position_8_16(2,3, (dis_now_temp/10%10) + '0');
  1015.             lcd_dis_position_8_16(2,4, '.');
  1016.             lcd_dis_position_8_16(2,5, (dis_now_temp/1%10) + '0');
  1017.                 }
  1018.         }
  1019. }

  1020. //kkkkkkkkkkkkkkkkkkkk
  1021. void key_pro(void)
  1022. {
  1023. key_value = key_scan();
  1024. if     (key_value == 1)//A 作為 自整定 跟 pid 切換的開關(guān)
  1025.         {
  1026.         pid_tune_flag ^= 1;
  1027.         LcmClear();//清屏
  1028.         //清除最后一行的內(nèi)容
  1029.         //dis_4_line_as_null();

  1030.         if(pid_tune_flag == 1)//自整定階段
  1031.                 {
  1032.                
  1033.                 //記錄此刻的狀態(tài) 即設(shè)定溫度是否 高于或等于 當(dāng)前溫度
  1034.                 if( SV_value >= PV_value )//設(shè)定溫度 高于 或者 等于  當(dāng)前溫度  啟動(dòng)加熱
  1035.                         {
  1036.                         pid_self_first_status_flag = 1;
  1037.                         once_add_1_flag = 0;
  1038.                         }
  1039.                 else//設(shè)定溫度 低于 當(dāng)前溫度
  1040.                         {
  1041.                         pid_self_first_status_flag = 0;
  1042.                         once_add_1_flag = 1;
  1043.                         }
  1044.                
  1045.                 dis_tune_once_flag = 1;
  1046.                 zero_across_counter = 0;
  1047.                 pid_self_time_sec = 0;
  1048.                 pid_self_calc_buffer[0]=0.0;
  1049.         pid_self_calc_buffer[1]=0.0;
  1050.         pid_self_calc_buffer[2]=0.0;
  1051.         pid_self_calc_buffer[3]=0.0;        
  1052.                 k_pid_self_counter = 0;
  1053.                 enable_calc_min_max_flag = 0;
  1054.                 max_temp = 0.0 ;  //初始溫度等于0
  1055.                 min_temp = 1024.0 ;//初始溫度等于1024
  1056.                 sum_temp = 0.0 ;  //初始溫度等于0
  1057.                 aver_temp = 0.0 ;
  1058.                 T_Hight  = 0.0;
  1059.                 T_LOW    = 1024.0; //溫度
  1060.                 TIME_Hight = 0;
  1061.                 TIME_LOW   = 0;        //具體的0.2s
  1062.                
  1063.                 }
  1064.         else if(pid_tune_flag == 0)//pid階段
  1065.                 {
  1066.                 comm_dis_once_flag    = 1;
  1067.                 special_dis_once_flag = 1;
  1068.                 }
  1069.         }
  1070. else if(key_value == 2)//B
  1071.         {
  1072.         
  1073.         }
  1074. else if((key_value == 3) || (key_value == 333))  //-  設(shè)定溫度
  1075.         {
  1076.         special_dis_once_flag = 1;
  1077.         if(key_value == 3)
  1078.                 {
  1079.                 SV_value-=1.0;
  1080.                 }
  1081.         else
  1082.                 {
  1083.                 SV_value-=10.0;
  1084.                 }
  1085.         if(SV_value < 0.0)
  1086.                 {
  1087.                 SV_value = 999.9;
  1088.                 }
  1089.         }
  1090. else if((key_value == 4) || (key_value == 444)) //+
  1091.         {
  1092.         special_dis_once_flag = 1;
  1093.         if(key_value == 4)
  1094.                 {
  1095.                 SV_value+=1.0;
  1096.                 }
  1097.         else
  1098.                 {
  1099.                 SV_value+=10.0;
  1100.                 }
  1101.         if(SV_value > 999.9)
  1102.                 {
  1103.                 SV_value = 0.0;
  1104.                 }
  1105.         }

  1106. }        

  1107. //dddddddddddddddddddddd
  1108. void display_pro(void)
  1109. {
  1110. if( pid_tune_flag == 0 )//pid階段
  1111.         {
  1112.         //第1行 當(dāng)前溫度
  1113.         //第2行 設(shè)定溫度
  1114.         //第3行 顯示pid 各參數(shù)的名字
  1115.         //第4行 顯示pid 各參數(shù)的具體值
  1116.         if (comm_dis_once_flag == 1)//基本信息只顯示一次
  1117.                 {
  1118.                 comm_dis_once_flag = 0;
  1119.                
  1120.                 lcd_dis_position_16_16(1,1,"當(dāng)");
  1121.                 lcd_dis_position_16_16(1,2,"前");
  1122.                 lcd_dis_position_16_16(1,3,"溫");
  1123.                 lcd_dis_position_16_16(1,4,"度");
  1124.                
  1125.                 lcd_dis_position_16_16(2,1,"設(shè)");
  1126.                 lcd_dis_position_16_16(2,2,"定");
  1127.                 lcd_dis_position_16_16(2,3,"溫");
  1128.                 lcd_dis_position_16_16(2,4,"度");
  1129.                
  1130.                 lcd_dis_position_8_16(1,15,'C');
  1131.                 lcd_dis_position_8_16(2,15,'C');
  1132.                
  1133.                 lcd_dis_position_16_16(3,1,"比");
  1134.                 lcd_dis_position_16_16(3,2,"例");
  1135.                 lcd_dis_position_16_16(3,4,"積");
  1136.                 lcd_dis_position_16_16(3,5,"分");
  1137.                 lcd_dis_position_16_16(3,7,"微");
  1138.                 lcd_dis_position_16_16(3,8,"分");
  1139.                
  1140.                 }
  1141.         
  1142.         if (special_dis_once_flag == 1)//獨(dú)立信息  0.2秒1次
  1143.                 {
  1144.                 special_dis_once_flag = 0;
  1145.                
  1146.                 //lcd_s_12864_light_1;delay_ms(10);lcd_s_12864_light_0;//test

  1147.                 //當(dāng)前溫度
  1148.                 lcd_dis_position_8_16(1,9, ((uint)(PV_value*10)/1000)%10 + '0');//百位
  1149.                 lcd_dis_position_8_16(1,10,((uint)(PV_value*10)/100)%10 + '0');
  1150.                 lcd_dis_position_8_16(1,11,((uint)(PV_value*10)/10)%10 + '0');
  1151.                 lcd_dis_position_8_16(1,12,'.');
  1152.                 lcd_dis_position_8_16(1,13,((uint)(PV_value*10)/1)%10 + '0');
  1153.         
  1154.                 //設(shè)定溫度
  1155.                 lcd_dis_position_8_16(2,9, ((uint)(SV_value*10)/1000)%10 + '0');
  1156.                 lcd_dis_position_8_16(2,10,((uint)(SV_value*10)/100)%10 + '0');
  1157.                 lcd_dis_position_8_16(2,11,((uint)(SV_value*10)/10)%10 + '0');
  1158.                 lcd_dis_position_8_16(2,12,'.');
  1159.                 lcd_dis_position_8_16(2,13,((uint)(SV_value*10)/1)%10 + '0');
  1160.                
  1161.                 lcd_dis_position_8_16(4,6,'%');
  1162.                 lcd_dis_position_8_16(4,11,'S');
  1163.                 lcd_dis_position_8_16(4,16,'S');
  1164.         
  1165.                 if( pid_tune_flag == 1 )//如果啟動(dòng)了pid自整定 ,則顯示 pid自整定中...
  1166.                         {
  1167.                         lcd_dis_position_8_16(4,1,'P');
  1168.                         lcd_dis_position_8_16(4,2,'I');
  1169.                         lcd_dis_position_8_16(4,3,'D');
  1170.                         
  1171.                         lcd_dis_position_16_16(4,3,"自");
  1172.                         lcd_dis_position_16_16(4,4,"整");
  1173.                         lcd_dis_position_16_16(4,5,"定");
  1174.                         lcd_dis_position_16_16(4,6,"中");
  1175.                         
  1176.                         if     ( three_dot_dis_flag == 1 )//顯示不斷閃爍的3個(gè)點(diǎn) 表示運(yùn)算中
  1177.                                 {
  1178.                                 lcd_dis_position_8_16(4,14,'.');
  1179.                                 lcd_dis_position_8_16(4,15,'.');
  1180.                                 lcd_dis_position_8_16(4,16,'.');
  1181.                                 }
  1182.                         else if( three_dot_dis_flag == 0 )
  1183.                                 {
  1184.                                 lcd_dis_position_8_16(4,14,' ');
  1185.                                 lcd_dis_position_8_16(4,15,' ');
  1186.                                 lcd_dis_position_8_16(4,16,' ');
  1187.                                 }
  1188.                         }
  1189.                 else if( pid_tune_flag == 0 )//整定ok后 顯示計(jì)算獲得的pid值 正常pid控制的時(shí)候顯示的內(nèi)容
  1190.                         {
  1191.                         //比例 積分 微分
  1192.                         lcd_dis_position_8_16(4,1,((uint)(P_value*10)/1000)%10 + '0');
  1193.                         lcd_dis_position_8_16(4,2,((uint)(P_value*10)/100)%10 + '0');
  1194.                         lcd_dis_position_8_16(4,3,((uint)(P_value*10)/10)%10 + '0');
  1195.                         lcd_dis_position_8_16(4,4,'.');
  1196.                         lcd_dis_position_8_16(4,5,((uint)(P_value*10)/1)%10 + '0');
  1197.                         
  1198.                         lcd_dis_position_8_16(4,7,((I_value*1)/1000)%10 + '0');
  1199.                         lcd_dis_position_8_16(4,8,((I_value*1)/100)%10 + '0');
  1200.                         lcd_dis_position_8_16(4,9,((I_value*1)/10)%10 + '0');
  1201.                         lcd_dis_position_8_16(4,10,((I_value*1)/1)%10 + '0');
  1202.                         
  1203.                         lcd_dis_position_8_16(4,13,((D_value*1)/100)%10 + '0');
  1204.                         lcd_dis_position_8_16(4,14,((D_value*1)/10)%10 + '0');
  1205.                         lcd_dis_position_8_16(4,15,((D_value*1)/1)%10 + '0');
  1206.                         }
  1207.                 }        
  1208.         }
  1209. else if( pid_tune_flag == 1 )//自整定階段
  1210.         {
  1211.         if(dis_tune_once_flag == 1)//顯示一次  
  1212.                 {
  1213.                 dis_tune_once_flag = 0;
  1214.                 dis_pid_self_value();
  1215.                 }
  1216.         }
  1217. }


  1218. int pid_calc(float set_temp ,float now_temp )// pid計(jì)算  set_temp 為設(shè)定的溫度  now_temp  代表實(shí)際輸入的當(dāng)前溫度值  0 - 100的輸出值
  1219. {
  1220. Error = set_temp - now_temp;                 // 偏差
  1221. if(( Error < max_value_error  ) && ( Error > (min_value_error)  ))//只有在一定的溫差范圍內(nèi)才pid計(jì)算
  1222.     {   
  1223.     SumError += Error;
  1224.     dError    = LastError - PrevError;   // 當(dāng)前微分
  1225.     PrevError = LastError;
  1226.     LastError = Error;
  1227.     temp_pid  =  (int)((Proportion * Error) + (Integral * SumError) + (Derivative * dError));   
  1228.     //temp_pid  =  (int)(temp_pid * 0.5) ;//輸出比例控制
  1229.         }
  1230. else//只有開關(guān)作用
  1231.     {
  1232.     if( Error >= max_value_error )//遠(yuǎn)大于當(dāng)前溫度,加熱
  1233.         {
  1234.         temp_pid = 100;
  1235.         //temp_pid = 80;
  1236.                 }
  1237.     else if( Error <= (min_value_error) )//遠(yuǎn)小于當(dāng)前溫度,不加熱
  1238.         {
  1239.         temp_pid = 0;
  1240.         }
  1241.     }
  1242. if( temp_pid < 0 )
  1243.     {
  1244.     temp_pid = 0;
  1245.     }
  1246. else if( temp_pid > 100 )
  1247.     {
  1248.     temp_pid = 100;
  1249.     }
  1250. return temp_pid;
  1251. }


  1252. void pid_con(void)//由計(jì)算結(jié)果控制輸出
  1253. {

  1254. //適用于 pwm
  1255. //每200ms根據(jù)結(jié)果改變一次輸出電壓的值
  1256. if( pwm_con_time_flag == 1)
  1257.         {
  1258.         pwm_con_time_flag = 0;
  1259.         
  1260.         //lcd_s_12864_light_1;delay_ms(10);lcd_s_12864_light_0;//test

  1261.         //set_pwm_value(40 + (uchar)(pid_result * (((float)(237-40))/100.0)) );
  1262.         set_pwm_value(40 + (uchar)(pid_result * 1.97) );//跟上面這句話等價(jià)
  1263.         
  1264.         }

  1265. }


  1266. void pid_pro(void)//pid 自整定及控制輸出 ppppppppppppppppppppppppppppp
  1267. {
  1268. //每200ms獲得一次溫度
  1269. if( get_now_temp_flag == 1)//200ms秒獲得一次溫度
  1270.         {
  1271.         get_now_temp_flag = 0;
  1272.         
  1273.         //lcd_s_12864_light_1;delay_ms(10);lcd_s_12864_light_0;//test

  1274.         PV_value = read_max6675_temper();
  1275.         }

  1276. if     ( pid_tune_flag == 1 )//自整定階段  完畢之后轉(zhuǎn)成pid控制
  1277.         {
  1278.         //自整定ok后自動(dòng)轉(zhuǎn)為pid階段
  1279.         //自整定失敗的情況下 讓基本參數(shù)恢復(fù)默認(rèn)值

  1280.         if( pid_self_sec_flag == 1 )//自整定過程  0.2秒1次
  1281.                 {
  1282.                 pid_self_sec_flag = 0;
  1283.                 dis_tune_once_flag = 1;//0.2秒顯示1次基本信息
  1284.                 //lcd_s_12864_light_0;delay_ms(10);lcd_s_12864_light_1;//test

  1285.                 pid_self_time_sec++;
  1286.                 if(pid_self_time_sec > (3600*3)) // 如果總的自整定時(shí)間大于了3/5=0.6個(gè)小時(shí),則說明整定失敗
  1287.                         {
  1288.                         pid_self_time_sec = 0;                        
  1289.                         //lcd_s_12864_light_0;delay_ms(10);lcd_s_12864_light_1;//test
  1290.                         LcmClear();//清屏
  1291.                         comm_dis_once_flag    = 1;
  1292.                         special_dis_once_flag = 1;
  1293.                         pid_tune_flag = 0;//那么將自動(dòng)退出自整定過程 同時(shí)采用默認(rèn)值  進(jìn)入pid階段
  1294.                         KC = 1.0;//臨界比例系數(shù)  初始默認(rèn)的值
  1295.                         TC = 40; //振蕩周期    初始默認(rèn)的值

  1296.                         }

  1297.                 if(( pid_self_first_status_flag == 1) || ( pid_self_first_status_flag == 0))//0 設(shè)定溫度 低于 當(dāng)前溫度  //1設(shè)定溫度 高于 或者 等于  當(dāng)前溫度  啟動(dòng)加熱
  1298.                         {

  1299.                         //lcd_s_12864_light_0;delay_ms(10);lcd_s_12864_light_1;//test

  1300.                         //基本on/off控制
  1301.                         if( SV_value >= PV_value )//啟動(dòng)加熱
  1302.                                 {
  1303.                                 cool_ack_counter = 0;
  1304.                                 hot_ack_counter++;
  1305.                                 if(hot_ack_counter > 3)//連續(xù)3次都是一樣的結(jié)果 說明確定 SV_value >= PV_value
  1306.                                         {
  1307.                                        
  1308.                                         ssr_con_1;
  1309.                                         //pwm_con_1;//一旦pwm參與將不能通過操作io的形式控制該口線
  1310.                                         set_pwm_value(237);//全速加熱

  1311.                                         if(once_add_1_flag == 0)
  1312.                                                 {
  1313.                                                 once_add_1_flag = 1;
  1314.                                                 zero_across_counter++;
  1315.                                                 
  1316.                                                 //lcd_s_12864_light_0;delay_ms(10);lcd_s_12864_light_1;//test
  1317.                                                 
  1318.                                                 if(zero_across_counter == 3 )
  1319.                                                         {
  1320.                                                         TIME_LOW = pid_self_time_sec - 3;//此時(shí)的時(shí)間不是最低溫度對(duì)應(yīng)的時(shí)間
  1321.                                                         }
  1322.                                                 }
  1323.                                         }
  1324.                                 }
  1325.                         else//當(dāng)前溫度 大于 設(shè)定溫度 停止加熱
  1326.                                 {
  1327.                                 
  1328.                                 //lcd_s_12864_light_0;delay_ms(10);lcd_s_12864_light_1;//test
  1329.                                                                
  1330.                                 hot_ack_counter = 0;
  1331.                                 cool_ack_counter++;
  1332.                                 if(cool_ack_counter > 3)
  1333.                                         {
  1334.                                         ssr_con_0;
  1335.                                         set_pwm_value(40);//不加熱
  1336.                                         if(once_add_1_flag == 1)
  1337.                                                 {
  1338.                                                 once_add_1_flag = 0;
  1339.                                                 zero_across_counter++;
  1340.                                                 if(zero_across_counter == 3 )
  1341.                                                         {
  1342.                                                         TIME_LOW = pid_self_time_sec - 3;//此時(shí)的時(shí)間不是最低溫度對(duì)應(yīng)的時(shí)間
  1343.                                                         }
  1344.                                                 }
  1345.                                         }
  1346.                                 }

  1347.                         //最低溫度 出現(xiàn)在 zero_across_counter = 3 的階段
  1348.                         //最高溫度 出現(xiàn)在 zero_across_counter = 4 的階段
  1349.                         if((zero_across_counter == 3 ) || (zero_across_counter == 4 ))
  1350.                                 {                                
  1351.                                 pid_self_calc_buffer[k_pid_self_counter] = PV_value;
  1352.                                 k_pid_self_counter++;
  1353.                                 if(k_pid_self_counter > 3)//0--3 共4個(gè)元素
  1354.                                         {
  1355.                                         k_pid_self_counter = 0;
  1356.                                         enable_calc_min_max_flag = 1;
  1357.                                         }
  1358.                                 if(enable_calc_min_max_flag == 1)//只要有4個(gè)值,就可以計(jì)算了 后面來的值覆蓋了前面的值
  1359.                                         {
  1360.                                         //去掉最小值 最大值 取剩下2個(gè)值的平均值
  1361.                                         sum_temp = 0.0;  //先清0
  1362.                                         min_temp = 1024.0;
  1363.                                         max_temp = 0.0;
  1364.                                                 
  1365.                                         for(k_max_min = 0; k_max_min < 4; k_max_min++ )
  1366.                                                 {                                                
  1367.                                                 if(pid_self_calc_buffer[k_max_min] <= min_temp)
  1368.                                                         {
  1369.                                                         min_temp = pid_self_calc_buffer[k_max_min];
  1370.                                                         }
  1371.                                                 if(pid_self_calc_buffer[k_max_min] >= max_temp)
  1372.                                                         {
  1373.                                                         max_temp = pid_self_calc_buffer[k_max_min];
  1374.                                                         }                                                
  1375.                                                 sum_temp = (sum_temp + pid_self_calc_buffer[k_max_min]);
  1376.                                                 }
  1377.                                         sum_temp =  sum_temp - min_temp - max_temp ;
  1378.                                        
  1379.                                        
  1380.                                         //pid_self_first_status_flag = 1 時(shí) 最低溫度出現(xiàn)在3階段
  1381.                                         //pid_self_first_status_flag = 0 時(shí) 最低溫度出現(xiàn)在4階段
  1382.                                         if(pid_self_first_status_flag == 1)
  1383.                                                 {
  1384.                                                 if(zero_across_counter == 3 )//最低溫度
  1385.                                                         {
  1386.                                                         aver_temp = (sum_temp/2.0);                                       
  1387.                                                         if( aver_temp <= T_LOW )
  1388.                                                                 {
  1389.                                                                 T_LOW = aver_temp;
  1390.                                                                 }                                
  1391.                                                         }
  1392.                                                 else if(zero_across_counter == 4 )//最高溫度
  1393.                                                         {
  1394.                                                         aver_temp = (sum_temp/2.0);
  1395.                                                         if( aver_temp >= T_Hight )
  1396.                                                                 {
  1397.                                                                 T_Hight = aver_temp;
  1398.                                                                 }
  1399.                                                         }
  1400.                                                 }
  1401.                                         else if(pid_self_first_status_flag == 0)
  1402.                                                 {
  1403.                                                 if(zero_across_counter == 4 )//最低溫度
  1404.                                                         {
  1405.                                                         aver_temp = (sum_temp/2.0);                                       
  1406.                                                         if( aver_temp <= T_LOW )
  1407.                                                                 {
  1408.                                                                 T_LOW = aver_temp;
  1409.                                                                 }                                
  1410.                                                         }
  1411.                                                 else if(zero_across_counter == 3 )//最高溫度
  1412.                                                         {
  1413.                                                         aver_temp = (sum_temp/2.0);
  1414.                                                         if( aver_temp >= T_Hight )
  1415.                                                                 {
  1416.                                                                 T_Hight = aver_temp;
  1417.                                                                 }
  1418.                                                         }
  1419.                                                 }
  1420.                                         }
  1421.                                 }
  1422.                         else if(zero_across_counter == 5 )//4次過0 則說明出現(xiàn)了振蕩 整定成功
  1423.                                 {
  1424.                                 zero_across_counter = 0;                                
  1425.                                 pid_tune_flag = 0;//進(jìn)入pid階段
  1426.                                 //pid_tune_flag = 1;//test
  1427.                                 TIME_Hight = pid_self_time_sec - 3;//此時(shí)的時(shí)間不是最高溫度對(duì)應(yīng)的時(shí)間
  1428.                                 LcmClear();//清屏
  1429.                                 comm_dis_once_flag    = 1;
  1430.                                 special_dis_once_flag = 1;                                
  1431.                                 //dis_4_line_as_null();//清除最后一行的內(nèi)容
  1432.                                 //計(jì)算 T_Hight T_LOW TIME_Hight TIME_LOW 這4個(gè)值
  1433.                                 //根據(jù)以上4個(gè)值  KC 與 TC 的值便會(huì)計(jì)算出來
  1434.                                 
  1435.                                 KC = 12.7/(T_Hight - T_LOW);
  1436.                                 KC = 5.0 * KC;//因?yàn)槭?.2s一次 所以擴(kuò)大5倍
  1437.                                 TC = 1 * (TIME_Hight - TIME_LOW);//如果記錄了 最低溫度 與 最高溫度對(duì)應(yīng)的時(shí)間 那么沿用這個(gè)公式:TC = 2 * (TIME_Hight - TIME_LOW);
  1438.                                 }
  1439.                         }
  1440.                 //顯示具體的值  測(cè)試用
  1441.                 //dis_pid_self_value(); //test
  1442.                 }
  1443.         }
  1444. else if( pid_tune_flag == 0 )//pid 階段  默認(rèn)開機(jī)進(jìn)入此階段
  1445.         {
  1446.         //0 算出 臨界增益 KC 及 振蕩周期 TC
  1447.         // KC = (4*d)/(3.14*A)  ---> d = 5(輸出幅值) ; A = 記錄的溫度最高值與最低值的差值的0.5倍 即:(T_Hight - T_LOW)*0.5
  1448.         // KC = (4*5)/(3.14*((T_Hight - T_LOW)*0.5)) = 40/3.14/(T_Hight - T_LOW) =  12.7/(T_Hight - T_LOW)
  1449.         // KC = 12.7/(T_Hight - T_LOW)
  1450.         // TC = 2 * (TIME_Hight - TIME_LOW) ---> 2 * ( 高點(diǎn)溫度對(duì)應(yīng)時(shí)間 - 低點(diǎn)溫度對(duì)應(yīng)時(shí)間 )
  1451.         // TC = 2 * (TIME_Hight - TIME_LOW)
  1452.         //1 算出 具體的比例系數(shù) 積分秒數(shù) 微分秒數(shù)
  1453.         //Proportion = 0.6*KC
  1454.         //I_value    = 0.5*TC
  1455.         //D_value    = 0.125*TC
  1456.         //2 算出具體的 比例帶 積分系數(shù) 微分系數(shù)
  1457.         //P_value     = (1/Proportion)*100
  1458.         //Integral          = Proportion/I_value = (0.6*KC)/(0.5*TC)
  1459.         //Derivative  = Proportion*D_value = (0.6*KC)*(0.125*TC)  
  1460.         //3顯示用的3個(gè)變量的值
  1461.         //P_value     = (1/Proportion)*100  百分比
  1462.         //I_value     = 0.5*TC                                秒
  1463.         //D_value     = 0.125*TC                        秒
  1464.         //4pid計(jì)算用的3個(gè)變量的值
  1465.         //Proportion  = 0.6*KC
  1466.         //Integral          = Proportion/I_value = (0.6*KC)/(0.5*TC)
  1467.         //Derivative  = Proportion*D_value = (0.6*KC)*(0.125*TC)  
  1468.         
  1469.         //KC = 21.4;//test
  1470.         //TC = 471;//test
  1471.         
  1472.         if(enable_pid_sec_flag == 1)//進(jìn)入pid時(shí),0.2秒計(jì)算1次
  1473.                 {
  1474.   

  1475. ……………………

  1476. …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼

所有資料51hei提供下載:
熱風(fēng) 自整定 PID 51單片機(jī)程序 + 原理圖 PCB.7z (162.76 KB, 下載次數(shù): 289)


評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏17 分享淘帖 頂2 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:228467 發(fā)表于 2020-2-29 09:54 | 只看該作者
好資料,感謝。。
回復(fù)

使用道具 舉報(bào)

板凳
ID:97678 發(fā)表于 2020-2-29 10:03 | 只看該作者
好東西,值得分享。。。。。。
回復(fù)

使用道具 舉報(bào)

地板
ID:196702 發(fā)表于 2020-2-29 10:41 | 只看該作者
慢慢學(xué)習(xí)  謝謝樓主分享!
回復(fù)

使用道具 舉報(bào)

5#
ID:399111 發(fā)表于 2020-2-29 13:08 | 只看該作者
這個(gè)自整定PID,有詳細(xì)解說過程就好了,,,,
回復(fù)

使用道具 舉報(bào)

6#
ID:764574 發(fā)表于 2020-5-30 09:28 | 只看該作者
可惜自己不懂沒有學(xué)過單片機(jī)
回復(fù)

使用道具 舉報(bào)

7#
ID:667717 發(fā)表于 2020-6-19 21:20 | 只看該作者
新手學(xué)習(xí)中
回復(fù)

使用道具 舉報(bào)

8#
ID:430492 發(fā)表于 2021-3-29 22:59 | 只看該作者
自整定PID,還是有點(diǎn)難度的,謝謝樓主分享。!
回復(fù)

使用道具 舉報(bào)

9#
ID:253710 發(fā)表于 2021-7-10 12:25 | 只看該作者
正需要研究自整定,不錯(cuò)的資料,謝謝樓主分享
回復(fù)

使用道具 舉報(bào)

10#
ID:33455 發(fā)表于 2021-8-31 22:08 | 只看該作者
感謝樓主正在搞自整定pid可以借鑒
回復(fù)

使用道具 舉報(bào)

11#
ID:842922 發(fā)表于 2021-12-19 12:21 | 只看該作者
分析了一下感覺程序不會(huì)引起震蕩首先zero_across_counter每次都會(huì)在主循環(huán)里復(fù)位如果溫度在很短的時(shí)間不會(huì)震蕩的話zero_across_counter會(huì)不斷的清零,所以就采集不到最高和最低溫度,如果把zero_across_counter清零語句屏蔽掉zero_across_counter會(huì)瞬間加到5然后在清零,這樣程序會(huì)直接跳到自整定結(jié)束。有沒有人看明白討論一下
回復(fù)

使用道具 舉報(bào)

12#
ID:933601 發(fā)表于 2024-1-25 08:56 | 只看該作者
慢慢學(xué)習(xí)  謝謝樓主分享!
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表