#include "board.h" uint8_t instant_flow_zero_flag = 0; // 瞬时流量为零标志(1: 瞬时流量为0,0: 瞬时流量非零) extern uint8_t LCD_CharAry[]; #define LCD_POINT_Dx 0x10u void lcd_init(void) { // LCD_COM0 : PA09 // LCD_COM1 : PA10 // LCD_COM2 : PA11 // LCD_COM3 : PA12 GpioInit(PA09_AF0, GPIO_ANA); GpioInit(PA10_AF0, GPIO_ANA); GpioInit(PA11_AF0, GPIO_ANA); GpioInit(PA12_AF0, GPIO_ANA); // LCD_SEG0 : PA08 // LCD_SEG1 : PC09 // LCD_SEG2 : PC08 // LCD_SEG3 : PC07 // LCD_SEG4 : PC06 // LCD_SEG5 : PB15 // LCD_SEG6 : PB14 // LCD_SEG7 : PB13 GpioInit(PA08_AF0, GPIO_ANA); GpioInit(PC09_AF0, GPIO_ANA); GpioInit(PC08_AF0, GPIO_ANA); GpioInit(PC07_AF0, GPIO_ANA); GpioInit(PC06_AF0, GPIO_ANA); GpioInit(PB15_AF0, GPIO_ANA); GpioInit(PB14_AF0, GPIO_ANA); GpioInit(PB13_AF0, GPIO_ANA); // LCD_SEG8 : PB12 // LCD_SEG9 : PB11 // LCD_SEG10: PB10 // LCD_SEG11: PB02 // LCD_SEG12: PB01 // LCD_SEG13: PB00 // LCD_SEG14: PC05 // LCD_SEG15: PC04 GpioInit(PB12_AF0, GPIO_ANA); GpioInit(PB11_AF0, GPIO_ANA); GpioInit(PB10_AF0, GPIO_ANA); GpioInit(PB02_AF0, GPIO_ANA); GpioInit(PB01_AF0, GPIO_ANA); GpioInit(PB00_AF0, GPIO_ANA); GpioInit(PC05_AF0, GPIO_ANA); GpioInit(PC04_AF0, GPIO_ANA); // LCD_SEG16: PA07 // LCD_SEG17: PA06 // LCD_SEG18: PA05 // LCD_SEG19: PA04 // LCD_SEG20: PA03 // LCD_SEG21: PA02 // LCD_SEG22: PA01 // LCD_SEG23: PA00 GpioInit(PA07_AF0, GPIO_ANA); GpioInit(PA06_AF0, GPIO_ANA); GpioInit(PA05_AF0, GPIO_ANA); GpioInit(PA04_AF0, GPIO_ANA); GpioInit(PA03_AF0, GPIO_ANA); GpioInit(PA02_AF0, GPIO_ANA); GpioInit(PA01_AF0, GPIO_ANA); GpioInit(PA00_AF0, GPIO_ANA); PeriClk_MutEnable(PeriClk_Lcd); M0P_LCD->CR1 = (0u << 8) | // 0:mode0; 1:mode1; (0u << 7) | // 0:RCL; 1:XTL; (0u << 6); // blink, 0:disable; 1:enable; // SEG out, 0:enable; 1:disable M0P_LCD->POEN0 = 0xFF000000u; #ifdef LCD_EXT_CAP // VLCD1:PB06(SEG32) // VLCD2:PB05(SEG33) // VLCD3:PB04(SEG34) // VLCDH:PB03(SEG35) GpioInit(PB06_AF0, GPIO_ANA); GpioInit(PB05_AF0, GPIO_ANA); GpioInit(PB04_AF0, GPIO_ANA); GpioInit(PB03_AF0, GPIO_ANA); M0P_LCD->POEN1 = 0x001FEFF0u; #else // COM out, 0:enable; 1:disable M0P_LCD->POEN1 = 0x001FFFFFu; #endif M0P_LCD->RAM0 = 0x00000000; M0P_LCD->RAM1 = 0x00000000; M0P_LCD->RAM2 = 0x00000000; M0P_LCD->RAM3 = 0x00000000; M0P_LCD->RAM4 = 0x00000000; M0P_LCD->RAM5 = 0x00000000; M0P_LCD->RAM6 = 0x00000000; M0P_LCD->RAM7 = 0x00000000; // BIAS 1/3, DUTY 1/4 M0P_LCD->CR0 = (0u << 12) | // Constrast, 0x0~0xf, more small more brighter #ifdef LCD_EXT_CAP (1u << 9) | // BSEL, 0:ext resist; 1:ext cap; 2:internal mid p; 4:internal little; 6:internal big #else (4u << 9) | // BSEL, 0:ext resist; 1:ext cap; 2:internal mid p; 4:internal little; 6:internal big #endif (3u << 6) | // Duty, 0:static; 1:1/2; 2:1/3; 3:1/4; 5:1/6; 7:1/8; (0u << 5) | // Bias, 0:1/3; 1:1/2; (3u << 3) | // bump freq, 0:2KHz; 1:4KHz; 2:8KHz; 3:16KHz (2u << 1) | // com freq, 0:64Hz, 1:128Hz, 2:256Hz, 3:512Hz (1u << 0); // EN, 0:disable; 1:enable; // wait 50ms for LCD tSTAB us_delay(50000); } uint8_t DispMem_Dec[10]; // D1~D10, [0] for MSB; [9] for LSB; uint32_t DispMem_Status = 0x0u; void LCD_ClrDec(void) { uint8_t i; for (i = 0; i < 10; i++) { DispMem_Dec[i] = 0x00u; } } uint32_t LCD_D2RAM(uint8_t d0, uint8_t d1) { uint32_t d32; d32 = d1; d32 <<= 4; d32 |= d1; d32 <<= 12; d32 |= d0; d32 <<= 4; d32 |= d0; d32 &= 0x0F0F0F0Fu; return (d32); } void LCD_Update(void) { uint32_t Tu32; Tu32 = 0x0u; if (DispMem_Status & LCD_STATUS_BAR5) { Tu32 |= 0x00000100u; } if (DispMem_Status & LCD_STATUS_CIRCLE) { Tu32 |= 0x01000000u; } M0P_LCD->RAM0 = LCD_D2RAM(DispMem_Dec[0], DispMem_Dec[1]) | Tu32; Tu32 = 0x0u; if (DispMem_Status & LCD_STATUS_CUM) { Tu32 |= 0x00000100u; } M0P_LCD->RAM1 = LCD_D2RAM(DispMem_Dec[2], DispMem_Dec[3]) | Tu32; M0P_LCD->RAM2 = LCD_D2RAM(DispMem_Dec[4], DispMem_Dec[5]); M0P_LCD->RAM3 = LCD_D2RAM(DispMem_Dec[6], DispMem_Dec[7]); Tu32 = 0x0u; if (DispMem_Status & LCD_STATUS_M3) { Tu32 |= 0x01000000u; } M0P_LCD->RAM4 = LCD_D2RAM(DispMem_Dec[8], DispMem_Dec[9]) | Tu32; M0P_LCD->RAM5 = DispMem_Status & 0x0F0F0F0Fu; } ///////disp all lcd segment////////// // param:none /////////////////// void lcd_show_all(void) { // wait for add code here uint8_t i; for (i = 0; i < 10; i++) { DispMem_Dec[i] = 0xffu; } DispMem_Status = 0xffffffff; } void LCD_ClrStatus(void) //add by HBR 20260604 { DispMem_Status = 0; } void LCD_ClrAll(void) { uint8_t i; for (i = 0; i < 10; i++) { DispMem_Dec[i] = 0x00u; } DispMem_Status = 0; } // pos: start position, range [0, 9] // dl : data number length, range [1,10] // pos + dl <= 10 void LCD_DispDec(uint32_t val, uint8_t pos, uint8_t dl) { uint32_t base; uint8_t i; uint8_t TmpU8; uint8_t HeadZero; HeadZero = 1; base = 1; for (i = 1; i < dl; i++) { base *= 10; } for (i = 0; i < dl; i++) { TmpU8 = val / base; if (TmpU8 > 9 || (TmpU8 == 0 && HeadZero && i < (dl - 1))) { DispMem_Dec[i + pos] = 0x00u; } else { HeadZero = 0; DispMem_Dec[i + pos] = LCD_CharAry[TmpU8 + '0']; } val -= TmpU8 * base; base /= 10; } } void LCD_DispDecAllPos(uint32_t val, uint8_t pos, uint8_t dl) { uint32_t base; uint8_t i; uint8_t TmpU8; base = 1; for (i = 1; i < dl; i++) { base *= 10; } for (i = 0; i < dl; i++) { TmpU8 = val / base; DispMem_Dec[i + pos] = LCD_CharAry[TmpU8 + '0']; val -= TmpU8 * base; base /= 10; } } // pos: start position, range [0, 9] // dl : data number length, range [1,10] // il : integer number length, range [1,10] // pos + dl <= 10 // 1<= il <=dl // 4<= pos + il <=10 void LCD_DispFloat(float val, uint8_t pos, uint8_t dl, uint8_t il) { uint32_t Tu32; int8_t i; uint32_t base; uint8_t TmpU8; uint8_t HeadZero; i = dl - il; while (i--) { val *= 10; } Tu32 = (uint32_t)(val + 0.5f); if(Tu32<1) { instant_flow_zero_flag=1; } HeadZero = 1; base = 1; for (i = 1; i < dl; i++) { base *= 10; } for (i = 0; i < dl; i++) { TmpU8 = Tu32 / base; if (TmpU8 > 9 || (TmpU8 == 0 && HeadZero && i < (il - 1))) { DispMem_Dec[i + pos] = 0x00u; } else { HeadZero = 0; if (i == (il - 1) && (pos + i) >= 3 && (pos + i) <= 8) { DispMem_Dec[i + pos] = LCD_CharAry[TmpU8 + '0'] | LCD_POINT_Dx; } else { DispMem_Dec[i + pos] = LCD_CharAry[TmpU8 + '0']; } } Tu32 -= TmpU8 * base; base /= 10; } } //modify by HBR 20260609 // pos: start position, range [0, 9] // dl : data number length, range [1,10] // il : integer number length, range [1,10] // pos + dl <= 10 // 1<= il <=dl // 4<= pos + il <=10 void LCD_DispDouble(double val, uint8_t pos, uint8_t dl, uint8_t il) { static double last_val=0; //add by HBR 20260604 static uint8_t last_pos=0; static uint8_t last_dl=0; static uint8_t last_il=0; if( val==last_val && pos==last_pos && dl==last_dl && il==last_il&&cumulative_flow_display_update_flag==0) { return; } cumulative_flow_display_update_flag=0; uint32_t Tu32; int8_t i; uint32_t base; uint8_t TmpU8; uint8_t HeadZero; uint32_t int_part=(uint32_t)val; //add by HBR 20260604 double frac_part = val - (double)int_part; i = dl - il; uint8_t frac_digits = dl - il; // 小数位数 //add by HBR 20260604 // ---- 将小数部分转为整数 ---- // 例如 0.45 要显示 2 位小数 → 乘以 100 再四舍五入 → 45 uint32_t frac_int = 0; if (frac_digits > 0) { double mul = 1.0; for (i = 0; i < frac_digits; i++) { mul *= 10.0; } frac_int = (uint32_t)(frac_part * mul + 0.5); // 四舍五入后的整数小数部分 //add by HBR 20260604 } HeadZero = 1; base = 1; for(i=1; i9 || (TmpU8==0 && HeadZero && i<(il-1))){ DispMem_Dec[i+pos] = 0x00u; } else { HeadZero = 0; if (i==(il-1) && ((pos + i)>=3 && (pos + i)<=8) || i==(il-1) && ((pos + i)>=12 && (pos + i)<=16)){ DispMem_Dec[i+pos] = LCD_CharAry[TmpU8 + '0'] | LCD_POINT_Dx; } else { DispMem_Dec[i+pos] = LCD_CharAry[TmpU8 + '0']; } } Tu32 -= TmpU8*base; base /= 10; } if (frac_digits > 0) { Tu32 = frac_int; base = 1; for (i = 1; i < frac_digits; i++) { base *= 10; } for (i = 0; i < frac_digits; i++) { TmpU8 = Tu32 / base; // 小数部分强制显示,即使是 0 也显示 DispMem_Dec[pos + il + i] = LCD_CharAry[TmpU8 + '0']; Tu32 -= TmpU8 * base; base /= 10; } } last_val=val; last_pos=pos; last_dl=dl; last_il=il; } void LCD_DispStr(char *str, uint8_t pos, uint8_t dl) { uint8_t i; for (i = 0; i < dl; i++) { DispMem_Dec[i + pos] = LCD_CharAry[str[i]]; } } void LCD_DispPoint(uint8_t num) { DispMem_Dec[num] |= LCD_POINT_Dx; }