lcd_drv.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. #include "board.h"
  2. uint8_t instant_flow_zero_flag = 0; // 瞬时流量为零标志(1: 瞬时流量为0,0: 瞬时流量非零)
  3. extern uint8_t LCD_CharAry[];
  4. #define LCD_POINT_Dx 0x10u
  5. void lcd_init(void)
  6. {
  7. // LCD_COM0 : PA09
  8. // LCD_COM1 : PA10
  9. // LCD_COM2 : PA11
  10. // LCD_COM3 : PA12
  11. GpioInit(PA09_AF0, GPIO_ANA);
  12. GpioInit(PA10_AF0, GPIO_ANA);
  13. GpioInit(PA11_AF0, GPIO_ANA);
  14. GpioInit(PA12_AF0, GPIO_ANA);
  15. // LCD_SEG0 : PA08
  16. // LCD_SEG1 : PC09
  17. // LCD_SEG2 : PC08
  18. // LCD_SEG3 : PC07
  19. // LCD_SEG4 : PC06
  20. // LCD_SEG5 : PB15
  21. // LCD_SEG6 : PB14
  22. // LCD_SEG7 : PB13
  23. GpioInit(PA08_AF0, GPIO_ANA);
  24. GpioInit(PC09_AF0, GPIO_ANA);
  25. GpioInit(PC08_AF0, GPIO_ANA);
  26. GpioInit(PC07_AF0, GPIO_ANA);
  27. GpioInit(PC06_AF0, GPIO_ANA);
  28. GpioInit(PB15_AF0, GPIO_ANA);
  29. GpioInit(PB14_AF0, GPIO_ANA);
  30. GpioInit(PB13_AF0, GPIO_ANA);
  31. // LCD_SEG8 : PB12
  32. // LCD_SEG9 : PB11
  33. // LCD_SEG10: PB10
  34. // LCD_SEG11: PB02
  35. // LCD_SEG12: PB01
  36. // LCD_SEG13: PB00
  37. // LCD_SEG14: PC05
  38. // LCD_SEG15: PC04
  39. GpioInit(PB12_AF0, GPIO_ANA);
  40. GpioInit(PB11_AF0, GPIO_ANA);
  41. GpioInit(PB10_AF0, GPIO_ANA);
  42. GpioInit(PB02_AF0, GPIO_ANA);
  43. GpioInit(PB01_AF0, GPIO_ANA);
  44. GpioInit(PB00_AF0, GPIO_ANA);
  45. GpioInit(PC05_AF0, GPIO_ANA);
  46. GpioInit(PC04_AF0, GPIO_ANA);
  47. // LCD_SEG16: PA07
  48. // LCD_SEG17: PA06
  49. // LCD_SEG18: PA05
  50. // LCD_SEG19: PA04
  51. // LCD_SEG20: PA03
  52. // LCD_SEG21: PA02
  53. // LCD_SEG22: PA01
  54. // LCD_SEG23: PA00
  55. GpioInit(PA07_AF0, GPIO_ANA);
  56. GpioInit(PA06_AF0, GPIO_ANA);
  57. GpioInit(PA05_AF0, GPIO_ANA);
  58. GpioInit(PA04_AF0, GPIO_ANA);
  59. GpioInit(PA03_AF0, GPIO_ANA);
  60. GpioInit(PA02_AF0, GPIO_ANA);
  61. GpioInit(PA01_AF0, GPIO_ANA);
  62. GpioInit(PA00_AF0, GPIO_ANA);
  63. PeriClk_MutEnable(PeriClk_Lcd);
  64. M0P_LCD->CR1 = (0u << 8) | // 0:mode0; 1:mode1;
  65. (0u << 7) | // 0:RCL; 1:XTL;
  66. (0u << 6); // blink, 0:disable; 1:enable;
  67. // SEG out, 0:enable; 1:disable
  68. M0P_LCD->POEN0 = 0xFF000000u;
  69. #ifdef LCD_EXT_CAP
  70. // VLCD1:PB06(SEG32)
  71. // VLCD2:PB05(SEG33)
  72. // VLCD3:PB04(SEG34)
  73. // VLCDH:PB03(SEG35)
  74. GpioInit(PB06_AF0, GPIO_ANA);
  75. GpioInit(PB05_AF0, GPIO_ANA);
  76. GpioInit(PB04_AF0, GPIO_ANA);
  77. GpioInit(PB03_AF0, GPIO_ANA);
  78. M0P_LCD->POEN1 = 0x001FEFF0u;
  79. #else
  80. // COM out, 0:enable; 1:disable
  81. M0P_LCD->POEN1 = 0x001FFFFFu;
  82. #endif
  83. M0P_LCD->RAM0 = 0x00000000;
  84. M0P_LCD->RAM1 = 0x00000000;
  85. M0P_LCD->RAM2 = 0x00000000;
  86. M0P_LCD->RAM3 = 0x00000000;
  87. M0P_LCD->RAM4 = 0x00000000;
  88. M0P_LCD->RAM5 = 0x00000000;
  89. M0P_LCD->RAM6 = 0x00000000;
  90. M0P_LCD->RAM7 = 0x00000000;
  91. // BIAS 1/3, DUTY 1/4
  92. M0P_LCD->CR0 = (0u << 12) | // Constrast, 0x0~0xf, more small more brighter
  93. #ifdef LCD_EXT_CAP
  94. (1u << 9) | // BSEL, 0:ext resist; 1:ext cap; 2:internal mid p; 4:internal little; 6:internal big
  95. #else
  96. (4u << 9) | // BSEL, 0:ext resist; 1:ext cap; 2:internal mid p; 4:internal little; 6:internal big
  97. #endif
  98. (3u << 6) | // Duty, 0:static; 1:1/2; 2:1/3; 3:1/4; 5:1/6; 7:1/8;
  99. (0u << 5) | // Bias, 0:1/3; 1:1/2;
  100. (3u << 3) | // bump freq, 0:2KHz; 1:4KHz; 2:8KHz; 3:16KHz
  101. (2u << 1) | // com freq, 0:64Hz, 1:128Hz, 2:256Hz, 3:512Hz
  102. (1u << 0); // EN, 0:disable; 1:enable;
  103. // wait 50ms for LCD tSTAB
  104. us_delay(50000);
  105. }
  106. uint8_t DispMem_Dec[10]; // D1~D10, [0] for MSB; [9] for LSB;
  107. uint32_t DispMem_Status = 0x0u;
  108. void LCD_ClrDec(void)
  109. {
  110. uint8_t i;
  111. for (i = 0; i < 10; i++)
  112. {
  113. DispMem_Dec[i] = 0x00u;
  114. }
  115. }
  116. uint32_t LCD_D2RAM(uint8_t d0, uint8_t d1)
  117. {
  118. uint32_t d32;
  119. d32 = d1;
  120. d32 <<= 4;
  121. d32 |= d1;
  122. d32 <<= 12;
  123. d32 |= d0;
  124. d32 <<= 4;
  125. d32 |= d0;
  126. d32 &= 0x0F0F0F0Fu;
  127. return (d32);
  128. }
  129. void LCD_Update(void)
  130. {
  131. uint32_t Tu32;
  132. Tu32 = 0x0u;
  133. if (DispMem_Status & LCD_STATUS_BAR5)
  134. {
  135. Tu32 |= 0x00000100u;
  136. }
  137. if (DispMem_Status & LCD_STATUS_CIRCLE)
  138. {
  139. Tu32 |= 0x01000000u;
  140. }
  141. M0P_LCD->RAM0 = LCD_D2RAM(DispMem_Dec[0], DispMem_Dec[1]) | Tu32;
  142. Tu32 = 0x0u;
  143. if (DispMem_Status & LCD_STATUS_CUM)
  144. {
  145. Tu32 |= 0x00000100u;
  146. }
  147. M0P_LCD->RAM1 = LCD_D2RAM(DispMem_Dec[2], DispMem_Dec[3]) | Tu32;
  148. M0P_LCD->RAM2 = LCD_D2RAM(DispMem_Dec[4], DispMem_Dec[5]);
  149. M0P_LCD->RAM3 = LCD_D2RAM(DispMem_Dec[6], DispMem_Dec[7]);
  150. Tu32 = 0x0u;
  151. if (DispMem_Status & LCD_STATUS_M3)
  152. {
  153. Tu32 |= 0x01000000u;
  154. }
  155. M0P_LCD->RAM4 = LCD_D2RAM(DispMem_Dec[8], DispMem_Dec[9]) | Tu32;
  156. M0P_LCD->RAM5 = DispMem_Status & 0x0F0F0F0Fu;
  157. }
  158. ///////disp all lcd segment//////////
  159. // param:none
  160. ///////////////////
  161. void lcd_show_all(void)
  162. {
  163. // wait for add code here
  164. uint8_t i;
  165. for (i = 0; i < 10; i++)
  166. {
  167. DispMem_Dec[i] = 0xffu;
  168. }
  169. DispMem_Status = 0xffffffff;
  170. }
  171. void LCD_ClrStatus(void) //add by HBR 20260604
  172. {
  173. DispMem_Status = 0;
  174. }
  175. void LCD_ClrAll(void)
  176. {
  177. uint8_t i;
  178. for (i = 0; i < 10; i++)
  179. {
  180. DispMem_Dec[i] = 0x00u;
  181. }
  182. DispMem_Status = 0;
  183. }
  184. // pos: start position, range [0, 9]
  185. // dl : data number length, range [1,10]
  186. // pos + dl <= 10
  187. void LCD_DispDec(uint32_t val, uint8_t pos, uint8_t dl)
  188. {
  189. uint32_t base;
  190. uint8_t i;
  191. uint8_t TmpU8;
  192. uint8_t HeadZero;
  193. HeadZero = 1;
  194. base = 1;
  195. for (i = 1; i < dl; i++)
  196. {
  197. base *= 10;
  198. }
  199. for (i = 0; i < dl; i++)
  200. {
  201. TmpU8 = val / base;
  202. if (TmpU8 > 9 || (TmpU8 == 0 && HeadZero && i < (dl - 1)))
  203. {
  204. DispMem_Dec[i + pos] = 0x00u;
  205. }
  206. else
  207. {
  208. HeadZero = 0;
  209. DispMem_Dec[i + pos] = LCD_CharAry[TmpU8 + '0'];
  210. }
  211. val -= TmpU8 * base;
  212. base /= 10;
  213. }
  214. }
  215. void LCD_DispDecAllPos(uint32_t val, uint8_t pos, uint8_t dl)
  216. {
  217. uint32_t base;
  218. uint8_t i;
  219. uint8_t TmpU8;
  220. base = 1;
  221. for (i = 1; i < dl; i++)
  222. {
  223. base *= 10;
  224. }
  225. for (i = 0; i < dl; i++)
  226. {
  227. TmpU8 = val / base;
  228. DispMem_Dec[i + pos] = LCD_CharAry[TmpU8 + '0'];
  229. val -= TmpU8 * base;
  230. base /= 10;
  231. }
  232. }
  233. // pos: start position, range [0, 9]
  234. // dl : data number length, range [1,10]
  235. // il : integer number length, range [1,10]
  236. // pos + dl <= 10
  237. // 1<= il <=dl
  238. // 4<= pos + il <=10
  239. void LCD_DispFloat(float val, uint8_t pos, uint8_t dl, uint8_t il)
  240. {
  241. uint32_t Tu32;
  242. int8_t i;
  243. uint32_t base;
  244. uint8_t TmpU8;
  245. uint8_t HeadZero;
  246. i = dl - il;
  247. while (i--)
  248. {
  249. val *= 10;
  250. }
  251. Tu32 = (uint32_t)(val + 0.5f);
  252. if(Tu32<1)
  253. {
  254. instant_flow_zero_flag=1;
  255. }
  256. HeadZero = 1;
  257. base = 1;
  258. for (i = 1; i < dl; i++)
  259. {
  260. base *= 10;
  261. }
  262. for (i = 0; i < dl; i++)
  263. {
  264. TmpU8 = Tu32 / base;
  265. if (TmpU8 > 9 || (TmpU8 == 0 && HeadZero && i < (il - 1)))
  266. {
  267. DispMem_Dec[i + pos] = 0x00u;
  268. }
  269. else
  270. {
  271. HeadZero = 0;
  272. if (i == (il - 1) && (pos + i) >= 3 && (pos + i) <= 8)
  273. {
  274. DispMem_Dec[i + pos] = LCD_CharAry[TmpU8 + '0'] | LCD_POINT_Dx;
  275. }
  276. else
  277. {
  278. DispMem_Dec[i + pos] = LCD_CharAry[TmpU8 + '0'];
  279. }
  280. }
  281. Tu32 -= TmpU8 * base;
  282. base /= 10;
  283. }
  284. }
  285. //modify by HBR 20260609
  286. // pos: start position, range [0, 9]
  287. // dl : data number length, range [1,10]
  288. // il : integer number length, range [1,10]
  289. // pos + dl <= 10
  290. // 1<= il <=dl
  291. // 4<= pos + il <=10
  292. void LCD_DispDouble(double val, uint8_t pos, uint8_t dl, uint8_t il)
  293. {
  294. static double last_val=0; //add by HBR 20260604
  295. static uint8_t last_pos=0;
  296. static uint8_t last_dl=0;
  297. static uint8_t last_il=0;
  298. if( val==last_val && pos==last_pos && dl==last_dl && il==last_il&&cumulative_flow_display_update_flag==0)
  299. {
  300. return;
  301. }
  302. cumulative_flow_display_update_flag=0;
  303. uint32_t Tu32;
  304. int8_t i;
  305. uint32_t base;
  306. uint8_t TmpU8;
  307. uint8_t HeadZero;
  308. uint32_t int_part=(uint32_t)val; //add by HBR 20260604
  309. double frac_part = val - (double)int_part;
  310. i = dl - il;
  311. uint8_t frac_digits = dl - il; // 小数位数 //add by HBR 20260604
  312. // ---- 将小数部分转为整数 ----
  313. // 例如 0.45 要显示 2 位小数 → 乘以 100 再四舍五入 → 45
  314. uint32_t frac_int = 0;
  315. if (frac_digits > 0) {
  316. double mul = 1.0;
  317. for (i = 0; i < frac_digits; i++) {
  318. mul *= 10.0;
  319. }
  320. frac_int = (uint32_t)(frac_part * mul + 0.5); // 四舍五入后的整数小数部分 //add by HBR 20260604
  321. }
  322. HeadZero = 1;
  323. base = 1;
  324. for(i=1; i<il; i++){
  325. base *= 10;
  326. }
  327. Tu32 = int_part; //add by HBR 20260604
  328. if(il==4)
  329. {
  330. if(Tu32 < 10000) //add by HBR 20260604
  331. {
  332. HeadZero = 1;
  333. }
  334. else
  335. {
  336. HeadZero = 0; //add by HBR 20260604
  337. }
  338. Tu32 = int_part % 10000; //截断大于5位整数部分
  339. }
  340. for(i=0; i<il; i++){
  341. TmpU8 = Tu32/base;
  342. if (TmpU8>9 || (TmpU8==0 && HeadZero && i<(il-1))){
  343. DispMem_Dec[i+pos] = 0x00u;
  344. } else {
  345. HeadZero = 0;
  346. if (i==(il-1) && ((pos + i)>=3 && (pos + i)<=8) || i==(il-1) && ((pos + i)>=12 && (pos + i)<=16)){
  347. DispMem_Dec[i+pos] = LCD_CharAry[TmpU8 + '0'] | LCD_POINT_Dx;
  348. }
  349. else {
  350. DispMem_Dec[i+pos] = LCD_CharAry[TmpU8 + '0'];
  351. }
  352. }
  353. Tu32 -= TmpU8*base;
  354. base /= 10;
  355. }
  356. if (frac_digits > 0) {
  357. Tu32 = frac_int;
  358. base = 1;
  359. for (i = 1; i < frac_digits; i++) {
  360. base *= 10;
  361. }
  362. for (i = 0; i < frac_digits; i++) {
  363. TmpU8 = Tu32 / base;
  364. // 小数部分强制显示,即使是 0 也显示
  365. DispMem_Dec[pos + il + i] = LCD_CharAry[TmpU8 + '0'];
  366. Tu32 -= TmpU8 * base;
  367. base /= 10;
  368. }
  369. }
  370. last_val=val;
  371. last_pos=pos;
  372. last_dl=dl;
  373. last_il=il;
  374. }
  375. void LCD_DispStr(char *str, uint8_t pos, uint8_t dl)
  376. {
  377. uint8_t i;
  378. for (i = 0; i < dl; i++)
  379. {
  380. DispMem_Dec[i + pos] = LCD_CharAry[str[i]];
  381. }
  382. }
  383. void LCD_DispPoint(uint8_t num)
  384. {
  385. DispMem_Dec[num] |= LCD_POINT_Dx;
  386. }