数码之家

 找回密码
 立即注册

QQ登录

只需一步,快速开始

微信登录

微信扫一扫,快速登录

搜索
查看: 55|回复: 1

[Arduino] 驱动查理复用(Charlieplexing)数码管

[复制链接]
发表于 昨天 23:25 | 显示全部楼层 |阅读模式
本帖最后由 kpj001 于 2025-10-27 23:32 编辑

视频先登:https://www.bilibili.com/video/BV1s8sDzwEWg/
实物介绍(非广告):https://item.taobao.com/item.htm?id=800826018081

数码管通常分为共阳共阴,共同特点引脚比较多,一般我都不用的。
最近流行“查理复用(Charlieplexing)数码管”,就是单排引脚这种。
到手发现居然没有现成驱动,于是试着从 01 10 这样的组合开始测试,几个回合就找出来段码。
这样需要显示0-199 整数的场合,直插面包板style,就多了一种及其便宜的选择(1毛钱一颗)。

代码为 arduino uno nano D6-D2 直插【看视频】,作为点亮测试还是可以的,实际使用可以考虑用中断代替延时。
当然这款数码管搭配arduino略显浪费,STC DIP 封装的才是良配,代码略微修改即可。

  1. const int seg188_pins[] = {6, 5, 4, 3, 2};
  2. int segDuration = 1;      // 每个段点亮时间,实测1ms合适
  3. bool digits[10][7] = {    // 7段数码管显示数字所需点亮之段码,格式: {a, b, c, d, e, f, g}
  4.   {1, 1, 1, 1, 1, 1, 0},  // 0
  5.   {0, 1, 1, 0, 0, 0, 0},  // 1
  6.   {1, 1, 0, 1, 1, 0, 1},  // 2
  7.   {1, 1, 1, 1, 0, 0, 1},  // 3
  8.   {0, 1, 1, 0, 0, 1, 1},  // 4
  9.   {1, 0, 1, 1, 0, 1, 1},  // 5
  10.   {1, 0, 1, 1, 1, 1, 1},  // 6
  11.   {1, 1, 1, 0, 0, 0, 0},  // 7
  12.   {1, 1, 1, 1, 1, 1, 1},  // 8
  13.   {1, 1, 1, 1, 0, 1, 1}   // 9
  14. };

  15. int currentNumber = 0;
  16. unsigned long lastChangeTime = 0;
  17. int displayCounter = 0;

  18. void setup() {
  19.   Serial.begin(115200);
  20. }

  21. void loop() {  
  22.   showNumber(currentNumber);
  23.   
  24.   // 每隔一段时间改变显示的数字(测试用)
  25.   if (millis() - lastChangeTime > 100) {
  26.     lastChangeTime = millis();
  27.     currentNumber = (currentNumber + 1) % 200; // 循环显示0-199
  28.     Serial.println("Displaying: " + String(currentNumber));
  29.   }
  30. }

  31. void showNumber(int a) {            // 数字范围 0-199
  32.   int tens = (a % 100) / 10;
  33.   int ones = a % 10;
  34.   showDigit(3, ones);               // 个位
  35.   if(a>9)showDigit(2, tens);        // 十位  
  36.   if(a>99)showDigit(1, 1);          // 百位
  37. }

  38. void showDigit(int digitPos, int number) {
  39.   bool* segments = digits[number];  
  40.   // 个位
  41.   if (digitPos == 3) {
  42.     if (segments[0]) lightSegment(0, 1); // a3
  43.     if (segments[1]) lightSegment(1, 0); // b3
  44.     if (segments[2]) lightSegment(0, 2); // c3
  45.     if (segments[3]) lightSegment(2, 0); // d3
  46.     if (segments[4]) lightSegment(0, 3); // e3
  47.     if (segments[5]) lightSegment(3, 0); // f3
  48.     if (segments[6]) lightSegment(4, 0); // g3
  49.   }
  50.   // 十位
  51.   else if (digitPos == 2) {
  52.     if (segments[0]) lightSegment(1, 2); // a2
  53.     if (segments[1]) lightSegment(2, 1); // b2
  54.     if (segments[2]) lightSegment(3, 2); // c2
  55.     if (segments[3]) lightSegment(3, 1); // d2
  56.     if (segments[4]) lightSegment(4, 1); // e2
  57.     if (segments[5]) lightSegment(4, 2); // f2
  58.     if (segments[6]) lightSegment(4, 3); // g2
  59.   }
  60.   // 百位,比较特殊,只有显示1 和不显示两种状态
  61.   else if (digitPos == 1) {
  62.     lightSegment(2, 3); // b1 (对应a1)
  63.     lightSegment(1, 3); // c1 (对应b1)
  64.   }
  65. }

  66. void lightSegment(int anodePin, int cathodePin) {  
  67.   for (int i = 0; i < 5; i++) pinMode(seg188_pins[i], INPUT);
  68.   pinMode(seg188_pins[anodePin], OUTPUT);digitalWrite(seg188_pins[anodePin], HIGH);  
  69.   pinMode(seg188_pins[cathodePin], OUTPUT);digitalWrite(seg188_pins[cathodePin], LOW);
  70.   delay(segDuration);
  71. }
复制代码



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x
发表于 1 小时前 | 显示全部楼层
谢谢分享好东西
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册 微信登录

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-10-28 03:12 , Processed in 0.078000 second(s), 6 queries , Gzip On, Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

快速回复 返回顶部 返回列表