| 
 这次带来的设计是基于 Ch552 的 HPDL-1414 数码管计数器。 HPDL-1414 是一款历史悠久的数码管显示器,和最常见的7段数码管不同,它除了能够显示数字之外,因为有着足够的线段,还能显示英文字符。  
 HPDL-1414 控制很简单,通过 GPIO 就可以选择点亮那些数码段组成。接下来的问题就是:对于CH552来说,GPIO 引脚不够。 传统的扩展方法是使用I2C或者 74HC595 来进行扩展,这次选择的是ESR1117:这是一款国产串口GPIO芯片。显而易见的是:相比其他接口,通过串口扩展GPIO的方案更加简单方便。我们只需要将 TX RX 交叉连接之后即可。 最终的电路设计如下:  
  
 除了支持 HPDL-1414 进行显示,还预留了3个 WS2812B 的位置,可以通过代码控制这些灯的颜色。  
 完整代码如下:  
 
			
			
			- uint16_t Ascii2GPIO(uint8_t data, uint8_t pos)
 - {
 -   uint16_t Esr = 0;
 - 
 -   Esr = pos << 2;
 -   if ((data & (1 << 0)) != 0) {
 -     Esr = Esr | (1 << 1); //D0
 -   }
 -   if ((data & (1 << 1)) != 0) {
 -     Esr = Esr | (1 << 0);
 -   }
 -   if ((data & (1 << 2)) != 0) {
 -     Esr = Esr | (1 << 9);
 -   }
 -   if ((data & (1 << 3)) != 0) {
 -     Esr = Esr | (1 << 8);
 -   }
 -   if ((data & (1 << 4)) != 0) {
 -     Esr = Esr | (1 << 5);
 -   }
 -   if ((data & (1 << 5)) != 0) {
 -     Esr = Esr | (1 << 4);
 -   }
 -   if ((data & (1 << 6)) != 0) {
 -     Esr = Esr | (1 << 7);
 -   }
 -   return Esr;
 - }
 - 
 - void output(uint8_t HiByte, uint8_t LowByte) {
 - 
 -     USBSerial_print("Serial out, HI:[");
 -     USBSerial_print(HiByte, HEX);
 -     USBSerial_print("] Low[");
 -     USBSerial_print(LowByte, HEX);
 -     USBSerial_println("]");
 - 
 - 
 -   // GPIO 先准备好,RW 设置为  HIGH,防止误动作
 -   Serial0_write(0x3F); Serial0_write(0xC0); Serial0_write(0x98 | HiByte); Serial0_write(LowByte | 0b01000000);
 -   USBSerial_print(LowByte, HEX);
 -   delay(10);
 -   // RW 设置为  LOW, ESR 会直接拉GPIO
 -   Serial0_write(0x3F); Serial0_write(0xC0); Serial0_write(0x98 | HiByte); Serial0_write(LowByte);
 -   USBSerial_print(LowByte | 0b01000000, HEX);
 -   delay(10);
 -   // RW 设置为  HIGH, RW 设置为  HIGH,防止误动作
 -   Serial0_write(0x3F); Serial0_write(0xC0); Serial0_write(0x98 | HiByte); Serial0_write(LowByte | 0b01000000);
 -   delay(10);
 - }
 - 
 - void setup() {
 -   Serial0_begin(9600);
 -   delay(2000);
 - 
 -   // GPIO 设置为 OUTPUT
 -   Serial0_write(0x3F); Serial0_write(0xC0); Serial0_write(0x8F); Serial0_write(0xFF);
 -   delay(10);
 -   
 - 
 -   uint16_t c;
 -   // 清除第1位显示(输出一个空格)
 -   c = Ascii2GPIO( ' ', 0);
 -   output(c >> 8, c & 0xFF);
 -   
 -   // 清除第2位显示(输出一个空格)
 -   c = Ascii2GPIO(' ', 1);
 -   output(c >> 8, c & 0xFF);
 -   
 -   // 清除第3位显示(输出一个空格)
 -   c = Ascii2GPIO(' ', 2);
 -   output(c >> 8, c & 0xFF);
 -   
 -   // 清除第4位显示(输出一个空格)
 -   c = Ascii2GPIO(' ', 3);
 -   output(c >> 8, c & 0xFF);
 -   delay(2000);      
 -   USBSerial_println("Start");
 - }
 - 
 - uint16_t Counter = 0;
 - uint16_t OldCounter = 0;
 - 
 - void loop() {
 -     USBSerial_print("Counter");
 -     USBSerial_println(Counter);
 -     uint16_t c;
 -     c = Ascii2GPIO(Counter % 10 + '0', 0);
 -     output(c >> 8, c & 0xFF);
 - 
 -     // 只在发生变化时才更新,减少闪烁感
 -     if (((Counter / 10) % 10) != (OldCounter / 10) % 10) {
 -     c = Ascii2GPIO((Counter / 10) % 10 + '0', 1);
 -     output(c >> 8, c & 0xFF);
 -     }
 - 
 -     if (((Counter / 100) % 10) != (OldCounter / 100) % 10) {
 -     c = Ascii2GPIO((Counter / 100) % 10 + '0', 2);
 -     output(c >> 8, c & 0xFF);
 -     }
 - 
 -     if (((Counter / 1000) % 10) != (OldCounter / 1000) % 10) {
 -     c = Ascii2GPIO((Counter / 1000) % 10 + '0', 3);
 -     output(c >> 8, c & 0xFF);
 -     }
 - 
 -     OldCounter=Counter;
 -     Counter++;
 -     if (Counter > 9999) {
 -     Counter = 0;
 -     OldCounter=0;
 -     }
 - }
 
  复制代码
 成品如下:  
  
  
  
  
  
  
 |