目录
一、LM1640引脚说明
二、LM1640时序分析
三、LM1640指令分析
四、LM1620芯片驱动程序分析
1、LM1640的声明文件
2、LM1640读写数据的底层通信程序
3、LM1640应用层程序
五、LM1640硬件线路连接图
TM1640 是一种LED(发光二极管显示器)驱动控制与用电路,内部集成有MCU 数字接口、数据锁存器、LED 驱动等电路。本产品性能优良,质量可靠。主要应用于电子产品LED显示屏驱动。采用SOP28的封装形式。采用两线串行接口(SCLK,DIN) 总线输入方式。
LM1640功能强大,还可以设值数码管显示的亮度。
LM1640是8位段选输出,16位位选输出(可以控制16个数码管)
微处理器的数据通过两线总线接口和TM1640 通信,在输入数据时当CLK 是高电平时,DIN 上的信号必须保持不变;只有CLK 上的时钟信号为低电平时,DIN 上的信号才能改变。数据的输入总是低位在前,高位在后传输.数据输入的开始条件是CLK 为高电平时,DIN 由高变低;结束条件是CLK 为高时,DIN 由低电平变为高电平。
这就说明数据的传输需要有一个开始信号和一个结束信号。
LM1640还有一个地址自动加一的数据传输模式,通过LM1640命令系统开启和关闭。该模式对于单字节数据的传输也采用上述数据传输时序,只是在连续传输数据是不用向固定地址传输那样一个地址一个数据的传输,而是写入一个地址后连续写入多个数据。
LM1640有三种不同的指令,以最高两位的编码来区分。
通过DIN输入的第一个字节作为一条指令,输入0x40 是地址自动加一模式,输入0x44是固定地址模式。
这里的地址就是数码管的显示地址,想让哪个数码管显示,就向对应的地址中写入数据,相当于位选了。
显示控制命令用来设置数码管亮度。
在LM1640.h文件中对LM1640的各种指令进行宏定义,方便程序中进行设置。
#ifndef __TM1640_H__
#define __TM1640_H__
//头文件
#include "sys.h"
//定义IO接口
#define TM1640_GPIOPORT GPIOA
#define TM1640_DIN GPIO_Pin_12
#define TM1640_SCLK GPIO_Pin_11
#define TM1640_LEDPORT 0xc8 //用到芯片中的第9位选 GRID9
//通信速率定义
#define DEL 1 //通信速率(默认为1 通信速度最快)如果不能通信可以加大数值,减慢速度
//地址模式的设置
//#define TM1640Mode_Addr 0x40 //自动加1模式
#define TM1640Mode_Addr 0X44 //固定地址模式(推荐)
//显示亮度的设置
//#define TM1640Mode_Display 0x88 //亮度最小
//#define TM1640Mode_Display 0x89 //亮度
//#define TM1640Mode_Display 0x8a //亮度
//#define TM1640Mode_Display 0x8b //亮度
#define TM640Mode_Display 0x8c //亮度 (推荐)
//#define TM1640Mode_Display 0x8d //亮度
//#define TM1640Mode_Display 0x8f //亮度最大
#define TM640Mode_Display_Off 0x80 //亮度关
//函数声明
//底层通信协议
void TM1640_Start(void);
void TM1640_Write(u8 data);
void TM1640_Stop(void);
//初始化
void TM1640_Init(void);
//显示函数
void TM1640_LED(u8 data);
void TM1640_Display(u8 addr, u8 data);
void TM1640_Display_Add(u8 addr, u8 data);
#endif
LM1640的底层通信程序由开始条件,写入指令数据,结束条件三部分组成,TM1640_Start()、TM1640_Write(u8 data)、TM1640_Stop()三个构成完整的底层通信协议。
/********************************************************************************
函数:TM1640_Start()
功能:TM1640通信时序开始条件
参数:无
返回值:无
********************************************************************************/
void TM1640_Start(void)
{
GPIO_WriteBit(TM1640_GPIOPORT, TM1640_DIN, (BitAction)(1));
GPIO_WriteBit(TM1640_GPIOPORT, TM1640_SCLK, (BitAction)(1)); //起始都置高
delay_us(DEL); //DEL 1 通信速率(默认为1 通信速度最快)如果不能通信可以加大数值,减慢速度
//数据输入的开始条件是CLK 为高电平时,DIN 由高变低
GPIO_WriteBit(TM1640_GPIOPORT, TM1640_DIN, (BitAction)(0));
delay_us(DEL);
GPIO_WriteBit(TM1640_GPIOPORT, TM1640_SCLK, (BitAction)(0)); //SCLK也置低
delay_us(DEL);
}
/********************************************************************************
函数:TM1640_Stop()
功能:TM1640通信时序结束条件
参数:无
返回值:无
********************************************************************************/
void TM1640_Stop(void)
{
GPIO_WriteBit(TM1640_GPIOPORT, TM1640_DIN, (BitAction)(0));
GPIO_WriteBit(TM1640_GPIOPORT, TM1640_SCLK, (BitAction)(1));//SCLK置高 DIN置低
delay_us(DEL);
//结束条件是CLK 为高时,DIN 由低电平变为高
GPIO_WriteBit(TM1640_GPIOPORT, TM1640_DIN, (BitAction)(1));
delay_us(DEL);
}
/********************************************************************************
函数:TM1640_Write(u8 data)
功能:TM1640通信时序写入数据
参数:u8 data 一个字节 8位的数据
返回值:无
********************************************************************************/
void TM1640_Write(u8 data)
{
u8 i;
u8 aa; //数据暂存变量
aa = data;
GPIO_WriteBit(TM1640_GPIOPORT, TM1640_DIN, (BitAction)(0));
GPIO_WriteBit(TM1640_GPIOPORT, TM1640_SCLK, (BitAction)(0));//SCLK与DIN都置低
for(i = 0; i < 8; i++)
{
//SCLK为低,DIN上的数据才能改变
GPIO_WriteBit(TM1640_GPIOPORT, TM1640_SCLK, (BitAction)(0));
delay_us(DEL);
if(aa & 0x01) //按位写入数据
{
GPIO_WriteBit(TM1640_GPIOPORT, TM1640_DIN, (BitAction)(1));
delay_us(DEL);
}
else
{
GPIO_WriteBit(TM1640_GPIOPORT, TM1640_DIN, (BitAction)(0));
delay_us(DEL);
}
GPIO_WriteBit(TM1640_GPIOPORT, TM1640_SCLK, (BitAction)(1)); //SCLK拉高准备写入下一位
delay_us(DEL);
aa >>= 1;
}
GPIO_WriteBit(TM1640_GPIOPORT, TM1640_DIN, (BitAction)(0));
GPIO_WriteBit(TM1640_GPIOPORT, TM1640_SCLK, (BitAction)(0)); //写完两个都置低
}
使用地址加1模式时,LM1640初始化中的地址模式命令要改为0x40。
/********************************************************************************
函数:TM1640_Init()
功能:TM1640初始化函数
参数:u8 data 一个字节 8位的数据
返回值:无
********************************************************************************/
void TM1640_Init(void)
{
//GPIO接口初始化
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = TM1640_DIN | TM1640_SCLK;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 设定推挽输出模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(TM1640_GPIOPORT, &GPIO_InitStructure);
//GPIO接口电平初始化
GPIO_WriteBit(TM1640_GPIOPORT, TM1640_DIN, (BitAction)(1));
GPIO_WriteBit(TM1640_GPIOPORT, TM1640_SCLK, (BitAction)(1));
//芯片设定初始化 用到底层通信协议内容
TM1640_Start();
TM1640_Write(TM1640Mode_Addr);//设定为固定地址模式
TM1640_Stop();
TM1640_Start();
TM1640_Write(TM640Mode_Display);//设定显示亮度
TM1640_Stop();
}
/********************************************************************************
函数:TM1640_Display(u8 addr, u8 data)
功能:数码管显示输出---固定地址模式
参数:u8 addr---位选地址, u8 data---段选数据
返回值:无
********************************************************************************/
void TM1640_Display(u8 addr, u8 data)
{
//数码管段码表 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 无 - C
const u8 buf[23] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0xbf, 0x86, 0xdb, 0xcf, 0xe6, 0xed, 0xfd, 0x87, 0xff, 0xef, 0x00, 0x40, 0x58};
TM1640_Start();
TM1640_Write(0xc0+addr); //传位选地址
TM1640_Write(buf[data]); //传段选数据
TM1640_Stop();
}
/********************************************************************************
函数:TM1640_LED(u8 data)
功能:数码管显示输出---数码管地址自动加1模式
参数:u8 addr---位选地址, u8 data---段选数据
返回值:无
********************************************************************************/
void TM1640_Display_Add(u8 addr, u8 data)
{
//数码管段码表 0 1 2 3 4 5 6 7 8 9 0. 1. 2. 3. 4. 5. 6. 7. 8. 9. 无 - C
const u8 buf[23] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0xbf, 0x86, 0xdb, 0xcf, 0xe6, 0xed, 0xfd, 0x87, 0xff, 0xef, 0x00, 0x40, 0x58};
u8 i;
TM1640_Start();
TM1640_Write(0xc0+addr); //传位选地址
for(i = 0; i < 16; i++)
{
TM1640_Write(buf[data]);
}
TM1640_Stop();
}