TM1621E 驱动程序

news2024/11/28 20:45:52

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 发送数据

  1. 写模式
    在这里插入图片描述
    格式: 写数据操作码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);
}
  1. 连续写模式
    在这里插入图片描述
    格式: 写数据操作码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);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1599203.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

健身管理小程序|基于微信开发健身管理小程序的系统设计与实现(源码+数据库+文档)

健身管理小程序目录 基于微信开发健身管理小程序设计与实现 一、前言 二、系统设计 三、系统功能设计 小程序端&#xff1a; 后台 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍&#xff1a;✌️大厂码…

Java-通过Maven导入本地jar包的常用方式

1.首先创建一个用于创建jar包的项目&#xff0c;进行测试 2.测试成功后进行项目打包 3.创建一个要导入本地jar包的项目&#xff0c;在项目下创建lib目录&#xff0c;并将刚才打包好的jar包复制进去 4.在pom.xml文件中引入 5.运行测试

fatal: Out of memory, malloc failed

git 切分支&#xff0c;或者clone仓库的时候碰到这个错误&#xff0c;看网上很多配置config文件&#xff0c;都尝试了没效果。 自测了一个可行的方式&#xff1a; 由于本人用的sourcetree 所以解决方式如下&#xff1a; git升级为最新版&#xff0c;选择系统GIt版本&#xf…

Qt编译静态链接库和动态链接库(WindowsLinux)

最近需要在Linux中编译相关程序动态库&#xff0c;对相关经验总结。 使用到的工具为Qt5.13.2 QT编译 1. WINDOWS1.1 静态库制作1.2 静态库的使用1.3 动态库制作1.4 动态库使用 2. LINUX2.1 静态链接库2.2动态库 附录gcc 编译程序查找顺序&#xff1a;Linux 程序运行时查找顺序&…

【静态分析】软件分析课程实验A1-活跃变量分析和迭代求解器

1 作业导览 为 Java 实现一个活跃变量分析&#xff08;Live Variable Analysis&#xff09;。实现一个通用的迭代求解器&#xff08;Iterative Solver&#xff09;&#xff0c;用于求解数据流分析问题&#xff0c;也就是本次作业中的活跃变量分析。 Live Variable Analysis 详…

Midjourney常见玩法及prompt关键词技巧

今天系统给大家讲讲Midjourney的常见玩法和prompt关键词的一些注意事项&#xff0c;带大家入门&#xff5e;&#xff08;多图预警&#xff0c;建议收藏&#xff5e;&#xff09; 一、入门及常见玩法 1、注册并添加服务器&#xff08;会的童鞋可跳过&#xff5e;&#xff09; …

Jmeter分布式压测操作流程

分布式压测原理 分布式压测操作 保证本机和执行机的JDK和Jmeter版本一致配置Jmeter环境变量配置Jmeter配置文件 上传每个执行机服务jmeter chmod -R 755 apache-jmeter-5.1.1/ 执行机配置写自己的ip 控制机配置所有执行机ip,把server.rmi.ssl.disable改成true 将本机也作为压…

骨传导耳机哪个品牌最好?六大压箱底干货,一看便知!

在当今的蓝牙耳机市场&#xff0c;骨传导耳机以其独特的佩戴方式逐渐晋升为耳机界的新宠。然而&#xff0c;随着骨传导耳机逐渐成为热门款式&#xff0c;市场上的骨传导耳机品牌琳琅满目&#xff0c;消费者在选购时往往感到无从下手。其中&#xff0c;还经常有人入手耳机后出现…

【知识】Latex中的em/pt/mm等长度单位及使用场景

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 目录 一、Latex中的em pt mm等度量单位说是什么意思&#xff1f;还有哪些&#xff1f; 二、在使用的时候应该如何选择&#xff1f;他们分别适用于那些场景&#xff1f; 三、有哪些使用示例&#xff1f; 1. 设…

文献学习-37-动态场景中任意形状针的单目 3D 位姿估计:一种高效的视觉学习和几何建模方法

On the Monocular 3D Pose Estimation for Arbitrary Shaped Needle in Dynamic Scenes: An Efficient Visual Learning and Geometry Modeling Approach Authors: Bin Li,† , Student Member, IEEE, Bo Lu,† , Member, IEEE, Hongbin Lin, Yaxiang Wang, Fangxun Zhong, Me…

刷代码随想录有感(33):滑动窗口滑行途中框内最大值

又是需要死记硬背理解的题目。 题干如下: 代码&#xff1a; class Solution { private:class MyQueue{deque<int> que;public:void pop(int value){if(!que.empty() && value que.front()){que.pop_front();}}void push(int value){while(!que.empty() &&…

「51媒体」媒体邀约采访的分类?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 媒体邀约采访可以根据不同的标准进行分类。以下是一些常见的分类方式&#xff1a; 1. 按照邀约形式&#xff1a; - 电话邀约&#xff1a;通过电话与媒体联系&#xff0c;说明采访或报道…

地质灾害监测预警系统:科技守护,构筑智能预警屏障

随着全球气候变化和人为活动的加剧&#xff0c;地质灾害频繁发生&#xff0c;给人们的生命财产安全带来了严重威胁。为了降低地质灾害带来的损失&#xff0c;地质灾害监测预警系统应运而生。本文将为您详细介绍地质灾害监测预警系统的原理、功能以及在实际应用中的效果。 一、地…

AI-数学-高中-37频率与概率、概率基础知识综合示例

原作者视频&#xff1a;【概率】【一数辞典】6频率与概率_哔哩哔哩_bilibili 当直接求概率不好求时&#xff0c;通过大量的实验的频率来估算概率。 在频数越大的情况下&#xff0c;波动越来越小&#xff0c;频率越稳定&#xff0c;去向一个稳定的数值&#xff0c;这个值就是概…

敢教日月换新天!SuperHarness-3D:电控行业生态圈的国产电控仿真利器!

SuperHarness-3D&#xff08;以下简称SH-3D&#xff09;是利驰软件基于三维建模软件SolidWorks平台开发的一款聚焦于电气/自动化一体化设备/柜体的布线设计仿真软件&#xff0c;是利驰首款机电协同设计理念产品。 SH-3D是一款电气端的高效管理&设计工具&#xff0c;在传统…

【LeetCode】 2724. 排序方式

排序方式 给定一个数组 arr 和一个函数 fn&#xff0c;返回一个排序后的数组 sortedArr。你可以假设 fn 只返回数字&#xff0c;并且这些数字决定了 sortedArr 的排序顺序。sortedArr 必须按照 fn 的输出值 升序 排序。 你可以假设对于给定的数组&#xff0c;fn 不会返回重复的…

普通人做抖音小店真的能赚钱吗?可以,但更取决于个人

大家好&#xff0c;我是电商花花。 现在做抖音小店的基本上都是一些新商家&#xff0c;对于我们众多零基础的朋友来说&#xff0c;是期待也是一份挑战。 抖音小店作为一个充满机会的新兴平台&#xff0c;许多人都欣喜的投入其中&#xff0c;期望能够借此来改变自己的命运&…

护眼灯哪个品牌好?五大护眼灯品牌推荐

护眼灯哪个品牌好&#xff1f;在挑选对眼睛有益的台灯时&#xff0c;专业护眼台灯无疑是明智的选择。这类台灯不仅严格按照国家的标准制造&#xff0c;确保了安全与质量的可靠性&#xff0c;除此之外护眼台灯还采用了经过精心设计的发光结构&#xff0c;有效减少了光线对眼睛的…

C++跨平台helloworld【安卓为特例得条件编译】

首先 遇到个问题略跨了我的技术栈盲区 虽然学过点u游戏开发 ue嘛侧重主机端 许是这问题角度略清奇等 总之竟没在csdn搜到 sos so 先问了某cpp技术栈语言能力者朋友 真人解答&#xff1a; 话虽这么说 实际上具体怎么写我还不确定&#x1f62c; 基于科学严谨的态度 于是又…

Linux 添加启动服务--Service

1&#xff0c;服务配置service文件 Service 服务的实际作用是开启后自动启动服务&#xff0c;运行一些不须要登录的程序&#xff0c;任务。 实例1、上电自动连接WIFI热点 1.1 新建.service文件 /etc/systemd/system/wificonnect.service [Unit] DescriptionService [wifico…