LED时钟.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696
  1. #include <REGx51.H>
  2. #include "ds1302.h" //包含DS1302头文件
  3. #include "music_two_tiger.h"
  4. //#include "AT25F4096.h"
  5. sfr P0M1 = 0X93;
  6. sfr P0M0 = 0X94;
  7. sfr P1M1 = 0X91;
  8. sfr P1M0 = 0X92;
  9. sfr P2M1 = 0X95;
  10. sfr P2M0 = 0X96;
  11. #define leddata P0 //定义LED数据口
  12. sbit SET=P2^0; //按键定义,下同
  13. sbit UP=P2^1;
  14. sbit DOWN=P2^2;
  15. sbit MODE=P2^3;
  16. sbit led0=P2^7; //LED位选,因为布线不是按顺序布的,程序定义一下就可以了,下同
  17. sbit led1=P2^6;
  18. sbit led2=P2^5;
  19. sbit led3=P2^4;
  20. sbit SYSLED=P1^4;
  21. sbit COL=P1^3;
  22. volatile SYSTEMTIME SysTime;
  23. unsigned char s_state = HOU_MIN;
  24. //sbit led4=P2^6;
  25. //sbit led5=P2^5;
  26. //**************函数声明*****************
  27. void delays(unsigned char);
  28. void display(void);
  29. void Scan_Key(void);
  30. void id_case1_key();
  31. void id_case2_key();
  32. void Set_id(unsigned char ,unsigned char);
  33. //*************变量定义******************
  34. bit If_start_run_ringtime=0;
  35. char per_run_time = _PER_RUN_TIME; //每首曲子运行2次
  36. char ring_space_1min = _RING_SPACE_1MIN; //每遍间隔1分钟
  37. char ring_run_time = _RING_RUN_TIME; //重复5遍
  38. char ring_flash_countdown = _RING_FLASH_COUNTDOWN/50; //闪烁3秒
  39. unsigned char Ringtime_HOU=0xFF,Ringtime_MIN=0xFF,Ringtime_HOU_tmp=0xFF,Ringtime_MIN_tmp=0xFF;
  40. unsigned char id=0,timecount=0,re_disp=0,second_time=0; //定义用到的变量,id为调整模式用,不为0时表示调整模式,调整哪个量由id值确定
  41. //timecount用于500ms定时记数,时间到取反flag标志位,re_disp记数200次共10s,调整状态下按键无操作10s自动返回正常显示状态
  42. bit hour,minute,second,month,days,years_1,years_2,flag,flag_1302_1s,system_1s_flag; //定义位变量,hour,minute,second分别为调整时闪烁标志位,flag 500ms取反一次,调整位闪烁及冒号闪烁用
  43. unsigned char system_26s_flag;
  44. unsigned char set_flash_flag = 0xFF;
  45. bit If_play_music = 0;
  46. bit If_start_flash = 0;
  47. bit If_Into_set_ringtime = 0; //1进入,0退出
  48. //unsigned char code tab[]={0x48,0xEE,0x54,0xC4,0xE2,0xC1,0x41,0xEC,0x40,0xC0,0x60}; //LED码表,根据硬件修改
  49. unsigned char code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
  50. unsigned char inittime[7]={0x00,0x00,0x12,0x16,0x07,0x29,0x24}; //初始化1302时用到的初始化数据 年2014-1990=24
  51. // 秒 分钟 小时 日 月 星期 年
  52. /*
  53. void t0(void) interrupt 1 using 0 //中断处理程序,主要用于取反标志位,返回正常显示状态
  54. {
  55. TH0=(65535-50000)/256; //50ms定时
  56. TL0=(65535-50000)%256;
  57. timecount++;re_disp++;second_time++;
  58. if(timecount == 9) //10*50ms == 500ms
  59. {
  60. flag=~flag;
  61. timecount = 0;
  62. }
  63. if(second_time == 19) //20*50ms == 1000ms
  64. {
  65. flag_1302_1s=~flag_1302_1s;
  66. second_time = 0;
  67. system_26s_flag++;
  68. if(system_26s_flag > 25) system_26s_flag = 0;
  69. }
  70. if(re_disp>200){re_disp=0;if(id)id=0;}
  71. }*/
  72. void delays(unsigned char k) //延时函数
  73. {
  74. unsigned char i,j;
  75. for(i=0;i<k;i++)
  76. for(j=0;j<50;j++);
  77. }
  78. void display() //显示函数
  79. {
  80. unsigned char year_temp; //获取一次
  81. unsigned char secound_temp; //COL的显示
  82. if(secound_temp != SysTime.Second)
  83. {
  84. flag_1302_1s = !flag_1302_1s;
  85. secound_temp = SysTime.Second;
  86. }
  87. if(If_start_flash == 1)
  88. {
  89. if(set_flash_flag == 0) {s_state=HOU_MIN;hour=1;minute=1;}
  90. else if(set_flash_flag == 1) {s_state=SET_HOU_MIN;hour=1;minute=1;} //不显示
  91. else if(set_flash_flag == 2) {s_state=SET_HOU_MIN;hour=1;minute=1;}
  92. else if(set_flash_flag == 3) {s_state=HOU_MIN;hour=1;minute=1;} //不显示
  93. }
  94. switch(s_state)
  95. {
  96. case HOU_MIN:
  97. if(flag&hour) //如hour为1表示调整时,flag为1时不显示
  98. {
  99. led0=0;leddata=0x7f|((P0_7?1:0)<<7);delays(10);led0=1;
  100. led1=0;leddata=0x7f|((P0_7?1:0)<<7);delays(10);led1=1; //&~((unsigned char)~flag<<6)该句根据flag的值决定来显示小数点,为1时显示,4个小数点组成两对冒号,下同
  101. }
  102. else //flag为0时显示,产生闪烁效果,下同
  103. {
  104. leddata=(tab[SysTime.Hour/16]&0x7F)|((P0_7?1:0)<<7);led0=0;delays(10);led0=1;
  105. leddata=(tab[SysTime.Hour%16]&0x7F)|((P0_7?1:0)<<7);led1=0;delays(10);led1=1;
  106. }
  107. if(flag&minute)
  108. {
  109. led2=0;leddata=0x7f|((P0_7?1:0)<<7);delays(10);led2=1;
  110. led3=0;leddata=0x7f|((P0_7?1:0)<<7);delays(10);led3=1;
  111. }
  112. else
  113. {
  114. leddata=(tab[SysTime.Minute/16]&0x7F)|((P0_7?1:0)<<7);led2=0;delays(10);led2=1;
  115. leddata=(tab[SysTime.Minute%16]&0x7F)|((P0_7?1:0)<<7);led3=0;delays(10);led3=1;
  116. }
  117. //dis cos
  118. P0_7 = COL = flag_1302_1s; delays(10);
  119. break;
  120. case MON_DAY_HOU_MIN:
  121. if(system_26s_flag < 20)
  122. {
  123. if(flag&hour) //如hour为1表示调整时,flag为1时不显示
  124. {
  125. led0=0;leddata=0x7f|((P0_7?1:0)<<7);delays(10);led0=1;
  126. led1=0;leddata=0x7f|((P0_7?1:0)<<7);delays(10);led1=1; //&~((unsigned char)~flag<<6)该句根据flag的值决定来显示小数点,为1时显示,4个小数点组成两对冒号,下同
  127. }
  128. else //flag为0时显示,产生闪烁效果,下同
  129. {
  130. leddata=(tab[SysTime.Hour/16]&0x7F)|((P0_7?1:0)<<7);led0=0;delays(10);led0=1;
  131. leddata=(tab[SysTime.Hour%16]&0x7F)|((P0_7?1:0)<<7);led1=0;delays(10);led1=1;
  132. }
  133. if(flag&minute)
  134. {
  135. led2=0;leddata=0x7f|((P0_7?1:0)<<7);delays(10);led2=1;
  136. led3=0;leddata=0x7f|((P0_7?1:0)<<7);delays(10);led3=1;
  137. }
  138. else
  139. {
  140. leddata=leddata=(tab[SysTime.Minute/16]&0x7F)|((P0_7?1:0)<<7);led2=0;delays(10);led2=1;
  141. leddata=(tab[SysTime.Minute%16]&0x7F)|((P0_7?1:0)<<7);led3=0;delays(10);led3=1;
  142. }
  143. //dis cos
  144. P0_7 = COL = flag_1302_1s; delays(10);
  145. }
  146. else
  147. {
  148. if(flag&month) //如min为1表示调整时,flag为1时不显示
  149. {
  150. led0=0;leddata=0x7f|((P0_7?1:0)<<7);delays(10);led0=1;
  151. led1=0;leddata=0x7f|((P0_7?1:0)<<7);delays(10);led1=1; //&~((unsigned char)~flag<<6)该句根据flag的值决定来显示小数点,为1时显示,4个小数点组成两对冒号,下同
  152. }
  153. else //flag为0时显示,产生闪烁效果,下同
  154. {
  155. leddata=(tab[SysTime.Month/16]&0x7F)|((P0_7?1:0)<<7);led0=0;delays(10);led0=1;
  156. leddata=(tab[SysTime.Month%16]&0x7F)|((P0_7?1:0)<<7);led1=0;delays(10);led1=1;
  157. }
  158. if(flag&days)
  159. {
  160. led2=0;leddata=0x7f|((P0_7?1:0)<<7);delays(10);led2=1;
  161. led3=0;leddata=0x7f|((P0_7?1:0)<<7);delays(10);led3=1;
  162. }
  163. else
  164. {
  165. leddata=(tab[SysTime.Day/16]&0x7F)|((P0_7?1:0)<<7);led2=0;delays(10);led2=1;
  166. leddata=(tab[SysTime.Day%16]&0x7F)|((P0_7?1:0)<<7);led3=0;delays(10);led3=1;
  167. }
  168. //dis cos
  169. P0_7 = COL = 1; delays(10);
  170. }
  171. break;
  172. case MIN_SECOND:
  173. if(flag&minute) //如min为1表示调整时,flag为1时不显示
  174. {
  175. led0=0;leddata=0x7f|((P0_7?1:0)<<7);delays(10);led0=1;
  176. led1=0;leddata=0x7f|((P0_7?1:0)<<7);delays(10);led1=1; //&~((unsigned char)~flag<<6)该句根据flag的值决定来显示小数点,为1时显示,4个小数点组成两对冒号,下同
  177. }
  178. else //flag为0时显示,产生闪烁效果,下同
  179. {
  180. leddata=(tab[SysTime.Minute/16]&0x7F)|((P0_7?1:0)<<7);led0=0;delays(10);led0=1;
  181. leddata=(tab[SysTime.Minute%16]&0x7F)|((P0_7?1:0)<<7);led1=0;delays(10);led1=1;
  182. }
  183. if(flag&second)
  184. {
  185. led2=0;leddata=0x7f|((P0_7?1:0)<<7);delays(10);led2=1;
  186. led3=0;leddata=0x7f|((P0_7?1:0)<<7);delays(10);led3=1;
  187. }
  188. else
  189. {
  190. leddata=(tab[SysTime.Second/16]&0x7F)|((P0_7?1:0)<<7);led2=0;delays(10);led2=1;
  191. leddata=(tab[SysTime.Second%16]&0x7F)|((P0_7?1:0)<<7);led3=0;delays(10);led3=1;
  192. }
  193. //dis cos
  194. P0_7 = COL = flag_1302_1s; delays(10);
  195. break;
  196. case MON_DAY:
  197. if(flag&month) //如min为1表示调整时,flag为1时不显示
  198. {
  199. led0=0;leddata=0x7f|((P0_7?1:0)<<7);delays(10);led0=1;
  200. led1=0;leddata=0x7f|((P0_7?1:0)<<7);delays(10);led1=1; //&~((unsigned char)~flag<<6)该句根据flag的值决定来显示小数点,为1时显示,4个小数点组成两对冒号,下同
  201. }
  202. else //flag为0时显示,产生闪烁效果,下同
  203. {
  204. leddata=(tab[SysTime.Month/16]&0x7F)|((P0_7?1:0)<<7);led0=0;delays(10);led0=1;
  205. leddata=(tab[SysTime.Month%16]&0x7F)|((P0_7?1:0)<<7);led1=0;delays(10);led1=1;
  206. }
  207. if(flag&days)
  208. {
  209. led2=0;leddata=0x7f|((P0_7?1:0)<<7);delays(10);led2=1;
  210. led3=0;leddata=0x7f|((P0_7?1:0)<<7);delays(10);led3=1;
  211. }
  212. else
  213. {
  214. leddata=(tab[SysTime.Day/16]&0x7F)|((P0_7?1:0)<<7);led2=0;delays(10);led2=1;
  215. leddata=(tab[SysTime.Day%16]&0x7F)|((P0_7?1:0)<<7);led3=0;delays(10);led3=1;
  216. }
  217. //dis cos
  218. P0_7 = COL = 1; delays(10); //关闭col
  219. break;
  220. case SET_HOU_MIN:
  221. if(flag&hour) //如hour为1表示调整时,flag为1时不显示
  222. {
  223. led0=0;leddata=0x7f|((P0_7?1:0)<<7);delays(10);led0=1;
  224. led1=0;leddata=0x7f|((P0_7?1:0)<<7);delays(10);led1=1; //&~((unsigned char)~flag<<6)该句根据flag的值决定来显示小数点,为1时显示,4个小数点组成两对冒号,下同
  225. }
  226. else //flag为0时显示,产生闪烁效果,下同
  227. {
  228. leddata=(tab[Ringtime_HOU_tmp/10]&0x7F)|((P0_7?1:0)<<7);led0=0;delays(10);led0=1; //已转化10进制
  229. leddata=(tab[Ringtime_HOU_tmp%10]&0x7F)|((P0_7?1:0)<<7);led1=0;delays(10);led1=1;
  230. }
  231. if(flag&minute)
  232. {
  233. led2=0;leddata=0x7f|((P0_7?1:0)<<7);delays(10);led2=1;
  234. led3=0;leddata=0x7f|((P0_7?1:0)<<7);delays(10);led3=1;
  235. }
  236. else
  237. {
  238. leddata=(tab[Ringtime_MIN_tmp/10]&0x7F)|((P0_7?1:0)<<7);led2=0;delays(10);led2=1; //已转化10进制
  239. leddata=(tab[Ringtime_MIN_tmp%10]&0x7F)|((P0_7?1:0)<<7);led3=0;delays(10);led3=1;
  240. }
  241. //dis cos
  242. P0_7 = COL = flag_1302_1s; delays(10);
  243. break;
  244. case YEAR_S:
  245. year_temp = SysTime.Year/16*10 + SysTime.Year%16;
  246. if(flag&years_1) //如min为1表示调整时,flag为1时不显示
  247. {
  248. led0=0;leddata=0x7f|((P0_7?1:0)<<7);delays(10);led0=1;
  249. led1=0;leddata=0x7f|((P0_7?1:0)<<7);delays(10);led1=1; //&~((unsigned char)~flag<<6)该句根据flag的值决定来显示小数点,为1时显示,4个小数点组成两对冒号,下同
  250. }
  251. else //flag为0时显示,产生闪烁效果,下同
  252. {
  253. leddata=(tab[((year_temp+1990)/1000)%10]&0x7F)|((P0_7?1:0)<<7);led0=0;delays(10);led0=1;
  254. leddata=(tab[((year_temp+1990)/100)%10]&0x7F)|((P0_7?1:0)<<7);led1=0;delays(10);led1=1;
  255. }
  256. if(flag&years_2)
  257. {
  258. led2=0;leddata=0x7f|((P0_7?1:0)<<7);delays(10);led2=1;
  259. led3=0;leddata=0x7f|((P0_7?1:0)<<7);delays(10);led3=1;
  260. }
  261. else
  262. {
  263. leddata=(tab[((year_temp+1990)/10)%10]&0x7F)|((P0_7?1:0)<<7);led2=0;delays(10);led2=1;
  264. leddata=(tab[((year_temp+1990)/1)%10]&0x7F)|((P0_7?1:0)<<7);led3=0;delays(10);led3=1;
  265. }
  266. //dis cos
  267. P0_7 = COL = 1; delays(10);
  268. break;
  269. default:
  270. break;
  271. }
  272. #if 0
  273. if(flag&second)
  274. {
  275. led4=0;leddata=0x7f|((P0_7?1:0)<<7);delays(10);led4=1;
  276. led5=0;leddata=0x7f|((P0_7?1:0)<<7);delays(10);led5=1;
  277. }
  278. else
  279. {
  280. leddata=tab[SysTime.Second/16];led4=0;delays(10);led4=1;
  281. leddata=tab[SysTime.Second%16];led5=0;delays(10);led5=1;
  282. }
  283. #endif
  284. }
  285. void just_play_when_beep(void)
  286. {
  287. unsigned char secound_temp; //COL的显示
  288. static char i=1;
  289. if(secound_temp != SysTime.Second)
  290. {
  291. flag_1302_1s = !flag_1302_1s;
  292. secound_temp = SysTime.Second;
  293. }
  294. if(!SET || !UP ||!DOWN ||!MODE)
  295. {
  296. //跳出铃声
  297. m=0xFF;n=0xFF;per_run_time=0; //跳出次数
  298. //关闭蜂鸣器
  299. TR0=0;beepIO=0;
  300. //初始化
  301. If_start_run_ringtime=0; //关着的
  302. ring_space_1min = _RING_SPACE_1MIN; //每遍间隔1分钟
  303. ring_run_time = _RING_RUN_TIME; //重复5遍
  304. }
  305. switch(i)
  306. {
  307. case 1:
  308. led3=1;leddata=(0x7F)|((P0_7?1:0)<<7);leddata=(tab[SysTime.Hour/16]&0x7F)|((P0_7?1:0)<<7);led0=0;i=2;
  309. break;
  310. case 2:
  311. led0=1;leddata=(0x7F)|((P0_7?1:0)<<7);leddata=(tab[SysTime.Hour%16]&0x7F)|((P0_7?1:0)<<7);led1=0;i=3;
  312. break;
  313. case 3:
  314. led1=1;leddata=(0x7F)|((P0_7?1:0)<<7);leddata=(tab[SysTime.Minute/16]&0x7F)|((P0_7?1:0)<<7);led2=0;i=4;
  315. break;
  316. case 4:
  317. led2=1;leddata=(0x7F)|((P0_7?1:0)<<7);leddata=(tab[SysTime.Minute%16]&0x7F)|((P0_7?1:0)<<7);led3=0;i=5;
  318. break;
  319. case 5:
  320. P0_7 = COL = flag_1302_1s;
  321. leddata=(0x7F)|((P0_7?1:0)<<7);led0=led1=led2=led3=1;
  322. i=1;
  323. break;
  324. default:
  325. break;
  326. }
  327. }
  328. void Set_ringtime_id(unsigned char sel,unsigned char sel_1) //执行调整项目的函数
  329. {
  330. signed char max,mini,address,item;
  331. if(sel==1) {address=DS1302_HOUR; max=23;mini=0;} //小时 //根据id值确定要调整的项,并确定调整上下限,下同
  332. else if(sel==2) {address=DS1302_MINUTE; max=59;mini=0;} //分钟
  333. if(sel==1)
  334. item=Ringtime_HOU_tmp; //从相应的地址读取当前数据并转换为十进制
  335. else if(sel==2)
  336. item=Ringtime_MIN_tmp;
  337. if (sel_1==0) item--; else item++; //确定是对项目加还是减,并对越限处理
  338. if(item>max) item=mini;
  339. if(item<mini) item=max;
  340. if(sel==1)
  341. Ringtime_HOU_tmp = item;
  342. if(sel==2)
  343. Ringtime_MIN_tmp = item;
  344. }
  345. void set_ringtime_case0(void) //键盘处理函数,只有按下set键时才会进入,
  346. {
  347. display();
  348. if (!DOWN) //不保存
  349. {
  350. while(!DOWN)display(); //等待按键释放,如一直按下一直调用显示函数,防止显示中断
  351. Ringtime_HOU = 0xFF;
  352. Ringtime_MIN = 0xFF;
  353. If_start_run_ringtime = 0; //闹钟计时不开始
  354. If_start_flash = 1; //退出模式,闪烁
  355. If_Into_set_ringtime = 0; //退出模式,进入小时-分
  356. }
  357. if (!UP) //保存
  358. {
  359. while(!UP)display();
  360. Ringtime_HOU = Ringtime_HOU_tmp/10*16+Ringtime_HOU_tmp%10; //16进制保存
  361. Ringtime_MIN = Ringtime_MIN_tmp/10*16+Ringtime_MIN_tmp%10;
  362. If_start_run_ringtime = 1; //闹钟计时开始
  363. If_start_flash = 1; //退出模式,进入闪烁
  364. If_Into_set_ringtime = 0; //退出模式,进入小时-分
  365. }
  366. //直接退出
  367. if (!MODE)
  368. {
  369. while(!MODE)display();
  370. Ringtime_HOU = 0xFF;
  371. Ringtime_MIN = 0xFF;
  372. If_start_run_ringtime = 0;
  373. If_Into_set_ringtime = 0;
  374. s_state=HOU_MIN;hour=0;minute=0; //退出模式,进入小时-分,不闪烁
  375. }
  376. }
  377. void set_ringtime_case1(void) //键盘处理函数,只有按下set键时才会进入,
  378. {
  379. display();
  380. if (!DOWN) //减少
  381. {
  382. while(!DOWN)display(); //等待按键释放,如一直按下一直调用显示函数,防止显示中断
  383. re_disp=0; //清除记数,重新开始10s定时
  384. Set_ringtime_id(id,0); //跳到加减判断函数,下同,
  385. }
  386. if (!UP) //增加
  387. {
  388. while(!UP)display();
  389. re_disp=0;
  390. Set_ringtime_id(id,1);
  391. }
  392. //直接退出
  393. if (!MODE)
  394. {
  395. while(!MODE)display();
  396. Ringtime_HOU = 0xFF;
  397. Ringtime_MIN = 0xFF;
  398. If_start_run_ringtime = 0;
  399. If_Into_set_ringtime = 0;
  400. s_state=HOU_MIN;hour=0;minute=0; //退出模式,进入小时-分,不闪烁
  401. }
  402. }
  403. void Into_set_ringtime(void) //定时铃声函数
  404. {
  405. unsigned char set_i;
  406. If_Into_set_ringtime = 1;
  407. If_start_flash = 1;//开始闪
  408. //初始化set time数据
  409. set_i = id = 1;
  410. Ringtime_HOU_tmp = SysTime.Hour/16*10+SysTime.Hour%16; //取出并转化10进制 (用)
  411. Ringtime_MIN_tmp = SysTime.Minute/16*10+SysTime.Minute%16;
  412. // Ringtime_HOU_tmp = item/10*16+item%10; //转化16进制 (存)
  413. // Ringtime_MIN_tmp = item/10*16+item%10;
  414. while(If_Into_set_ringtime)
  415. {
  416. //修改定时时间 SET移动,UP+,DOWN-
  417. if (!SET)
  418. {
  419. while(!SET)display(); //等待按键释放,如一直按下一直调用显示函数,防止显示中断
  420. re_disp=0; //清除记数,重新开始10s定时
  421. set_i++;if(set_i>2)set_i=0; //id加1,后面根据id值对应调整项目
  422. id = set_i;
  423. s_state=SET_HOU_MIN;
  424. }
  425. if(id==0){hour=0;minute=0;set_ringtime_case0();} //根据id值跳到相应处理函数
  426. if(id==1){hour=1;set_ringtime_case1();} //id为1,选择调整小时位,闪烁标志位置1,然后跳到键盘处理函数,下同
  427. else if(id==2){hour=0;minute=1;set_ringtime_case1();}
  428. }
  429. }
  430. void Scan_Key(void) //键盘检测函数
  431. {
  432. display(); //程序开头调用显示函数
  433. if(!SET)
  434. {
  435. while(!SET)display(); //等待按键释放,如一直按下一直调用显示函数,防止显示中断
  436. re_disp=0; //清除记数,重新开始10s定时
  437. id++;if(id>7)id=0; //id加1,后面根据id值对应调整项目
  438. switch(id)
  439. {
  440. case 0: s_state=HOU_MIN;break;
  441. case 1: s_state=HOU_MIN;break;
  442. case 2: s_state=HOU_MIN;break;
  443. case 3: s_state=MON_DAY;break;
  444. case 4: s_state=MON_DAY;break;
  445. case 5: s_state=YEAR_S;break;
  446. case 6: s_state=YEAR_S;break;
  447. case 7: s_state=SET_HOU_MIN;break;
  448. default:break;
  449. }
  450. }
  451. switch(id)
  452. {
  453. case 0: hour=0;minute=0;second=0;month=0;days=0;years_1=0;years_2=0;id_case2_key();break; //根据id值跳到相应处理函数
  454. case 1: hour=1;id_case1_key();break; //id为1,选择调整小时位,闪烁标志位置1,然后跳到键盘处理函数,下同
  455. case 2: hour=0;minute=1;id_case1_key();break;
  456. case 3: minute=0;month=1;id_case1_key();break;
  457. case 4: month=0;days=1;id_case1_key();break;
  458. case 5: days=0;years_1=1;id_case1_key();break;
  459. case 6: years_1=0;years_2=1;id_case1_key();break;
  460. case 7: years_2=0;Into_set_ringtime();break;
  461. default:break;
  462. }
  463. //if(id==3){minute=0;second=1;id_case1_key();}
  464. }
  465. void id_case1_key(void) //键盘处理函数,只有按下set键时才会进入,
  466. {
  467. display();
  468. if (!DOWN) //减少
  469. {
  470. while(!DOWN)display(); //等待按键释放,如一直按下一直调用显示函数,防止显示中断
  471. re_disp=0; //清除记数,重新开始10s定时
  472. Set_id(id,0); //跳到加减判断函数,下同,
  473. }
  474. if (!UP) //增加
  475. {
  476. while(!UP)display();
  477. re_disp=0;
  478. Set_id(id,1);
  479. }
  480. }
  481. void id_case2_key(void) //键盘处理函数,只有id==0时才会进入,
  482. {
  483. static char DOWN_key_add = HOU_MIN;
  484. display();
  485. if (!DOWN) //
  486. {
  487. while(!DOWN)display(); //等待按键释放,如一直按下一直调用显示函数,防止显示中断
  488. DOWN_key_add ++;
  489. if(DOWN_key_add > 2) DOWN_key_add = 0;
  490. if(DOWN_key_add == 0) s_state = HOU_MIN;
  491. else if(DOWN_key_add == 1) s_state = MON_DAY_HOU_MIN;
  492. else if(DOWN_key_add == 2) s_state = MIN_SECOND;
  493. }
  494. if (!UP) //
  495. {
  496. while(!UP)display(); //等待按键释放,如一直按下一直调用显示函数,防止显示中断
  497. DOWN_key_add --;
  498. if(DOWN_key_add < 0) DOWN_key_add = 2;
  499. if(DOWN_key_add == 0) s_state = HOU_MIN;
  500. else if(DOWN_key_add == 1) s_state = MON_DAY_HOU_MIN;
  501. else if(DOWN_key_add == 2) s_state = MIN_SECOND;
  502. }
  503. if (!MODE)
  504. {
  505. while(!MODE)display(); //等待按键释放,如一直按下一直调用显示函数,防止显示中断
  506. Into_set_ringtime();
  507. }
  508. }
  509. //根据选择调整相应项目并写入DS1302
  510. void Set_id(unsigned char sel,unsigned char sel_1) //执行调整项目的函数
  511. {
  512. signed char max,mini,address,item;
  513. switch(sel)
  514. {
  515. case 1: address=DS1302_HOUR; max=23;mini=0;break; //小时 //根据id值确定要调整的项,并确定调整上下限,下同
  516. case 2: address=DS1302_MINUTE; max=59;mini=0;break; //分钟
  517. case 3: address=DS1302_MONTH; max=12;mini=1;break; //月
  518. case 4: address=DS1302_DAY; max=31;mini=0;break; //日
  519. case 5: address=DS1302_YEAR; max=20;mini=20;break; //年20
  520. case 6: address=DS1302_YEAR; max=99;mini=0;break; //年14
  521. default:break;
  522. }
  523. //if(sel==3) {address=sec; max=0;mini=0;} //秒
  524. item=Read1302(address|DS1302_READ)/16*10+Read1302(address|DS1302_READ)%16; //从相应的地址读取当前数据并转换为十进制
  525. if (sel_1==0) item--; else item++; //确定是对项目加还是减,并对越限处理
  526. if(item>max) item=mini;
  527. if(item<mini) item=max;
  528. Write1302(0x8e,0x00);//允许写操作
  529. Write1302(address,item/10*16+item%10); //将调整结果转换成压缩BCD码重新写入1302
  530. Write1302(0x8e,0x80);//写保护,禁止写操作
  531. }
  532. void DS1302_SetTime(unsigned char Address, unsigned char Value) // 设置时间函数
  533. {
  534. Write1302(0x8e,0x00);//允许写操作
  535. Write1302(Address, ((Value/10)<<4 | (Value%10))); //高4位为十位,低4位为个位
  536. Write1302(0x8e,0x80);//写保护,禁止写操作
  537. }
  538. void Initial_DS1302(void)
  539. {
  540. unsigned char Second=Read1302(DS1302_SECOND|DS1302_READ);
  541. if(Second&0x80) //如果第七为1(表明没有启动), 则启动时钟
  542. DS1302_SetTime(DS1302_SECOND,Second&0x3F); //小于60秒 3F=63
  543. }
  544. void t1(void) interrupt 3 using 0 //中断处理程序,主要用于取反标志位,返回正常显示状态
  545. {
  546. TH1=(65535-50000)/256; //50ms定时
  547. TL1=(65535-50000)%256;
  548. timecount++;re_disp++;second_time++;
  549. if(If_start_flash == 1 && set_flash_flag <= 3)
  550. {
  551. if(ring_flash_countdown-- == 0) //50ms*60 == 3s
  552. {
  553. ring_flash_countdown = _RING_FLASH_COUNTDOWN/50;
  554. If_start_flash = 0;
  555. set_flash_flag = 0xFF;
  556. if(If_Into_set_ringtime) {s_state = SET_HOU_MIN;hour=1;minute=0;} //最后到设置,闪
  557. else {s_state = HOU_MIN;hour=0;minute=0;} //最后退出设置,不闪
  558. }
  559. }
  560. if(timecount >= 9) //10*50ms == 500ms
  561. {
  562. flag=~flag;
  563. if(set_flash_flag > 3) set_flash_flag = 0;
  564. if(If_start_flash == 1) set_flash_flag ++;
  565. timecount = 0;
  566. }
  567. if(second_time >= 19) //20*50ms == 1000ms
  568. {
  569. second_time = 0;
  570. system_1s_flag=~system_1s_flag; //系统读秒1302
  571. system_26s_flag++;
  572. if(system_26s_flag > 25) system_26s_flag = 0;
  573. }
  574. if(re_disp>200){re_disp=0;if(id)id=0;}
  575. }
  576. void InitialT0T1(void) //
  577. {
  578. TMOD=0x11; //初始化定时器 方式2 波特率发生器
  579. //TH0=0xFF; //T0高八位
  580. //TL0=0xFF; //T0低八位
  581. TH1=(65535-50000)/256; //T1高八位
  582. TL1=(65535-50000)%256; //T1低八位
  583. EA=1; //总中断开关
  584. ET0=1; //T0中断
  585. //TR0=0; //定时器T0 不开始计时
  586. ET1=1; //T1中断
  587. TR1=1; //定时器T1 开始计时
  588. }
  589. /*
  590. void InitialT1(void) //
  591. {
  592. TMOD|=0x10; //初始化定时器 方式2 波特率发生器
  593. TH1=(65535-50000)/256; //T0高八位
  594. TL1=(65535-50000)%256; //T0低八位
  595. EA=1; //总中断开关
  596. ET1=1; //T0中断
  597. TR1=1; //定时器T0 开始计时
  598. }*/
  599. void main() //主函数
  600. {
  601. //配置播放器T0 模式3下 占用T1资源,所以 只能用T1(波特率发生器)
  602. //配置定时器T1
  603. //InitialT1();
  604. InitialT0T1();
  605. //初始化,并启动DS1302的时钟
  606. Write1302(0x90,0xa0);//关闭充电二级管,不能对后备电池进行充电,防止发胀,原来的程序是打开的请关闭
  607. Write1302(0x8e,0x80);//写保护,禁止写操作
  608. Initial_DS1302();
  609. if(!UP&!DOWN)Set1302(inittime); //如果同时按下UP和DOWN键则初始化1302,该语句在while(1)前,只执行一次,需要复位,防止误操作
  610. //配置P0口,全部推挽输出 01
  611. P0M0 = 0x00;
  612. P0M1 = 0xFF;
  613. //延时稳定
  614. SYSLED = 0; //系统灯开
  615. delays(100);
  616. SYSLED = 1; //系统灯关
  617. while(1)
  618. {
  619. SYSLED = system_1s_flag; //系统灯闪
  620. DS1302_GetTime(&SysTime); //获取时间
  621. Scan_Key(); //键盘检测和显示
  622. if(!P3_0)
  623. {
  624. while(!P3_0)display(); //等待按键释放,如一直按下一直调用显示函数,防止显示中断
  625. If_play_music = 1;
  626. play_2tigers();
  627. If_play_music = 0;
  628. }
  629. if(If_start_run_ringtime)
  630. {
  631. if(Ringtime_HOU == SysTime.Hour && Ringtime_MIN == SysTime.Minute)
  632. {
  633. if(ring_run_time--==0) //到了次数,不再播放
  634. {
  635. Ringtime_HOU = 0xFF;
  636. Ringtime_MIN = 0xFF;
  637. If_start_run_ringtime = 0;
  638. ring_run_time = _RING_RUN_TIME; //初始化一下 下个5遍运行 ,不然ring_run_time--后,0xFF一直间隔响
  639. }
  640. else //重装,间隔x分钟 ring_space_1min
  641. {
  642. Ringtime_HOU_tmp = Ringtime_HOU_tmp + (Ringtime_MIN_tmp + ring_space_1min)/59;
  643. Ringtime_MIN_tmp = (Ringtime_MIN_tmp + ring_space_1min)%59;
  644. Ringtime_HOU = Ringtime_HOU_tmp/10*16+Ringtime_HOU_tmp%10; //16进制保存
  645. Ringtime_MIN = Ringtime_MIN_tmp/10*16+Ringtime_MIN_tmp%10;
  646. If_start_run_ringtime = 1;
  647. }
  648. If_play_music = 1;
  649. play_2tigers();
  650. If_play_music = 0;
  651. }
  652. }
  653. }
  654. }