数据手册:TM1638芯片详细手册.pdf

TM1638芯片同时支持LED控制与矩阵键盘扫描,数据通过仅3根线传输
549cc66029cb8dd7a3235c245be4a7383c2.png
26_DIO 数据I/O(数据低位开始)
27_CLK 时钟I(上升沿有效)
28_STB 片选I ( 在上升或下降沿初始化串行接口,随后等待接收指令。 STB 为低后的第一个字节作为指令)
557512acdb0937b85044d96eb92f09d5fdf.png
以这3个引脚为例配置好GPIO
5587eaed92381a2a9295921a3b22f62b7ff.png

/******************************************************************************/
//引脚控制定义
#define DIO_0   HAL_GPIO_WritePin(TM1638_DIO_GPIO_Port,TM1638_DIO_Pin,0)
#define DIO_1   HAL_GPIO_WritePin(TM1638_DIO_GPIO_Port,TM1638_DIO_Pin,1)
#define CLK_0 HAL_GPIO_WritePin(TM1638_DIOA5_GPIO_Port,TM1638_DIOA5_Pin ,0)
#define CLK_1 HAL_GPIO_WritePin(TM1638_DIOA5_GPIO_Port,TM1638_DIOA5_Pin ,1)
#define STB_0 HAL_GPIO_WritePin(TM1638_DIOA7_GPIO_Port,TM1638_DIOA7_Pin,0)
#define STB_1 HAL_GPIO_WritePin(TM1638_DIOA7_GPIO_Port,TM1638_DIOA7_Pin,1)
/******************************************************************************/


char dis_buff[8]={0x39,0x38,0x3F,0x6D,0x79,0,0,0};    //显存   8个字节的显存-_-

char num[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};//0-f字膜

void DIO_IN_OR_OUT(char a)                            //设置DIO输入或者输出  a=0时输入,a=1时输出
{
    GPIO_InitTypeDef GPIO_InitStruct;             //引脚设置的结构体  参考HAL库手册                
    if(a==0)
    {
        GPIO_InitStruct.Pin = TM1638_DIO_Pin;
        GPIO_InitStruct.Mode = GPIO_MODE_INPUT;//设为输入
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        HAL_GPIO_Init(TM1638_DIO_GPIO_Port, &GPIO_InitStruct);
    }
    if(a==1)
    {
        GPIO_InitStruct.Pin = TM1638_DIO_Pin;
        GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;//设为输出
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        HAL_GPIO_Init(TM1638_DIO_GPIO_Port, &GPIO_InitStruct);
    }
}

void TM1638_Write(char data)      //向芯片写入数据
{
    char a,ddata;             //缓存。。
    ddata=data;               //当时不知道发什么神经要这样写 问题不大
    DIO_IN_OR_OUT(1);         //把DIO设为输出
    for(a=0;a<8;a++)          //发送8位数据
    {
        CLK_0;            //拉低时钟线
        //HAL_Delay(1);
        if(ddata&0x01)    //最低位先开
        {
            DIO_1;
        }else
        {
            DIO_0;
        }
        CLK_1;             //1个位数据准备好后时钟拉高发送数据
        //HAL_Delay(1);
        ddata>>=1;       //数据向右移动
    }
}


char TM1638_Read()            //从芯片读取数据
{
    char a,data=0;        //缓存
    DIO_IN_OR_OUT(0);     //将引脚设为输入
    for(a=0;a<8;a++)      //读取8个数据
    {
        data>>=1;    //先位移数据,防止最后一位数据丢失
        CLK_0;       //拉低时钟
        //HAL_Delay(1);
        if(HAL_GPIO_ReadPin(TM1638_DIO_GPIO_Port,TM1638_DIO_Pin))  //直接读取DIO引脚状态
        {
            data|=0x80;    //因为是从最低位开始读所以把数据放在最高位,一位一位的推到最低位
        }
        CLK_1;
        //HAL_Delay(1);
    }
    return data;         //返回最后数据
}    


void TM1638_COM(char com)    //发送命令(参考下面图1)
{
    STB_0;
    TM1638_Write(com);
    STB_1;
}


void Write_DATA(unsigned char add,unsigned char DATA)  //向芯片某个地址发送数据(参考图2)     
{
    STB_0;
    TM1638_Write(0xc0|add);
    TM1638_Write(DATA);
    STB_1;
}



char TM1638_Read_Key()     //读取按键键值
{
    char key_buff[4];
    char a,key_value=0;//键值buff
    STB_0;
    TM1638_Write(0x42);//根据数据手册先发送0x42
    for(a=0;a<4;a++)   //后连续读4个数据
    {
        key_buff[a]=TM1638_Read();
    }
    if((key_buff[0]==0)&(key_buff[1]==0)&(key_buff[2]==0)&(key_buff[3]==0))
    {
        return 16;   //如果4个数据都是0说明没按键被按下(因为我只设计了16个按键键值是0-15,所以16是不存在的按键作为nothing的依据)
    }
    for(a=0;a<4;a++)    //这里是矩阵键盘的算法
    {
        if(a==0)
        {
            if(key_buff[a]==2)
            {
                key_value=0x07;
            }
            if(key_buff[a]==4)
            {
                key_value=0x01;
            }
            if(key_buff[a]==32)
            {
                key_value=0x08;
            }
            if(key_buff[a]==64)
            {
                key_value=0x02;
            }
        }
        if(a==1)
        {
            if(key_buff[a]==2)
            {
                key_value=0x09;
            }
            if(key_buff[a]==4)
            {
                key_value=0x03;
            }
            if(key_buff[a]==32)
            {
                key_value=0x0c;
            }
            if(key_buff[a]==64)
            {
                key_value=0x0a;
            }
        }
        if(a==2)
        {
            if(key_buff[a]==2)
            {
                key_value=0x0e;
            }
            if(key_buff[a]==4)
            {
                key_value=0x04;
            }
            if(key_buff[a]==32)
            {
                key_value=0x00;
            }
            if(key_buff[a]==64)
            {
                key_value=0x05;
            }
        }
        if(a==3)
        {
            if(key_buff[a]==2)
            {
                key_value=0x0f;
            }
            if(key_buff[a]==4)
            {
                key_value=0x06;
            }
            if(key_buff[a]==32)
            {
                key_value=0x0d;
            }
            if(key_buff[a]==64)
            {
                key_value=0x0b;
            }
        }
    }
        return key_value;    //返回键值


}

void Display()    //显示输出(需要循环调用)参考图3
{
    char a; 
    TM1638_COM(0x44);    //采用固定地址模式
    for(a=0;a<8;a++)
    {
        Write_DATA(a*2,dis_buff[a]);//因为地址在双数位置所以要*2  参考图4
    }
    TM1638_COM(0x8f);   //设置亮度
}


/*****************************/
//调用
void main()
{
    char key_v;//按键键值缓存
    while(1)
    {
        //修改dis_buff[8]里的数据就可以控制显示的内容
        key_v=TM1638_Read_Key();//读取按键的键值
        if(key_v!=16)            //判断有按键被按下
        {
            dis_buff[0]=num[key_v];//把键值显示在数码管第一位(通过num数组转成字膜)
        }      
        Display();             //显示出来

    }
}

5521eda40e2c6ca1725d3246e03149e4a0d.png
图1
553c9f4cf38ab2267b0e060b257fde87219.png
图2
5540b8b7309a2cb953e03c96d4d8d6b9ffc.png
图3
55534be44c1e413b58db4648bf3ea79386c.png
图4

最后修改:2020 年 06 月 28 日
声明:无闻风博客|版权所有,违者必究|如未注明,均为原创| 转载:转载请注明原文链接