初学者arduino编程在LCD上显示文字 应该怎么写程序 ?

初学者arduino编程在LCD上显示文字 应该怎么写程序 ?,第1张

//端口定义 诺基亚5110显示屏

int LCD_CE=2

int LCD_RST=3

int SCLK=4

int SDIN=5

int LCD_DC=6

int inputPin=8 // 定义超声波信号接收接口

int outputPin=9// 定义超声波信号发出接口

/****************************************************************/

void setup()

{

pinMode(inputPin, INPUT)

pinMode(outputPin, OUTPUT)

}

//****************************定义ASCII字符**********************//

/**********************************

6 x 8 font

1 pixel space at left and bottom

index = ASCII - 32

***********************************/

const unsigned char font6x8[][6] =

{

{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // sp

{ 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00 }, // !

{ 0x00, 0x00, 0x07, 0x00, 0x07, 0x00 }, // "含慎

{ 0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14 }, // #

{ 0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12 }, // $

{ 0x00, 0x62, 0x64, 0x08, 0x13, 0x23 }, // %

{ 0x00, 0x36, 0x49, 0x55, 0x22, 0x50 }, // &

{ 0x00, 0x00, 0x05, 0x03, 0x00, 0x00 }, // '

{ 0x00, 0x00, 0x1c, 0x22, 0x41, 0x00 }, //卜肢 (

{ 0x00, 0x00, 0x41, 0x22, 0x1c, 0x00 }, // )

{ 0x00, 0x14, 0x08, 0x3E, 0x08, 0x14 }, // *

{ 0x00, 0x08, 0x08, 0x3E, 0x08, 0x08 }, // +

{ 0x00, 0x00, 0x00, 0xA0, 0x60, 0x00 }, // ,

{ 0x00, 0x08, 0x08, 0x08, 0x08, 0x08 }, // -

{ 0x00, 0x00, 0x60, 0x60, 0x00, 0x00 }, // .

{ 0x00, 0x20, 0x10, 0x08, 0x04, 0x02 }, // /

{ 0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E }, // 0

{ 0x00, 0x00, 0x42, 0x7F, 0x40, 0x00 }, // 1

{ 0x00, 0x42, 0x61, 0x51, 0x49, 0x46 }, // 2

{ 0x00, 0x21, 0x41, 0x45, 0x4B, 0x31 }, // 3

{ 0x00, 0x18, 0x14, 0x12, 0x7F, 0x10 }, // 4

{ 0x00, 0x27, 0x45, 0x45, 0x45, 0x39 }, // 5

{ 0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30 }, // 6

{ 0x00, 0x01, 0x71, 0x09, 0x05, 0x03 }, /谈弊敬/ 7

{ 0x00, 0x36, 0x49, 0x49, 0x49, 0x36 }, // 8

{ 0x00, 0x06, 0x49, 0x49, 0x29, 0x1E }, // 9

{ 0x00, 0x00, 0x36, 0x36, 0x00, 0x00 }, // :

{ 0x00, 0x00, 0x56, 0x36, 0x00, 0x00 }, //

{ 0x00, 0x08, 0x14, 0x22, 0x41, 0x00 }, // <

{ 0x00, 0x14, 0x14, 0x14, 0x14, 0x14 }, // =

{ 0x00, 0x00, 0x41, 0x22, 0x14, 0x08 }, // >

{ 0x00, 0x02, 0x01, 0x51, 0x09, 0x06 }, // ?

{ 0x00, 0x32, 0x49, 0x59, 0x51, 0x3E }, // @

{ 0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C }, // A

{ 0x00, 0x7F, 0x49, 0x49, 0x49, 0x36 }, // B

{ 0x00, 0x3E, 0x41, 0x41, 0x41, 0x22 }, // C

{ 0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C }, // D

{ 0x00, 0x7F, 0x49, 0x49, 0x49, 0x41 }, // E

{ 0x00, 0x7F, 0x09, 0x09, 0x09, 0x01 }, // F

{ 0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A }, // G

{ 0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F }, // H

{ 0x00, 0x00, 0x41, 0x7F, 0x41, 0x00 }, // I

{ 0x00, 0x20, 0x40, 0x41, 0x3F, 0x01 }, // J

{ 0x00, 0x7F, 0x08, 0x14, 0x22, 0x41 }, // K

{ 0x00, 0x7F, 0x40, 0x40, 0x40, 0x40 }, // L

{ 0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F }, // M

{ 0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F }, // N

{ 0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E }, // O

{ 0x00, 0x7F, 0x09, 0x09, 0x09, 0x06 }, // P

{ 0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E }, // Q

{ 0x00, 0x7F, 0x09, 0x19, 0x29, 0x46 }, // R

{ 0x00, 0x46, 0x49, 0x49, 0x49, 0x31 }, // S

{ 0x00, 0x01, 0x01, 0x7F, 0x01, 0x01 }, // T

{ 0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F }, // U

{ 0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F }, // V

{ 0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F }, // W

{ 0x00, 0x63, 0x14, 0x08, 0x14, 0x63 }, // X

{ 0x00, 0x07, 0x08, 0x70, 0x08, 0x07 }, // Y

{ 0x00, 0x61, 0x51, 0x49, 0x45, 0x43 }, // Z

{ 0x00, 0x00, 0x7F, 0x41, 0x41, 0x00 }, // [

{ 0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55 }, // 55

{ 0x00, 0x00, 0x41, 0x41, 0x7F, 0x00 }, // ]

{ 0x00, 0x04, 0x02, 0x01, 0x02, 0x04 }, // ^

{ 0x00, 0x40, 0x40, 0x40, 0x40, 0x40 }, // _

{ 0x00, 0x00, 0x01, 0x02, 0x04, 0x00 }, // '

{ 0x00, 0x20, 0x54, 0x54, 0x54, 0x78 }, // a

{ 0x00, 0x7F, 0x48, 0x44, 0x44, 0x38 }, // b

{ 0x00, 0x38, 0x44, 0x44, 0x44, 0x20 }, // c

{ 0x00, 0x38, 0x44, 0x44, 0x48, 0x7F }, // d

{ 0x00, 0x38, 0x54, 0x54, 0x54, 0x18 }, // e

{ 0x00, 0x08, 0x7E, 0x09, 0x01, 0x02 }, // f

{ 0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C }, // g

{ 0x00, 0x7F, 0x08, 0x04, 0x04, 0x78 }, // h

{ 0x00, 0x00, 0x44, 0x7D, 0x40, 0x00 }, // i

{ 0x00, 0x40, 0x80, 0x84, 0x7D, 0x00 }, // j

{ 0x00, 0x7F, 0x10, 0x28, 0x44, 0x00 }, // k

{ 0x00, 0x00, 0x41, 0x7F, 0x40, 0x00 }, // l

{ 0x00, 0x7C, 0x04, 0x18, 0x04, 0x78 }, // m

{ 0x00, 0x7C, 0x08, 0x04, 0x04, 0x78 }, // n

{ 0x00, 0x38, 0x44, 0x44, 0x44, 0x38 }, // o

{ 0x00, 0xFC, 0x24, 0x24, 0x24, 0x18 }, // p

{ 0x00, 0x18, 0x24, 0x24, 0x18, 0xFC }, // q

{ 0x00, 0x7C, 0x08, 0x04, 0x04, 0x08 }, // r

{ 0x00, 0x48, 0x54, 0x54, 0x54, 0x20 }, // s

{ 0x00, 0x04, 0x3F, 0x44, 0x40, 0x20 }, // t

{ 0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C }, // u

{ 0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C }, // v

{ 0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C }, // w

{ 0x00, 0x44, 0x28, 0x10, 0x28, 0x44 }, // x

{ 0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C }, // y

{ 0x00, 0x44, 0x64, 0x54, 0x4C, 0x44 }, // z

{ 0x14, 0x14, 0x14, 0x14, 0x14, 0x14 }// horiz lines

}

/************************LCD初始化函数********************************/

void LCD_init(void)

{

//先设置为输出

pinMode(SCLK,OUTPUT)

pinMode(SDIN,OUTPUT)

pinMode(LCD_DC,OUTPUT)

pinMode(LCD_CE,OUTPUT)

pinMode(LCD_RST,OUTPUT)

// 产生一个让LCD复位的低电平脉冲

digitalWrite( LCD_RST, LOW)

delayMicroseconds(1)

digitalWrite( LCD_RST, HIGH)

// 关闭LCD

digitalWrite( LCD_CE, LOW)

delayMicroseconds(1)

// 使能LCD

digitalWrite( LCD_CE, HIGH)//LCD_CE = 1

delayMicroseconds(1)

LCD_write_byte(0x21, 0)// 使用扩展命令设置LCD模式

LCD_write_byte(0xc8, 0)// 设置偏置电压

LCD_write_byte(0x06, 0)// 温度校正

LCD_write_byte(0x13, 0)// 1:48

LCD_write_byte(0x20, 0)// 使用基本命令

LCD_clear()// 清屏

LCD_write_byte(0x0c, 0)// 设定显示模式,正常显示

// 关闭LCD

digitalWrite( LCD_CE, LOW) //LCD_CE = 0

}

/************************LCD清屏函数*******************************/

void LCD_clear(void)

{

unsigned int i

LCD_write_byte(0x0c, 0)

LCD_write_byte(0x80, 0)

for (i=0i<504i++)

{

LCD_write_byte(0, 1)

}

}

/*************************设置字符位置函数**************************/

void LCD_set_XY(unsigned char X, unsigned char Y)

{

LCD_write_byte(0x40 | Y, 0)// column

LCD_write_byte(0x80 | X, 0)// row

}

/*************************ASCII字符显示函数*************************/

void LCD_write_char(unsigned char c)

{

unsigned char line

c -= 32

for (line=0line<6line++)

{

LCD_write_byte(font6x8[c][line], 1)

}

}

/*******************************************************************/

/*-------------------------------------------------

LCD_write_english_String : 英文字符串显示函数

输入参数:*s :英文字符串指针;

X、Y: 显示字符串的位置,x 0-83 ,y 0-5

--------------------------------------------------*/

void LCD_write_english_string(unsigned char X,unsigned char Y,char *s)

{

LCD_set_XY(X,Y)

while (*s)

{

LCD_write_char(*s)

s++

}

}

/******************************************************************/

/*---------------------------------------------

LCD_write_byte: 写数据到LCD

输入参数:data:写入的数据;

command :写数据/命令选择;

---------------------------------------------*/

void LCD_write_byte(unsigned char dat, unsigned char command)

{

unsigned char i

digitalWrite( LCD_CE, LOW)// 使能LCD_CE = 0

if (command == 0)

{

digitalWrite( LCD_DC, LOW)// 传送命令 LCD_DC = 0

}

else

{

digitalWrite( LCD_DC, HIGH)// 传送数据LCD_DC = 1

}

for(i=0i<8i++)

{

if(dat&0x80)

{

digitalWrite( SDIN, HIGH)//SDIN = 1

}

else

{

digitalWrite( SDIN, LOW)//SDIN = 0

}

digitalWrite( SCLK, LOW)//SCLK = 0

dat = dat <<1

digitalWrite( SCLK, HIGH)//SCLK = 1

}

digitalWrite( LCD_CE, HIGH)//LCD_CE = 1

}

/*************************以下为主函数*****************************/

void loop()

{

LCD_init()//初始化液晶

LCD_clear()

LCD_write_english_string(0,0," --Arduino-- ")

LCD_write_english_string(0,2,"Renge:")

LCD_write_english_string(0,4,"DESIGN BY KENT")

LCD_write_english_string(0,5,"2010.6")

while(1)

{

digitalWrite(outputPin, LOW)// 使发出发出超声波信号接口低电平2μs

delayMicroseconds(2)

digitalWrite(outputPin, HIGH)// 使发出发出超声波信号接口高电平10μs,这里是至少10μs

delayMicroseconds(10)

digitalWrite(outputPin, LOW) // 保持发出超声波信号接口低电平

int distance = pulseIn(inputPin, HIGH) // 读出脉冲时间

distance= distance/58 // 将脉冲时间转化为距离(单位:厘米)

if(distance>120)

{

LCD_write_english_string(35,2,"???")

}

else

{

LCD_write_english_string(60,2,"cm")

LCD_set_XY(35, 2)

LCD_write_char( 0x30+distance%1000/100)//显示百位数

LCD_write_char( 0x30+distance%100/10) //显示十位数

LCD_write_char( 0x30+distance%10) //显示个位数

}

delay(10)

}

}

本帖最后由 qhdtc5 于 2015-3-25 08:00 编辑

说明:

使用了LCD5110作为显示屏,库为LCD5110_Basic

借鉴了其他程序的一些思路,用链表作为菜单结构,并使用首枣Action概念来确定菜单项动作

虽然动作类型设想有好几种,但我只写了设置逻辑值的菜单动作,其他的可自行完善(我也会继续写完)

代码未优化和未考虑内存占用等问题

请大家指教

先上图片和视频

[media]http://player.youku.com/player.php/sid/XOTE5MjkyOTg4/v.swf[/media]

代码:

[mw_shl_code=bash,true]#include <Wire.h>

#include <DS3231.h>

#include <LCD5110_Basic.h>

#define LIGHT_PIN 3

#define LED_PIN 13

// 菜单最大显示行数

#define MENU_MAX_ROW 5

/**

* 以下定义菜单项类型

*/

// 具有子菜单的菜单项

#define MENU_SUBMENU 0

// 参数项(用于执行参数设置)

#define MENU_PARAM 1

// 无动作的菜单项

#define MENU_ACTION_NONE 101

// 执行逻辑参数设置的菜单项(开/关、真/假等设置)

#define MENU_ACTION_LOGIC 102

// 执行数值调整设置的菜单项(时间、音量等设置)

#define MENU_ACTION_NUMBER 103

// 执行字符串设置的菜单项(欢迎语、LED显示文字等设置)

#define MENU_ACTION_STRING 104

/**

* 以下定义按键引脚

* 设置上拉电阻,低电平有效

*/

#define KEY_UP 7

#define KEY_DOWN 6

#define KEY_ENTER 5

#define KEY_EXIT 4

// 定义按键消抖延时时间

#define KEY_TREMBLE_TIME 20

// DS3231时做芹孙钟变量

DS3231 clock

// LCD5110液晶屏变量

LCD5110 myGLCD(8, 9, 10, 11, 12)

// LCD5110使用的字体

extern unsigned char SmallFont[]

/**

* 菜单结构

* 一个数组既代表一级菜单,数组中的一个元素就是一个菜单项,就是一个单独的结构体,

* 数组中的第一个元素中的num值很重要,表示本级菜单具有多少个菜单项。

*

* @var int num 本级菜单数量,必须在第一项中设置正确的菜单项数量

* @var char* label 菜单文本

* @var int type 此项类型,参考宏定义

* @var void (*action)(const char *) 指向动作的函数指针,此项要执行的纯链具体动作函数

* @var mymenu* next 下一级菜单,只需在菜单的第一项设置,其他项置空(NULL)即可

* @var mymenu* prev 上一级菜单,同上

*/

struct mymenu {

int num

char *label//display label

int type//0:item, 1:submenu, 2:param

void (*action)(const char *)

mymenu * next

mymenu * prev

}

/**

* 逻辑参数设置菜单

* 逻辑菜单表示菜单项中的action函数要执行逻辑设置动作,即设置某个参数的逻辑值

* 逻辑菜单只需两个菜单项代表true和false

* 需要遵守的规则为:菜单中的文本需要设置为“ON”和“OFF”,

* 在执行动作函数的时候,可以将正确的参数传递过去,

* 动作函数的规则参照函数说明

*/

mymenu logic_menu[2] = {

{2, "ON", MENU_PARAM, NULL, NULL, NULL},

{2, "OFF", MENU_PARAM, NULL, NULL, NULL}

}

/**

* 下面定义了三级菜单说明了菜单应该如何个定义

*/

// 第二级菜单

mymenu light_menu[2] = {

//第一项什么也不做,所以设置了类型为MENU_ACTION_NONE

{2, "light 1", MENU_ACTION_NONE, NULL, NULL, NULL},

//第二项指向了下级菜单,所以设置了类型为MENU_SUBMENU

{2, "light submenu", MENU_SUBMENU, NULL, NULL, NULL}

}

// 第三级菜单

mymenu test_level3_menu[7] = {

{7, "level3menu-1", MENU_ACTION_NONE, NULL, NULL, NULL},

{7, "level3menu-2", MENU_ACTION_NONE, NULL, NULL, NULL},

{7, "level3menu-3", MENU_ACTION_NONE, NULL, NULL, NULL},

{7, "level3menu-4", MENU_ACTION_NONE, NULL, NULL, NULL},

//定义了一个逻辑动作,这里是控制PIN13脚的LED

{7, "LED TEST", MENU_ACTION_LOGIC, NULL, NULL, NULL},

{7, "level3menu-6", MENU_ACTION_NONE, NULL, NULL, NULL},

{7, "level3menu-7", MENU_ACTION_NONE, NULL, NULL, NULL}

}

// 第一级菜单

mymenu main_menu[4] = {

{4, "item 1", MENU_ACTION_NONE, NULL, NULL, NULL},

{4, "item 2", MENU_ACTION_NONE, NULL, NULL, NULL},

//指向下一级菜单

{4, "item 2.1", MENU_SUBMENU, NULL, NULL, NULL},

{4, "item 3", MENU_ACTION_NONE, NULL, NULL, NULL}

}

// 定义菜单 *** 作需要的全局变量

// 分别为当前菜单、上一级菜单、当前菜单项索引和开始显示的菜单项索引

mymenu *cur_item, *prev_item

int item_index, start_index

bool stat

/**

* DS3231需要的全局变量

*/

bool Century=false

bool h12

bool PM

byte ADay, AHour, AMinute, ASecond, ABits

bool ADy, A12h, Apm

int second,minute,hour,date,month,year,temperature

int oldsecond//此变量用于判断是否更新显示内容

// 定义LCD背光显示计时变量,无按键 *** 作超时就关闭背光

unsigned long starttime

// 定义菜单的 *** 作按键(上、下、进入和返回)状态变量

bool old_up_stat, old_down_stat, old_enter_stat, old_exit_stat

void setup() {

//设置LCD背光引脚为输出

pinMode(LIGHT_PIN, OUTPUT)

//设置按键为上拉电阻输入(低电平有效)

for (int i=4i<=7i++){

pinMode(i, INPUT_PULLUP)

}

//初始化时打开LCD背光

backlight("ON")

stat = false

//初始化LCD5110

myGLCD.InitLCD()

myGLCD.setContrast(127)

myGLCD.setFont(SmallFont)

myGLCD.print("Initialize...", 0, 0)

/**

* 菜单的进一步设置

* 在这里将每一个菜单的关联设置好

* 对照每一个初始设置仔细填写它们之间的关系

*/

//第一级(main_menu)的第三项指向了下一级菜单(light_menu)

main_menu[2].next = light_menu

//第二级(light_menu)的上一级(main_menu)

light_menu[0].prev = main_menu

//第二级(light_menu)的第二项指向了下一级菜单(test_level3_menu)

light_menu[1].next = test_level3_menu

//第三级(test_level3_menu)的上一级(light_menu)

test_level3_menu[0].prev = light_menu

//第三级(test_level3_menu)的第五项定义了个逻辑动作

test_level3_menu[4].action = ledtest

/**

* 初始化当前菜单为第一级(main_menu)

*/

cur_item = main_menu

/**

* 上一级菜单为空

*/

prev_item = NULL

/**

* 当前选择了第一项

*/

item_index = 0

/**

* 从第一项开始显示菜单

*/

start_index = 0

/**

* 设置DS3231的日期和时间,只需在需要调整的时候执行一次

*/

//clock.setClockMode(true)

//I2C总线库初始化

Wire.begin()

//一些状态变量的初始化

oldsecond = -1

old_up_stat = HIGH

old_down_stat = HIGH

old_enter_stat = HIGH

old_exit_stat = HIGH

//为了视频中能看清楚,延时定义了3秒

delay(3000)

//所有初始化完成,清屏并关闭LCD背光

myGLCD.clrRow(0)

backlight("OFF")

starttime = millis()

}

void loop() {

//获取运行时间

unsigned long endtime = millis()

//获取当前菜单的项目数量

int menu_num = cur_item[0].num

//定义一个临时变量

int idx

//绘制菜单

renderMenu(&cur_item[0], menu_num>MENU_MAX_ROW ? MENU_MAX_ROW : menu_num)

//读取按键

int k_down = digitalRead(KEY_DOWN)

int k_up = digitalRead(KEY_UP)

int k_enter = digitalRead(KEY_ENTER)

int k_exit = digitalRead(KEY_EXIT)

//计算无按键时间,决定是否关闭LCD背光

if (endtime-starttime>5000) {

//myGLCD.enableSleep()

backlight("OFF")

}

//有键按下,打开LCD背光,计时清零

if (k_up==LOW || k_down==LOW || k_enter==LOW || k_exit==LOW) {

//myGLCD.disableSleep()

backlight("ON")

starttime = endtime

}

//检测按键,进入相应动作

if (k_up == LOW &&k_up!=old_up_stat){

//消抖

delay(KEY_TREMBLE_TIME)

if (k_up == LOW){

item_index --

}

} else if (k_down == LOW &&k_down!=old_down_stat){

//消抖

delay(KEY_TREMBLE_TIME)

if (k_down == LOW){

item_index ++

}

} else if (k_enter == LOW &&k_enter!=old_enter_stat){

//消抖

delay(KEY_TREMBLE_TIME)

if (k_enter == LOW){

//计算此时的菜单项索引值

idx = start_index+item_index

if (cur_item[idx].next != NULL &&cur_item[idx].type == MENU_SUBMENU){

//条件成立说明此菜单项指向了下一级菜单

//此级菜单变成了上一级菜单

prev_item = cur_item

//将指向的下一级菜单设置为当前菜单

cur_item = cur_item[idx].next

//重置菜单项索引和绘制索引

item_index = 0

start_index = 0

//清屏

myGLCD.clrScr()

} else if (cur_item[idx].action != NULL &&cur_item[idx].type != MENU_PARAM){

//条件成立说明此项菜单是动作

//此级菜单变成上一级菜单

prev_item = cur_item

//根据动作类型调用相应的下一级菜单

switch(cur_item[idx].type){

case MENU_ACTION_LOGIC:

//将动作函数传递给逻辑菜单,使逻辑菜单能够正确执行动作

logic_menu[0].action = cur_item[idx].action

//设置当前菜单为逻辑菜单

cur_item = logic_menu

//重置菜单项索引和绘制索引

item_index = 0

start_index = 0

break

case MENU_ACTION_NUMBER:

break

case MENU_ACTION_STRING:

break

default:

break

}

//清屏

myGLCD.clrScr()

} else if (cur_item[idx].type == MENU_PARAM){

//条件成立说明正在执行动作

//调用相应的动作函数,并传递参数(这里只举例逻辑设置)

cur_item[0].action((const char *)cur_item[idx].label)

}

}

} else if (k_exit == LOW &&k_exit!=old_exit_stat){

//消抖

delay(KEY_TREMBLE_TIME)

if (k_exit == LOW){

//返回上一级菜单的 *** 作

if (prev_item != NULL){

//设置上一级菜单为当前菜单

cur_item = prev_item

//设置当前菜单的上一级菜单

prev_item = cur_item[0].prev

//重置菜单项索引和绘制索引

item_index = 0

start_index = 0

//清屏

myGLCD.clrScr()

}

}

}

/**

* 菜单项上下选择是否越界

*/

if (item_index<0){

item_index = 0

start_index --

if (start_index<0) start_index = 0

}

if (item_index>=MENU_MAX_ROW || item_index>=menu_num){

if (item_index>=menu_num) item_index = menu_num-1

if (item_index>=MENU_MAX_ROW) item_index = MENU_MAX_ROW-1

if (start_index+MENU_MAX_ROW<menu_num) start_index ++

}

//保存按键状态

old_up_stat = digitalRead(KEY_UP)

old_down_stat = digitalRead(KEY_DOWN)

old_enter_stat = digitalRead(KEY_ENTER)

old_exit_stat = digitalRead(KEY_EXIT)

//renderClock(0, 0)

}

/**

* 关闭LCD背光

* 此函数符合菜单动作定义规则,即无返回值、一个字符串参数

*

* @var const char* stat 值为“ON"打开背光,为“OFF”关闭背光

*/

void backlight(const char *stat)

{

//这里定义了一个逻辑动作

//根据参数决定LCD背光的开关

digitalWrite(LIGHT_PIN, strcmp(stat,"ON") ? LOW : HIGH)

}

/**

* 逻辑动作测试函数

*

* @var const char* stat 根据此参数来执行动作,这里测试PIN13的LED

*/

void ledtest(const char *stat)

{

//根据参数决定LED开关

digitalWrite(LED_PIN, strcmp(stat,"ON") ? LOW : HIGH)

}

/**

* 绘制单个菜单项

*

* @var struct mymenu item 要绘制的项目

* @var int row 绘制坐标(LCD5110绘制文字时只需一个行坐标即可,可根据实际显示设备调整)

* @var bool rev 是否反相绘制,默认为不反相绘制(用于当前选中项绘制,可根据实际显示设备调整)

*/

void renderItem(struct mymenu item, int row, bool rev = false)

{

char label[15]

//规范显示项目文字(左对齐,补空格)

sprintf(label, "%-14s", item.label)

if (rev){

//打开5110的反相绘制功能

myGLCD.invertText(true)

}

//绘制菜单项

myGLCD.print(label, 0, row)

if (rev){

//关闭5110的反相绘制功能

myGLCD.invertText(false)

}

}

/**

* 绘制某一级菜单

*

* @var struct mymenu* items 需要绘制的菜单

* @var int menu_num 菜单项目数量

*/

void renderMenu(struct mymenu *items, int menu_num)

{

//绘制数量不能超过每一屏的最大绘制数量

int num = menu_num>MENU_MAX_ROW ? MENU_MAX_ROW : menu_num

for (int i=0i<numi++){

//绘制每个菜单项

renderItem(items[i+start_index], i*8, i==item_index ? true:false)

}

}

void renderClock(int row)

{

char s[12]

second = clock.getSecond()

minute = clock.getMinute()

hour = clock.getHour(h12, PM)

date = clock.getDate()

month = clock.getMonth(Century)

year = clock.getYear()

temperature = clock.getTemperature()

if (oldsecond!=second){

sprintf(s, "20%02d-%02d-%02d", year, month, date)

myGLCD.print(s, 0, row)

sprintf(s, "%02d:%02d:%02d", PM==0 ? hour:hour+12, minute, second)

myGLCD.print(s, 0, row+8)

sprintf(s, "%3d", sizeof(main_menu)/sizeof(mymenu))

myGLCD.print(s, 0, row+16)

oldsecond = second

}

}

void clockSetting(int year, int month, int day, int hour, int minute, int second)

clock.setSecond(second)//配置秒

clock.setMinute(minute


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12421195.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-25
下一篇 2023-05-25

发表评论

登录后才能评论

评论列表(0条)

保存