#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
unsigned int second = 0; //初始时间-秒
unsigned int minute = 0; //初始时间-分钟
unsigned int hour = 0; //初始时间-小时
int timer1_counter;
String inc; //输入的字符串
int num; //输入的时间
int buzzerpin = 8; //定义蜂鸣器接口
float sinVal; //闹钟声音所需
int toneVal; //闹钟声音所需
int flag1 = 0; //是否已有闹钟的标志
int fHour = 1; //闹钟时间
int fMinute = 1; //闹钟时间
int flag2 = 0; //闹钟响起标志
bool flag = true;
void setup() {
Serial.begin(9600);
Serial.println("电子钟");
Serial.println("输入setHour修改小时,setMinute修改分钟,setSecond修改秒");
Serial.println("输入setAlarm设置闹钟,输入cancelAlarm取消闹钟,输出changeAlarm修改闹钟");
Serial.println("(注意区分字母大小写!)");
lcd.init();
lcd.backlight();
lcd.setCursor(1, 0);
lcd.println("");
pinMode(buzzerpin, OUTPUT);
//定时器
noInterrupts();
TCCR1A = 0;
TCCR1B = 0;
//timer1_counter = 65536-(62500*1); //1s 定时器中断
timer1_counter = 3036;
TCNT1 = timer1_counter;
TCCR1B |= (1 << CS12);
TIMSK1 |= (1<< TOIE1);
interrupts();
//蜂鸣器频率设置
for(int x = 0;x < 180;x++){
sinVal = (sin(x*(3.1412/180)));
toneVal = 2000 + (int(sinVal*1000));
}
}
//秒+1
ISR(TIMER1_OVF_vect) {
TCNT1 = timer1_counter;
second++;
}
void loop() {
simTime(); //化简时间
showTime(); //输出时间
//当检测到数据输入时
if (Serial.available() > 0){
if(changeTime() == false) //修改时间,若没有找到相关指令
alarm(); //在闹钟设置寻找指令
}
alarmOpen(); //打开闹钟
}
//化简时间
void simTime()
{
if(second >= 60){
second = second % 60;
minute++;
}
if(minute >= 60){
minute = minute % 60;
hour++;
}
if(hour == 24){
hour == 0;
}
}
//格式化输出时间
void showTime()
{
//格式化输出小时
sim(4, hour);
//格式化输出分钟
sim(7, minute);
//格式化输出秒
sim(10, second);
//时间中冒号的显示
if (second % 2 == 1)
{
lcd.setCursor(6, 1);
lcd.print(":");
lcd.setCursor(9, 1);
lcd.print(":");
}
else if (second % 2 == 0)
{
lcd.setCursor(6, 1);
lcd.print(" ");
lcd.setCursor(9, 1);
lcd.print(" ");
}
}
//格式化代码
void sim(int cursor, int time)
{
lcd.setCursor(cursor, 1);
if(time < 10){
lcd.print(0);
lcd.setCursor(cursor + 1, 1);
lcd.print(time);
}
else
lcd.print(time);
}
//修改时间
bool changeTime()
{
//获取得到的字符串
inc = Serial.readString();
inc.trim(); //去除尾部的换行符
if(inc == "setHour")
{
Serial.println("请输入小时(0-23整数)");
while(Serial.available() == 0); //等待输入
inc = Serial.readString();
inc.trim();
if(inc.toInt() >= 0 && inc.toInt() <= 23){
hour = inc.toInt();
Serial.println("修改完成");
return true;
}
else{
Serial.println("输入的必须是0-23的整数");
return true;
}
}
else if(inc == "setMinute"){
Serial.println("请输入分钟(0-59整数)");
while(Serial.available() == 0); //等待输入
inc = Serial.readString();
inc.trim();
if(inc.toInt() >= 0 && inc.toInt() <= 59){
minute = inc.toInt();
Serial.println("修改完成");
return true;
}
else{
Serial.println("输入的必须是0-59的整数");
return true;
}
}
else if(inc == "setSecond"){
Serial.println("请输入秒(0-59整数)");
while(Serial.available() == 0); //等待输入
inc = Serial.readString();
inc.trim();
if(inc.toInt() >= 0 && inc.toInt() <= 59){
second = inc.toInt();
Serial.println("修改完成");
return true;
}
else{
Serial.println("输入的必须是0-59的整数");
return true;
}
}
else{
return false;
}
}
//闹钟设置
void alarm()
{
//设置闹钟
if(inc == "setAlarm" && flag1 == 0) //指令正确且无已有闹钟
{
setAlarm();
}
else if(inc == "setAlarm" && flag1 == 1){ //指令正确且已有闹钟
Serial.println("已有闹钟,无法重复设置!");
}
//取消闹钟
else if(inc == "cancelAlarm" && flag1 == 1){ //指令正确且已有闹钟
flag1 == 0;
}
else if(inc == "cancelAlarm" && flag1 == 0){ //指令正确但没有闹钟
Serial.println("还没有设置闹钟!");
}
//修改闹钟
else if(inc == "changeAlarm" && flag1 == 1){ //指令正确且已有闹钟
setAlarm();
}
else if(inc == "changeAlarm" && flag1 == 0){ //指令正确但没有闹钟
Serial.println("还没有设置闹钟!");
}
//关闭正在响起的闹钟指令
else if(inc == "close" && flag1 == 1){
flag2 = 0;
Serial.println("闹钟已关闭");
noTone(buzzerpin);
}
//其他
else{
Serial.println("无效指令!");
}
}
//设置闹钟时间
void setAlarm(){
//设置小时
Serial.println("设置小时(0-23整数)");
while(Serial.available() == 0);
inc = Serial.readString();
inc.trim();
if(inc.toInt() >= 0 && inc.toInt() <= 23){
fHour = inc.toInt();
Serial.println("小时设置成功");
}
else{
Serial.println("输入的必须是0-23的整数,请重新输入指令设置闹钟");
}
//设置分钟
Serial.println("设置分钟(0-59整数)");
while(Serial.available() == 0);
inc = Serial.readString();
inc.trim();
if(inc.toInt() >= 0 && inc.toInt() <= 59){
fMinute = inc.toInt();
Serial.print("闹钟设置成功,时间为 ");
Serial.print(fHour);
Serial.print("时");
Serial.print(fMinute);
Serial.println("分");
flag1 = 1;
}
else{
Serial.println("输入的必须是0-59的整数,请重新输入指令设置闹钟");
}
}
void alarmOpen(){
if(hour == fHour && minute == fMinute && second == 0 && flag2 == 0 && flag1 == 1){ //打开闹钟
flag2 = 1;
Serial.println("闹钟已开,输入close关闭闹钟");
}
if(flag2)
tone(buzzerpin,toneVal);
}