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

该博客主要分享LCD液晶屏资料,介绍了其重要参数,重点讲解HT1621 LCD控制驱动芯片,强调VLCD和VCC电压需符合规格,还提及ESP32 for Arduino与HT1621结合,展示了Arduino UNO TH1621 LCD成果,并提供资料下载和参考资料。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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


LCD液晶屏资料

LCD液晶屏资料

在这里插入图片描述

重要参数:

  • 工作电压: 3V
  • 可视角度:120°
  • 1/4 ,1/3

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


TH1621 驱动

HT1621 LCD控制驱动芯片介绍

VLCD 和 VCC 电压符合规格书,最好都取3.3V 。电压太高或太低都会出现段码液晶屏乱码的情况,要么多一笔,要么若隐若现的显示一笔。

在这里插入图片描述

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 2018

This 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-seg

Permission 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_DEBUG


class  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 1
	void 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 func
	void 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 2018

This 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-seg

Permission 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 off
		default:
			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 checks
		num = 999999; // clip into 999999
	if(num < -99999) // basic checks
		num = -99999; // clip into -99999

	char localbuffer[7]; //buffer to work within the function
	snprintf(localbuffer, 7, flags, num); // convert the decimal into string
	#ifdef _HTDEBUG
		Serial.begin(9600);
		Serial.print(localbuffer);
		Serial.print("\t");
	#endif

	// horrible handling but should get us working. needs refactor in next major
	if (precision > 0 && (num) < pow(10, precision)) {
		// we remove extra leading zeros
		for (int i = 0; i < (5 - precision); i++) {
			#ifdef _HTDEBUG
				Serial.print(localbuffer[1]);
			#endif // _HTDEBUG
			if(localbuffer[i+1] == '0' && localbuffer[i] != '-'){ // we remove only if there is another zero ahead AND if it's not a minus sign
				localbuffer[i] = ' ';
			}
			else{
				break;
			} 
			#ifdef _HTDEBUG
				Serial.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 checks
		num = 999999; // clip into 999999
	if(num < -99999) // basic checks
		num = -99999; // clip into -99999

	if(precision > 3 && num > 0)
		precision = 3; // if positive max precision allowed = 3
	else if(precision > 2 && num < 0)
		precision = 2;// if negative max precision allowed = 2
	if(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 number
	setdecimalseparator(precision); // draw the decimal point

	update();
}


void HT1621::printCelsius(double num){
	if(num > 9999) // basic checks
		num = 9999; // clip into 999999
	if(num < -999) // basic checks
		num = -999; // clip into -99999

	int precision;
	
	if(num <= -100 || num >= 999)
		precision = 0;	// if negative max precision allowed = 0
	else 
		precision = 1;	// if positive max precision allowed = 1

	const 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 number
	if(precision > 0)
		setdecimalseparator(precision+2); // draw the decimal point shifted by 2
	else 	
		setdecimalseparator(0); // or clear the decimal separator

	update();
}

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 point
		char character = leftPadded
				 		 ? i < padding ? ' ' : str[i - padding]
				 		 : i >= chars ? ' ' : str[i];
		_buffer[i] |= charToSegBits(character);
	}

	setdecimalseparator(0); // Hide decimal point
	update();
}

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 now
		return 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 Levels

  Displays the various battery levels with 500ms
  pause between.

  The circuit:
  cs to pin 13
  wr to pin 12
  Data to pin 8
  backlight to pin 10

  Created 9 dec 2018
  By valerio\new (5N44P)

  https://github.com/valerionew/ht1621-7-seg

*/

#include <HT1621.h> // include our library


HT1621 lcd; // create an "lcd" object

unsigned 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 want


  lcd.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 led

  lcd.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;}
    //设置四前面千/百/十位不要显示0
    if(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);
}

ESP32 for Arduino + HT1621

/**
* @brief @param @return @author @date @version是代码书写的一种规范
* @brief :简介,简单介绍函数作用
* @param :介绍函数参数
* @return:NULL
* @exception  NULL
* @author NAIVA
* @date 2024-04-11 22:23:00 
* @version 1.1
* @property :功能:1.实现ESP32 WiFi获取网络时间显示在段码LCD屏;2.早上7时2分闹钟循环响直到关机重启;3.每天24:59:20有自动重启、连接网络失败重启;4.晚上18:00至早上7:00打开背光;
* */

#include <Arduino.h>
#include <ESP32Tone.h> // tone库 ESP32 for Arduino IDE  
#include <Wire.h>
#include <WiFi.h>
#include <time.h>
#include <HT1621.h>

// BUZZER_PIN pin
const int      BUZZER_PIN = 19;
//#define ADC_PIN 34
//#define BUTTON 18

const int      CS_PIN = 27;
const int      WR_pin = 26;
const int    DATA_PIN = 25;
const int      BL_PIN = 33;

HT1621 Mylcd; // create an "Mylcd" object
unsigned char LCD_Display_Tmp[7];  // 存储LCD显示内容
bool _reboot_flag = false;    // 重启标志
bool _alarmClock_flag = false;// 闹钟标志


// Insert your network credentials
const char* ssid     = "";// wifi名称
const char* password = ""; // wifi 密码

// NTP Server Details
const char* ntpServer = "pool.ntp.org"; //"ntp.ntsc.ac.cn";
const long  gmtOffset_sec = 28800;  // 北京时区
const int   daylightOffset_sec = 0;//夏令时的偏移量(也就是时差,以秒为单位)。一般是一小时,相当于3600秒 ,这里不偏移。

unsigned char  clockHour = 0;
unsigned char  clockMinute = 0;
unsigned char  clockSecond = 0;

/**
  * @brief  page1GetTime 函数
  * @param  NULL
  * @retval NULL
  */
void page1GetTime(void) {
  //DATE AND TIME
  struct tm timeinfo;
  if(!getLocalTime(&timeinfo)){
    Serial.println("Failed to obtain time");
//     _reboot_flag = true;// 重启标志
  }
  
  
  Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");// Thursday, April 11 2024 20:14:07
  //GET DATE
  //Get full weekday name
  char weekDay[10];
  strftime(weekDay, sizeof(weekDay), "%a", &timeinfo);
  //Get day of month
  char dayMonth[4];
  strftime(dayMonth, sizeof(dayMonth), "%d", &timeinfo);
  //Get abbreviated month name
  char monthName[5];
  strftime(monthName, sizeof(monthName), "%b", &timeinfo);
  //Get year
  char year[6];
  strftime(year, sizeof(year), "%Y", &timeinfo);

  //GET TIME
  //Get hour (12 hour format)
  /*char hour[4];
  strftime(hour, sizeof(hour), "%I", &timeinfo);*/
  
  //Get hour (24 hour format)
  char hour[4];
  strftime(hour, sizeof(hour), "%H", &timeinfo);
  clockHour = atoi(hour);  // c标准库函数-- atoi() 将字符串转换为整型
  
  //Get minute
  char minute[4];
  strftime(minute, sizeof(minute), "%M", &timeinfo);
  clockMinute = atoi(minute); // c标准库函数-- atoi() 将字符串转换为整型

   //Get second
  char second[4];
  strftime(second, sizeof(second), "%S", &timeinfo);
  clockSecond = atoi(second); // c标准库函数-- atoi() 将字符串转换为整型
  
  LCD_Display_Tmp[0] = 10; // 万位:第1位显示的内容(左->右)
  LCD_Display_Tmp[1] = clockHour/10%10;   // 十位
  LCD_Display_Tmp[2] = clockHour%10;      // 个位
  LCD_Display_Tmp[3] = clockMinute/10%10; // 十位
  LCD_Display_Tmp[4] = clockMinute%10;    // 个位
  LCD_Display_Tmp[5] = 13;    // 显示 0x10  "Hour"
  
  // 间隔1s闪烁 “ :”
  if(clockSecond % 2 == 0){
    LCD_Display_Tmp[6] = 11;       // CODE[11] = 0x81 显示 ":" + "运行"符号
  }else{
    LCD_Display_Tmp[6] = 12;      // CODE[12] = 0x01 显示"运行"符号
  } 
   // 背光显示
  if(7 >= clockHour || clockHour >= 18){Mylcd.backlight();}
  else{Mylcd.noBacklight();}
  
  Mylcd.setBatteryLevel(3,LCD_Display_Tmp);
  
  vTaskDelay(100);
}


/**
  * @brief  《两只老虎》简谱
  * @param  无
  * @param  无
  * @retval 无
  */
void two_tigers_music_play()
{
byte count = 0;                 // byte 占1个字节 1*8bit=8位 0~256 节省内存
// low 1-7 低音
unsigned int  LOW_1 = 262;      // unsigned int 占4个字节 4*8bit=32位  0~4294967295
unsigned short LOW_1_P_5 = 277; // unsigned short 等于 uint16_t
uint16_t LOW_2 = 294;           // uint16_t 占2个字节 2*8bit=16位  0~65535
uint16_t LOW_2_P_5 = 311;
uint16_t LOW_3 = 330;
uint16_t LOW_4 = 349;
uint16_t LOW_4_P_5 = 370;
uint16_t LOW_5 = 392;
uint16_t LOW_5_P_5 = 415;
uint16_t LOW_6 = 440;
uint16_t LOW_6_P_5 = 466;
uint16_t LOW_7 = 494;

for (count = 0; count < 2; count++) // 每句歌词唱两遍
{
  tone(BUZZER_PIN, LOW_1);
  delay(500);
  tone(BUZZER_PIN, LOW_2);
  delay(500);
  tone(BUZZER_PIN, LOW_3);
  delay(500);
  tone(BUZZER_PIN, LOW_1);
  delay(500);
  
  noTone(BUZZER_PIN);
  delay(500);
}

for (count = 0; count < 2; count++)
{
  tone(BUZZER_PIN, LOW_3);
  delay(500);
  tone(BUZZER_PIN, LOW_4);
  delay(500);
  tone(BUZZER_PIN, LOW_5);
  delay(1000);

  noTone(BUZZER_PIN);
  delay(500);
}

for (count = 0; count < 2; count++)
{
  tone(BUZZER_PIN, LOW_5);
  delay(350);
  tone(BUZZER_PIN, LOW_6);
  delay(150); 
  tone(BUZZER_PIN, LOW_5);
  delay(350);
  tone(BUZZER_PIN, LOW_4);
  delay(150); 
  tone(BUZZER_PIN, LOW_3);
  delay(500);
  tone(BUZZER_PIN, LOW_1);       
  delay(500);

  noTone(BUZZER_PIN);
  delay(500);
}

for (count = 0; count < 2; count++)
{
  tone(BUZZER_PIN, LOW_1_P_5);
  delay(500);
  tone(BUZZER_PIN, LOW_5_P_5);
  delay(500);
  tone(BUZZER_PIN, LOW_1_P_5);
  delay(1000);

  noTone(BUZZER_PIN);
  delay(500);
}

} 

/**
  * @brief  任务2函数
  * @param  无
  * @param  无
  * @retval pvParameters:
  */
void task_2( void * pvParameters ){
for(;;){
  page1GetTime(); 
  vTaskDelay(1);
  }
}
/**
  * @brief  任务3函数
  * @param  无
  * @param  无
  * @retval pvParameters:
  */
void task_3( void * pvParameters ){
for(;;){    
  if((clockHour == 7) && (clockMinute == 2)){
    _alarmClock_flag = 1;  
    }
   // _alarmClock_flag
   while(clockMinute % 60 == 0){    
    two_tigers_music_play();// 循环播放 
    }
  if((clockHour == 24) && (clockMinute == 59) && (clockSecond == 20)){  
    _reboot_flag = true;// 重启标志
  }
  else{_reboot_flag = false;}
   while(_reboot_flag == true){
    ESP.restart();_reboot_flag = false;
    } //重启

  vTaskDelay(1);
  }
}

/**
  * @brief  初始化setup()
  * @param  无
  * @param  无
  * @retval 
  */
void setup() {
  Serial.begin(115200);
  pinMode(BUZZER_PIN, OUTPUT);
//  pinMode(ADC_PIN, INPUT);
//  pinMode(BUTTON,INPUT_PULLUP);
  
  Mylcd.begin(CS_PIN, WR_pin, DATA_PIN, BL_PIN); // (cs, wr, Data, backlight)
  Mylcd.backlight(); // turn on the backlight led
  Mylcd.clear(); // clear the screen

  // Connect to Wi-Fi
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
//    if(((millis()%3600000%60000)/1000)>=30){ESP.restart();}// 30秒连接网络超时 重启
//Time_second = ((start_time % Time_hour_setting) % Time_minute_setting) / Time_second_setting;  
//unsigned long Time_hour_setting = 3600000;   //1小时 = 3600000 毫秒
//unsigned long Time_minute_setting = 60000; // 1分钟 = 60000 毫秒
//unsigned long Time_second_setting = 1000; //1秒 = 1000 毫秒
    
  }
  Serial.println("");
  Serial.println("WiFi connected.");
  
  // Init and get the time
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);

  xTaskCreatePinnedToCore(task_2, "task_2", 4096, NULL, 2, NULL, 1);
  xTaskCreatePinnedToCore(task_3, "task_3", 4096, NULL, 1, NULL, 1);
//xTaskCreatePinnedToCore 函数参数说明:
// task_2:实现任务的函数名称(task1)
// "task_2":任务的任何名称(“ task1”等)
// 4096:分配给任务的堆栈大小,以字为单位
// NULL:任务输入参数(可以为NULL)
// 2:任务的优先级(0是最低优先级)
// NULL:任务句柄(可以为NULL)
// 1:任务将运行的ESP32D的内核ID(0或1)
}

void loop() {
  vTaskDelay(1);
}




成果展示

“Arduino UNO TH1621 LCD成果展示”

资料下载

参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Naiva

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值