本文地址:https://www.cnblogs.com/jqdy/p/14262485.html
米字数码管可以显示数字和26个英文字母,应用范围比8字数码管更广泛一些。
市面上常见的米字数码管有三种,一种是15段的,另一种是16段,还有一种是17段的。TM1629A可以驱动15和16段的数码管。
一、TM1629A主要参数
- 共阴数码管:16 段 × 8 位
- 共阳数码管:8 段 × 16 位
- 8级辉度调节
- 串行接口(CLK,STB,DIO)
- 逻辑电源电压范围:-0.5~7.0V
- 正常工作电压电压:5.0V
手册在天微官网上有,百度一下也很多。
二、电路设计
手册给出了两个驱动8位数码管的电路,并未给出驱动米字数码管的电路。参照这两个电路设计了驱动15位红色米字管的电路。
经过试验,电源电压完全可以使用3.3V,亮度非常高,甚至曾烧坏过一个笔画,也不知是不是数码管的质量问题。
三、驱动程序
该芯片有3个控制线,分别是:
- DIO:数据输入线
- CLK:时钟输入线
- STB:片选线
需要注意的是,TM1629A的CLK的时钟周期较慢(大于500ns),要根据MCU的频率测试一下,如果不能满足要求,要加入适当的延时。
特别需要注意的是时序图中的tCLK-STB和PWSTB,都要求最小1us。
最好的办法是在DIO、CLK、STB变化的前后都插入足够长时间的延时,整个调通后再优化时间。
3.1 初始化工作
首先进行初始化工作,主要是定义功能脚的工作模式。
1 /**************************************************** 2 *说明:初始化TM1629A 3 *备注:io.h中定义了 STB P3^2,CLK P3^3,DIO P5^5 4 ****************************************************/ 5 void TM1629A_Init(void) 6 { 7 /*GPIO初始化,均为开漏输出*/ 8 SET_BIT(P3M1, 2); //宏功能:令P3M1的BIT2=1 9 SET_BIT(P3M0, 2); 10 SET_BIT(P3M1, 3); 11 SET_BIT(P3M0, 3); 12 SET_BIT(P5M1, 5); 13 SET_BIT(P5M0, 5); 14 /*STB、CLK赋初值*/ 15 STB = 1; 16 CLK = 1; 17 }
3.2 基本的写入函数
实际工作频率设定的是5.5296MHz。
#include <stc8g.h> #include <intrins.h>
sbit STB = P3^2; sbit CLK = P3^3; sbit DIO = P5^5; /**************************************************** *说明:TM1629A写操作驱动函数 ****************************************************/ void wrt(unsigned char dt) { unsigned char i = 8; do{ CLK = 0; dt >>= 1; DIO = CY; CLK = 1;
_nop_();
_nop_(); }while(--i); }
3.3 显示函数
1 /**************************************************** 2 *说明:显示每个数码管的内容 3 *参数:ch为指向显示信息的第一个地址指针 4 * bright为亮度,取值范围0~7,越大越亮 5 *备注:参考手册中”地址增加模式“的信息,以及时序图 6 *1. 提供的字符串长度要与实际数码管位数一致 7 *2. ch指针指向连续几个地址内容为123456,在数码管上显示为654321
8 ****************************************************/ 9 void TM1629A_Display(unsigned char *ch, unsigned char brightness) 10 { 11 unsigned char tem; 12 STB = 0; 13 wrt(COMMAND_WRITE_DDRM_AND_ADDRESS_INCREASE); // 写显存命令,地址自动加1 14 STB = 1; 15 delay1us();//STB选通脉冲宽度大于1us 16 STB = 0; 17 wrt(COMMAND_ADDRESS); // 设置显示地址命令 18 do{ 19 tem = *ch; 20 if(tem >= '0' && tem <= '9') //为数字 21 { 22 tem -= '0'; 23 tem += tem; //15段码一个字符占用两个字节 24 wrt(number[tem]); //将数字转化成数组位置 25 wrt(number[tem + 1]); //这是第二个字节 26 continue; 27 } 28 else if(tem >= 'A' && tem <= 'Z') //为大写字母 29 { 30 tem -= 'A'; 31 tem += tem; 32 wrt(charactor[tem]); //将大写字母转化成数组位置 33 wrt(charactor[tem + 1]); 34 continue; 35 } 36 else if(tem >= 'a' && tem <= 'z') //为小写字母 37 { 38 tem -= 'a'; 39 tem += tem; 40 wrt(charactor[tem]); //将小写字母转化成数组位置 41 wrt(charactor[tem + 1]); 42 continue; 43 } 44 }while(*(++ch) != 0); 45 STB = 1; 46 delay1us(); 47 STB = 0; 48 wrt(COMMAND_DISPLAY_ON | brightness); 49 STB = 1; 50 }
STC8G工作在5.5296MHz时,延时函数delay1us()仅为一个空函数。
/**************************************************** *说明:5.5296MHz时延时1us ****************************************************/ static void delay1us(void) { }
3.4 用到的宏及字模
1 unsigned char code number[] = 2 { 3 0x3f, 0x00, 0x06, 0x00, 0xdb, 0x00, 0xcf, 0x00, 0xe6, 0x00, 4 0xed, 0x00, 0xfd, 0x00, 0x07, 0x00, 0xff, 0x00, 0xef, 0x00 5 }; //0~9,每个数字占连续两个字节 6 unsigned char code charactor[] = 7 { 8 0xf7, 0x00, 0xfc, 0x00, 0x39, 0x00, 0x0f, 0x12, 0xf9, 0x00, 0xf1, 0x00, 0xbd, 0x00, 9 0xf6, 0x00, 0x09, 0x12, 0x1e, 0x00, 0x70, 0x0c, 0x38, 0x00, 0x36, 0x15, 0x36, 0x09, 10 0xdc, 0x00, 0xf3, 0x00, 0x3f, 0x08, 0xf3, 0x08, 0x8d, 0x02, 0x01, 0x12, 0x3e, 0x00, 11 0x30, 0x24, 0x36, 0x2a, 0x00, 0x2d, 0x00, 0x15, 0x09, 0x24 12 }; //a~z,每个字母占连续两个字节 13 14 #define COMMAND_WRITE_DDRM_AND_ADDRESS_INCREASE 0x40 15 #define COMMAND_WRITE_DDRM_AND_ADDRESS_KEEPED 0x44 16 #define COMMAND_DISPLAY_ON 0x88 17 #define COMMAND_DISPLAY_OFF 0x80 18 #define COMMAND_ADDRESS 0xC0 //地址从00H~0FH共16个
3.5 实际效果
TM1629A电源电压=3.3V,亮度级别等于0。