最近好多某宝的商家在做免费LED点阵胸牌的活动,撸了好几个。看着只能显示文字,没啥意思,堆灰不划算,就寻思着改造改造。
整理了下手上的胸牌的款式,发现大概有三款。
本贴就一一整理这三款胸牌的重新编程并点亮改造的过程
先上成果图
涉及这三款led胸牌
从上到下,定义
最上面款为:双按键,黑色PCB,单片机为GD32F150C6
中间款为:侧按键,绿色PCB,单片机为未知打磨芯片
最下面款为:单按键,黑色PCB,单片机为GD32F150C6

三款同时点亮的效果



改造成简易时钟

先折腾第一款。
单按键,黑色PCB,单片机为GD32F150C6 usb接口是mini口
就是这款

这个板子比较蛋疼,因为是黑色油墨
先拆下芯片跑走线

先找出哪些脚是LED驱动脚,那些脚是其他的功能引脚
这个比较简单
图中蓝色点标记的就是LED驱动引脚,其他脚都是功能脚或者空脚

同时可以标出设计者引出的测试点。
其中PA13/PA14用于*载下**程序,还引出了一个串口

接着找LED的顺序
找LED顺序的方法是通过看PCB背面的走线,可以看出有一排灯间距过孔的走线就一定是LED驱动走线。然后按照着顺序一路用万用表测量下来就能找出驱动序列的顺序(这个步骤比较浪费时间)

因为设计者使用列阵法来驱动LED,所以通过这个顺序就能恢复出LED点亮序列

后来看了坛友的一个帖子,说是github上也有一个类似工程,引脚和这款胸牌一样,我吧整理好的引脚也贴下

引脚的驱动方式是,每两列用同一个列选拉高,每一行用两个行选拉低

吧芯片焊回去,开始测试点亮

连接SWD口调试口如下,使用JLINK联机(PS:这种细硅胶线用来飞线简直不要太爽)

打开JLINK 命令行软件,可以看到找到了CORTEX M3内核的设备,说明连接线没错

经检测这个GD32被设计者上锁了读取保护。
所以需要进行解锁
注意:这款胸牌一旦解锁,就不能回到原装出厂的程序,以后只能使用DIY的程序
解锁方法:
找到jlink安装目录 打开jlinkstm32*ex.e** 选择按照stm32f1系列方式解锁
解锁后会提示以下成功消息。此时芯片已经被擦除干净,已经没有回头路了

使用jlink进行*载下**的时候,因为jlink支持列表里面没有GD32,所以,选择的芯片型号应该是
STM32F103C6
如图

程序因为太复杂,就只贴一小部分核心了
具体的看附件
复制代码
-
uint32_t Led_GPIO_Port_Arrange[22] = {GPIOF, GPIOB, GPIOB, GPIOB, GPIOB,
-
GPIOB, GPIOB, GPIOA, GPIOA, GPIOF,
-
GPIOB, GPIOB, GPIOA, GPIOF, GPIOB,
-
GPIOB, GPIOB, GPIOB, GPIOA, GPIOB,
-
GPIOB, GPIOB
-
};
-
const uint16_t Led_GPIO_Pin_Arrange[22] = {GPIO_Pin_7, GPIO_Pin_15, GPIO_Pin_14, GPIO_Pin_11, GPIO_Pin_12,
-
GPIO_Pin_2, GPIO_Pin_1, GPIO_Pin_6, GPIO_Pin_7, GPIO_Pin_0,
-
GPIO_Pin_9, GPIO_Pin_8, GPIO_Pin_5, GPIO_Pin_1, GPIO_Pin_4,
-
GPIO_Pin_13, GPIO_Pin_10, GPIO_Pin_0, GPIO_Pin_4, GPIO_Pin_6,
-
GPIO_Pin_5, GPIO_Pin_7
-
};
-
/**********************************************/
-
/* 函数功能;清除所有led对应io为复位 */
-
/* 入口参数:无 */
-
/**********************************************/
-
void Clear_All_LED(void)
-
{
-
GPIO_CTL(GPIOA) &=0xffcc00ff;//清空A GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_10
-
GPIO_CTL(GPIOB) &=0x000000c0;//清空除了b3
-
GPIO_CTL(GPIOF) &=0xffff3ff0;//清空 f0,1,7
-
GPIO_OCTL(GPIOA) &=~(GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_10);//清空A GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_10
-
GPIO_OCTL(GPIOB) &=~(GPIO_Pin_ALL-GPIO_Pin_3);//清空除了b3
-
GPIO_OCTL(GPIOF) &=~(GPIO_Pin_1|GPIO_Pin_0|GPIO_Pin_7);//清空 f0,1,7
-
}
-
void Write_One_LED_Pin(uint32_t GPIOx, uint16_t GPIO_Pin,uint8_t pin_satae)
-
{
-
uint32_t i,pins;
-
for(i=0;i<16;i++)
-
{
-
if((GPIO_Pin>>i)&0x01)pins=i;
-
}
-
GPIO_CTL(GPIOx) |=(uint32_t)0x00000001<<pins*2;
-
if(pin_satae)GPIO_BOP(GPIOx)|=GPIO_Pin;
-
else GPIO_BC(GPIOx)|=GPIO_Pin;
-
}
-
/**********************************************/
-
/* 函数功能;点亮对应位置的led */
-
/* 入口参数:xy */
-
/**********************************************/
-
void LED_Open(uint8_t x, uint8_t y)
-
{
-
if(x > 43 || y > 10)return;
-
Clear_All_LED();
-
Write_One_LED_Pin(Led_GPIO_Port_Arrange[x / 2], Led_GPIO_Pin_Arrange[x / 2], 1);
-
if(y == 0)
-
{
-
if(x % 2 == 0)
-
{
-
Write_One_LED_Pin(GPIOA, GPIO_Pin_10, 0);
-
}
-
else
-
{
-
if(x > 1)Write_One_LED_Pin(GPIOF, GPIO_Pin_7, 0);
-
else Write_One_LED_Pin(GPIOB, GPIO_Pin_15, 0);
-
}
-
}
-
else
-
{
-
if(y==10&&x==42)
-
{
-
Write_One_LED_Pin(GPIOB,GPIO_Pin_5,0);
-
return;
-
}
-
if(y==10&&x==43)
-
{
-
Write_One_LED_Pin(GPIOB,GPIO_Pin_6,0);
-
return;
-
}
-
if(x % 2 == 0)
-
{
-
if(x <= 4 * y - 2) Write_One_LED_Pin(Led_GPIO_Port_Arrange[y * 2], Led_GPIO_Pin_Arrange[y * 2], 0);
-
else Write_One_LED_Pin(Led_GPIO_Port_Arrange[y * 2 - 1], Led_GPIO_Pin_Arrange[y * 2 - 1], 0);
-
}
-
else
-
{
-
if(x <= 4 * y + 2) Write_One_LED_Pin(Led_GPIO_Port_Arrange[y * 2 + 1], Led_GPIO_Pin_Arrange[y * 2 + 1], 0);
-
else Write_One_LED_Pin(Led_GPIO_Port_Arrange[y * 2], Led_GPIO_Pin_Arrange[y * 2], 0);
-
}
-
}
-
}
最后全屏点亮的效果

第二款:双按键,黑色PCB,单片机为GD32F150C6 usb口为mini口
就是他
注意 这款胸牌焊接质量不怎么样,建议加固usb口和开关,不然很容易坏

同样的,国际惯例,先拆芯片跑走线

跑走线的过程,发现一个真心蛋疼的问题。
这个胸牌的开发设计者应该被祖宗8辈子全部骂一遍过来。居然胆大包天敢吧SWD调试接口给使用掉了,吧调试接口给使用掉了,给使用掉了,用掉了。
你这不就是给大家找麻烦吗?
没办法,只能一边骂一边跑走线了呗~
芯片下的走线细节

图中绿色点表示的是LED驱动引脚。我只想问你用PF6和PF7去驱动LED,检测按键会死啊。居然敢丧心病狂的吧PA13和PA14都占用
还很奇葩的吧PF6和PF7接了vcc和gnd,这是几个意思啊????简直是醉了醉了

绘出板载的测试点位置
其中串口的位置在正面,又是一个奇葩。在正面,只要接了线就没法转进壳子了啊。。。。
这里注意到这个设计者,在左边的按键设计了上拉结构。这个按键接了PA15作为按键检测,同时又用一个电阻上拉到boot0.
也就是说,只要在给芯片上电前按住按键,就会加入程序*载下**的ISP模式,然后使用串口*载下**程序

*载下**程序的软件使用GD32官方提供的ISP工具,就是这货。
这款胸牌不能使用JLINK进行调试

不过唯一值得欣慰的是,这款胸牌的程序没有上锁,所以可以读取出原装的固件。也就是说,玩累了还能吧原装固件恢复回去
楼下附件会给出拷贝读取出来的固件。
跑出LED的线序

这款胸牌的驱动列阵比楼上那款要稍微简单一些 但同样是使用23个引脚来扫描点亮11*44的LED列阵
下图中
蓝色为行编号(此处的0,1,2为物理行LED号)
橙色为列编号(此处的0,1,2为物理列LED号)
绿色为驱动对应的列需要拉高的引脚(此处的0,1,2为驱动管脚顺序号,也是就上图)
黄色为驱动对应的行需要拉低的引脚(此处的0,1,2为驱动管脚顺序号,也是就上图)

规律性更强
复制代码
-
void LED_Open(uint8_t x, uint8_t y)
-
{
-
if(x > 43 || y > 10)return;
-
Clear_All_LED();
-
Write_One_LED_Pin(Led_GPIO_Port_Arrange[x / 2], Led_GPIO_Pin_Arrange[x / 2], 1);
-
if(y == 0)
-
{
-
if(x % 2 == 0)
-
{
-
if(x > 0)Write_One_LED_Pin(Led_GPIO_Port_Arrange[0], Led_GPIO_Pin_Arrange[0], 0);
-
else Write_One_LED_Pin(Led_GPIO_Port_Arrange[2], Led_GPIO_Pin_Arrange[2], 0);
-
}
-
else
-
{
-
if(x == 3)Write_One_LED_Pin(Led_GPIO_Port_Arrange[2], Led_GPIO_Pin_Arrange[2], 0);
-
else Write_One_LED_Pin(Led_GPIO_Port_Arrange[1], Led_GPIO_Pin_Arrange[1], 0);
-
}
-
}
-
else
-
{
-
if(x % 2 == 0)
-
{
-
if(x <= 4 * y) Write_One_LED_Pin(Led_GPIO_Port_Arrange[y * 2 + 1], Led_GPIO_Pin_Arrange[y * 2 + 1], 0);
-
else Write_One_LED_Pin(Led_GPIO_Port_Arrange[y * 2], Led_GPIO_Pin_Arrange[y * 2], 0);
-
}
-
else
-
{
-
if(x <= 4 * y + 4) Write_One_LED_Pin(Led_GPIO_Port_Arrange[y * 2 + 2], Led_GPIO_Pin_Arrange[y * 2 + 2], 0);
-
else Write_One_LED_Pin(Led_GPIO_Port_Arrange[y * 2 + 1], Led_GPIO_Pin_Arrange[y * 2 + 1], 0);
-
}
-
}
-
}
完整点亮的效果
肉眼看是均匀的,只是因为相机的问题,才会有个斜的亮条,实际是不影响的

第三款 比较复杂地一款
侧按键,绿色PCB,单片机为未知打磨芯片
就是这款 侧按键 没有磁铁,只有别针


那么要想先玩起来,就得先分析这款打磨芯片是啥
我们注意到有一下三个个特征
1、引脚兼容stm32f0xxc系列芯片
2、芯片的供电直接是用4.2V锂电池供电
先分析这两个特征。锂电池4.2V直接供电。可以直接排除stm32全系列和gd32全系列。因为这两款芯片的供电电压极限都是3.6V,那么锂电池4.2V直接接上去肯定是不行的
3、我手上有一个牌上面的芯片没怎么打磨干净,那么就可以看到一些蛛丝马迹
首先用铅笔给芯片表面涂一下
可以看到两个图标 一个应该是芯片厂商的商标,另外一个是ARM

那么,想象+联想,再天马行空一下,再来点灵感
duang!!!
像不像?就问你们像不像?哈哈~

本来绿油是不想要拆芯片跑走线的。但是因为测试条件不方便施展开来,为了方便分析芯片,还是拆下来了

上stm32系列48脚通用转接板测试

使用jlink的命令行工具联机
可以看到CORTEX M0内核

你们上芯片厂商官网找一圈 发现只有mm32l0xx系列符合条件(cm0内核,带usb)
范围缩小到mm32l062/072/073其中的一款

想办法确定下芯片具体型号。结果发现个蛋疼的问题。官方提供的手册居然有错(果然是国内小厂尿性)
翻开mm32l0系列的参考手册,DBG部分
可以看到swd id和dev id

结果发现,根本对于不上
手册上写swd id是0x2BA01477
实际读取值是0x0bb11477

再对照下读取dev id
发现也是根本对不上
手册上写dev id是0xCC88xxx3
实际读取值是0xcc568091

一开始我还以为是我打开方式有问题
换了好几种方法读取都是这样的。
无奈之下去*载下**了mm32f103系列的手册,哈哈,真相大白
手册之间互抄也不记得改改内容啊。
cm3内核和cm0内核id居然一样,贻笑大方啊

这次翻开正宗大厂 意法家的stm32f0系列的手册看看
写的明明白白,CORTEX M0 内核的swd id规定就是0x0BB01477
根本不是0x2BA01477

本来通过dev id是能确定具体的芯片型号的
比如stm32f0系列就可以这样区别出来

但是奈何国内小厂,手册瞎写,所以芯片型号根本没法确定。
anyway,反正都是mm32l0xx系列,都是兼容的,只是容量大小有点区别,不影响使用啦。
继续分析是否锁定读保护。
查看参考手册

用jlink直接读这几个位置

很遗憾,符合读保护特征,芯片被锁读保护了

测试读取 0x800000位置的数据,不能读取
那就只能擦除了呗~
注意:这款胸牌一旦解锁,就不能回到原装出厂的程序,以后只能使用DIY的程序
擦除教程:(此处就偷懒借用官方图片了)
(该文件附件提供*载下**)

2、打开unlock工程(附件提供*载下**)

添加Flash选项:


擦除完成,没回头路啦
开始跑走线。这里也比较蛋疼。虽然这个板子是绿油,走线很容易看清楚。但是这个板子过孔盖油盖的太严实了,只能刮开走线才能方便测量了

测试出引脚占用图
图中绿色为LED驱动脚

板子上设计者所留的测试点,蛮多的,良心

测绘出LED列阵顺序

这款胸牌除了引脚不同外,驱动方法和上面的双按键款一模一样(讲道理这三款胸牌居然LED引脚完全不一样)

焊接回去芯片

焊接swd调试*载下**接口

成功点亮

显示测试

改造时钟
大家比较喜闻乐见的项目哈
因为时间精力有限,不可能三款胸牌都改时钟。那选其中一款来弄。另外两款需要各位简单移植,很简单的。
选择单按键款 就是这货

时钟芯片用ds3231。
因为是实验,就先用模块测试了,实际上是可以直接芯片飞线的。只需要飞iic的sda和scl,电源线和备用电压就行(电源线和单片机接一起,备用电源直接接在锂电池上)
这款胸牌上,设定
IIC_SDA_PIN 是 PA2
IIC_SCL_PIN 是 PA3
如图接线

效果如图


(程序见附件)
讲一下程序构架
整个程序
LED驱动部分分为三个部分
led_drv是led的底层驱动,负责驱动io(这部分每个胸牌各不相同)
led_scan负责led的扫描 (led_scan和led_drv部分一般写好了就不需要动了)
led_display负责显示内容的呈现

这里有个重要的东西 显示缓存

也就是说,所有要显示的内容,都是写到显示缓存内的。然后刷屏程序会自动读取并刷屏,具体刷屏部分不用操心。
这个显示缓存,每个uint16_t数负责一列,只取前11位
开源代码需至原帖获取,地址:http://bbs.mydigit.cn/read.php?tid=2324306
谢谢观看!
浏览更多精彩内容请登录数码之家网站
技术交流请联系原作者
作者:2545889167
本文来源:数码之家