Arduino 项目笔记 |TH1621 LCD液晶显示屏驱动(SSOP-24封装)

2024-04-09 12:52

本文主要是介绍Arduino 项目笔记 |TH1621 LCD液晶显示屏驱动(SSOP-24封装),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


LCD液晶屏资料

LCD液晶屏资料

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


TH1621 驱动程序

TH1621.h

/*******************************************************************************
Copyright 2016-2018 anxzhu (github.com/anxzhu)
Copyright 2018-2020 Valerio Nappi (github.com/valerionew) (changes)
Based on segment-lcd-with-ht1621 from anxzhu (2016-2018)
(https://github.com/anxzhu/segment-lcd-with-ht1621)Partially rewritten and extended by Valerio Nappi (github.com/valerionew) in 2018This file is part of the HT1621 arduino library, and thus under the MIT license.
More info on the project and the license conditions on :
https://github.com/valerionew/ht1621-7-segPermission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*******************************************************************************/#ifndef HT1621_H_
#define HT1621_H_   //防止重复包含const unsigned char  LCDCODE[11]={0xFA,0x0A,0xBC,0x9E,0x4E,0xD6,0xF6,0x8A,0xFE,0xDE,0x00};  // LCDCODE[10] = 0x00  不显示任何东西#define  BIAS     0x52             //0b1000 0101 0010  1/3duty 4com
#define  SYSDIS   0X00             //0b1000 0000 0000  关振系统荡器和LCD偏压发生器
#define  SYSEN    0X02             //0b1000 0000 0010 打开系统振荡器
#define  LCDOFF   0X04             //0b1000 0000 0100  关LCD偏压
#define  LCDON    0X06             //0b1000 0000 0110  打开LCD偏压
#define  XTAL     0x28             //0b1000 0010 1000 外部接时钟
#define  RC256    0X30             //0b1000 0011 0000  内部时钟
#define  TONEON   0X12             //0b1000 0001 0010  打开声音输出
#define  TONEOFF  0X10             //0b1000 0001 0000 关闭声音输出
#define  WDTDIS1  0X0A             //0b1000 0000 1010  禁止看门狗
#define  BUFFERSIZE 12// #define HT1621_DEBUGclass  HT1621
{
public:HT1621();void begin(int cs_p, int wr_p, int data_p, int backlight_p);void begin(int cs_p, int wr_p, int data_p);void clear();void backlight();void noBacklight();void setBatteryLevel(int level,unsigned char *s);void print(long num, const char* flags="%6li", int precision = 0);void print(double num, int precision = 3);void printCelsius(double num); // precision is always 1void print(const char* str, bool leftPadded = false);void display();void noDisplay();
private:int _cs_p;int _wr_p;int _data_p;int _backlight_p;bool _backlight_en;char _buffer[BUFFERSIZE];unsigned char _battery[3];void wrone(unsigned char addr, unsigned char sdata);void wrclrdata(unsigned char addr, unsigned char sdata);void wrCLR(unsigned char len);void wrDATA(unsigned char data, unsigned char cnt);void wrCMD(unsigned char CMD);void setdecimalseparator(int dpposition);void config(); // legacy: why not in begin funcvoid update();char charToSegBits(char character);
};
#endif

HT1621.cpp

/*******************************************************************************
Copyright 2016-2018 anxzhu (github.com/anxzhu)
Copyright 2018-2020 Valerio Nappi (github.com/5N44P) (changes)
Based on segment-lcd-with-ht1621 from anxzhu (2016-2018)
(https://github.com/anxzhu/segment-lcd-with-ht1621)Partially rewritten and extended by Valerio Nappi (github.com/5N44P) in 2018This file is part of the HT1621 arduino library, and thus under the MIT license.
More info on the project and the license conditions on :
https://github.com/5N44P/ht1621-7-segPermission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*******************************************************************************/#include <Arduino.h>
#include "HT1621.h"HT1621::HT1621(){_buffer[0] = 0x00;_buffer[1] = 0x00;_buffer[2] = 0x00;_buffer[3] = 0x00;_buffer[4] = 0x00;_buffer[5] = 0x00;_buffer[6] = 0x00;
}void HT1621::begin(int cs_p, int wr_p, int data_p, int backlight_p)
{pinMode(cs_p, OUTPUT);pinMode(wr_p, OUTPUT);pinMode(data_p, OUTPUT);pinMode(backlight_p, OUTPUT);_cs_p=cs_p;_wr_p=wr_p;_data_p=data_p;_backlight_p=backlight_p;_backlight_en=true;config();
}void HT1621::begin(int cs_p, int wr_p, int data_p)
{pinMode(cs_p, OUTPUT);pinMode(wr_p, OUTPUT);pinMode(data_p, OUTPUT);_cs_p=cs_p;_wr_p=wr_p;_data_p=data_p;_backlight_en = false;config();
}void HT1621::wrDATA(unsigned char data, unsigned char cnt) {unsigned char i;for (i = 0; i < cnt; i++) {digitalWrite(_wr_p, LOW);delayMicroseconds(4);if (data & 0x80) {digitalWrite(_data_p, HIGH);}else {digitalWrite(_data_p, LOW);}digitalWrite(_wr_p, HIGH);delayMicroseconds(4);data <<= 1;}
}
void HT1621::wrclrdata(unsigned char addr, unsigned char sdata)
{addr+=9;addr <<= 2;digitalWrite(_cs_p, LOW);wrDATA(0xa0, 3);wrDATA(addr, 6);wrDATA(sdata, 8);digitalWrite(_cs_p, HIGH);
}void HT1621::display()
{wrCMD(LCDON);
}void HT1621::noDisplay()
{wrCMD(LCDOFF);
}// 写数据到RAM命令格式为:101+6位RAM地址+4位数据,其中RAM地址为SEG序号 (参考:https://blog.csdn.net/qq_36347513/article/details/107330387)
// 
void HT1621::wrone(unsigned char addr, unsigned char sdata)// 101 数据模式  读写之间变换
{addr+=9;// HT1621 SSOP-24 芯片的SEG脚从SEG9开始的 ,所以addr+9;addr <<= 2;digitalWrite(_cs_p, LOW);wrDATA(0xa0, 3);// 101 wrDATA(addr, 6);wrDATA(sdata, 8);   // 0XF7  "8"  digitalWrite(_cs_p, HIGH);
}// void HT1621::update(){ the buffer is backwards with respect to the lcd. could be improved// wrone(0, _buffer[5]);// wrone(2, _buffer[4]);// wrone(4, _buffer[3]);// wrone(6, _buffer[2]);// wrone(8, _buffer[1]);// wrone(10,_buffer[0]);
// }
void HT1621::backlight()
{if (_backlight_en)digitalWrite(_backlight_p, HIGH);delay(1);
}void HT1621::noBacklight()
{if(_backlight_en)digitalWrite(_backlight_p, LOW);delay(1);
}void HT1621::wrCMD(unsigned char CMD) {  //100 命令模式digitalWrite(_cs_p, LOW);wrDATA(0x80, 4);wrDATA(CMD, 8);digitalWrite(_cs_p, HIGH);
}void HT1621::config()
{wrCMD(BIAS);wrCMD(RC256);wrCMD(SYSDIS);wrCMD(WDTDIS1);wrCMD(SYSEN);wrCMD(LCDON);
}// #define  BIAS     0x52             //0b1000 0101 0010  1/3duty 4com  
/*
1000 010abXcX 
c=0:1/2 偏置
c=1:1/3 偏置
ab=00:2 COMS
ab=01:3 COMS
ab=10:4 COMS
*/
// #define  SYSDIS   0X00             //0b1000 0000 0000  关振系统荡器和LCD偏压发生器
// #define  SYSEN    0X02             //0b1000 0000 0010 打开系统振荡器
// #define  LCDOFF   0X04             //0b1000 0000 0100  关LCD偏压
// #define  LCDON    0X06             //0b1000 0000 0110  打开LCD偏压
// #define  XTAL     0x28             //0b1000 0010 1000 外部接时钟
// #define  RC256    0X30             //0b1000 0011 0000  内部时钟
// #define  TONEON   0X12             //0b1000 0001 0010  打开声音输出
// #define  TONEOFF  0X10             //0b1000 0001 0000 关闭声音输出
// #define  WDTDIS1  0X0A             //0b1000 0000 1010  禁止看门狗void HT1621::wrCLR(unsigned char len) {unsigned char addr = 0;unsigned char i;for (i = 0; i < len; i++) {wrclrdata(addr, 0x00);addr = addr + 2;}
}void HT1621::setBatteryLevel(int level,unsigned char *s) {// zero out the previous (otherwise the or couldn't be possible)// _buffer[0] &= 0x7F;// _buffer[1] &= 0x7F;// _buffer[2] &= 0x7F;unsigned char i;for(i=0;i<6;i++){_buffer[i] &= 0x00;}switch(level){case 3: // battery on and all 3 segments// _buffer[0] |= 0x80;// _buffer[0] |= 0xFE;_buffer[0] |= LCDCODE[s[0]];_buffer[1] |= LCDCODE[s[1]];_buffer[2] |= LCDCODE[s[2]];_buffer[3] |= LCDCODE[s[3]];_buffer[4] |= LCDCODE[s[4]];// _buffer[5] |= 0xFE;// _buffer[6] |= 0xEF;case 2: // battery on and 2 segments// _buffer[1] |= 0x80;case 1: // battery on and 1 segment// _buffer[2] |= 0x80;case 0: // battery indication offdefault:break;}update();
}void HT1621::clear(){wrCLR(16);// wrCLR(31);
}// takes the buffer and puts it straight into the driver
void HT1621::update(){// the buffer is backwards with respect to the lcd. could be improved// wrone(0, _buffer[5]);wrone(0, _buffer[0]);wrone(2, _buffer[1]);wrone(4, _buffer[2]);wrone(6, _buffer[3]);wrone(8, _buffer[4]);// wrone(10, _buffer[5]);// wrone(12, _buffer[6]);// wrone(0, _buffer[5]);// wrone(2, _buffer[4]);// wrone(4, _buffer[3]);// wrone(6, _buffer[2]);// wrone(8, _buffer[1]);// wrone(10,_buffer[0]);
}void HT1621::print(long num, const char* flags, int precision){if(num > 999999) // basic checksnum = 999999; // clip into 999999if(num < -99999) // basic checksnum = -99999; // clip into -99999char localbuffer[7]; //buffer to work within the functionsnprintf(localbuffer, 7, flags, num); // convert the decimal into string#ifdef _HTDEBUGSerial.begin(9600);Serial.print(localbuffer);Serial.print("\t");#endif// horrible handling but should get us working. needs refactor in next majorif (precision > 0 && (num) < pow(10, precision)) {// we remove extra leading zerosfor (int i = 0; i < (5 - precision); i++) {#ifdef _HTDEBUGSerial.print(localbuffer[1]);#endif // _HTDEBUGif(localbuffer[i+1] == '0' && localbuffer[i] != '-'){ // we remove only if there is another zero ahead AND if it's not a minus signlocalbuffer[i] = ' ';}else{break;} #ifdef _HTDEBUGSerial.println();buffer[1]);#endif // _HTDEBUG}}for(int i=0; i<6; i++){_buffer[i] &= 0x80; // mask the first bit, used by batter and decimal point_buffer[i] |= charToSegBits(localbuffer[i]);}update();
}void HT1621::print(double num, int precision){if(num > 999999) // basic checksnum = 999999; // clip into 999999if(num < -99999) // basic checksnum = -99999; // clip into -99999if(precision > 3 && num > 0)precision = 3; // if positive max precision allowed = 3else if(precision > 2 && num < 0)precision = 2;// if negative max precision allowed = 2if(precision < 0)precision = 0; // negative precision?!const char* flags = (precision > 0 && abs(num) < 1) ? "%06li" : "%6li";long integerpart;integerpart = ((long)(num*pow(10,precision)));print(integerpart, flags, precision); // draw the integerized numbersetdecimalseparator(precision); // draw the decimal pointupdate();
}void HT1621::printCelsius(double num){if(num > 9999) // basic checksnum = 9999; // clip into 999999if(num < -999) // basic checksnum = -999; // clip into -99999int precision;if(num <= -100 || num >= 999)precision = 0;	// if negative max precision allowed = 0else precision = 1;	// if positive max precision allowed = 1const char* flags = (precision > 0 && abs(num) < 1) ? "%04li*C" : "%4li*C";long integerpart;integerpart = ((long)(num*pow(10,precision)));print(integerpart, flags, precision); // draw the integerized numberif(precision > 0)setdecimalseparator(precision+2); // draw the decimal point shifted by 2else 	setdecimalseparator(0); // or clear the decimal separatorupdate();
}void HT1621::print(const char* str, bool leftPadded){int chars = strlen(str);int padding = 6 - chars;for(int i = 0; i < 6; i++){_buffer[i] &= 0x80; // mask the first bit, used by batter and decimal pointchar character = leftPadded? i < padding ? ' ' : str[i - padding]: i >= chars ? ' ' : str[i];_buffer[i] |= charToSegBits(character);}setdecimalseparator(0); // Hide decimal pointupdate();
}void HT1621::setdecimalseparator(int decimaldigits) {// zero out the eight bit_buffer[3] &= 0x7F;_buffer[4] &= 0x7F;_buffer[5] &= 0x7F;if( decimaldigits <= 0 || decimaldigits > 3){return;}// 3 is the digit offset// the first three eights bits in the buffer are for the battery signs// the last three are for the decimal point_buffer[6-decimaldigits] |= 0x80;
}char HT1621::charToSegBits(char character) {switch (character) {case '*': // For degree for nowreturn 0b0110011;case '|':return 0b0000101;case '-':return 0b0000010;case '_':return 0b0001000;case '0':return 0b1111101;case '1':return 0b1100000;case '2':return 0b111110;case '3':return 0b1111010;case '4':return 0b1100011;case '5':return 0b1011011;case '6':return 0b1011111;case '7':return 0b1110000;case '8':return 0b1111111;case '9':return 0b1111011;case 'A':case 'a':return 0b1110111;case 'b':case 'B':return 0b1001111;case 'c'://	return 0b0001110;case 'C':return 0b0011101;case 'd':case 'D':return 0b1101110;case 'e'://	return 0b0001110;case 'E':return 0b0011111;case 'f'://	return 0b0000111;case 'F':return 0b0010111;case 'G':case 'g':return 0b1011101;case 'h'://	return 0b1000111;case 'H':return 0b1100111;case 'i'://	return 0b1000000;case 'I':return 0b1100000;case 'J':case 'j':return 0b1101000;case 'l'://	return 0b1100000;case 'L':return 0b0001101;case 'm':case 'M':return 0b1010100;case 'n':case 'N':return 0b1000110;case 'O': // we can keep this for zero//	return 0b1111101;case 'o':return 0b1001110;case 'P':case 'p':return 0b0110111;case 'q':case 'Q':return 0b1110011;case 'r':case 'R':return 0b0000110;case 'S':case 's':return 0b1011011;case 't':case 'T':return 0b0001111;case 'u'://	return 0b1001100;case 'U':return 0b1101101;case 'Y':case 'y':return 0b1101011;case 'z':case 'Z':return 0b0111110;case ' ':default:return 0b0000000;}
}

Battery_levels.ino

/*Battery LevelsDisplays the various battery levels with 500mspause between.The circuit:cs to pin 13wr to pin 12Data to pin 8backlight to pin 10Created 9 dec 2018By valerio\new (5N44P)https://github.com/valerionew/ht1621-7-seg*/#include <HT1621.h> // include our libraryHT1621 lcd; // create an "lcd" objectunsigned char LCD_tmp[5];void setup(){// start the lcd:// cs to pin 13// wr to pin 12// Data to pin 8// backlight to pin 10// you can chose whichever pin you wantlcd.begin(13, 12, 8, 10); // (cs, wr, Data, backlight)// if no backlight control is given, you can also use:// lcd.begin(13, 12, 8); // (cs, wr, Data)lcd.backlight(); // turn on the backlight ledlcd.clear(); // clear the screen
}void loop(){static unsigned int num = 0;num++;LCD_tmp[0] = num/10000%10; // 万位:第1位显示的内容(左->右)LCD_tmp[1] = num/1000%10;       // 千位LCD_tmp[2] = num/100%10;       // 百位LCD_tmp[3] = num/10%10; // 十位LCD_tmp[4] = num%10; // 个位if(num >= 100000){num = 0;}//设置四前面千/百/十位不要显示0if(LCD_tmp[0] <= 0 && num < 10000){LCD_tmp[0]=10;} if(LCD_tmp[1] <= 0 && num < 1000){LCD_tmp[1]=10;} // CODE[10] 是 0X00 不显示if(LCD_tmp[2] <= 0 && num < 100){LCD_tmp[2]=10;}if(LCD_tmp[3] <= 0 && num < 10){LCD_tmp[3]=10;}lcd.setBatteryLevel(3,LCD_tmp);delay(100);  lcd.setBatteryLevel(2);
//  delay(500);
//  lcd.setBatteryLevel(3);
//  delay(500);
}

成果展示


参考资料

  • [1] 【Github】ht1621-7-seg (forked from anxzhu/segment-lcd-with-ht1621)
  • [2] 【CSDN@weiDev101】LCD Glass段码屏的驱动
  • [3] 【CSDN】STM32F103学习笔记(4)——LCD段码屏HT1621使用

这篇关于Arduino 项目笔记 |TH1621 LCD液晶显示屏驱动(SSOP-24封装)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/888199

相关文章

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

如何用Docker运行Django项目

本章教程,介绍如何用Docker创建一个Django,并运行能够访问。 一、拉取镜像 这里我们使用python3.11版本的docker镜像 docker pull python:3.11 二、运行容器 这里我们将容器内部的8080端口,映射到宿主机的80端口上。 docker run -itd --name python311 -p

在cscode中通过maven创建java项目

在cscode中创建java项目 可以通过博客完成maven的导入 建立maven项目 使用快捷键 Ctrl + Shift + P 建立一个 Maven 项目 1 Ctrl + Shift + P 打开输入框2 输入 "> java create"3 选择 maven4 选择 No Archetype5 输入 域名6 输入项目名称7 建立一个文件目录存放项目,文件名一般为项目名8 确定

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

Linux_kernel驱动开发11

一、改回nfs方式挂载根文件系统         在产品将要上线之前,需要制作不同类型格式的根文件系统         在产品研发阶段,我们还是需要使用nfs的方式挂载根文件系统         优点:可以直接在上位机中修改文件系统内容,延长EMMC的寿命         【1】重启上位机nfs服务         sudo service nfs-kernel-server resta

Vue3项目开发——新闻发布管理系统(六)

文章目录 八、首页设计开发1、页面设计2、登录访问拦截实现3、用户基本信息显示①封装用户基本信息获取接口②用户基本信息存储③用户基本信息调用④用户基本信息动态渲染 4、退出功能实现①注册点击事件②添加退出功能③数据清理 5、代码下载 八、首页设计开发 登录成功后,系统就进入了首页。接下来,也就进行首页的开发了。 1、页面设计 系统页面主要分为三部分,左侧为系统的菜单栏,右侧

SpringBoot项目是如何启动

启动步骤 概念 运行main方法,初始化SpringApplication 从spring.factories读取listener ApplicationContentInitializer运行run方法读取环境变量,配置信息创建SpringApplication上下文预初始化上下文,将启动类作为配置类进行读取调用 refresh 加载 IOC容器,加载所有的自动配置类,创建容器在这个过程

Maven创建项目中的groupId, artifactId, 和 version的意思

文章目录 groupIdartifactIdversionname groupId 定义:groupId 是 Maven 项目坐标的第一个部分,它通常表示项目的组织或公司的域名反转写法。例如,如果你为公司 example.com 开发软件,groupId 可能是 com.example。作用:groupId 被用来组织和分组相关的 Maven artifacts,这样可以避免

论文阅读笔记: Segment Anything

文章目录 Segment Anything摘要引言任务模型数据引擎数据集负责任的人工智能 Segment Anything Model图像编码器提示编码器mask解码器解决歧义损失和训练 Segment Anything 论文地址: https://arxiv.org/abs/2304.02643 代码地址:https://github.com/facebookresear