STM32的TM1629D驱动程序

TM1629D是一种LED驱动芯片,常用于控制LED数码管、LED点阵等显示设备。它具有多种功能,包括控制LED的亮度、显示模式和数据传输等。要使用TM1629D芯片驱动LED显示设备,你需要了解其通信协议和使用方法,通常需要通过微控制器或者其他主控芯片来控制TM1629D,发送数据和命令来控制LED的显示。如果你有具体的问题或者需要更详细的信息,请告诉我,我可以帮助你进一步。

代码如下

#include "lcd.h"
#include "string.h"
#include "stdio.h"
#include <stdlib.h> 
//#include "beep.h"
//PC12  Lcd SCk
//PC2   Lcd cs1
//PC1       Lcd cs
//PD2   Lcd sda
// 定义TM1629D相关引脚
#define BOOT_TM1629D_CS_PIN_H    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1, GPIO_PIN_SET)
#define BOOT_TM1629D_CS_PIN_L    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1, GPIO_PIN_RESET)

#define BOOT_TM1629D_CS1_PIN_H   HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_SET)
#define BOOT_TM1629D_CS1_PIN_L    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_RESET)


#define BOOT_TM1629D_SDA_PIN_H    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET)
#define BOOT_TM1629D_SDA_PIN_L    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET)

#define BOOT_TM1629D_SCK_PIN_H    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_12, GPIO_PIN_SET)
#define BOOT_TM1629D_SCK_PIN_L    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_12, GPIO_PIN_RESET)

#define  BOOT_TM1629D_SDA_PIN_Read     (HAL_GPIO_ReadPin(GPIOD,GPIO_PIN_2));

int BOOT_CS_Flag=0;
const uint8_t pot[10]= {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0xfe, 0xff}; //10位数码管
const uint8_t code[]= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D,
                  0x7D, 0x07, 0x7F, 0x6F, 0x77,
                  0x7c, 0x39, 0x5e, 0x79, 0x71, 0x3d, 0x76, 0x06, 0x1F, 0x7A, 0x38, 0x15, 0x54,
                  0x3F, 0x73, 0x67, 0x50, 0x6D, 0x78, 0x3E, 0x1C, 0x2A, 0x76, 0x6E, 0x5B, 0x80, 0x00
                 };//'0','1','2','3','4','5','6','7','8','9'A'b'C'd'E'F'.....'z'
int sgTmReg[16]={0};
int boot_arr_pot_9=0;
int boot_arr_pot_10=0;
int boot_arr[10]= {0};
int boot_arr2[10]= {0};
int boot_iy=0, boot_iy_2=0;

void lcd_delay_us(uint8_t t)
{
    SysTick->CTRL=0;
    SysTick->LOAD=21-1;
    SysTick->CTRL &=~(1<<2);
    SysTick->VAL =0;
    SysTick->CTRL |=(1<<0);

    for (; t>0; t--)
    {
        while ((SysTick->CTRL&(1<<16))==0)
        {
        };
    }
    SysTick->CTRL &=~(1<<0);
     SysTick->VAL =0;
}
void lcd_delay_ms(uint16_t t)
{
    SysTick->CTRL=0;
    SysTick->LOAD=21000-1;
    SysTick->CTRL &=~(1<<2);
    SysTick->VAL =0;
    SysTick->CTRL |=(1<<0);
    for (; t>0; t--)
    {
        while ((SysTick->CTRL&(1<<16))==0)
        {
        };
    }
    SysTick->CTRL &=~(1<<0);
     SysTick->VAL =0;
}

/*****************************************************************
函数名:TM1629D_Init
功  能:对TM1629D初始化
参  数:无
返回值:无
备  注:对BOOT_TM1629D_SDA_PIN引脚设置开漏输出,能方便读取数据
作  者:
时  间:2024-3-20
*****************************************************************/
void TM1629D_Init(void)
{
    BOOT_TM1629D_SDA_PIN_H;
    BOOT_TM1629D_CS_PIN_H;
    BOOT_TM1629D_CS1_PIN_H;
    BOOT_TM1629D_SCK_PIN_H;

    BOOT_CS_Flag=1;
    TM1629D_Send_Command(0x8e);//14/16

    for (uint8_t j=0; j<16; j++)
    {
        //初始化-显示清零
      TM1629D_WriteAddressData(0XC0+j, 0X00);
    }

    TM1629D_Send_Command(0x8f);//显示控制-显示开
    Displayclean();
    lcd_delay_ms(50);
    BOOT_CS_Flag=0;
    TM1629D_Send_Command(0x8e);//14/16

    for (uint8_t j=0; j<16; j++)
    {
        //初始化-显示清零
        TM1629D_WriteAddressData(0XC0+j, 0X00);
    }

    TM1629D_Send_Command(0x8f);//显示控制-显示开
    Displayclean();
}
/*****************************************************************
函数名:TM1629D_Send_8bit
功  能:对TM1629D发送数据
参  数:uint8_t com:发送数据

返回值:无
备  注:无
作  者:
时  间:2024-3-20
*****************************************************************/
void TM1629D_Send_8bit(uint8_t cmd)
{
    if (BOOT_CS_Flag==0)
        BOOT_TM1629D_CS_PIN_L;  // 片选拉低
    else
        BOOT_TM1629D_CS1_PIN_L;  // 片选拉低

    for (int i = 0; i < 8; i++)
    {
        BOOT_TM1629D_SCK_PIN_L;  // 时钟拉低

        if (cmd & 0x01)
        {
            BOOT_TM1629D_SDA_PIN_H;  // 数据引脚拉高
        }
        else
        {
            BOOT_TM1629D_SDA_PIN_L;  // 数据引脚拉低
        }

        lcd_delay_us(1);
        BOOT_TM1629D_SCK_PIN_H; // 时钟拉高
        cmd >>= 1;
    }

    if (BOOT_CS_Flag==0)
        BOOT_TM1629D_CS_PIN_H;  // 片选拉高
    else
        BOOT_TM1629D_CS1_PIN_H;  // 片选拉高
}
/*****************************************************************
函数名:TM1629D_Send_Command
功  能:对TM1629D发送命令
参  数:uint8_t com:发送的命令

返回值:无
备  注:无
作  者:
时  间:2024-3-20
*****************************************************************/
void TM1629D_Send_Command(uint8_t com)
{
    //写显示地址
    if (BOOT_CS_Flag==0)
        BOOT_TM1629D_CS_PIN_H;  // 片选拉低
    else
        BOOT_TM1629D_CS1_PIN_H;  // 片选拉低

    lcd_delay_us(1);

    if (BOOT_CS_Flag==0)
        BOOT_TM1629D_CS_PIN_L;  // 片选拉低
    else
        BOOT_TM1629D_CS1_PIN_L;  // 片选拉低

    TM1629D_Send_8bit(com);
    lcd_delay_us(1);
}
/*****************************************************************
函数名:TM1629D_SendData
功  能:对TM1629D发送数据
参  数:uint8_t addr:发送的地址0xc0-0xcf
                uint8_t data: 发送的数据,一次发送8位
返回值:无
备  注:无
作  者:
时  间:2024-3-20
*****************************************************************/
void TM1629D_SendData(uint8_t addr, uint8_t data)
{
    TM1629D_Send_Command(0x40);//写数据

    if (BOOT_CS_Flag==0)
        BOOT_TM1629D_CS_PIN_L;  // 片选拉低
    else
        BOOT_TM1629D_CS1_PIN_L;  // 片选拉低

    // 发送地址
    for (int i = 0; i < 8; i++)
    {
        BOOT_TM1629D_SCK_PIN_L;  // 时钟拉低

        if (addr & 0x01)
        {
            BOOT_TM1629D_SDA_PIN_H;  // 数据引脚拉高
        }
        else
        {
            BOOT_TM1629D_SDA_PIN_L;  // 数据引脚拉低
        }

        lcd_delay_us(10);
        BOOT_TM1629D_SCK_PIN_H;  // 时钟拉高
        addr >>= 1;
    }

    // 发送数据
    for (int i = 0; i < 8; i++)
    {
        BOOT_TM1629D_SCK_PIN_L;  // 时钟拉低

        if (data & 0x01)
        {
            BOOT_TM1629D_SDA_PIN_H;  // 数据引脚拉高
        }
        else
        {
            BOOT_TM1629D_SDA_PIN_L;  // 数据引脚拉低
        }

        lcd_delay_us(10);
        BOOT_TM1629D_SCK_PIN_H;  // 时钟拉高
        data >>= 1;
    }

    if (BOOT_CS_Flag==0)
        BOOT_TM1629D_CS_PIN_H;  // 片选拉低
    else
        BOOT_TM1629D_CS1_PIN_H;  // 片选拉低
}
void TM1629D_WriteAddressData(uint8_t addr, uint8_t data) //TM1638指定地址写数据函数
{
    TM1629D_Send_Command(0x44); //显示模式-固定地址
    TM1629D_Send_Command(addr); //写显示地址
    TM1629D_Send_8bit(data);    //写显示数据

    if (BOOT_CS_Flag==0)
        BOOT_TM1629D_CS_PIN_H;  // 片选拉低
    else
        BOOT_TM1629D_CS1_PIN_H;  // 片选拉低
}
void DisplayON(void)
{
    TM1629D_Send_Command(0x8f);//显示控制-显示开
}
void DisplayOFF(void)
{
    TM1629D_Send_Command(0x80);//显示控制-显示关
}

/*****************************************************************
函数名:Displayclean
功  能:清空TM1629D显存
参  数:无
返回值:无
备  注:在实时显示时,需要刷新
作  者:
时  间:2024-3-20
*****************************************************************/
int lcd_temp[16]={0};
void Displayclean_test(uint8_t pot_num)
{
    
    int num=0;
    for (int i=0; i<16; i+=1)
      {
         lcd_temp[i]&=~pot[pot_num];
      }
     TM1629D_Send_Command(0x40);                            //设置写显存数据命令
    TM1629D_Send_Command(0xC0);                            //设置起始地址
     for(int i=0;i<16;i++)
     {
     TM1629D_SendData(0xc0+i, lcd_temp[i]);
     }
      TM1629D_Send_Command(0x8b);                            //亮度
}
void Displayclean()
{
    boot_iy=0;
    boot_arr_pot_9=0;
    boot_arr_pot_10=0;
    memset(boot_arr, 0, sizeof(boot_arr));
    memset(boot_arr2, 0, sizeof(boot_arr2));
    // 发送数据清空LCD显示内容
     BOOT_CS_Flag=1;
    for(int i=0;i<2;i++)
    {
        BOOT_CS_Flag=i;
    TM1629D_SendData(0xc0, 0x00);
    TM1629D_SendData(0xc1, 0x00);
    TM1629D_SendData(0xc2, 0x00);
    TM1629D_SendData(0xc3, 0x00);
    TM1629D_SendData(0xc4, 0x00);
    TM1629D_SendData(0xc5, 0x00);
    TM1629D_SendData(0xc6, 0x00);
    TM1629D_SendData(0xc7, 0x00);
    TM1629D_SendData(0xc8, 0x00);
    TM1629D_SendData(0xc9, 0x00);
    TM1629D_SendData(0xca, 0x00);
    TM1629D_SendData(0xcb, 0x00);
    TM1629D_SendData(0xcc, 0x00);
    TM1629D_SendData(0xcd, 0x00);
    TM1629D_SendData(0xce, 0x00);
    TM1629D_SendData(0xcf, 0x00);
     
    }
}
/*****************************************************************
函数名:Display_Num_Pot
功  能:显示数字
参  数:uint8_t pot_num:要显示的位置0-9,右边为0-4,左边为5-9
                uint8_t buf:要显示的数字0123456789
返回值:无
备  注:无
作  者:
时  间:2024-3-20
*****************************************************************/


void Display_Num_Pot(uint8_t pot_num, uint8_t buf, uint8_t mode,uint8_t flag)
{
    int num=0;
    pot_num=pot[pot_num];
    buf=code[buf];
    
    if (mode==1)
        buf|=0x80;
     
    if (pot_num==0xfe)
    {
        for (int i=0; i<16; i+=2)
        {

            if (buf&(1<<num)&&flag)
            {
                         lcd_temp[i]|=1;
            }
                else
                {
                        lcd_temp[i]&=~1;
                }
            num++;
        }
    }
    else if (pot_num==0xff)
    {
        for (int i=0; i<16; i+=2)
        {
            if (buf&(1<<num)&&flag)
            {
                    lcd_temp[i]|=2;
            }
                else
                 {
                lcd_temp[i]&=~2;
                 }
            num++;
        }
    }
    else  if ((pot_num!=0xff)&&(pot_num!=0xfe))
    {
        for (int i=0; i<16; i+=2)
        {
            if (buf&(1<<num)&&flag)
            {
                         lcd_temp[i]|=pot_num;
            }
                else
                {
                  lcd_temp[i]&=~pot_num;
                }
            num++;
        }
    }
     TM1629D_Send_Command(0x40);                            //设置写显存数据命令
    TM1629D_Send_Command(0xC0);                            //设置起始地址
     for(int i=0;i<16;i++)
     {
     TM1629D_SendData(0xc0+i, lcd_temp[i]);
     }
      TM1629D_Send_Command(0x8b);                            //亮度
}

/*****************************************************************
函数名:Display_Str
功  能:显示字符串
参  数:uint8_t star:要显示的位置0-9,右边为0-4,左边为5-9
                char* buf:要显示的字符 0123456789abcdefghijk...z,不分大小写
                字符自动后移
返回值:无
备  注:字符自动后移不要超出10位,否则显示不对,led灯也会亮起
作  者:
时  间:2024-3-20
*****************************************************************/
void Display_Str(uint8_t star, char* buf, uint8_t flag)
{
     static int g;
     int temp=0;
    if (flag==0)
    {
        BOOT_CS_Flag=0;
    }
    else
    {
        BOOT_CS_Flag=1;
    }
     temp=atof(buf);
     if(temp<10)
     {
        Display_Num_Pot(0, *buf-48, 0,0);
        star++;
     }
     else if(temp<100)
    {
        Display_Num_Pot(0, *buf-48, 0,0);
        star++;
    }
      else if(temp<1000)
      {
          Display_Num_Pot(0, *buf-48, 0,0);
          star++;
      }
      else if(temp<10000)
      {
            Display_Num_Pot(0, *buf-48, 0,0);
           star++;
      }
      
     while (*buf!=0)
    {
        if (*buf==' ')
        {
            buf++;
            star++;
        }
        if (*buf>57)
        {
            if (*buf>=97)
            {
                Display_Num_Pot(star, (*buf-87), 0,1);
            }
            else
            {
                Display_Num_Pot(star, (*buf-55), 0,1);
            }
        }
        else
        {
            if (*(buf+1)=='.')
            {
                Display_Num_Pot(star, *buf-48, 1,1);
                buf++;
            }
            else
            {
                Display_Num_Pot(star, *buf-48, 0,1);
            }
        }
        buf++;
        star++;
    
    }
}
void Display_VPG()
{
    static int i=0;

    switch (i)
    {
        case 0:
            TM1629D_SendData(0xcf, (0x01));
            lcd_delay_ms(100);
            break;

        case 1:
            TM1629D_SendData(0xcf, (0x03));
            lcd_delay_ms(100);
            break;

        case 2:
            TM1629D_SendData(0xce, (0x01));
            lcd_delay_ms(100);
            break;

        case 3:
            TM1629D_SendData(0xce, (0x03));
            lcd_delay_ms(100);
            break;

        case 4:
            TM1629D_SendData(0xce, (0x07));
            lcd_delay_ms(100);
            break;

        case 5:
            TM1629D_SendData(0xce, (0x0f));
            lcd_delay_ms(100);
            break;

        case 6:
            TM1629D_SendData(0xce, (0x1f));
            lcd_delay_ms(100);
            break;

        case 7:
            TM1629D_SendData(0xce, (0));
            TM1629D_SendData(0xcf, (0));
            lcd_delay_ms(100);
            break;
    }
    i++;
    i%=8;
}
/*****************************************************************
函数名:TM1629D_read_comd
功  能:对TM1629D发送读命令
参  数:uint8_t cmd:直接填0x42
返回值:无
备  注:对TM1629D发送读命令,后不需要再拉高CS
作  者:
时  间:2024-3-21
*****************************************************************/
void TM1629D_read_comd(uint8_t cmd)
{
    BOOT_TM1629D_CS_PIN_H;  // 片选拉高
    lcd_delay_us(1);
    BOOT_TM1629D_CS_PIN_L;  // 片选拉低

    for (int i = 0; i < 8; i++)
    {
        BOOT_TM1629D_SCK_PIN_L;  // 时钟拉低

        if (cmd & 0x01)
        {
            BOOT_TM1629D_SDA_PIN_H;  // 数据引脚拉高
        }
        else
        {
            BOOT_TM1629D_SDA_PIN_L;  // 数据引脚拉低
        }

        lcd_delay_us(2);
        BOOT_TM1629D_SCK_PIN_H;  // 时钟拉高
        cmd >>= 1;
    }

    BOOT_TM1629D_CS_PIN_L;  // 片选拉低
}

/*****************************************************************
函数名:readTM1629DData
功  能:对TM1629D读数据,数据保存到key_Num
参  数:无
返回值:无
备  注:该函数目前只读一个字节,
                如果需要读四个字节,
                可以去掉注释把数据保存到数组中
作  者:
时  间:2024-3-21
*****************************************************************/
uint8_t key_Num=0;
void readTM1629DData()
{
    int i;
    TM1629D_read_comd(0x42);
    BOOT_TM1629D_CS_PIN_L;  // 片选拉低

    BOOT_TM1629D_SDA_PIN_H;
    lcd_delay_us(5);

    //  for(int j=0;j<4;j++)
    //  {
    for (i=0; i<8; i++)
    {
        BOOT_TM1629D_SCK_PIN_L;  // 时钟拉低
        key_Num>>=1;
        BOOT_TM1629D_SCK_PIN_H;  // 时钟拉高
        lcd_delay_us(2);
        if (HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_2))
            key_Num|=0x80;
    }

    //  }
    BOOT_TM1629D_SCK_PIN_L;  // 时钟拉低
    BOOT_TM1629D_SDA_PIN_L;
    BOOT_TM1629D_CS_PIN_H;  // 片选拉高
}

/*****************************************************************
函数名:Display_led_OFF
功  能:关闭led灯
参  数:uint8_t buf:要关灯的位置
返回值:无
备  注:led灯从左到右为 7 5 1 2 4 3 6 0
作  者:
时  间:2024-3-20
*****************************************************************/
void Display_led_OFF(uint8_t buf)
{
    switch (buf)
    {
        case 0:
            TM1629D_SendData(0xc1, 0);
            break;

        case 1:
            TM1629D_SendData(0xc3, 0);
            break;

        case 2:
            TM1629D_SendData(0xc5, 0);
            break;

        case 3:
            TM1629D_SendData(0xc7, 0);
            break;

        case 4:
            TM1629D_SendData(0xc9, 0);
            break;

        case 5:
            TM1629D_SendData(0xcb, 0);
            break;

        case 6:
            TM1629D_SendData(0xcd, 0);
            break;

        case 7:
            TM1629D_SendData(0xcf, 0);
            break;
    }
}
/*****************************************************************
函数名:Display_led_ON
功  能:开启led灯
参  数:uint8_t buf:要开灯的位置
返回值:无
备  注:led灯从左到右为 7 5 1 2 4 3 6 0
作  者:
时  间:2024-3-20
*****************************************************************/
void Display_led_ON(uint8_t buf)
{

    switch (buf)
    {
        case 0:
            TM1629D_SendData(0xc1, 4);
            break;

        case 1:
            TM1629D_SendData(0xc3, 4);
            break;

        case 2:
            TM1629D_SendData(0xc5, 4);
            break;

        case 3:
            TM1629D_SendData(0xc7, 4);
            break;

        case 4:
            TM1629D_SendData(0xc9, 4);
            break;

        case 5:
            TM1629D_SendData(0xcb, 4);
            break;

        case 6:
            TM1629D_SendData(0xcd, 4);
            break;

        case 7:
            TM1629D_SendData(0xcf, 4);
            break;
    }
}

flag My_flag= {0, 0, 9, 0.001, 0.001};
/*****************************************************************
函数名:TM1629D_Read_key
功  能:读取按键按下
参  数:无
返回值:第几个按键按下,1-8
备  注:从左到右分别为 1 4 3 2 8 7 6 1
作  者:
时  间:2024-3-21
*****************************************************************/
uint8_t TM1629D_Read_key(void)
{
    uint8_t keyState=0;
    readTM1629DData();

    if (key_Num!=0x00)
    {
        if (key_Num==0x01)
            keyState=1;

        else if (key_Num==0x02)
        {
            keyState=2;
            My_flag.OI_OV=!My_flag.OI_OV;
        }

        else if (key_Num==0x04)
        {
            keyState=3;
            My_flag.prev--;

            if (My_flag.prev<0)My_flag.prev=9;

            switch (My_flag.prev)
            {
                case 4:
                    My_flag.I_wei=0.001;
                    break;

                case 3:
                    My_flag.I_wei=0.01;
                    break;

                case 2:
                    My_flag.I_wei=0.1;
                    break;

                case 1:
                    My_flag.I_wei=1;
                    break;

                case 0:
                    My_flag.I_wei=1;
                    break;

                case 9:
                    My_flag.V_wei=0.001;
                    break;

                case 8:
                    My_flag.V_wei=0.01;
                    break;

                case 7:
                    My_flag.V_wei=0.1;
                    break;

                case 6:
                    My_flag.V_wei=1;
                    break;

                case 5:
                    My_flag.V_wei=1;
                    break;
            }
        }
        else if (key_Num==0x08)
            keyState=4;

        else if (key_Num==0x10)
            keyState=5;

        else if (key_Num==0x20)
        {
            keyState=6;
            My_flag.On_Off=!My_flag.On_Off;
        }

        else if (key_Num==0x40)
            keyState=7;

        else if (key_Num==0x80)
            keyState=8;

        //BEEP();

//        while (key_Num!=0x00)
//        {
//            readTM1629DData();
//        }
    }

    return keyState;

}
谢谢浏览,有需要完整的程序可以加QQ153443979或者私我。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值