TM1621E 驱动程序
- TM1621E 芯片引脚
- TM1621E 发送数据
- TM1621E 发送指令
- TM1621E 写入时序
- 屏幕真值表
- 完整驱动
- 显示函数
TM1621E 芯片引脚
CS——片选引脚,低电平有效。
WR——数据输入,在WR信号的上升沿,DATA 线上的数据写到TM1621E。
DATA——串行数据输入/输出。
COM0-COM3——4个COM口
SEG8、SEG11、SEG14、SEG17、SEG20、SEG23——6个SEG段输出端口
TM1621E 发送数据
- 写模式
格式: 写数据操作码101 + 6位写地址 + 4位写数据
注意:
① 如图所示,写地址时高位在前,写数据时低位在前。
② 注意与TM1622的区别,TM1622的COM口有8个,它的数据位是8位。
/*
HT1621写入数据
HT1621写入数据要求4位,输入数据8位,低位在前。所以程序中操作左移4位。
*/
void HT1621Wr_byte(uchar addr,uchar data)
{
addr <<= 2;
data <<= 4;
HT1621_CS(0); //HT1621_CS = 1;
HT1621Wr(0xa0,3); //写入命令101
HT1621Wr(addr,6); //写入地址
HT1621Wr(data,4); //写入数据
HT1621_CS(1); //HT1621_CS = 0;
delay_us(5);
delay_us(5);
}
- 连续写模式
格式: 写数据操作码101 + 6位写地址 + 4位写数据+4位写数据+…
/*
HT1621连续写入函数
addr为写入初始地址,dat为写入数据,cnt为写入数据总数
注意:HT1621写入数据4位,如果是HT1622写入数据是8位,因为HT1622有8个COM口
这里输入的写入数据为8位,程序里有左移操作
*/
void HT1621Wr_AllData(uchar addr,uchar *p,uchar cnt)
{
uchar i;
addr <<= 2;
HT1621_CS(0);
HT1621Wr(0xa0,3); //写入命令
HT1621Wr(addr,6); //写入地址
for(i=0;i<cnt;i++,p++)
{
*p <<= 4; //HT1621写入4位,输入数据是低位在前,这里左移4位
HT1621Wr(*p,4); //写入数据
}
HT1621_CS(1);
delay_us(5);
}
TM1621E 发送指令
如图所示,根据手册中的命令概述,可以得到指令的命令格式。编写一个宏定义,将需要用到的命令定义。
//TM1621模块命令定义
#define SYSDIS 0x00 //关系统振荡器和LCD偏压发生器
#define SYSEN 0x02 //打开系统振荡器
#define LCDOFF 0x04 //关LCD偏压
#define LCDON 0x06 //开LCD偏压
#define RC 0x30 //内部RC振荡
#define BIAS 0x52 //1/3偏压 4公共口
根据命令时序图,发送命令的格式为:命令操作数100 + 9位的命令代码,宏定义时,定义的是后8位,因为我们使用的操作命令,在操作数100后的第一位都是0,在代码发送中,使用的是"HT1621Wr(0x80,4);"截取了4位,前3位是100,第4位是0,后面只需发送8位控制命令即可。
//HT1621命令写入函数
void HT1621Wr_cmd(uchar cmd)
{
HT1621_CS(0); // HT1621_CS = 0;
delay_us(5);
HT1621Wr(0x80,4); // 写入命令100
HT1621Wr(cmd,8); // 写入控制命令
HT1621_CS(1); // HT1621_CS = 1;
delay_us(5);
}
TM1621E 写入时序
在发送数据中提到“写地址时高位在前,写数据时低位在前。”
下面的代码中:
写入地址——例如:8 <<= 2; HT1621Wr(8,6); 表示先将8左移2位,再截取前6位写入,写入的效果是(001000)。
写入数据——例如:0x0A <<= 4; HT1621Wr(0xA0,4); 写入效果是(1010)。
/*
数据写入时序
data为数据,cnt为传送数据位数,数据传送低位在前
HT1621地址写入是从高位开始写
HT1621数据写入是从低位开始写
*/
void HT1621Wr(uchar data,uchar cnt)
{
uchar i;
for(i=0;i<cnt;i++)
{
HT1621_WR(0); //HT1621_WR = 0;
delay_us(5);
if(data&0x80)
{
HT1621_DAT(1); //HT1621_DAT = 1;
}
else
{
HT1621_DAT(0); //HT1621_DAT = 0;
}
delay_us(5);
HT1621_WR(1); //HT1621_WR = 1;
delay_us(5);
data <<= 1;
}
}
屏幕真值表
以此屏幕为例,如果想要让数码管1显示数字5,需要点亮1A,1F,1G,1C,1D,向地址pin2中发送数据0x0B,地址pin1中发送数据0x0C即可。
使用上面的代码即可实现:
HT1621Wr_byte(8,0x0C);
HT1621Wr_byte(11,0x0B);
此段代码,芯片引脚SEG8接的是屏幕pin1,SEG11接的是屏幕引脚pin2。屏幕的COM1、COM2、COM3、COM4与芯片的COM口对应相接,如果不是这种接法,代码需要调整。
完整驱动
#include "stm32f10x.h"
#include "TM1621E.h"
extern void delay_us(u32 nus);
//TM1621模块命令定义
#define SYSDIS 0x00 //关系统振荡器和LCD偏压发生器
#define SYSEN 0x02 //打开系统振荡器
#define LCDOFF 0x04 //关LCD偏压
#define LCDON 0x06 //开LCD偏压
#define RC 0x30 //内部RC振荡
#define BIAS 0x52 //1/3偏压 4公共口
void HT1621_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(HT1621_CS_GPIO_CLK | HT1621_WR_GPIO_CLK | HT1621_DAT_GPIO_CLK, ENABLE);
GPIO_InitStructure.GPIO_Pin = HT1621_CS_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(HT1621_CS_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = HT1621_WR_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(HT1621_WR_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = HT1621_DAT_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(HT1621_DAT_GPIO_PORT, &GPIO_InitStructure);
GPIO_SetBits(HT1621_CS_GPIO_PORT,HT1621_CS_GPIO_PIN);
GPIO_SetBits(HT1621_WR_GPIO_PORT,HT1621_WR_GPIO_PIN);
GPIO_SetBits(HT1621_DAT_GPIO_PORT,HT1621_DAT_GPIO_PIN);
}
/*
数据写入时序
data为数据,cnt为传送数据位数,数据传送低位在前
HT1621地址写入是从高位开始写
HT1621数据写入是从低位开始写
*/
void HT1621Wr(uchar data,uchar cnt)
{
uchar i;
for(i=0;i<cnt;i++)
{
HT1621_WR(0); //HT1621_WR = 0;
delay_us(5);
if(data&0x80)
{
HT1621_DAT(1); //HT1621_DAT = 1;
}
else
{
HT1621_DAT(0); //HT1621_DAT = 0;
}
delay_us(5);
HT1621_WR(1); //HT1621_WR = 1;
delay_us(5);
data <<= 1;
}
}
/*
HT1621写入数据
HT1621写入数据要求4位,输入数据8位,低位在前。所以程序中操作左移4位。
*/
void HT1621Wr_byte(uchar addr,uchar data)
{
addr <<= 2;
data <<= 4;
HT1621_CS(0); //HT1621_CS = 1;
HT1621Wr(0xa0,3); //写入命令101
HT1621Wr(addr,6); //写入地址
HT1621Wr(data,4); //写入数据
HT1621_CS(1); //HT1621_CS = 0;
delay_us(5);
delay_us(5);
}
/*
HT1621连续写入函数
addr为写入初始地址,dat为写入数据,cnt为写入数据总数
注意:HT1621写入数据4位,如果是HT1622写入数据是8位,因为HT1622有8个COM口
这里输入的写入数据为8位,程序里有左移操作
*/
void HT1621Wr_AllData(uchar addr,uchar *p,uchar cnt)
{
uchar i;
addr <<= 2;
HT1621_CS(0);
HT1621Wr(0xa0,3); //写入命令
HT1621Wr(addr,6); //写入地址
for(i=0;i<cnt;i++,p++)
{
*p <<= 4; //HT1621写入4位,输入数据是低位在前,这里左移4位
HT1621Wr(*p,4); //写入数据
}
HT1621_CS(1);
delay_us(5);
}
//HT1621命令写入函数
void HT1621Wr_cmd(uchar cmd)
{
HT1621_CS(0); // HT1621_CS = 0;
delay_us(5);
HT1621Wr(0x80,4); // 写入命令100
HT1621Wr(cmd,8); // 写入控制命令
HT1621_CS(1); // HT1621_CS = 1;
delay_us(5);
}
//HT1621初始化
void HT1621_Init(void)
{
HT1621_GPIO_Init(); //HT1621 GPIO初始化
HT1621_CS(1); //HT1621_CS = 1;
HT1621_WR(1); //HT1621_WR = 1;
HT1621_DAT(1); //HT1621_DAT = 1;
delay_us(5);
delay_us(5);
HT1621Wr_cmd(SYSDIS); // 关振系统荡器和LCD偏压发生器
HT1621Wr_cmd(BIAS); // 1/3duty 4com
HT1621Wr_cmd(LCDON); // - - 打开lcd偏压
HT1621Wr_cmd(RC); // 使用内部振荡器
HT1621Wr_cmd(SYSEN); // - - 打开系统振荡器
}
#ifndef __TM1621E_H
#define __TM1621E_H
#include "stm32f10x.h"
#define uchar unsigned char
#define uint unsigned int
#define HT1621_CS_GPIO_PORT GPIOB /* GPIO端口 */
#define HT1621_CS_GPIO_CLK RCC_APB2Periph_GPIOB /* GPIO端口时钟 */
#define HT1621_CS_GPIO_PIN GPIO_Pin_12
#define HT1621_WR_GPIO_PORT GPIOB /* GPIO端口 */
#define HT1621_WR_GPIO_CLK RCC_APB2Periph_GPIOB /* GPIO端口时钟 */
#define HT1621_WR_GPIO_PIN GPIO_Pin_13
#define HT1621_DAT_GPIO_PORT GPIOB /* GPIO端口 */
#define HT1621_DAT_GPIO_CLK RCC_APB2Periph_GPIOB /* GPIO端口时钟 */
#define HT1621_DAT_GPIO_PIN GPIO_Pin_14
#define HT1621_CS(a) if (a) \
GPIO_SetBits(HT1621_CS_GPIO_PORT,HT1621_CS_GPIO_PIN);\
else \
GPIO_ResetBits(HT1621_CS_GPIO_PORT,HT1621_CS_GPIO_PIN)
#define HT1621_WR(a) if (a) \
GPIO_SetBits(HT1621_WR_GPIO_PORT,HT1621_WR_GPIO_PIN);\
else \
GPIO_ResetBits(HT1621_WR_GPIO_PORT,HT1621_WR_GPIO_PIN)
#define HT1621_DAT(a) if (a) \
GPIO_SetBits(HT1621_DAT_GPIO_PORT,HT1621_DAT_GPIO_PIN);\
else \
GPIO_ResetBits(HT1621_DAT_GPIO_PORT,HT1621_DAT_GPIO_PIN)
void HT1621_Init(void);
void HT1621Wr(uchar data,uchar cnt);
void HT1621Wr_byte(uchar addr,uchar data);
void HT1621Wr_AllData(uchar addr,uchar *p,uchar cnt);
void HT1621Wr_cmd(uchar cmd);
#endif
显示函数
/* 0 1 2 3 4 5 6 7 8 9 - */
unsigned char num1[24]={0x0A,0x0F,0x00,0x06,0x06,0x0D,0x04,0x0F,0x0C,0x06,0x0C,0x0B,0x0E,0x0B,0x00,0x0E,0x0E,0x0F,0x0C,0x0F,0x04,0x00,0x00,0x00};
unsigned char lcdnum[32]={0};
//num的范围是0-99
void Dispaly_Number(uint8_t num)
{
u8 i=0,shi=0,ge=0;
//清屏
for(i=0;i<32;i++)
{
lcdnum[i]=0x00;
}
HT1621Wr_AllData(0,lcdnum,32);
//显示输入数据
shi = num/10;
ge = num%10;
lcdnum[8]=num1[shi*2];
lcdnum[11]=num1[shi*2+1];
lcdnum[14]=num1[ge*2];
lcdnum[17]=num1[ge*2+1];
HT1621Wr_AllData(0,lcdnum,32);
}