main.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749
  1. #include "STC8XXXX.h"
  2. #include "oled.h"
  3. #include "bmp.h"
  4. #include "timer0.h"
  5. #include "ADC.h"
  6. #include "EEPROM.h"
  7. #include <math.h>
  8. #define vol_channel 0
  9. #define tem_channel 1
  10. #define vcc_channel 15
  11. void prekey(void);//计算按键按下时长
  12. void relkey_page0(void);//对按键操作做出反应
  13. void relkey_page1(void);//对按键操作做出反应
  14. void page0(void);//第0个页面
  15. void page1(void);//第1个页面
  16. void mode0(void);//模式0
  17. void mode1(void);//模式1
  18. void pid_p(void);
  19. unsigned int presstime=500;//长按时间ms
  20. unsigned int tartem=300;//设定温度
  21. unsigned int keyi0=0;//按键0时长
  22. unsigned int keyi1=0;//按键1时长
  23. unsigned int keyi=0;//同时按下时长
  24. unsigned int maxtartem=350;//最大设定温度,可设置
  25. unsigned int mintartem=1;//最小设定温度,可设置
  26. unsigned int i;//for循环变量
  27. unsigned int time;//定时器计时
  28. unsigned int kp=10,ki=20,kd=30;
  29. int pwm=0;
  30. int pagenum=0;
  31. int err=0,lasterr=0;
  32. int integral=0;
  33. int derivative=0;
  34. double showpwm=0;
  35. double showpwm_opp=0;
  36. double powvol;//电源电压统计
  37. double powvol_average[30]=0;//电源电压均值
  38. double realtem=200;//真实温度
  39. double realtem_average[30]=0;//实际温度统计
  40. double p1= 0.00000016;//温度曲线参数1
  41. double p2= -0.00089441;//温度曲线参数2
  42. double p3= 1.91367865;//温度曲线参数3
  43. double p4=-1537.97459730;//温度曲线参数4
  44. double vcc=0;
  45. unsigned char count=0;//电源电压统计计数
  46. unsigned char page = 0;//页面选择
  47. unsigned char modesel=0;//模式选择
  48. unsigned char keyx0,keyx1;
  49. unsigned char page1_iconnum=4;//页面1选项数量
  50. unsigned char page1_PIDnum=4;//PID二级页面选项数量
  51. unsigned char page1_TEMnum=3;//温度二级页面选项数量
  52. unsigned char page1_MODEnum=3;//模式二级页面选项数量
  53. unsigned char eeptart[2]=0;
  54. unsigned char eepkp[2]=0;
  55. unsigned char eepki[2]=0;
  56. unsigned char eepkd[2]=0;
  57. unsigned char eepmaxt[2]=0;
  58. unsigned char eepmint[2]=0;
  59. unsigned char mapline[101]=0;//温度记录
  60. unsigned char numofsam=30;//取样次数
  61. sbit heat=P3^4;//加热
  62. sbit key0=P3^2;//按键0
  63. sbit key1=P3^3;//按键1
  64. bit swclose=1;//按键休眠开关
  65. bit keyj0;//按键0标志位
  66. bit keyj1;//按键1标志位
  67. bit keyj;//同时按下标志位-1
  68. bit keyp;//同时按下标志位-2
  69. bit eeprom_tartem=1;//设定温度标志位
  70. bit eeprom_pid=1;//PID参数标志位
  71. bit eeprom_limtem=1;//温度限制标志位
  72. bit eeprom_mode=1;
  73. bit pageflag;//切换页面标志位
  74. bit blinker;//刷新标志位
  75. bit pidflag;
  76. void init(void)
  77. {
  78. EEPROM_read_n(0x0000,&eeptart[0],2);
  79. EEPROM_read_n(0x0200,&eepkp[0],2);
  80. EEPROM_read_n(0x0204,&eepki[0],2);
  81. EEPROM_read_n(0x0208,&eepkd[0],2);
  82. EEPROM_read_n(0x0400,&eepmaxt[0],2);
  83. EEPROM_read_n(0x0404,&eepmint[0],2);
  84. EEPROM_read_n(0x0600,&modesel,1);
  85. tartem=(256*eeptart[1])+eeptart[0];
  86. kp=(256*(eepkp[1]))+(eepkp[0]);
  87. ki=(256*(eepki[1]))+(eepki[0]);
  88. kd=(256*(eepkd[1]))+(eepkd[0]);
  89. maxtartem=(256*(eepmaxt[1]))+(eepmaxt[0]);
  90. mintartem=(256*(eepmint[1]))+(eepmint[0]);
  91. if(maxtartem>350){maxtartem=350;}
  92. else if(maxtartem<200){maxtartem=200;}
  93. if(mintartem>200){mintartem=0;}
  94. else if(mintartem<0){mintartem=0;}
  95. if(tartem>maxtartem){tartem=maxtartem;}
  96. else if(tartem<mintartem){tartem=mintartem;}
  97. if(kp>1000){kp=500;}
  98. else if(kp<0){kp=0;}
  99. if(ki>1000){ki=500;}
  100. else if(ki<0){ki=0;}
  101. if(kd>1000){kd=500;}
  102. else if(kd<0){kd=0;}
  103. if(modesel>page1_MODEnum-2 || page1_MODEnum<0)
  104. {
  105. modesel=0;
  106. }
  107. P1M0 = 0x00;//00000011
  108. P1M1 = 0xff;//11111100
  109. P3M0 = 0xff;//11111111
  110. P3M1 = 0x0c;//00001100
  111. heat=0;
  112. swclose=0;
  113. powvol=0;
  114. adc_init();//初始化ADC
  115. OLED_Init();//初始化屏幕
  116. Timer0Init();//初始化定时器0
  117. EA=1;
  118. showpwm_opp=100-showpwm;
  119. for(i=0;i<numofsam;i++)
  120. {
  121. powvol_average[i]=get_adc(vol_channel);//读取电源ADC值
  122. realtem_average[i]=transform(get_adc(tem_channel),p1,p2,p3,p4);
  123. }
  124. for(i=0;i<numofsam;i++)
  125. {
  126. vcc+=(1.19*4096)/get_adc(vcc_channel);//计算电源电压
  127. }
  128. vcc/=numofsam;
  129. for(i=0;i<numofsam;i++)
  130. {
  131. powvol+=19*vcc*(powvol_average[i]/4096);
  132. realtem+=realtem_average[i];
  133. }
  134. powvol/=numofsam;
  135. realtem/=numofsam;
  136. }
  137. void main(void)
  138. {
  139. init();
  140. while(1)
  141. {
  142. if(page==0){page0();}//页面0
  143. if(page==1){page1();}//页面1
  144. }
  145. }
  146. void timer0()interrupt 1
  147. {
  148. time++;
  149. time %= 1000;
  150. if(time%1000==0){blinker=0;if(swclose){pidflag=1;}}
  151. if(pwm>=time && swclose){heat=1;}
  152. else/* if(pwm<time || !swclose)*/{heat=0;}
  153. prekey();//检测和计算按键按下时长
  154. }
  155. void prekey(void)
  156. {
  157. if(!key0 && key1 && !keyj)
  158. {keyi0++;keyj0=1;}
  159. if(!key1 && key0 && !keyj)
  160. {keyi1++;keyj1=1;}
  161. if(!key0 && !key1 && keyi0<presstime && keyi1<presstime)
  162. {keyi0=keyi1=keyj0=keyj1=0;keyi++;keyj=1;}
  163. }
  164. void relkey_page0(void)
  165. {
  166. if(!key0 && keyi0>=presstime)//长按0
  167. {
  168. if(tartem<maxtartem)
  169. {
  170. tartem++;
  171. eeprom_tartem=0;
  172. }
  173. }
  174. else if(key0 && keyj0)//短按0
  175. {
  176. if(tartem<maxtartem)
  177. {
  178. tartem++;keyi0=0;keyj0=0;eeprom_tartem=0;
  179. }
  180. }
  181. if(!key1 && keyi1>=presstime)//长按1
  182. {
  183. if(tartem>mintartem)
  184. {
  185. tartem--;
  186. eeprom_tartem=0;
  187. }
  188. }
  189. else if(key1 && keyj1 && !pageflag)//短按1
  190. {
  191. if(tartem>mintartem)
  192. {
  193. tartem--;keyi1=0;keyj1=0;eeprom_tartem=0;
  194. }
  195. }
  196. if(!key0 && !key1 && keyi>=presstime && keyj && keyp)//同时长按
  197. {
  198. page=!page;
  199. swclose=0;
  200. heat=0;
  201. keyj=0;
  202. keyi=0;
  203. keyp=0;
  204. pagenum=1;
  205. }
  206. else if(key1 && key0 && keyj && keyi<presstime && keyp)//同时短按
  207. {
  208. swclose=!swclose;
  209. pagenum=1;
  210. heat=swclose;
  211. integral=0;
  212. pwm=0;
  213. keyj=0;
  214. keyi=0;
  215. }
  216. if(key1 && key0)//松开
  217. {
  218. keyi=0;
  219. keyj=0;
  220. keyp=1;
  221. keyi0=0;
  222. keyi1=0;
  223. keyj0=0;
  224. keyj1=0;
  225. if(eeprom_tartem==0)
  226. {
  227. eeptart[0]=(tartem%256);
  228. eeptart[1]=(tartem/256);
  229. EEPROM_SectorErase(0x0000);
  230. EEPROM_write_n(0x0000,&eeptart[0],2);
  231. eeptart[0]=eeptart[1]=0;
  232. eeprom_tartem=1;
  233. }
  234. }
  235. if(pageflag)
  236. {
  237. pageflag=0;
  238. }
  239. }
  240. void page0(void)
  241. {
  242. OLED_display_clear();
  243. count++;
  244. count%=numofsam;
  245. powvol_average[count]=get_adc(vol_channel);//读取电源ADC值
  246. realtem_average[count]=transform(get_adc(tem_channel),p1,p2,p3,p4);
  247. realtem=0;
  248. powvol=0;
  249. vcc=0;
  250. for(i=0;i<numofsam;i++)
  251. {
  252. vcc+=(1.19*4096)/get_adc(vcc_channel);//计算参考电压
  253. }
  254. vcc/=numofsam;
  255. for(i=0;i<numofsam;i++)
  256. {
  257. powvol+=20*vcc*(powvol_average[i]/4096);//计算电源电压
  258. realtem+=realtem_average[i];//计算实际温度
  259. }
  260. powvol/=numofsam;
  261. realtem/=numofsam;
  262. //realtem=pidflag;
  263. if(realtem>400 || realtem<0)
  264. {
  265. realtem=0;
  266. }
  267. if(pidflag){pid_p();pidflag=0;}
  268. if(modesel==0){mode0();}//显示第0个模式
  269. else if(modesel==1){mode1();}//显示第一个模式
  270. OLED_display();
  271. relkey_page0();
  272. }
  273. void relkey_page1(void)
  274. {
  275. if(!key0 && keyi0>=presstime)//长按0
  276. {
  277. if(pagenum>=100 && pagenum<110)
  278. {
  279. switch(pagenum%10)
  280. {
  281. case 0: if(kp<500) {kp++;eeprom_pid=0;} break;
  282. case 1: if(ki<500) {ki++;eeprom_pid=0;} break;
  283. case 2: if(kd<500) {kd++;eeprom_pid=0;} break;
  284. }
  285. }
  286. else if(pagenum>=200 && pagenum<210)
  287. {
  288. switch(pagenum%10)
  289. {
  290. case 0: if(maxtartem<350) {maxtartem++;eeprom_limtem=0;} break;
  291. case 1: if(mintartem<200) {mintartem++;eeprom_limtem=0;} break;
  292. }
  293. }
  294. }
  295. else if(key0 && keyj0)//短按0
  296. {
  297. if(pagenum<100)
  298. {
  299. pagenum++;
  300. }
  301. else if(pagenum>=100 && pagenum<110)
  302. {
  303. switch(pagenum%10)
  304. {
  305. case 0: if(kp<500) {kp++;eeprom_pid=0;} break;
  306. case 1: if(ki<500) {ki++;eeprom_pid=0;} break;
  307. case 2: if(kd<500) {kd++;eeprom_pid=0;} break;
  308. }
  309. }
  310. else if(pagenum>=200 && pagenum<210)
  311. {
  312. switch(pagenum%10)
  313. {
  314. case 0: if(maxtartem<350) {maxtartem++;eeprom_limtem=0;} break;
  315. case 1: if(mintartem<200) {mintartem++;eeprom_limtem=0;} break;
  316. }
  317. }
  318. if(pagenum==page1_iconnum+1)
  319. {
  320. pagenum=1;
  321. }
  322. else if(pagenum==10+page1_PIDnum)
  323. {
  324. pagenum-=page1_PIDnum;
  325. }
  326. else if(pagenum==20+page1_TEMnum)
  327. {
  328. pagenum-=page1_TEMnum;
  329. }
  330. else if(pagenum==30+page1_MODEnum)
  331. {
  332. pagenum-=page1_TEMnum;
  333. }
  334. keyi0=0;
  335. keyj0=0;
  336. }
  337. if(!key1 && keyi1>=presstime)//长按1
  338. {
  339. if(pagenum>=100 && pagenum<110)
  340. {
  341. switch(pagenum%10)
  342. {
  343. case 0: if(kp>0){kp--;eeprom_pid=0;} break;
  344. case 1: if(ki>0){ki--;eeprom_pid=0;} break;
  345. case 2: if(kd>0){kd--;eeprom_pid=0;} break;
  346. }
  347. }
  348. else if(pagenum>=200 && pagenum<210)
  349. {
  350. switch(pagenum%10)
  351. {
  352. case 0: if(maxtartem>200) {maxtartem--;eeprom_limtem=0;} break;
  353. case 1: if(mintartem>0) {mintartem--;eeprom_limtem=0;} break;
  354. }
  355. }
  356. }
  357. else if(key1 && keyj1)//短按1
  358. {
  359. if(pagenum<100)
  360. {
  361. pagenum--;
  362. }
  363. else if(pagenum>=100 && pagenum<110)
  364. {
  365. switch(pagenum%10)
  366. {
  367. case 0: if(kp>0){kp--;eeprom_pid=0;} break;
  368. case 1: if(ki>0){ki--;eeprom_pid=0;} break;
  369. case 2: if(kd>0){kd--;eeprom_pid=0;} break;
  370. }
  371. }
  372. else if(pagenum>=200 && pagenum<210)
  373. {
  374. switch(pagenum%10)
  375. {
  376. case 0: if(maxtartem>200) {maxtartem--;eeprom_limtem=0;} break;
  377. case 1: if(mintartem>0) {mintartem--;eeprom_limtem=0;} break;
  378. }
  379. }
  380. if(pagenum==0)
  381. {
  382. pagenum=page1_iconnum;
  383. }
  384. else if(pagenum==9)
  385. {
  386. pagenum+=page1_PIDnum;
  387. }
  388. else if(pagenum==19)
  389. {
  390. pagenum+=page1_TEMnum;
  391. }
  392. else if(pagenum==29)
  393. {
  394. pagenum+=page1_TEMnum;
  395. }
  396. keyi1=0;
  397. keyj1=0;
  398. }
  399. if(!key0 && !key1 && keyi>=presstime && keyj && keyp)//同时长按
  400. {
  401. if(pagenum<10)
  402. {
  403. if(tartem<mintartem)
  404. {
  405. tartem=mintartem;
  406. }
  407. else if(tartem>maxtartem)
  408. {
  409. tartem=maxtartem;
  410. }
  411. page=!page;
  412. pageflag=0;
  413. pagenum=0;
  414. swclose=0;
  415. heat=0;
  416. keyj=0;
  417. keyi=0;
  418. keyp=0;
  419. }
  420. else
  421. {
  422. pagenum/=10;
  423. keyj=0;
  424. keyi=0;
  425. keyp=0;
  426. }
  427. }
  428. else if(key1 && key0 && keyj && keyi<presstime && keyp)//同时短按
  429. {
  430. if(pagenum==page1_iconnum)
  431. {
  432. if(tartem<mintartem)
  433. {
  434. tartem=mintartem;
  435. }
  436. else if(tartem>maxtartem)
  437. {
  438. tartem=maxtartem;
  439. }
  440. page=!page;
  441. pageflag=0;
  442. pagenum=0;
  443. swclose=0;
  444. heat=0;
  445. keyj=0;
  446. keyi=0;
  447. keyp=0;
  448. }
  449. else if(pagenum>=100)
  450. {
  451. pagenum=pagenum/10+pagenum%10;
  452. }
  453. else if(pagenum==13 || pagenum==22)
  454. {
  455. pagenum/=10;
  456. }
  457. else if(pagenum<10)
  458. {
  459. pagenum=pagenum*10;
  460. }
  461. else if(pagenum>=30 && pagenum<40)// && pagenum%10!=page1_MODEnum-1)
  462. {
  463. if(pagenum%10!=page1_MODEnum-1)
  464. {
  465. modesel=pagenum%10;
  466. eeprom_mode=0;
  467. }
  468. else
  469. {
  470. pagenum/=10;
  471. }
  472. }
  473. else
  474. {
  475. pagenum=(pagenum/10)*100+pagenum%10;
  476. }
  477. keyj=0;
  478. keyi=0;
  479. }
  480. if(key1 && key0)//松开
  481. {
  482. keyi=0;
  483. keyj=0;
  484. keyp=1;
  485. if(eeprom_pid==0)
  486. {
  487. eepkp[0]=(kp%256);
  488. eepkp[1]=(kp/256);
  489. eepki[0]=(ki%256);
  490. eepki[1]=(ki/256);
  491. eepkd[0]=(kd%256);
  492. eepkd[1]=(kd/256);
  493. EEPROM_SectorErase(0x0200);
  494. EEPROM_write_n(0x0200,&eepkp[0],2);
  495. EEPROM_write_n(0x0204,&eepki[0],2);
  496. EEPROM_write_n(0x0208,&eepkd[0],2);
  497. eeprom_pid=1;
  498. }
  499. if(eeprom_limtem==0)
  500. {
  501. eepmaxt[0]=maxtartem%256;
  502. eepmaxt[1]=maxtartem/256;
  503. eepmint[0]=mintartem%256;
  504. eepmint[1]=mintartem/256;
  505. EEPROM_SectorErase(0x0400);
  506. EEPROM_write_n(0x0400,&eepmaxt[0],2);
  507. EEPROM_write_n(0x0404,&eepmint[0],2);
  508. eeprom_limtem=1;
  509. }
  510. if(eeprom_mode==0)
  511. {
  512. EEPROM_SectorErase(0x0600);
  513. EEPROM_write_n(0x0600,&modesel,1);
  514. eeprom_mode=1;
  515. }
  516. }
  517. if(!pageflag)
  518. {
  519. pageflag=1;
  520. }
  521. }
  522. void page1()
  523. {
  524. OLED_display_clear();
  525. relkey_page1();
  526. //Draw_realnum(pagenum);
  527. if(pagenum<10)//一级页面
  528. {
  529. OLED_DrawBMP_2(109,1,17,48,page1_arrrw);
  530. OLED_DrawBMP_2(2,1,17,48,page1_arrlw);
  531. OLED_DrawBMP_2(48,0,32,64,page1_icon[pagenum-1]);
  532. }
  533. else if(pagenum>=10 && pagenum < 20)//二级页面-PID
  534. {
  535. OLED_DrawBMP_2(109,1,17,48,page1_arrrw);
  536. OLED_DrawBMP_2(2,1,17,48,page1_arrlw);
  537. OLED_DrawBMP_2(52,0,54,32,kpid[pagenum%10]);
  538. if(pagenum%10<page1_PIDnum-1)
  539. {
  540. OLED_DrawBMP_2(22,0,28,56,PIDopp[pagenum%10]);
  541. }
  542. else if(pagenum%10==page1_PIDnum-1)
  543. {
  544. OLED_DrawBMP_2(22,0,28,56,PID[page1_PIDnum-1]);
  545. }
  546. for(i=0;i<page1_PIDnum;i++)
  547. {
  548. if(i!=pagenum%10)
  549. {
  550. OLED_DrawBMP_2((72/(page1_PIDnum-1))*i+22,7,12,8,tab);
  551. }
  552. else
  553. {
  554. OLED_DrawBMP_2((72/(page1_PIDnum-1))*i+22,7,12,8,tab2);
  555. }
  556. }
  557. }
  558. else if(pagenum>=20 && pagenum < 30)//二级页面-温度
  559. {
  560. OLED_DrawBMP_2(109,1,17,48,page1_arrrw);
  561. OLED_DrawBMP_2(2,1,17,48,page1_arrlw);
  562. OLED_DrawBMP_2(52,0,54,32,templimit[pagenum%10]);
  563. if(pagenum%10<page1_TEMnum-1)
  564. {
  565. OLED_DrawBMP_2(22,0,28,56,TEMPopp[pagenum%10]);
  566. }
  567. else if(pagenum%10==page1_TEMnum-1)
  568. {
  569. OLED_DrawBMP_2(22,0,28,56,TEMP[pagenum%10]);
  570. }
  571. for(i=0;i<page1_TEMnum;i++)
  572. {
  573. if(i!=pagenum%10)
  574. {
  575. OLED_DrawBMP_2((72/(page1_TEMnum-1))*i+22,7,12,8,tab);
  576. }
  577. else
  578. {
  579. OLED_DrawBMP_2((72/(page1_TEMnum-1))*i+22,7,12,8,tab2);
  580. }
  581. }
  582. }
  583. else if(pagenum>=30 && pagenum<=40)//二级页面-模式
  584. {
  585. OLED_DrawBMP_2(109,1,17,48,page1_arrrw);
  586. OLED_DrawBMP_2(2,1,17,48,page1_arrlw);
  587. OLED_DrawBMP_2(52,0,54,32,modeexp[pagenum%10]);
  588. if(pagenum%10==page1_MODEnum-1)
  589. {
  590. OLED_DrawBMP_2(22,0,28,56,mode[pagenum%10]);
  591. }
  592. else if(modesel==pagenum%10)
  593. {
  594. OLED_DrawBMP_2(22,0,28,56,mode[pagenum%10]);
  595. }
  596. else
  597. {
  598. OLED_DrawBMP_2(22,0,28,56,modopp[pagenum%10]);
  599. }
  600. for(i=0;i<page1_MODEnum;i++)
  601. {
  602. if(i!=pagenum%10)
  603. {
  604. OLED_DrawBMP_2((72/(page1_MODEnum-1))*i+22,7,12,8,tab);
  605. }
  606. else
  607. {
  608. OLED_DrawBMP_2((72/(page1_MODEnum-1))*i+22,7,12,8,tab2);
  609. }
  610. }
  611. }
  612. else if(pagenum >=100 && pagenum<110)//三级页面-PID设置
  613. {
  614. OLED_DrawBMP_2(109,1,17,48,page1_arrrb);
  615. OLED_DrawBMP_2(2,1,17,48,page1_arrlb);
  616. OLED_DrawBMP_2(22,0,28,56,PID[pagenum%10]);
  617. OLED_DrawBMP_2(52,0,54,32,kpid[pagenum%10]);
  618. //Draw_midnum(53,4,pagenum,4);
  619. switch(pagenum%10)
  620. {
  621. case 0: Draw_midnum(53,4,kp,4); break;
  622. case 1: Draw_midnum(53,4,ki,4); break;
  623. case 2: Draw_midnum(53,4,kd,4); break;
  624. }
  625. for(i=0;i<page1_PIDnum;i++)
  626. {
  627. if(i!=pagenum%10)
  628. {
  629. OLED_DrawBMP_2((72/(page1_PIDnum-1))*i+22,7,12,8,tab);
  630. }
  631. else
  632. {
  633. OLED_DrawBMP_2((72/(page1_PIDnum-1))*i+22,7,12,8,tab2);
  634. }
  635. }
  636. }
  637. else if(pagenum>=200 && pagenum<210)//三级页面-温度设置
  638. {
  639. OLED_DrawBMP_2(109,1,17,48,page1_arrrb);
  640. OLED_DrawBMP_2(2,1,17,48,page1_arrlb);
  641. OLED_DrawBMP_2(22,0,28,56,TEMP[pagenum%10]);
  642. OLED_DrawBMP_2(52,0,54,32,templimit[pagenum%10]);
  643. switch(pagenum%10)
  644. {
  645. case 0: Draw_midnum(53,4,maxtartem,3); break;
  646. case 1: Draw_midnum(53,4,mintartem,3); break;
  647. }
  648. for(i=0;i<page1_TEMnum;i++)
  649. {
  650. if(i!=pagenum%10)
  651. {
  652. OLED_DrawBMP_2((72/(page1_TEMnum-1))*i+22,7,12,8,tab);
  653. }
  654. else
  655. {
  656. OLED_DrawBMP_2((72/(page1_TEMnum-1))*i+22,7,12,8,tab2);
  657. }
  658. }
  659. }
  660. OLED_display();
  661. }
  662. void mode0()
  663. {
  664. Draw_realnum(0,0,realtem);//显示测量温度
  665. Draw_tarnum(48,3,tartem,1);//绘制设定温度到缓存
  666. Draw_voltage(48,0,powvol);//绘制电源电压到缓存
  667. if(realtem>=mintartem && realtem <= maxtartem)
  668. {
  669. Draw_Loading(8,6,0,((realtem-mintartem)*100)/(maxtartem-mintartem));//绘制左侧进度条
  670. }
  671. else if(realtem>maxtartem)
  672. {
  673. Draw_Loading(8,6,0,100);
  674. }
  675. else
  676. {
  677. Draw_Loading(8,6,0,0);//绘制左侧进度条
  678. }
  679. if(showpwm!=pwm && swclose){showpwm_opp=(pwm/10-showpwm);showpwm_opp=showpwm_opp*0.8;showpwm=pwm/10-showpwm_opp;}
  680. else if(!swclose){showpwm*=0.8;}
  681. Draw_Loading(65,6,1,showpwm+1);//绘制右侧进度条
  682. Draw_Sign(11,48,((tartem-(mintartem))*100)/((maxtartem)-(mintartem)),tartem,realtem);//绘制左侧进度条标记
  683. if(swclose==0){OLED_DrawBMP_2(84, 0, 42, 48, &state[2]);}
  684. else if(err>5){OLED_DrawBMP_2(84, 0, 42, 48, &state[1]);}
  685. else{OLED_DrawBMP_2(84, 0, 42, 48, &state[0]);}
  686. }
  687. void mode1()
  688. {
  689. Draw_tarnum(0,0,realtem,0);//绘制设定温度到缓存
  690. Draw_tarnum(0,3,tartem,0);//绘制设定温度到缓存
  691. if(swclose==0){OLED_DrawBMP_2(4,6,16,16,switch_clo);}
  692. else{OLED_DrawBMP_2(4,6,16,16,switch_ope);}
  693. //OLED_DrawLine(26,60,128,60,1);
  694. OLED_DrawBMP_2(25,0,103,64,xy);//绘制坐标轴
  695. for(i=26;i<128;i++)
  696. {
  697. if((i+1)%4==0)
  698. {
  699. OLED_DrawPixel(i,60-((tartem*60)/(maxtartem-mintartem)),1);
  700. }
  701. }
  702. if(!blinker)
  703. {
  704. for(i=0;i<100;i++)
  705. {
  706. mapline[i]=mapline[i+1];
  707. }
  708. blinker=1;
  709. mapline[100]=realtem;
  710. }
  711. for(i=0;i<101;i++)
  712. {
  713. OLED_DrawPixel(27+i,60-((mapline[i]*60)/maxtartem),1);
  714. }
  715. }
  716. void pid_p(void)
  717. {
  718. err=tartem-realtem;//误差
  719. if(fabs(err)<10){integral=integral+err;}
  720. derivative = err-lasterr;//微分
  721. if(integral>500){integral=500;}
  722. if(integral<-500){integral=-500;}//避免积分值太大
  723. if(kp*err>1000){err=1000/kp;}
  724. if(ki*integral>1000){integral=1000/ki;}
  725. if(kd*derivative>1000){integral=1000/kd;}
  726. pwm=kp*err+ki*integral+kd*derivative;
  727. if(pwm>1000){pwm=1000;}
  728. if(pwm<0){pwm=0;}//防止溢出
  729. lasterr=err;
  730. }