一、概览
芯片引脚定义如下,其中GRID1~GRID8驱动共阴极数码管的COM端,但不知道为何用GRID表示,GRID一般指的是VFD显示器的栅极。SEG1~SEG16驱动数码管的各个段。
从数据手册中可以了解到TM1629A采用SPI接口,可以驱动8位16段的LED数码管,如下所示。
这里采用的是用于电梯的数码管显示器,总共有17段,因此在设计电路时,将不常用的逗号和箭头指示符用短接线隔开,根据实际使用需要焊接。
二、芯片指令
在STB下降沿后由DIN输入的第一个字节作为指令,可分为数据命令、显示控制命令和地址命令。
1.数据命令设置格式
高位为01,低位不同以区分不同的数据命令。在C程序中设置宏定义:
#define AUTO_ADDR_INC 2 //自动地址增加 #define FIXED_ADDR 4 //固定地址
2.显示命令设置格式
高位为10,低位不同以区分不同的显示命令,显示命令用于设置显示亮度、显示打开或关闭。消光数量即驱动波形的占空比。
#define DISP_DIM 0 #define DISP_MID 3 #define DISP_BRT 6 #define DISP_OFF 9
因为个人应用不需要连续切换占空比,这里仅定义几个常用的即可。
3.地址命令设置格式
该命令用于固定地址时,设置数据的写入地址。写入数据的地址表如下,设置数据命令为固定地址后,先写入显示缓存地址,再写入显示数据,即可更改某一具体地址的缓存内容,从而更改显示效果。
从下面的地址表可以知道,TM1629A的16段分别与两个字节的数据对应,因此要在数码管上显示一个数字,就必须写入两个字节的数据。
三、SPI时序及软件模拟
首先设置各数据线的电平,CLK和SPI均为高,在STB下降沿后,由DIN在CLK的同步下将数据串行输入至芯片缓存。
void TM1629A_Init(void){ CLK = 1; STB = 1; delay_us(100); STB = 0; } void TM1629A_WriteData(u8 dat){ u8 i; STB = 0; delay(100); for(i = 0; i < 8; i++){ CLK = 0; delay_us(100); if((dat >> i) & 0x01) DIN = 1; else DIN = 0; delay(100); CLK = 1; delay_us(100); } }
四、用户代码(方便后续调用)
1.第一字节指令设置函数
void TM1629A_SetCommand(u8 cmd){ STB = 0; switch(cmd){ case AUTO_ADDR_INC:{ TM1629A_WriteData(0x40); //自动地址增加 break; } case FIXED_ADDR:{ TM1629A_WriteData(0x44); //固定地址 break; } case DISP_DIM:{ TM1629A_WriteData(0x88 | DISP_DIM); //显示最暗 break; } case DISP_MID:{ TM1629A_WriteData(0x88 | DISP_MID); //显示亮度中等 break; } case DISP_BRT :{ TM1629A_WriteData(0x88 | DISP_BRT); //显示最亮 break; } case DISP_OFF :{ TM1629A_WriteData(0x80); //关闭显示 break; } default:break; } STB = 1; }
2.设置地址,TM1629A的显示缓存地址为0xc0~0xcf,为与数码管的位相对应,在位的基础上加0xc0即可:
void TM1629A_SetAddr(u8 addr){ TM1629A_WriteData(0xc0 + addr); }
3.清屏函数,使用自动地址增加方式写入数据。根据数据手册的建议添加,避免上电后的显示乱码。
void TM1629A_Disp_clr(void){ u8 i; TM1629A_SetCommand(AUTO_ADDR_INC); STB = 0; TM1629A_SetAddr(0); for(i = 0;i < 8;i ++){ TM1629A_WriteData(0X00); TM1629A_WriteData(0X00); } STB = 1; }
4.任意位写入数据函数,使用固定地址方式写入数据。其中digi是数码管的位,num是要显示的数字,0~9有效。
void TM1629A_DispNum(u8 digi, u8 num){ STB = 0; TM1629A_SetAddr(digi * 2); TM1629A_WriteData(number[num * 2]); STB = 1; STB = 0; TM1629A_SetAddr(digi * 2 + 1); TM1629A_WriteData(number[num * 2 + 1]); STB = 1; }
五、参考数字码表
u8 code number[] = { 0x53,0x22, //0 0x50,0x00, //1 0x91,0x23, //2 0xd1,0x03, //3 0xd2,0x01, //4 0xc3,0x03, //5 0xc3,0x23, //6 0x51,0x00, //7 0xd3,0x23, //8 0xd3,0x03 //9 };
显示效果如下,可加滤光片使显示效果更加清晰。