Fireduino 定时器
更新时间:2017-09-26 阅读:16624
Fireduino 定时器
Fireuino 定时器是一个具有实时显示时间以及定时警报的一个实例,当定时时间达到时,闪屏和响起警报,并能通过按键修改实时时间以及定时时间。
操作流程
1.上电开始从RTC读取时间,并绘制时间信息至显示屏。
2.按下MODE 键,显示定时器时间,抬起按键显示时钟时间。
3.长按MODE 键进入调定时器模式,在此模式短按MODE 切换位,短按UP、DOWN调相应值,长按快速UP、DOWN调相应值,长按MODE进入调时间模式。
4.在调定时器模式,长按MODE进入调时间模式,修改值的方法与其类似,长按MODE键进入显示时间模式,并把时间写入RTC。
5.定时器值与时间值相同时,进入警报模式(调定时器与调时间期间不进入),警报模式下,按任意键退出警报模式。
硬件连接
1.Fireuino
Fireduino 作为主MCU,为驱动TFT、RTC、KEY、BEEP等提供逻辑运行环境。
2.TFT
TFT 为显示设备,主要提供显示表盘以及时间字符。
3.RTC
RTC 是板载的RTC独立单元,用于保存和获取实时时间,使用的为HYM8563,挂载在I2C1 接口,Fireduino 为此提供了专门的RTC库可供直接使用。
4.KEY & BEEP
按键 用于修改本地时间,定时时间,BEEP用于定时器到达时引起警报。
软件逻辑
模式
定时器主要分以下几种模式
#define MODE_DISPALY_TIME 0 //显示时间模式#define MODE_MODIFY_ALARM 1 //修改定时器模式#define MODE_MODIFY_TIME 2 //修改时间模式#define MODE_ALARM 3 //定时器模式#define MODE_DISPALY_ALARM 4 //显示定时器值模式
事件
事件由按键触发,为事件处理提供依据。
#define EVENT_MODE 1 //模式键抬起事件#define EVENT_UP 2 // UP事件 #define EVENT_DOWN 3 // DOWN事件#define EVENT_MODE_CHANG 4 // 模式改变时间#define EVENT_MODE_CLICK 5 //模式键按下事件
按键处理
本示例使用了3个按键,使用了pin 5、6、7,每20ms 扫描一次按键状态,支持长按和短按。
按键
#define KEY_MODE 0x01#define KEY_UP 0x02#define KEY_DOWN 0x04
按键扫描
每20ms扫描一次
void key_sacn(void){unsigned char pin_level = 0;if(digitalRead(5) == HIGH){ pin_level |= KEY_MODE;}if(digitalRead(6) == HIGH){ pin_level |= KEY_UP;}if(digitalRead(7) == HIGH){ pin_level |= KEY_DOWN;} key_trg = pin_level&(pin_level^key_count); key_count = pin_level;}
按键处理
根据状态,生成事件
void key_proc(void){if(key_trg & KEY_UP){ event_key = EVENT_UP ;} if(key_count & KEY_UP){ up_count++;if(up_count > 100){ up_count = 80 + up_count_i;if(up_count_i++ >100){ up_count_i = 100;} event_key = EVENT_UP;}}else{ up_count = 0; up_count_i = 0;} }
显示处理
根据不同模式,显示不同场景。
1.MODE_DISPALY_TIME 模式显示时钟表盘及时钟字符,颜色为白色。
2.MODE_MODIFY_ALARM 模式显示定时器表盘及定时器字符,颜色为黄色,修改的位与表针的位闪烁。
3.MODE_MODIFY_TIME 模式显示时钟表盘及时钟字符,颜色为白色,修改的位与表针的位闪烁。
4.MODE_ALARM 模式定时器表盘及定时器字符,颜色为红色,时钟与表针闪烁。
5.MODE_DISPALY_ALARM 模式显示定时器表盘及定时器字符,颜色为黄色。
void display_proc(void){switch(curr_mode){case MODE_DISPALY_TIME:...... break;case MODE_DISPALY_ALARM:...... break;case MODE_MODIFY_TIME :...... break;case MODE_MODIFY_ALARM :...... break;case MODE_ALARM :...... break;}}
事件处理
事件处理在按键处理之后,根据时间对于不同的处理。
void event_proc(void){if(event_key){switch(event_key){case EVENT_MODE_CLICK :.....break;case EVENT_MODE :.....break;case EVENT_UP :..... break;case MODIFY_HOUR :..... break;case EVENT_DOWN :..... break;case EVENT_MODE_CHANG :..... break;} event_key = 0;}}
绘图处理
绘制表盘
绘制表针
绘制时间字符
清除表针、相应字符
void draw_dial(void);void clear_pointer(void);void clear_txt(unsigned char flash_bit);void draw_txt(RTCTime *time,unsigned char flash_bit);void draw_pointer(RTCTime *time);void draw_time(RTCTime *time);
Arduino 程序结构
setup()
void setup() { Serial.begin(115200); alarm_time.sec = 0; alarm_time.min = 0; alarm_time.hour = 0; delay(1); TFTscreen.begin(); delay(1); // clear the screen with a pretty color TFTscreen.background(0, 0, 0); TFTscreen.setTextSize(2); TFTscreen.stroke(255,255,255); draw_dial(); Wire1.begin(); RTC.getTime(&time); draw_time(&time); pinMode(BEEP,OUTPUT); digitalWrite(BEEP,HIGH); pinMode(5,INPUT_PULLUP); pinMode(6,INPUT_PULLUP); pinMode(7,INPUT_PULLUP);}
loop()
void loop() { if(millis() > curr_ms){curr_ms = millis() + 250;//显示处理display_proc();}//20ms 检测一次按键状态if(millis() > curr_ms_key){curr_ms_key = millis() + 20;key_sacn(); //按键扫描key_proc(); //按键生成事件event_proc(); //事件处理 }}
示例程序 -- Fireduino 定时器
#include <TFT.h> // Arduino LCD library#include "Wire.h"#include "RTC.h"TFT TFTscreen = TFT();unsigned char Lcd_TimeX(unsigned char circle_x,unsigned char Length,unsigned char Angle){ unsigned char x; if((Angle>0) && (Angle<=15)) { x = circle_x + Length * (sin(PI * Angle / 30)); } else if(Angle > 15 && Angle <= 30) { x = circle_x + Length * cos((PI * Angle) / 30 - (PI / 2 )); } else if(Angle > 30 && Angle <= 45) { x = circle_x - Length * sin((PI * Angle) / 30- PI); } else { x = circle_x-Length * cos((PI * Angle) / 30 - ((3 * PI) / 2)); }return x;}unsigned char Lcd_TimeY(unsigned char circle_y,unsigned char Length,unsigned char Angle){ unsigned char y; if((Angle>0) && (Angle<=15)) { y = circle_y - Length * (cos(PI * Angle / 30)); } else if(Angle > 15 && Angle <= 30) { y = circle_y + Length * sin((PI * Angle) / 30 - (PI / 2 )); } else if(Angle > 30 && Angle <= 45) { y = circle_y + Length * cos((PI * Angle) / 30- PI); } else { y = circle_y - Length * sin((PI * Angle) / 30 - ((3 * PI) / 2)); } return y;}void draw_dial(void){unsigned int i ; TFTscreen.circle(64,64,62); TFTscreen.circle(64,64,63);for(i=0;i<60;i++){ if((i%5) == 0) { TFTscreen.line(Lcd_TimeX(64,62,i),Lcd_TimeY(64,62,i),Lcd_TimeX(64,58,i),Lcd_TimeY(64,58,i)); }}}void clear_pointer(void){unsigned char i;for(i = 0;i<60;i++){ TFTscreen.line(Lcd_TimeX(64,48,i) ,Lcd_TimeY(64,48,i) ,64,64); TFTscreen.line(Lcd_TimeX(64,34,i) ,Lcd_TimeY(64,34,i) ,64,64); TFTscreen.line(Lcd_TimeX(64,24,i) ,Lcd_TimeY(64,24,i) ,64,64);}}void clear_txt(unsigned char flash_bit){switch(flash_bit){case 0: TFTscreen.fillRect(90, 140,22,14,0);break;case 1: TFTscreen.fillRect(54, 140,22,14,0);break;case 2: TFTscreen.fillRect(18, 140,22,14,0);break;default: TFTscreen.fillRect(18, 140,94,14,0);break;}}void draw_txt(RTCTime *time,unsigned char flash_bit){char temp[9];switch(flash_bit){case 0:sprintf(temp,"%02d",time->sec); temp[3] = 0; TFTscreen.text(temp, 90, 140);break;case 1:sprintf(temp,"%02d",time->min); temp[3] = 0; TFTscreen.text(temp, 54, 140);break;case 2:sprintf(temp,"%02d",time->hour); temp[3] = 0; TFTscreen.text(temp, 18, 140);break;default:sprintf(temp,"%02d:%02d:%02d",time->hour,time->min,time->sec); temp[8] = 0; TFTscreen.text(temp, 18, 140);break;