查看:
17952
回复: 40 |
参赛作品《多功能遥控电子时钟》 (已完成)
|
|
发表于2017-06-03 16:01:44
|
显示全部楼层
1#
电梯直达
【报名阶段需要填写的内容】 1. 参赛者姓名(必填项):
【作品正式发表(报名成功后进入设计阶段)需要填写的内容】 一、作品简介 例如,可以包括但不局限于以下内容: 1.作品的整机外观图片或焊接组装好的PCBA图片; 2.作品的研究背景、目的和功能、市场应用前景; 3.作品在创新性、趣味性、实用性甚至公益性方面,有哪些亮点可体现?
3.1.1 设计效果:
3.1.2 实际效果
3.1.3 运行效果 二、系统构架图 用流程图或思维导图等形式,描述您的作品的组成构架,即方案图。 三、硬件部分的描述 1.附上原理图&PCB实物图的图片或者源文件(官方建议大家尽量用源文件上传),如果是图片,请确保图片是清晰可辨的; 2.用文字把该作品的实现原理、系统的工作过程大致讲解一下。 显示电路部份,采用模块结构。多片串行显示,可以不局限于线路板大小,而可以将产品尺寸做大;
2、主板电路
以前做过一个版本是IR的,现在IR的遥控器手上难找,且IR的有方向性不能穿墙。将原IR部份电路改成RF方式的。另外增加了485的总线接口。可以与485总线的智能家居系统等实现系统对接。实现一定的模块功能。 主板到显示模块,输出外围了一个NMOS,可以实现PWM亮度调节,夜晚时分,可以自动调低亮度。
四、材料清单(BOM列表) 列出您这个作品所用到的主要器件(关键器件即可),比如单片机&ARM芯片、专用集成芯片(ASIC)、传感器、功能模块等。 如果所列出的芯片是来自我们立创商城上的,最好能写出该器件的商品编号或附上对应购买链接。 失误更正: 显示板BOM清单内,数码显示器LED1,正确型号为:FJ11001AH, 编号:C10687,购买链接:http://www.szlcsc.com/product/details_11231.html 五、软件部分的描述(选填) 如果您的作品涉及到软件,请列出作品对应的软件工作流程图,及关键部分的例程、源码(如果您想开源的话请上传全部源码)。 5.1、按键处理流程:
5.2 按键部份处理代码:
#include "Config.h" extern DATE date; extern TIME time; extern volatile Alam_t on_Alam; #if OPT_COUNTER extern volatile Counter_t on_Ct; #endif extern volatile uCHAR dis_buffer[11]; extern volatile WatchSet_t WatchSet; extern volatile WatchCfg_t WatchCofing; extern volatile XTIMER Timer[e_Timer_Max]; //------------------------------- //Function: Key Adjust Process //------------------------------- void Key_Adjust_Value(u8 dig, s8 v) { if(!WatchSet.in.item.set) return; if(!WatchSet.in.item.adj) return; dig = dig?10:0; v += dig; //己进入调整状态 switch(WatchSet.item){ case MENUMOD_ITEM_TIME: Watch_Set_Time(WatchSet.sub, v); break; case MENUMOD_ITEM_DATE: Watch_Set_Date(WatchSet.sub, v); break; #if OPT_COUNTER case MENUMOD_ITEM_COUNT: Watch_Set_Count(WatchSet.sub, v); break; #endif case MENUMOD_ITEM_ALAM0: case MENUMOD_ITEM_ALAM1: case MENUMOD_ITEM_ALAM2: case MENUMOD_ITEM_ALAM3: case MENUMOD_ITEM_ALAM4: case MENUMOD_ITEM_ALAM5: case MENUMOD_ITEM_ALAM6: case MENUMOD_ITEM_ALAM7: case MENUMOD_ITEM_ALAM8: case MENUMOD_ITEM_ALAM9: Watch_Set_Alam(WatchSet.item-MENUMOD_ITEM_ALAM0, WatchSet.sub, v); break; default: break; } } //------------------------------- //Function: Key action Process //------------------------------- void KeyProcess(void) { uCHAR Keytemp,Out = 200,i; Keytemp = IR_KeyB(); if(Keytemp==KEY_SEL_NOSEL)return; Beeper(TRUE, 100, 0); if(IS_TIMERSTART(e_Timer_SET)) { RESET_TIMER(e_Timer_SET); } else { START_TIMER(e_Timer_SET, 25000); } if(on_Alam.inw) { memclr(&on_Alam, sizeof(Alam_t)); return; #if OPT_COUNTER } else if(on_Ct.full && on_Ct.use) { on_Ct.use = FALSE; on_Ct.full = FALSE; return; #endif } switch(Keytemp) { case KEY_SEL_DIG0: case KEY_SEL_DIG1: case KEY_SEL_DIG2: case KEY_SEL_DIG3: case KEY_SEL_DIG4: case KEY_SEL_DIG5: case KEY_SEL_DIG6: case KEY_SEL_DIG7: case KEY_SEL_DIG8: case KEY_SEL_DIG9: //己进入调整状态 Keytemp -= KEY_SEL_DIG0; Key_Adjust_Value(TRUE, Keytemp); if(!WatchSet.in.item.set) break; if(!WatchSet.in.item.adj) break; case KEY_SEL_SET: if(WatchSet.in.item.show) { Alert_t* alam = WatchCofing.alart+WatchSet.sub; if(WatchSet.item==MENUSHOW_ITEM_ALAM) { if(alam->on) { alam->on = FALSE; if(on_Alam.id==WatchSet.sub) { memclr(&on_Alam, sizeof(Alam_t)); } } else { alam->on = TRUE; } Watch_Show_Alam(WatchSet.sub); WatchCofing.dirty = TRUE; } break; #if OPT_COUNTER } else if(on_Ct.use) { on_Ct.use = FALSE; break; #endif } if(WatchSet.in.item.set) { if(WatchSet.in.item.adj) { //调整设置项目 //WatchSet.in.item.adj = FALSE; WatchSet.sub++; if(WatchSet.item==MENUMOD_ITEM_DATE){ if(WatchSet.sub>=7) { ExitMenu(TRUE); break; } } else { if(WatchSet.sub>=6) { ExitMenu(TRUE); break; } } } else { WatchSet.sub = 0; WatchSet.item++; if(WatchSet.item>=MENUMOD_ITEM_MAX) { ExitMenu(TRUE); break; } } Watch_Show_SetItem(WatchSet.item, WatchSet.sub); break; //WatchSet.in.item.adj = TRUE; } WatchSet.in.items = 0; WatchSet.in.item.set = TRUE; WatchSet.sub = 0; WatchSet.item = MENUMOD_ITEM_TIME; Watch_Show_SetItem(MENUMOD_ITEM_TIME, 0); break; case KEY_SEL_INC: if(WatchSet.in.item.set) { Key_Adjust_Value(FALSE, 1); break; #if OPT_COUNTER } else if(on_Ct.use && on_Ct.pause) { on_Ct.base = SecondsToTime(TimeToSeconds(time)+on_Ct.run); on_Ct.pause = FALSE; break; #endif } //显示闹钟 if(WatchSet.in.item.show) { WatchSet.sub++; if(WatchSet.sub>9) { WatchSet.in.item.show = FALSE; } } else { WatchSet.in.item.show = TRUE; WatchSet.item = MENUSHOW_ITEM_ALAM; WatchSet.sub = 0; } Watch_Show_Alam(WatchSet.sub); break; case KEY_SEL_DEC: if(WatchSet.in.item.set) { //己进入调整状态 if(WatchSet.in.item.adj) { Key_Adjust_Value(FALSE, -1); } else { WatchSet.sub = 0; WatchSet.in.item.adj = TRUE; Watch_Show_SetItem(WatchSet.item, 0); } break; } if(WatchSet.in.item.show ) { ExitMenu(TRUE); #if OPT_COUNTER } else if(on_Ct.use){ on_Ct.pause = TRUE; break; #endif } else { //显示日期 WatchSet.in.items = 0; WatchSet.in.item.show = TRUE; WatchSet.item = MENUSHOW_ITEM_DATE; Watch_Display_Date(date); } break; } } void ExitMenu(char force) { if(IS_TIMEROVER(e_Timer_SET)||force) { if(WatchSet.in.item.modify) { switch(WatchSet.item) { case MENUMOD_ITEM_TIME: Watch_Save_Time(); break; case MENUMOD_ITEM_DATE: Watch_Save_Date(); break; #if OPT_COUNTER case MENUMOD_ITEM_COUNT: Watch_Save_Count();//show the countdown time break; #endif case MENUMOD_ITEM_ALAM0: case MENUMOD_ITEM_ALAM1: case MENUMOD_ITEM_ALAM2: case MENUMOD_ITEM_ALAM3: case MENUMOD_ITEM_ALAM4: case MENUMOD_ITEM_ALAM5: case MENUMOD_ITEM_ALAM6: case MENUMOD_ITEM_ALAM7: case MENUMOD_ITEM_ALAM8: case MENUMOD_ITEM_ALAM9: Save_WatchCofing(); break; default: WatchSet.in.items = 0; break; } } WatchSet.sub = 0; WatchSet.item = 0; WatchSet.temp = 0; WatchSet.in.items = 0; STOP_TIMER(e_Timer_SET); } } 5.3 按键/遥控读取部份代码 #include "Config.h" extern volatile _Bool Synch; extern volatile u8 RF_data; extern volatile XTIMER Timer[e_Timer_Max]; const u8 rfcodes[] = { 0XCC, 0X03, 0X0C, 0X0F, 0X30, 0X33, 0X3C, 0X3F, 0XC0, 0XC3, 0XCF, 0XF0 }; void Key_Init(void) { set_io_isinput(PORT_KEY_SET, BIT_KEY_SET); set_io_isinput(PORT_KEY_INC, BIT_KEY_INC); set_io_isinput(PORT_KEY_DEC, BIT_KEY_DEC); set_io_pushpull(PORT_KEY_SET, BIT_KEY_SET); set_io_pushpull(PORT_KEY_INC, BIT_KEY_INC); set_io_pushpull(PORT_KEY_DEC, BIT_KEY_DEC); } uCHAR GetKeyVal(void) { char temp, i; static key_bak, key_temp=KEY_SEL_NOSEL; temp = 0; if(!get_bit(PORT_KEY_SET, BIT_KEY_SET)) { temp |= BIT(0); } if(!get_bit(PORT_KEY_INC, BIT_KEY_INC)) { temp |= BIT(1); } if(!get_bit(PORT_KEY_DEC, BIT_KEY_DEC)) { temp |= BIT(2); } if(temp == KEY_SEL_NOSEL) { //unpressed key_temp = KEY_SEL_NOSEL; return KEY_SEL_NOSEL; } //the last key event not free if(key_temp==temp) return KEY_SEL_NOSEL; //key noise filter if(!IS_TIMERSTART(e_Timer_KeyFilter)) { key_bak = temp; START_TIMER(e_Timer_KeyFilter, 10); } else if(key_bak!=temp) { //key changed in filter STOP_TIMER(e_Timer_KeyFilter); return KEY_SEL_NOSEL; } if(!IS_TIMEROVER(e_Timer_KeyFilter)) return KEY_SEL_NOSEL; STOP_TIMER(e_Timer_KeyFilter); key_temp = temp; if(temp==0x01) { return KEY_SEL_SET; } else if(temp==0x02) { return KEY_SEL_INC; } else if(temp==0x04) { return KEY_SEL_DEC; } else { //KEY_SEL_MOV,KEY_SEL_POW if(temp==0x03) { return KEY_SEL_MOV; } else if(temp==0x05) { return KEY_SEL_POW; } } return KEY_SEL_NOSEL; } uCHAR IR_KeyB(void) { uCHAR Keytemp; static uCHAR RF_Temp = 0xFF; if(!Synch) { Keytemp = GetKeyVal(); } else { Synch = FALSE; if(IS_TIMERSTART(e_Timer_Remote)) { if(!IS_TIMEROVER(e_Timer_Remote)) { return KEY_SEL_NOSEL; } STOP_TIMER(e_Timer_Remote); } //遥控解码间隙超时 START_TIMER(e_Timer_Remote, 300); for(Keytemp=0; Keytemp<12; Keytemp++) { if(rfcodes[Keytemp]==RF_data) { Synch = TRUE; break; } } if(Synch) { switch(Keytemp) { case 10: Keytemp = KEY_SEL_SET; break; case 11: Keytemp = KEY_SEL_DEC; break; } } Synch = FALSE; } return Keytemp; }
5.4 电子表核心处理代码 #include "Config.h" #if OPT_COUNTER volatile Counter_t on_Ct = {0}; #endif volatile Alam_t on_Alam = {0, 0, 0, 0}; volatile uCHAR dis_buffer[11]; volatile WatchSet_t WatchSet; extern DATE date; extern TIME time; extern volatile WatchCfg_t WatchCofing; extern volatile XTIMER Timer[e_Timer_Max]; //----------------------------------- #define isLeampyear(year) ((year%4==0&&year%100!=0)||(year%400==0)) //----------------------------------- //led show codes //0~9, ' ', -, A, C, H const uCHAR LED[] = { 0XDE,0X06,0XEC,0XAE,0X36, //0~4 0XBA,0XFA,0X0E,0XFE,0XBE, //5~9 0x00, //String - ' ' 0X20, //String - '-' 0X7E, //String - 'A' 0XD8, //String - 'C' 0X76, //String - 'H' 0XD6, //String - 'U' 0X5E, //String - 'N' 0XF0, //String - 't' 0XD0, //String - 'L' 0X01 //String - '.' }; const uCHAR SEGMENT[] = { 0x08,0x04,0x02,0x80,0x40,0x10,0x20,0x01 }; //----------------------------------- //FUNCTION: DISPLAY THE DATA //----------------------------------- static void Watch_Update_Display(void) { uCHAR i; uCHAR v; for(i=0; i<11; i++) { v = *(dis_buffer+i); if(v>=LEDWORD_USEDEF) { MC74HC595_Shift(v-LEDWORD_USEDEF); } else { MC74HC595_Shift(LED[v]); } } MC74HC595_Update(); } void write_DisBuffer(u8 ID, u8 v) { *(dis_buffer+ID) = v; } u8 read_DisBuffer(u8 ID) { return *(dis_buffer+ID); } //---------------------------------- //FUNCTION: display the year //---------------------------------- void Watch_Display_Date(DATE date) { write_DisBuffer(LEDITEM_MAIN_1, math_div(date.year, 10)); //year ten write_DisBuffer(LEDITEM_MAIN_2, math_mod(date.year, 10)); //year signed write_DisBuffer(LEDITEM_MAIN_3, LEDWORD_LINE); //"-" write_DisBuffer(LEDITEM_MAIN_4, math_div(date.month, 10)); //month ten write_DisBuffer(LEDITEM_MAIN_5, math_mod(date.month, 10)); //month signed write_DisBuffer(LEDITEM_MAIN_6, LEDWORD_LINE); //"-" write_DisBuffer(LEDITEM_MAIN_7, math_div(date.day, 10)); //date ten write_DisBuffer(LEDITEM_MAIN_8, math_mod(date.day, 10)); //date signed write_DisBuffer(LEDITEM_WEEK, math_mod(date.week, 10)); //week if(WatchSet.in.item.show) { write_DisBuffer(LEDITEM_TEMP_H, LEDWORD_WORDA); write_DisBuffer(LEDITEM_TEMP_L, LEDWORD_WORDT); } Watch_Update_Display(); } //---------------------------------- //Function: display the date //---------------------------------- void Watch_Display_Time(TIME time) { uCHAR temp; static u8 scrow = TRUE; write_DisBuffer(LEDITEM_MAIN_1, math_div(time.hour, 10)); //Hour ten write_DisBuffer(LEDITEM_MAIN_2, math_mod(time.hour, 10)); //Hour signed write_DisBuffer(LEDITEM_MAIN_3, LEDWORD_LINE); //"-" write_DisBuffer(LEDITEM_MAIN_4, math_div(time.min, 10)); //minute ten write_DisBuffer(LEDITEM_MAIN_5, math_mod(time.min, 10)); //minute signed write_DisBuffer(LEDITEM_MAIN_6, LEDWORD_LINE); //"-" write_DisBuffer(LEDITEM_MAIN_7, math_div(time.sec, 10)); //second ten write_DisBuffer(LEDITEM_MAIN_8, math_mod(time.sec, 10)); //second signed if(!WatchSet.in.items) { #if OPT_COUNTER if(on_Ct.use) { if(!on_Ct.full) { on_Ct.segLeds |= SEGMENT[on_Ct.sCount++]; if(on_Ct.sCount>=6) { on_Ct.sCount = 0; } on_Ct.segLeds &= ~SEGMENT[on_Ct.sCount]; write_DisBuffer(LEDITEM_TEMP_H, LEDWORD_WORDC); write_DisBuffer(LEDITEM_TEMP_L, LEDWORD_DIG0); write_DisBuffer(LEDITEM_WEEK, LEDWORD_USEDEF+on_Ct.segLeds); } else { if(scrow) { write_DisBuffer(LEDITEM_TEMP_H, LEDWORD_BLANK); write_DisBuffer(LEDITEM_TEMP_L, LEDWORD_BLANK); write_DisBuffer(LEDITEM_WEEK, LEDWORD_BLANK); } else { write_DisBuffer(LEDITEM_TEMP_H, LEDWORD_WORDC); write_DisBuffer(LEDITEM_TEMP_L, LEDWORD_DIG0); write_DisBuffer(LEDITEM_WEEK, LEDWORD_LINE); } scrow = !scrow; } } else #endif if(on_Alam.inw) { if(scrow) { write_DisBuffer(LEDITEM_TEMP_H, LEDWORD_WORDA); write_DisBuffer(LEDITEM_TEMP_L, on_Alam.id); write_DisBuffer(LEDITEM_WEEK, LEDWORD_LINE); } else { write_DisBuffer(LEDITEM_TEMP_H, LEDWORD_BLANK); write_DisBuffer(LEDITEM_TEMP_L, LEDWORD_BLANK); write_DisBuffer(LEDITEM_WEEK, LEDWORD_BLANK); } scrow = !scrow; } else { temp = Temperature_Read(); if(temp>=100) { write_DisBuffer(LEDITEM_TEMP_H, LEDWORD_LINE); write_DisBuffer(LEDITEM_TEMP_L, LEDWORD_LINE); } else { write_DisBuffer(LEDITEM_TEMP_H, math_div(temp, 10)); write_DisBuffer(LEDITEM_TEMP_L, math_mod(temp, 10)); } write_DisBuffer(LEDITEM_WEEK, math_mod(date.week, 10)); //week } } Watch_Update_Display(); } void Watch_Display_Temp(s8 temp) { if(temp>=0) { write_DisBuffer(LEDITEM_TEMP_H, math_div(temp, 10)); write_DisBuffer(LEDITEM_TEMP_L, math_mod(temp, 10)); } else { write_DisBuffer(LEDITEM_TEMP_H, LEDWORD_LINE); write_DisBuffer(LEDITEM_TEMP_L, (0-temp)); } Watch_Update_Display(); } //---------------------------------- //Function: Adjust the time //---------------------------------- void setv(uCHAR ID, s8 v, const char min, const char max) { s8 ss = -1; if(v>=10) { ss = v-10; if((ss>=min)&&(ss<=max))write_DisBuffer(ID, ss); } else { ss = (char)(read_DisBuffer(ID)+v); if(ss > max) { write_DisBuffer(ID, min); } else if(ss < min) { write_DisBuffer(ID, max); } else { write_DisBuffer(ID, (uCHAR)ss); } } if(v!=0)WatchSet.in.item.modify = TRUE; } void setCV(uCHAR ID, s8 v, const char min, const char max) { setv(ID, v, min, max); //更新闪烁缓存数值 WatchSet.temp = read_DisBuffer(ID); } static TIME Watch_Adjust_Time(char AdjItem, s8 val) { TIME new_time; switch(AdjItem){ case 0: setCV(LEDITEM_MAIN_1, val, 0, 2); if(read_DisBuffer(LEDITEM_MAIN_1)==2){ setv(LEDITEM_MAIN_2, val, 0, 3); } break; case 1: if(read_DisBuffer(LEDITEM_MAIN_1)==2){ setCV(LEDITEM_MAIN_2, val, 0, 3); } else { setCV(LEDITEM_MAIN_2, val, 0, 9); } break; case 2: setCV(LEDITEM_MAIN_4, val, 0, 5); break; case 3: setCV(LEDITEM_MAIN_5, val, 0, 9); break; case 4: setCV(LEDITEM_MAIN_7, val, 0, 5); break; case 5: setCV(LEDITEM_MAIN_8, val, 0, 9); break; default: break; } new_time.hour = math_mux(read_DisBuffer(LEDITEM_MAIN_1),10) + read_DisBuffer(LEDITEM_MAIN_2); new_time.min = math_mux(read_DisBuffer(LEDITEM_MAIN_4),10) + read_DisBuffer(LEDITEM_MAIN_5); new_time.sec = math_mux(read_DisBuffer(LEDITEM_MAIN_7),10) + read_DisBuffer(LEDITEM_MAIN_8); Watch_Update_Display(); return new_time; } //--------------------------------- //Function: Adjust date //--------------------------------- void Adjust_Date_Value(u8 ID) { u8 month, x; u16 year = 2000; uCHAR lagermonth[] = {1,3,5,7,8,10,12}; year += read_DisBuffer(LEDITEM_MAIN_1)*10 + read_DisBuffer(LEDITEM_MAIN_2); month = read_DisBuffer(LEDITEM_MAIN_4)*10 + read_DisBuffer(LEDITEM_MAIN_5); if(month==2) { if(read_DisBuffer(LEDITEM_MAIN_7)==2) { if(isLeampyear(year)) { setv(LEDITEM_MAIN_8, 0, 0, 8); } else { setv(LEDITEM_MAIN_8, 0, 0, 9); } } } else if(read_DisBuffer(LEDITEM_MAIN_7)==3) { for(x=0; x<sizeof(lagermonth); x++) { if(month==lagermonth[x]) { setv(LEDITEM_MAIN_8, 0, 0, 1); break; } } if(x>=sizeof(lagermonth)) { write_DisBuffer(LEDITEM_MAIN_8, 0); } } //更新闪烁缓存数值 if(ID==LEDITEM_MAIN_8) { WatchSet.temp = read_DisBuffer(LEDITEM_MAIN_8); } } static DATE Watch_Adjust_Date(char AdjItem, s8 val) { u8 month; DATE new_date; switch(AdjItem){ case 0: //Year-H setCV(LEDITEM_MAIN_1, val, 0, 9); break; case 1: //Year-L setCV(LEDITEM_MAIN_2, val, 0, 9); break; case 2: //Month-H setCV(LEDITEM_MAIN_4, val, 0, 1); if(read_DisBuffer(LEDITEM_MAIN_4)) { setv(LEDITEM_MAIN_5, val, 0, 2); } else { setv(LEDITEM_MAIN_5, val, 1, 9); } Adjust_Date_Value(LEDITEM_MAIN_4); break; case 3: //Month-L if(read_DisBuffer(LEDITEM_MAIN_4)) { setCV(LEDITEM_MAIN_5, val, 0, 2); } else { setCV(LEDITEM_MAIN_5, val, 1, 9); } Adjust_Date_Value(LEDITEM_MAIN_5); break; case 4: //DAY-H month = read_DisBuffer(LEDITEM_MAIN_4)*10 + read_DisBuffer(LEDITEM_MAIN_5); if(month==2) { setCV(LEDITEM_MAIN_7, val, 0, 2); } else { setCV(LEDITEM_MAIN_7, val, 0, 3); } Adjust_Date_Value(LEDITEM_MAIN_7); break; case 5: if(read_DisBuffer(LEDITEM_MAIN_7)==3) { setCV(LEDITEM_MAIN_8, val, 0, 1); } else { setCV(LEDITEM_MAIN_8, val, 0, 9); } Adjust_Date_Value(LEDITEM_MAIN_8); break; case 6: setCV(LEDITEM_WEEK, val, 0, 6); break; default: break; } new_date.year = math_mux(read_DisBuffer(LEDITEM_MAIN_1),10) + read_DisBuffer(LEDITEM_MAIN_2); new_date.month = math_mux(read_DisBuffer(LEDITEM_MAIN_4),10) + read_DisBuffer(LEDITEM_MAIN_5); new_date.day = math_mux(read_DisBuffer(LEDITEM_MAIN_7),10) + read_DisBuffer(LEDITEM_MAIN_8); new_date.week = read_DisBuffer(LEDITEM_WEEK); Watch_Update_Display(); return new_date; } //--------------------------------- //Check alam time //--------------------------------- void Watch_Start_Alam(void) { u8 i; u16 nowtime; Alert_t alam; static u8 beepn = 0; nowtime = (time.hour<<8)+time.min; if((nowtime>=0x0700)&&(nowtime<0x1200)) { //7:00~18:00 MC74HC595_Light_Set(80); } else { MC74HC595_Light_Set(30); } if(WatchSet.in.item.set) return; if(on_Alam.enb) { if(on_Alam.inw) { if(on_Alam.time==nowtime) { if(IS_TIMERSTART(e_Timer_Beep)) { if(!IS_TIMEROVER(e_Timer_Beep)) return; } if(++beepn<3) { Beeper(TRUE, 150, 150); } else { beepn = 0; Beeper(TRUE, 150, 250); } } else { on_Alam.inw = FALSE; if(on_Alam.cnt==0) on_Alam.enb = FALSE; } } else { if((nowtime-on_Alam.time)>=3) { on_Alam.inw = TRUE; on_Alam.cnt--; on_Alam.time = nowtime; } } } if(time.sec) return; for(i=0; i<10; i++) { alam = WatchCofing.alart[i]; if(!alam.on) continue; if((alam.begin>alam.end)&&(date.week>alam.end)&&(date.week<alam.begin)) continue; if((alam.begin<alam.end)&&((date.week<alam.begin)||(date.week>alam.end))) continue; if((alam.begin==alam.end)&&(date.week!=alam.begin))continue; if(nowtime==alam.time) { on_Alam.inw = TRUE; on_Alam.enb = TRUE; on_Alam.cnt = 2; on_Alam.id = i; on_Alam.time = nowtime; beepn = 0; return; } } } void Watch_Show_SetItem(MENUMOD_ITEM mi, char sub) { switch(mi) { case MENUMOD_ITEM_TIME: write_DisBuffer(LEDITEM_TEMP_H, LEDWORD_WORDC); write_DisBuffer(LEDITEM_TEMP_L, LEDWORD_WORDH); write_DisBuffer(LEDITEM_WEEK, LEDWORD_BLANK); Watch_Display_Time(time); Watch_Adjust_Time(sub, 0); break; case MENUMOD_ITEM_DATE: write_DisBuffer(LEDITEM_TEMP_H, LEDWORD_WORDC); write_DisBuffer(LEDITEM_TEMP_L, LEDWORD_WORDU); Watch_Display_Date(date); Watch_Adjust_Date(sub, 0); break; #if OPT_COUNTER case MENUMOD_ITEM_COUNT: write_DisBuffer(LEDITEM_TEMP_H, LEDWORD_WORDC); write_DisBuffer(LEDITEM_TEMP_L, 0); write_DisBuffer(LEDITEM_WEEK, LEDWORD_LINE); Watch_Display_Time(on_Ct.set); Watch_Adjust_Time(sub, 0); break; #endif case MENUMOD_ITEM_ALAM0: case MENUMOD_ITEM_ALAM1: case MENUMOD_ITEM_ALAM2: case MENUMOD_ITEM_ALAM3: case MENUMOD_ITEM_ALAM4: case MENUMOD_ITEM_ALAM5: case MENUMOD_ITEM_ALAM6: case MENUMOD_ITEM_ALAM7: case MENUMOD_ITEM_ALAM8: case MENUMOD_ITEM_ALAM9: Watch_Show_Alam(mi-MENUMOD_ITEM_ALAM0); Watch_Adjust_Time(sub, 0); break; } } //++++++++++++++++++++++++++++++++++ //+ Grounp: time + //++++++++++++++++++++++++++++++++++ //--------------------------------- //Function:Watch_Set_ time //--------------------------------- void Watch_Set_Time(char item, char val) { Watch_Display_Time(time); time = Watch_Adjust_Time(item, val); } //--------------------------------- //--------------------------------- void Watch_Save_Time(void) { Writetime(time); } //+++++++++++++++++++++++++++++++++Grounp: Count down++++++++++++++++++++++++++ #if OPT_COUNTER //--------------------------------- //Function: Watch_Set_ count down //--------------------------------- void Watch_Set_Count(char item, char val) { Watch_Display_Time(on_Ct.set); on_Ct.set = Watch_Adjust_Time(item, val); } //--------------------------------- //--------------------------------- void Watch_Start_Count(void) { u32 setV; if(!on_Ct.use) return; setV = TimeToSeconds(on_Ct.set); if(on_Ct.pause) { Watch_Display_Time(SecondsToTime(setV-on_Ct.run)); return; } if(!on_Ct.full) { if(math_Time(time, on_Ct.base)==0) goto COUNT_DISPLAY; on_Ct.run += math_Time(time, on_Ct.base); on_Ct.base = time; if(on_Ct.run>=setV) { on_Ct.run = setV; on_Ct.full = TRUE; STOP_TIMER(e_Timer_Count); START_TIMER(e_Timer_Alam, 30000); } } else { if(IS_TIMEROVER(e_Timer_Alam)) { on_Ct.use = FALSE; on_Ct.full = FALSE; STOP_TIMER(e_Timer_Alam); STOP_TIMER(e_Timer_Count); return; } else { Beeper(TRUE, 300, 500); if(IS_TIMERSTOP(e_Timer_Count)) { START_TIMER(e_Timer_Count, 400); } } } COUNT_DISPLAY: if(IS_TIMEROVER(e_Timer_Count)) { RESET_TIMER(e_Timer_Count); Watch_Display_Time(SecondsToTime(setV-on_Ct.run)); } } void Watch_Save_Count(void) { time = Readtime(); on_Ct.run = 0; on_Ct.sCount = 0; on_Ct.segLeds= 0; on_Ct.full = FALSE; on_Ct.pause = FALSE; on_Ct.use = TRUE; on_Ct.base = time; START_TIMER(e_Timer_Count, 150); } #endif //++++++++++++++++++++++++++++++++++Grounp: Alam++++++++++++++++++++++++++++++++ //--------------------------------- //Function: show the alam time //--------------------------------- void Watch_Show_Alam(char alamID) { u8 s; Alert_t alam; alam = WatchCofing.alart[alamID]; write_DisBuffer(LEDITEM_TEMP_H, LEDWORD_WORDA); write_DisBuffer(LEDITEM_TEMP_L, alamID); s = (u8)(alam.time>>8); write_DisBuffer(LEDITEM_MAIN_1, math_div(s, 10)); //Hour ten write_DisBuffer(LEDITEM_MAIN_2, math_mod(s, 10)); //Hour signed write_DisBuffer(LEDITEM_MAIN_3, LEDWORD_LINE); //"-" s = (u8)(alam.time); write_DisBuffer(LEDITEM_MAIN_4, math_div(s, 10)); //minute ten write_DisBuffer(LEDITEM_MAIN_5, math_mod(s, 10)); //minute signed write_DisBuffer(LEDITEM_MAIN_6, LEDWORD_BLANK); //"." write_DisBuffer(LEDITEM_MAIN_7, alam.begin); write_DisBuffer(LEDITEM_MAIN_8, alam.end); if(alam.on) { write_DisBuffer(LEDITEM_WEEK, LEDWORD_LINE); } else { write_DisBuffer(LEDITEM_WEEK, LEDWORD_BLANK); } Watch_Update_Display(); } //--------------------------------- //Funtion: Watch_Set_ Alam time //--------------------------------- void Watch_Set_Alam(char alamID, char item, char val) { u8 v; Alert_t* alam; TIME alamTime; Watch_Show_Alam(alamID); switch(item) { case 0: setCV(LEDITEM_MAIN_1, val, 0, 2); if(read_DisBuffer(LEDITEM_MAIN_1)==2){ setv(LEDITEM_MAIN_2, val, 0, 3); } break; case 1: if(read_DisBuffer(LEDITEM_MAIN_1)==2){ setCV(LEDITEM_MAIN_2, val, 0, 3); } else { setCV(LEDITEM_MAIN_2, val, 0, 9); } break; case 2: setCV(LEDITEM_MAIN_4, val, 0, 5); break; case 3: setCV(LEDITEM_MAIN_5, val, 0, 9); break; case 4: setCV(LEDITEM_MAIN_7, val, 0, 6); break; case 5: setCV(LEDITEM_MAIN_8, val, 0, 6); break; } WatchCofing.dirty = TRUE; alam = WatchCofing.alart+alamID; alam->on = TRUE; alam->time = (read_DisBuffer(LEDITEM_MAIN_1)*10+read_DisBuffer(LEDITEM_MAIN_2))<<8; alam->time += (read_DisBuffer(LEDITEM_MAIN_4)*10+read_DisBuffer(LEDITEM_MAIN_5)); alam->begin = read_DisBuffer(LEDITEM_MAIN_7); alam->end = read_DisBuffer(LEDITEM_MAIN_8); write_DisBuffer(LEDITEM_WEEK, LEDWORD_LINE); Watch_Update_Display(); } //--------------------------------- //--------------------------------- void Watch_Save_Alam(void) { } //++++++++++++++++++++++++++++++++Grounp: Date+++++++++++++++++++++++++++++++++ //--------------------------------- //Function: set the date //--------------------------------- void Watch_Set_Date(char item, char val) { Watch_Display_Date(date); date = Watch_Adjust_Date(item, val); } //--------------------------------- //--------------------------------- void Watch_Save_Date(void) { Writedaliy(date); } //--------------------------------- //--------------------------------- void Watch_Flash_SetItem(void) { uCHAR i, item; static char scrow = TRUE; if(WatchSet.in.item.adj) { switch(WatchSet.sub) { case 0: item = LEDITEM_MAIN_1; break; case 1: item = LEDITEM_MAIN_2; break; case 2: item = LEDITEM_MAIN_4; break; case 3: item = LEDITEM_MAIN_5; break; case 4: item = LEDITEM_MAIN_7; break; case 5: item = LEDITEM_MAIN_8; break; default: item = LEDITEM_WEEK; break; } if(scrow) { WatchSet.temp = *(dis_buffer+item); *(dis_buffer+item) = LEDWORD_BLANK; } else { *(dis_buffer+item) = WatchSet.temp; } } scrow = !scrow; Watch_Update_Display(); } //--------------------------------- //--------------------------------- void Watch_Init(void) { uCHAR i; MC74HC595_Init(); for(i=0; i<11; i++) { dis_buffer[i] = LEDWORD_LINE; } Watch_Update_Display(); Ds1302_Init(); } 5.5 电子表核心数据结构 typedef struct { uCHAR hour; uCHAR min; uCHAR sec; }TIME; typedef struct { uCHAR year; uCHAR month; uCHAR day; uCHAR week; }DATE; typedef struct { u8 on:1; //响闹开关 u8 begin:6; //响闹周期开始 u8 end; //响闹周期结束 u16 time; //响闹时间 }Alert_t; typedef struct { u8 dirty; u8 leddute; u16 rfaddr; //==================== //Alert Set //==================== Alert_t alart[10]; }WatchCfg_t; typedef struct { u8 enb:1; //闹钟已经打开 u8 inw:1; //闹钟正在运行 u8 id:6; //闹钟编号 u8 cnt; //重复提醒次数 u16 time; //最后一次响闹时间 }Alam_t; #if OPT_COUNTER typedef struct { u8 use:1; u8 full:1; u8 pause:1; u8 sCount:5; u8 segLeds; TIME run; TIME set; TIME base; }Counter_t; #endif typedef struct { union { struct { u8 set:1; //in set statu u8 adj:1; //in adjust statu u8 show:1; //in show alam item or date u8 modify:1; //item is modify }item; u8 items; }in; u8 item; //main set item u8 sub; //sub set item u8 temp; //backup digtal value }WatchSet_t; 5.6 主任务程序 Main.c /* MAIN.C file * * Copyright (c) 2002-2005 STMicroelectronics */ #include "Config.h" DATE date; TIME time; extern volatile _Bool Synch; extern volatile Alam_t on_Alam; #if OPT_COUNTER extern volatile Counter_t on_Ct; #endif extern volatile WatchSet_t WatchSet; extern volatile WatchCfg_t WatchCofing; extern volatile XTIMER Timer[e_Timer_Max]; void memclr(void* src, u8 len) { while(len--){ *((u8*)src+len) = 0x00; } } void RESTART(void) { WWDG_CR |= BIT(7); WWDG_CR &= ~BIT(6); } #if OPT_WATCHDOGDEMON void Watchdog_Init(void) { WWDG_CR &= ~BIT(7); //Stop Window watchdog WWDG_CR = 0x7F; IWDG_KR = 0xCC; //启动IWDG IWDG_KR = 0x55; //解除 PR 及 RLR 的写保护 IWDG_RLR = 0xff; //看门狗计数器重装载数值 IWDG_PR = 0x06; //分频系数为256,最长超时时间为:1.02S IWDG_KR = 0xAA; //刷新IDDG,避免产生看门狗复位,同时恢复 PR 及 RLR 的写保护状态 } #else void Watchdog_Init(void) {_asm("nop"); } #endif /********************************************* 函数功能:系统内部时钟配置 *********************************************/ void Init_SystemClock(void) { //时钟配置为内部RC,16M CLK_CKDIVR &= ~(BIT(4)|BIT(3)); } void Ready(void) { START_TIMER(e_Timer_RunTick, 500); //in 800mS } //_Bool on = FALSE; void doTaskScheduler(void) { static s8 taskID = -1, c=0; Decode_Task(); switch(taskID) { case 0: Beeper_Task(); break; case 1: KeyProcess();//Countflag break; case 2: if(c)Watch_Start_Alam(); break; case 3: Temperature_Task(); break; case 4: ExitMenu(FALSE); break; case 5: #if OPT_COUNTER if(!WatchSet.in.items && on_Ct.use) { Watch_Start_Count(); } break; #endif default: taskID = -1; if(!IS_TIMEROVER(e_Timer_RunTick)) break; RESET_TIMER(e_Timer_RunTick); if(WatchSet.in.items) { if(WatchSet.in.item.adj) { Watch_Flash_SetItem(); } } else { c = 1; date = Readdaliy(); time = Readtime(); #if OPT_COUNTER if(!on_Ct.use) #endif { Watch_Display_Time(time); } } break; } ++taskID; } void InitDeviceConfig(void) { memclr((void*)0, 1024); Load_WatchCofing(); Watch_Init(); //TimerInit(); Key_Init(); Beeper_Init(); Decode_Init(); Temperature_Init(); SystemTimer_Init(); //初始化系统定时器,软定时器时钟源 Watchdog_Init(); _asm("rim"); //开总中断 } int main(void) { Init_SystemClock(); //Init Device Hardware InitDeviceConfig(); Ready(); for(;;) { RESETWDT(); doTaskScheduler(); } } 单帖长度限制,部份代码,后面跟贴附上 六、作品演示 请上传您的作品的功能演示到腾讯视频,并编辑到本楼(或附上视频链接)。按要求上传视频可获得5分,具体详见活动规则。 演示视频: https://v.qq.com/x/page/i0541pw1mvs.html 七、总结 例如您在完成该作品过程中的一些体会、碰到的技术问题或调试经验、作品的未来规划,及对我们主办方的建议和意见等。 小朋友的暑假快结束了,这个项目的时间也所剩无几。因为工作的原因,也因为小朋友磨蹭的原因,这个项目过程中也耽误了不少的时间,只到在距结束不到一周的时间才开始写代码。还好因为这个项目是十多年之前做过的,只需要做一些移植。但是因为电路结构的变化,以前对十年前水平的不满意,还是对代码进行了大手术。在暑假中带孩子完成这个项目还是挺有成就感的。孩子在过程中焊接了全部的电路,而我只做一些指导,进行程序调试。以及明天22号还需要演示,我只负责录象以及视频的剪辑等等。希望通过这样的项目可以让孩子了解并喜欢发明(开发)这个行业。培养他的动手能力等。
想重制的请下载资料:重制资料.rar |
|
发表于2017-07-18 16:09:44
|
显示全部楼层
11#
强!我十岁的时候还在玩泥巴
|
|