|
老当益壮的麦兜也混迹一下开源社区。
从老王家买过蓝牙播放器的主板,上面有一个看上去还不错的led时钟屏,总想着怎么把它点起来。可惜不知道屏是如何接线的。
借助坛子里大家的智慧,感谢zj97czb坛友、得知这叫做 “四位七脚led数码管”。参见:《求助 一个时钟屏有37个段码却只有7个引脚是怎么做到的》 https://www.mydigit.cn/thread-526378-1-1.html
595953427@qq坛友、撒飒飒坛友 都提示了控制亮度,得用pwm波控制占空比。
又找到了坛子里6年前的老帖子,感谢 hecat、bg4rff 坛友提供了驱动程序的设计思路。参见:《五脚三位数码管的编码应该怎么编写》 https://www.mydigit.cn/thread-14059-1-2.html
有了以上框架和设计思路,就可以动手写软件了。基于软件是需要控制GPIO切换正负极,分别驱动LED的阳极A和阴极K来完成动态显示,所以给这个软件起了个名字叫做 AKClock。
V0.0.1的初始版本,放到码云开源平台了。 https://gitee.com/maidoo/AKClock/tree/v0.0.1
大家要用首个初始版本V0.0.1的话,需要:
- 修改主程序里的 SSID和WIFI密码。 下个版本把WifiManager模块加上就可以手机配置WIFI密码了。
- 数码管内部接线如有不同,修改 ledmap.h 头文件即可重新适配。
- 使用了ESP32中的LEDC设备输出PWM控制LED亮度(0~255),代码里设置初始值55。启动后,可以通过开发版的USB CDC串口设置亮度值(直接发送三个ASCII字符255,不要带回车)。
初始版本还很粗糙,后续功能展望:
- 增加闹钟,直接模拟红外遥控器打开机顶盒、打开电视机,调到13频道看新闻联播
- 开启蓝牙配置功能
- 闹钟可以播放8bit音乐
代码创建了一个7x7的数组作为显示缓存,清楚表述了每个引脚作为正极时,其它6个引脚哪些该拉低(亮)或者高阻(灭)。
一个刷新显示的任务周期执行下面这个 refresh_led_one_frame()函数来实现动态显示
- /*
- * [url=home.php?mod=space&uid=650075]@brief[/url] 刷新一帧LED显示数据,执行时间16毫秒。
- * 该函数通过逐引脚扫描的方式,依次激活每个数码管控制引脚,
- * 根据显示缓存数据决定对应LED的亮灭,实现数码管的动态显示。
- * 最后会补充一个消隐时间,避免余晖影响显示效果。
- */
- void refresh_led_one_frame(void)
- {
- uint8_t a, k;
- // 7个正极引脚逐个扫描,依次激活每个数码管控制引脚
- for(a = 0 ; a < IO_NUM7 ; a++) {
- // 先将所有引脚设置为高阻态,即输入状态,避免引脚间的干扰
- led_gpio_clear();
- // 再将当前引脚设置为高电平,即选中当前引脚,作为正极输出(推挽模式,作为正极公共极)
- pinMode (led_pin_gpio[a], OUTPUT);
- digitalWrite(led_pin_gpio[a], HIGH);
-
- // 配置LEDC通道,控制PWM占空比来控制LED亮度
- pinMatrixOutAttach(led_pin_gpio[a], LEDC_CHANNEL0_FUNC, false, false);
- // 每个正极对应的6个负极引脚逐个扫描,处理每个点位
- for (k = 0; k < IO_NUM7; k++) {
- if (display_cache[a][k] == 1) {
- // 若当前显示点位需要点亮,则需要拉低对应的负极引脚(OD或者推挽模式都可以)。
- digitalWrite (led_pin_gpio[k], LOW);
- }
- else if (display_cache[a][k] == 0) {
- // 若当前显示点位需要熄灭,将对应负极设置为高阻态,即OD输出模式下拉高
- // 前面 led_gpio_clear() 已经设置为默认的HIGH状态,这里可以减少重复操作
- // digitalWrite (led_pin_gpio[k], HIGH);
- } else {
- // 其他的=3的值,是数组中a==k情况,无意义,无需任何操作
- // pinMode(led_pin_gpio[k], OUTPUT_OPEN_DRAIN);
- }
- }
- // 每个公共正极引脚扫描显示暂留2毫秒,一轮16毫秒(7个引脚 * 2毫秒 + 2ms),显示整体刷新速率约62赫兹。
- vTaskDelay(pdMS_TO_TICKS(2));
- // 拆除公共正极的PWM调制波
- ledcDetachPin(led_pin_gpio[a]);
- // 扮演完毕的公共极,从推挽输出模式切换为OD开漏输出模式,默认状态为高阻态
- pinMode(led_pin_gpio[a], OUTPUT_OPEN_DRAIN);
- digitalWrite(led_pin_gpio[a], HIGH);
- }
- // 补充一个周期的消隐时间,熄灭所有段位,避免余晖影响显示效果
- led_gpio_clear();
- vTaskDelay(pdMS_TO_TICKS(2));
- }
复制代码
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
打赏
-
查看全部打赏
|