提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
实验准备
实验所用元件:
元件 | 功能 |
---|---|
Arduino UNO板 | 编程开发 |
LCD 1602 | 时间显示 |
手柄 | 时间调整 |
杜邦线若干 | 元件连接 |
电位器 | 对比度调节 |
实验连线:
Arduino | LCD 1602 |
---|---|
GND | VSS |
5V | VDD |
Pin 6 | V0 |
Pin 12 | RS |
GND | RW |
Pin 11 | EN |
Pin 5 | D4 |
Pin 4 | D5 |
Pin 3 | D6 |
Pin 2 | D7 |
GND | BLK(K) |
Arduino | 电位器 |
---|---|
3.3V | VCC |
GND | GND |
LCD 1602 | 电位器 |
---|---|
BLA(A) | S |
实验原理
1.使用LCD1602库函数<LiquidCrystal.h>实现数字显示,利用定时器1和定时器2的库函数:<TimerOne.h>和<MsTimer2.h>实现时间的更新显示。
Arduino UNO有三个定时器:
timer0:一个被Arduino的delay(), millis()和micros()使用的8位定时器
timer1:一个被Arduino的Servo()库使用的16位定时器
timer2:一个被Arduino的Tone()库使用的8位定时器
常见的定时器使用方式有自定义触发、MsTimer2库、TimeOne库三种方式,操作寄存器比较复杂,所以本实验采用库函数的操作方式。
2.PS2手柄左右移动切换到需要调整的位置,上下移动控制当前位置值(时分秒)的增减。
3.电位器旋转时可以输出不同大小的电压值,而LCD显示器的对比度可以通过3号引脚的输入电压控制,故可以将电位器输出接至LCD的3号引脚,实现通过旋钮电位器模块调整LCD显示屏的对比度。
4.控制状态转换原理图:
实验代码
#include <LiquidCrystal.h> // 加载LCD1602的库
#include <MsTimer2.h> //加载定时器2的库
#include <TimerOne.h> //加载定时器1的库
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2; // 定义引脚
LiquidCrystal lcd(rs, en, d4, d5, d6, d7); // 根据引脚,创建一个 lcd 实例
int Hour=0,Min=0,Sec=0,flag=0; //初始化时分秒
void tick(){
if(Sec>=59)
{
Sec=0;
Min=Min+1;
lcd.setCursor(7,0);
lcd.print(" ");
}
if(Min==60)
{
Min=0;
Hour=Hour+1;
}
if(Hour==24)
{
Hour=0;
}
Sec=Sec+1;
//LCD时间显示
lcd.setCursor(0,0);
lcd.print(Hour);
lcd.setCursor(2,0);
lcd.print(":");
lcd.setCursor(3,0);
lcd.print(Min);
lcd.setCursor(5,0);
lcd.print(":");
lcd.setCursor(6,0);
lcd.print(Sec);
}
//时钟位调整函数
void H()
{ //PS2手柄向上
if ((analogRead(A1)) == 1023) {
Hour++;
lcd.setCursor(0,0);
lcd.print(" ");
if(Hour>=24)
{
Hour=0;
}
lcd.setCursor(0,0);
lcd.print(Hour);
} else {
//PS2手柄向下
if ((analogRead(A1)) == 0) {
Hour--;
lcd.setCursor(0,0);
lcd.print(" ");
if(Hour<=-1)
{
Hour=23;
}
lcd.setCursor(0,0);
lcd.print(Hour);
}
}
}
//分钟位调整函数
void M()
{ //PS2手柄向上
if ((analogRead(A1)) == 1023) {
Min++;
lcd.setCursor(3,0);
lcd.print(" ");
if(Min>=59)
{
Min=0;
}
lcd.setCursor(3,0);
lcd.print(Min);
} else {
//PS2手柄向下
if ((analogRead(A1)) == 0) {
Min--;
lcd.setCursor(3,0);
lcd.print(" ");
if(Min<=-1)
{
Min=59;
}
lcd.setCursor(3,0);
lcd.print(Min);
}
}
}
//秒钟位调整函数
void S()
{ //PS2手柄向上
if ((analogRead(A1)) == 1023) {
Sec=0;
lcd.setCursor(7,0);
lcd.print(" "); }
//PS2手柄向下
if ((analogRead(A1)) == 0) {
Sec=0;
lcd.setCursor(7,0);
lcd.print(" ");
}
}
void timer1(){
//PS2手柄向右
if ((analogRead(A0)) == 1023) {
flag++;
if(flag==4)
{
flag=0;
}
} else {
// PS2手柄向左
if ((analogRead(A0)) == 0) {
flag--;
if(flag==-1)
{
flag=3;
}
}
}
//时间调整状态切换
switch(flag){
case 1:{
lcd.setCursor(0,1);
lcd.print("^^");
lcd.setCursor(2,1);
lcd.print(" ");
lcd.setCursor(4,1);
lcd.print(" ");
H();
break;
}
case 2:{
lcd.setCursor(3,1);
lcd.print("^^");
lcd.setCursor(0,1);
lcd.print(" ");
lcd.setCursor(6,1);
lcd.print(" ");
M();
break;
}
case 3:{
lcd.setCursor(6,1);
lcd.print("^^");
lcd.setCursor(3,1);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print(" ");
S();
break;
}
default:{
lcd.setCursor(6,1);
lcd.print(" ");
lcd.setCursor(3,1);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print(" ");
}
}
}
void setup() {
lcd.begin(16, 2); // 初始化lcd ,并定义LCD1602的规格
MsTimer2::set(1000,tick);//1000ms的刷新频率
MsTimer2::start();
Timer1.initialize(200000);//200ms的刷新频率
Timer1.attachInterrupt(timer1);
}
void loop()
{}