mapleft的笔记 https://bbs.21ic.com/?41444 [收藏] [复制] [RSS]

日志

TM1629驱动及使用共阳数码管显示解释函数

已有 231 次阅读2020-5-10 11:41 |个人分类:工蚁手记|系统分类:兴趣爱好

TM1629是一款带键盘扫描和LED扫描驱动的国货芯片,芯片默认配套为使用共阴数码管; 但考虑到降低物料库存种类,选用了共阳数码管
先说TM1629的初始化
//*----------------------------------------------------------------------------
//* Function Name       : InitTM1629
//* Object              : TM1629初始化函数
//* Input Parameters    : none
//* Output Parameters   : none
//*----------------------------------------------------------------------------
void InitTM1629(void)
{
    INT8U tx[1]= {0x40};
    INT8U rx[1];
    
    port_pin_set_output_level(SPI4_SS,0);
    SPIMasterCOM4TC((INT8U *)tx, rx, 1);
    port_pin_set_output_level(SPI4_SS,1);
    
     
    port_pin_set_output_level(SPI4_SS,0);
    tx[0] = 0x8f;
    SPIMasterCOM4TC((INT8U *)tx, rx, 1);
    port_pin_set_output_level(SPI4_SS,1);
}

其实就是设置2个参数
0X40  设置写数据到寄存器地址自动+1模式
0x8f   设置LED的脉冲宽度为14/16 (亮度为全亮模式),显示开关为开

LED数据传输函数:
 port_pin_set_output_level(SPI4_SS,0);
    cmd = 0xc0;
    SPIMasterCOM4TC((INT8U *)(&cmd), (INT8U*)(&cmd), 1);
    SPIMasterCOM4TC((INT8U *)(buf), (INT8U *)buf, 16);
    port_pin_set_output_level(SPI4_SS,1)
数据发送流程为先设置数据的开始地址为0,  命令: 0XC0
后面跟着16个显示数据;
这里需要说明一下的是,如果你为了装显B格使用硬件DMA SPI发送数据时, 发送命令字节和数据之间要延时一下,手册上说在这里要等待1个uS;
之前我为了凸显硬件水平,一个DMA SPI 数据包扔过去,结果显示鬼畜;

显示数据解析

由于用了共阳的数码管,LED原来的段码引脚现在要接到1629芯片GRID引脚上,原理的数码管列扫描信号接到1629芯片SED引脚上;
乱套了。。。。
用共阴数码管,往芯片送一个字节,对应一个数码管的7个笔段+1个数码管,这种显示数据关系简单明了。
现在用共阳数码管,往芯片送一个字节,对应是8个数码管的其中一个段码的数据,送2个字节表示16个数码管的其中一个笔段的数据;
也就是说,每2个字节描述了16个数码管的其中一个笔段的状态, 送16个字节描述了16个数码管的8个笔段的状态;

这时候就需要一个函数来转换显示和笔段的数据;
显示数字的笔段定义
 INT8U LEDSegs[ ][7] = {Num0,Num1,Num2,Num3,Num4,Num5,Num6,Num7,Num8,Num9,Numblk,
 };

/*
   a
  ---
f| g |b    
  ---
e|   |c    
  ---
   d
*/

#define Sega    0
#define Segb    1
#define Segc    2
#define Segd    3

#define Sege    6
#define Segf    4
#define Segg    5
#define segp    7

#define ____     segp  //

#define Num0    { Sega , Segb , Segc , Segd , Sege , Segf  , ____  }
数字0的定义
INT16U buf[8] = {0,0,0,0, 0,0,0,0};
 for(i=0;i<MAXDigi;i++)
    {
          for(n=0;n<7;n++)
          {
              pos = LEDSegs[Dig[i]][n];
              buf[pos] |= (1 << i);
          }
    }
说明下,buf是显示LED显示段码缓冲区,16个字节, 
Dig是显示内容缓冲区,就是要显示的内容 如1.2.3之类


完整的显示函数:
//*----------------------------------------------------------------------------
//* Function Name       : LEDDisplay
//* Object              : 数码管显示函数
//* Input Parameters    : 数字显示缓冲器区指针,小数点缓冲器指针,闪烁数字 0:不闪烁 1-x闪烁数字位置
//  0-3 :第一行4位数字
//  4-7 :第二行4位数字
//  8   :第二行1位数字
//* Output Parameters   : none
//*----------------------------------------------------------------------------
void LEDDisplay(INT8U *Dig,INT8U *Point,INT8U flash)
{
    INT16U buf[8] = {0,0,0,0, 0,0,0,0};
    INT8U i,n,pos;
    INT8U cmd;
    INT16U bitmap = 0xffff;
    
    if(flash != 0 )
        bitmap &= (~(1<<flash));
    
    for(i=0;i<MAXDigi;i++)
    {
        if(bitmap & (1<<i))
        {
          for(n=0;n<7;n++)
          {
              pos = LEDSegs[Dig[i]][n];
              buf[pos] |= (1 << i);
          }
        }
    }
    
    buf[segp] = 0;
    for(i=0;i<MAXDigi;i++) //小数点
    {
        if(Point[i])
           buf[segp] |=  (1<<i);
    }
    
    port_pin_set_output_level(SPI4_SS,0);
    cmd = 0xc0;
    SPIMasterCOM4TC((INT8U *)(&cmd), (INT8U*)(&cmd), 1);
    SPIMasterCOM4TC((INT8U *)(buf), (INT8U *)buf, 16);
    port_pin_set_output_level(SPI4_SS,1);
}
源代码下载:

路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)