Fireduino 开源创意平台 立即购买

拥有双核Cortex-M3处理器,集成高质量音频Codec和WiFi模组,拥有良好的IOT扩展性能,完美兼容Arduino IDE和Arduino标准接口,并支持FireBlock图形化编程软件,是一款首选的编程启蒙教学平台,更是一款开源的创意原型平台。

Fireduino 定时器

更新时间:2017-09-26 阅读:2000

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 为显示设备,主要提供显示表盘以及时间字符。

LCD SCH.jpg

3.RTC

RTC 是板载的RTC独立单元,用于保存和获取实时时间,使用的为HYM8563,挂载在I2C1 接口,Fireduino 为此提供了专门的RTC库可供直接使用。

Fireduino RTC SCH.jpg

4.KEY & BEEP

按键 用于修改本地时间,定时时间,BEEP用于定时器到达时引起警报。

Fireduino TFT WDT.jpg

软件逻辑

模式

定时器主要分以下几种模式

#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;