Fórum témák

» Több friss téma
Cikkek » Digitális óra, egy kicsit másképp
Digitális óra, egy kicsit másképp
Szerző: Karcsy, idő: Márc 26, 2012, Olvasva: 25674, Oldal olvasási idő: kb. 8 perc
Lapozás: OK   8 / 10

Két programot írtam. Egy tesztet és egyet, ami vezérli az órát.

Kezdjük is mindjárt a tesztprogrammal. A tesztprogram csak annyit csinál, hogy beállítja a be és kimeneteket és "futófényt" futtat sorban minden LED-en. A program elég egyszerű, vastagon van kommentálva, remélem, hogy érthető. A programkód és a .hex file innen tölthető le.

  1. /***********************************************************
  2. *
  3. *   LED-es óra SHIFT regiszterekkel
  4. *
  5. *             TESZT
  6. *
  7. ************************************************************
  8. *
  9. * ATmega8
  10. * 74HC595 Shift regiszter
  11. *
  12. ************************************************************
  13. *
  14. * 74HC595 bekötése: GND -> GND
  15. *
  16. * Vcc -> VCC
  17. * OE -> GND
  18. * MR -> VCC
  19. *
  20. * Q0-Q7 - Out
  21. * Q7' - Serial Out
  22. *
  23. ************************************************************
  24. *
  25. * 74HC595 működése:
  26. *
  27. * Hogy ha a SH_CP értéke alacsonyról magasra változik,
  28. * akkor a Shift regiszter beolvasssa DS értékét.
  29. * Ahogy az adat léptetve lessz, elmenti a belső
  30. * memóriájába.
  31. * Ha az ST_CP értéke alacsonyról magasra változik,
  32. * akkor a memóriában tárolt adatot kirakja a
  33. * kimenetekre.
  34. *
  35. ************************************************************
  36. *
  37. * Portkiosztás:
  38. *
  39. * Óra beállítása PB4
  40. * Perc beállítása PB3
  41. *
  42. * Óra Data PD3
  43. * Óra Latch PD4
  44. * Óra Clk PD5
  45. *
  46. * Perc & másodperc Data PC0
  47. * Perc & másodperc Latch PC1
  48. * Perc & másodperc Clk PC2
  49. *
  50. ***********************************************************/
  51. #include <avr/io.h>
  52. #include <avr/interrupt.h>
  53. #include <avr/wdt.h>
  54. #include <stdio.h>
  55. #include <util/delay.h>
  56. //=============================Definek============================
  57. #define Min() (bit_is_clear(PINB,3))
  58. #define Hour() (bit_is_clear(PINB,4))
  59. //=========================Saját header filek=========================
  60. #include "bit_operations.h" // Bitműveletek: bs,bc,btg
  61. //=========================Saját függvények==========================
  62. void _delay_10ms (unsigned int v) { while(v--) _delay_ms(10); } // 10ms késleltetés
  63. void Hour_DS (int); // Data kiküldése (0/1)
  64. void Hour_SH_CP (void); // Shift regiszter feltöltése
  65. void Hour_ST_CP (void); // Kirakása a kimenetre
  66. void Min_sec_DS (int); // Data kiküldése (0/1)
  67. void Min_sec_SH_CP (void); // Shift regiszter feltöltése
  68. void Min_sec_ST_CP (void); // Kirakása a kimenetre
  69. //==============================
  70. int main (void)
  71. //==============================
  72. {
  73. DDRD = 0xFF;
  74. DDRC = 0x3F;
  75. DDRB = 0x00;
  76. PORTB = 0xFF;
  77. int x=0;
  78. while (1)
  79. {
  80. // Óra körbefutása
  81. Hour_DS (1); // Adat megadása
  82. Hour_SH_CP (); // Beolvastatom
  83. Hour_ST_CP (); // Kipakolom a kimenetre
  84. _delay_10ms (3);
  85. for (x=1;x<13;x++)
  86. {
  87. Hour_DS (0); // Adat megadása
  88. Hour_SH_CP (); // Beolvastatom
  89. Hour_ST_CP (); // Kipakolom a kimenetre
  90. _delay_10ms (3);
  91. }
  92. // Perc és másodperc körbefutása
  93. Min_sec_DS (1); // Adat megadása
  94. Min_sec_SH_CP (); // Beolvastatom
  95. Min_sec_ST_CP (); // Kipakolom a kimenetre
  96. _delay_10ms (1);
  97. for (x=1;x<61;x++)
  98. {
  99. Min_sec_DS (0); // Adat megadása
  100. Min_sec_SH_CP (); // Beolvastatom
  101. Min_sec_ST_CP (); // Kipakolom a kimenetre
  102. _delay_10ms (1);
  103. }
  104. }
  105. }
  106. //=========================Külső függvények==========================
  107. //----------------Data kiküldése (0/1)-----------------
  108. void Hour_DS (int bit)
  109. {
  110. if (bit==0) bc (PORTD,3); // Adat láb értéke = 0
  111. if (bit==1) bs (PORTD,3); // Adat láb értéke = 1
  112. }
  113. //-------------Shift regiszter feltöltése--------------
  114. void Hour_SH_CP (void)
  115. {
  116. bc (PORTD,5); // Alacsonyról magasra kell állítani, ezért a biztonság
  117. // kedvéért alacsonyra teszem.
  118. bs (PORTD,5); // Magas szintre teszem SH_CP - t így beolvassa DS értékét
  119. _delay_us(25); // Várok, hát ha túl gyors a proci
  120. bc (PORTD,5); // Visszaállítom SH_CP - t alacsonyba
  121. }
  122. //---Latch megrángatása, az adatot a kimenetre teszi---
  123. //----------------Kirakása a kimenetre-----------------
  124. void Hour_ST_CP (void)
  125. {
  126. bc (PORTD,4); // Alacsonyról magasra kell állítani, hogy kitegye a kimenetre,
  127. // ezért a biztonság kedvéért alacsonyra teszem.
  128. bs (PORTD,4); // Magas szintre teszem ST_CP - t így beolvassa DS értékét
  129. _delay_us(25); // Várok, hát ha túl gyors a proci
  130. bc (PORTD,4); // Visszaállítom ST_CP - t alacsonyba
  131. }
  132. /****************************************************************************************/
  133. /****************************************************************************************/
  134. /****************************************************************************************/
  135. //----------------Data kiküldése (0/1)-----------------
  136. void Min_sec_DS (int bit)
  137. {
  138. if (bit==0) bc (PORTC,0); // Adat láb értéke = 0
  139. if (bit==1) bs (PORTC,0); // Adat láb értéke = 1
  140. }
  141. //-------------Shift regiszter feltöltése--------------
  142. void Min_sec_SH_CP (void)
  143. {
  144. bc (PORTC,2); // Alacsonyról magasra kell állítani, ezért a biztonság
  145. // kedvéért alacsonyra teszem.
  146. bs (PORTC,2); // Magas szintre teszem SH_CP - t így beolvassa DS értékét
  147. _delay_us(25); // Várok, hát ha túl gyors a proci
  148. bc (PORTC,2); // Visszaállítom SH_CP - t alacsonyba
  149. }
  150. //---Latch megrángatása, az adatot a kimenetre teszi---
  151. //----------------Kirakása a kimenetre-----------------
  152. void Min_sec_ST_CP (void)
  153. {
  154. bc (PORTC,1); // Alacsonyról magasra kell állítani, hogy kitegye a kimenetre,
  155. // ezért a biztonság kedvéért alacsonyra teszem.
  156. bs (PORTC,1); // Magas szintre teszem ST_CP - t így beolvassa DS értékét
  157. _delay_us(25); // Várok, hát ha túl gyors a proci
  158. bc (PORTC,1); // Visszaállítom ST_CP - t alacsonyba
  159. }

A második program maga az óra vezérlése. (Igyekeztem minél egyszerűbben és átláthatóbban megoldani.) A programkód és a .hex file innen tölthető le.

  1. /***********************************************************
  2. *
  3. *   LED-es óra SHIFT regiszterekkel
  4. *
  5. ************************************************************
  6. *
  7. * ATmega8
  8. * 74HC595 Shift regiszter
  9. *
  10. ************************************************************
  11. *
  12. * 74HC595 bekötése: GND -> GND
  13. *
  14. * Vcc -> VCC
  15. * OE -> GND
  16. * MR -> VCC
  17. *
  18. * Q0-Q7 - Out
  19. * Q7' - Serial Out
  20. *
  21. ************************************************************
  22. *
  23. * 74HC595 működése:
  24. *
  25. * Hogy ha a SH_CP értéke alacsonyról magasra változik,
  26. * akkor a Shift regiszter beolvasssa DS értékét.
  27. * Ahogy az adat léptetve lessz, elmenti a belső
  28. * memóriájába.
  29. * Ha az ST_CP értéke alacsonyról magasra változik,
  30. * akkor a memóriában tárolt adatot kirakja a
  31. * kimenetekre.
  32. *
  33. ************************************************************
  34. *
  35. * Portkiosztás:
  36. *
  37. * Óra beállítása PB4
  38. * Perc beállítása PB3
  39. *
  40. * Óra Data PD3
  41. * Óra Latch PD4
  42. * Óra Clk PD5
  43. *
  44. * Perc & másodperc Data PC0
  45. * Perc & másodperc Latch PC1
  46. * Perc & másodperc Clk PC2
  47. *
  48. ***********************************************************/
  49. #include <avr/io.h>
  50. #include <avr/interrupt.h>
  51. #include <avr/wdt.h>
  52. #include <stdio.h>
  53. #include <util/delay.h>
  54. //=============================Definek==============================
  55. #define Min() (bit_is_clear(PINB,3))
  56. #define Hour() (bit_is_clear(PINB,4))
  57. #define nop() asm volatile ("nop;")
  58. volatile unsigned char prescale=0;
  59. volatile unsigned char sec=1, sec_a=1;
  60. volatile unsigned char min=1, min_a=1;
  61. volatile unsigned char hour=1;
  62. volatile unsigned char my_nop_delay=0;
  63. ISR(TIMER1_OVF_vect)
  64. {
  65. if(++prescale == 225){prescale = 0; sec++; sec_a++;};
  66. if(sec>59) {min++; min_a++; sec=1;};
  67. if(sec_a>60) {sec_a=1; sec=1;};
  68. if(min>59) {hour++; min=1;};
  69. if(min_a>60) {min_a=1; min=1;};
  70. if(hour>12) {hour=1;};
  71. for (my_nop_delay=1;my_nop_delay<22;my_nop_delay++){nop();}
  72. if(Min())
  73. {
  74. min++;
  75. min_a++;
  76. prescale = 0;
  77. sec=0;
  78. sec_a=0;
  79. while (Min()); // Addig "vár" a program amég nem engedem fel az aktuális billentyűt
  80. _delay_ms(10); // Mini késleltetés, mert hogy ha az ujjam lassan engedem fel,
  81. }
  82. if(Hour())
  83. {
  84. hour++;
  85. prescale = 0;
  86. sec=0;
  87. sec_a=0;
  88. while (Hour()); // Addig "vár" a program amég nem engedem fel az aktuális billentyűt
  89. _delay_ms(10); // Mini késleltetés, mert hogy ha az ujjam lassan engedem fel,
  90. }
  91. return;
  92. }
  93. //========================Saját header filek=========================
  94. #include "bit_operations.h" // Bitműveletek: bs,bc,btg
  95. //=========================Saját függvények==========================
  96. void _delay_10ms (unsigned int v) { while(v--) _delay_ms(10); } // 10ms késleltetés
  97. void Hour_DS (int); // Data kiküldése (0/1)
  98. void Hour_SH_CP (void); // Shift regiszter feltöltése
  99. void Hour_ST_CP (void); // Kirakása a kimenetre
  100. void Min_sec_DS (int); // Data kiküldése (0/1)
  101. void Min_sec_SH_CP (void); // Shift regiszter feltöltése
  102. void Min_sec_ST_CP (void); // Kirakása a kimenetre
  103. //==============================
  104. int main (void)
  105. //==============================
  106. {
  107. TIMSK = 0x04;
  108. TCCR1B = 0x01;
  109. DDRD = 0xFF;
  110. DDRC = 0x3F;
  111. DDRB = 0x00;
  112. PORTB = 0xFF;
  113. sei();
  114. int x=0;
  115. while (1)
  116. {
  117. for (x=0;x<12;x++)
  118. {
  119. if (x==(12-hour))
  120. {
  121. Hour_DS (1); // Adat megadása
  122. Hour_SH_CP (); // Beolvastatom
  123. }
  124. else
  125. {
  126. Hour_DS (0); // Adat megadása
  127. Hour_SH_CP (); // Beolvastatom
  128. }
  129. }
  130. if (((60-min_a)== 0)||((60-min_a)==59)||((60-min_a)==58)||
  131. ((60-min_a)==57)||((60-min_a)==56)) //5
  132. {
  133. for (x=0;x<60;x++)
  134. {
  135. if ((x==(60-sec_a)) ||
  136. (x==(60-min_a)) ||
  137. (x==0 ) || (x==5 ) || (x==10) || (x==15) || (x==20) ||(x==25) ||// Az "órák" megjelenítése a
  138.                                                                                                      //perc és msodperc sávban
  139. (x==30) || (x==35) || (x==40) || (x==45) || (x==50))
  140. { Min_sec_DS (1); Min_sec_SH_CP (); }
  141. else
  142. { Min_sec_DS (0); Min_sec_SH_CP (); } }
  143. Min_sec_ST_CP ();
  144. Hour_ST_CP ();
  145. }
  146. if (((60-min_a)==55)||((60-min_a)==54)||((60-min_a)==53)||
  147. ((60-min_a)==52)||((60-min_a)==51)) //10
  148. {
  149. for (x=0;x<60;x++)
  150. {
  151. if ((x==(60-sec_a)) ||
  152. (x==(60-min_a)) ||
  153. (x==0 ) || (x==5 ) || (x==10) || (x==15) || (x==20) ||(x==25) ||
  154. (x==30) || (x==35) || (x==40) || (x==45) || (x==55))
  155. { Min_sec_DS (1); Min_sec_SH_CP (); }
  156. else
  157. { Min_sec_DS (0); Min_sec_SH_CP (); } }
  158. Min_sec_ST_CP ();
  159. Hour_ST_CP ();
  160. }
  161. if (((60-min_a)==50)||((60-min_a)==49)||((60-min_a)==48)||
  162. ((60-min_a)==47)||((60-min_a)==46)) //15
  163. {
  164. for (x=0;x<60;x++)
  165. {
  166. if ((x==(60-sec_a)) ||
  167. (x==(60-min_a)) ||
  168. (x==0 ) || (x==5 ) || (x==10) || (x==15) || (x==20) ||(x==25) ||
  169. (x==30) || (x==35) || (x==40) || (x==50) || (x==55))
  170. { Min_sec_DS (1); Min_sec_SH_CP (); }
  171. else
  172. { Min_sec_DS (0); Min_sec_SH_CP (); } }
  173. Min_sec_ST_CP ();
  174. Hour_ST_CP ();
  175. }
  176. if (((60-min_a)==45)||((60-min_a)==44)||((60-min_a)==43)||
  177. ((60-min_a)==42)||((60-min_a)==41)) //20
  178. {
  179. for (x=0;x<60;x++)
  180. {
  181. if ((x==(60-sec_a)) ||
  182. (x==(60-min_a)) ||
  183. (x==0 ) || (x==5 ) || (x==10) || (x==15) || (x==20) ||(x==25) ||
  184. (x==30) || (x==35) || (x==45) || (x==50) || (x==55))
  185. { Min_sec_DS (1); Min_sec_SH_CP (); }
  186. else
  187. { Min_sec_DS (0); Min_sec_SH_CP (); } }
  188. Min_sec_ST_CP ();
  189. Hour_ST_CP ();
  190. }
  191. if (((60-min_a)==40)||((60-min_a)==39)||((60-min_a)==38)||
  192. ((60-min_a)==37)||((60-min_a)==36)) //25
  193. {
  194. for (x=0;x<60;x++)
  195. {
  196. if ((x==(60-sec_a)) ||
  197. (x==(60-min_a)) ||
  198. (x==0 ) || (x==5 ) || (x==10) || (x==15) || (x==20) ||(x==25) ||
  199. (x==30) || (x==45) || (x==40) || (x==55) || (x==50))
  200. { Min_sec_DS (1); Min_sec_SH_CP (); }
  201. else
  202. { Min_sec_DS (0); Min_sec_SH_CP (); } }
  203. Min_sec_ST_CP ();
  204. Hour_ST_CP ();
  205. }
  206. if (((60-min_a)==35)||((60-min_a)==34)||((60-min_a)==33)||
  207. ((60-min_a)==32)||((60-min_a)==31)) //30
  208. {
  209. for (x=0;x<60;x++)
  210. {
  211. if ((x==(60-sec_a)) ||
  212. (x==(60-min_a)) ||
  213. (x==0 ) || (x==5 ) || (x==10) || (x==15) || (x==20) ||(x==25) ||
  214. (x==35) || (x==45) || (x==40) || (x==55) || (x==50))
  215. { Min_sec_DS (1); Min_sec_SH_CP (); }
  216. else
  217. { Min_sec_DS (0); Min_sec_SH_CP (); } }
  218. Min_sec_ST_CP ();
  219. Hour_ST_CP ();
  220. }
  221. if (((60-min_a)==30)||((60-min_a)==29)||((60-min_a)==28)||
  222. ((60-min_a)==27)||((60-min_a)==26)) //35
  223. {
  224. for (x=0;x<60;x++)
  225. {
  226. if ((x==(60-sec_a)) ||
  227. (x==(60-min_a)) ||
  228. (x==0 ) || (x==5 ) || (x==10) || (x==15) || (x==20) ||(x==30) ||
  229. (x==35) || (x==45) || (x==40) || (x==55) || (x==50))
  230. { Min_sec_DS (1); Min_sec_SH_CP (); }
  231. else
  232. { Min_sec_DS (0); Min_sec_SH_CP (); } }
  233. Min_sec_ST_CP ();
  234. Hour_ST_CP ();
  235. }
  236. if (((60-min_a)==25)||((60-min_a)==24)||((60-min_a)==23)||
  237. ((60-min_a)==22)||((60-min_a)==21)) //40
  238. {
  239. for (x=0;x<60;x++)
  240. {
  241. if ((x==(60-sec_a)) ||
  242. (x==(60-min_a)) ||
  243. (x==0 ) || (x==5 ) || (x==10) || (x==15) || (x==25) ||(x==35) ||
  244. (x==30) || (x==45) || (x==40) || (x==55) || (x==50))
  245. { Min_sec_DS (1); Min_sec_SH_CP (); }
  246. else
  247. { Min_sec_DS (0); Min_sec_SH_CP (); } }
  248. Min_sec_ST_CP ();
  249. Hour_ST_CP ();
  250. }
  251. if (((60-min_a)==20)||((60-min_a)==19)||((60-min_a)==18)||
  252. ((60-min_a)==17)||((60-min_a)==16)) //45
  253. {
  254. for (x=0;x<60;x++)
  255. {
  256. if ((x==(60-sec_a)) ||
  257. (x==(60-min_a)) ||
  258. (x==0 ) || (x==5 ) || (x==10) || (x==25) || (x==20) ||(x==35) ||
  259. (x==30) || (x==45) || (x==40) || (x==55) || (x==50))
  260. { Min_sec_DS (1); Min_sec_SH_CP (); }
  261. else
  262. { Min_sec_DS (0); Min_sec_SH_CP (); } }
  263. Min_sec_ST_CP ();
  264. Hour_ST_CP ();
  265. }
  266. if (((60-min_a)==15)||((60-min_a)==14)||((60-min_a)==13)||
  267. ((60-min_a)==12)||((60-min_a)==11)) //50
  268. {
  269. for (x=0;x<60;x++)
  270. {
  271. if ((x==(60-sec_a)) ||
  272. (x==(60-min_a)) ||
  273. (x==0 ) || (x==5 ) || (x==15) || (x==25) || (x==20) ||(x==35) ||
  274. (x==30) || (x==45) || (x==40) || (x==55) || (x==50))
  275. { Min_sec_DS (1); Min_sec_SH_CP (); }
  276. else
  277. { Min_sec_DS (0); Min_sec_SH_CP (); } }
  278. Min_sec_ST_CP ();
  279. Hour_ST_CP ();
  280. }
  281. if (((60-min_a)==10)||((60-min_a)== 9)||((60-min_a)== 8)||
  282. ((60-min_a)== 7)||((60-min_a)== 6)) //55
  283. {
  284. for (x=0;x<60;x++)
  285. {
  286. if ((x==(60-sec_a)) ||
  287. (x==(60-min_a)) ||
  288. (x==0 ) || (x==15) || (x==10) || (x==25) || (x==20) ||(x==35) ||
  289. (x==30) || (x==45) || (x==40) || (x==55) || (x==50))
  290. { Min_sec_DS (1); Min_sec_SH_CP (); }
  291. else
  292. { Min_sec_DS (0); Min_sec_SH_CP (); } }
  293. Min_sec_ST_CP ();
  294. Hour_ST_CP ();
  295. }
  296. if (((60-min_a)== 5)||((60-min_a)== 4)||((60-min_a)== 3)||
  297. ((60-min_a)== 2)||((60-min_a)== 1)) //60
  298. {
  299. for (x=0;x<60;x++)
  300. {
  301. if ((x==(60-sec_a)) ||
  302. (x==(60-min_a)) ||
  303. (x==5 ) || (x==15) || (x==10) || (x==25) || (x==20) ||(x==35) ||
  304. (x==30) || (x==45) || (x==40) || (x==55) || (x==50))
  305. { Min_sec_DS (1); Min_sec_SH_CP (); }
  306. else
  307. { Min_sec_DS (0); Min_sec_SH_CP (); } }
  308. Min_sec_ST_CP ();
  309. Hour_ST_CP ();
  310. }
  311. }
  312. }
  313. //=========================Külső függvények==========================
  314. //----------------Data kiküldése (0/1)-----------------
  315. void Hour_DS (int bit)
  316. {
  317. if (bit==0) bc (PORTD,3); // Adat láb értéke = 0
  318. if (bit==1) bs (PORTD,3); // Adat láb értéke = 1
  319. }
  320. //-------------Shift regiszter feltöltése--------------
  321. void Hour_SH_CP (void)
  322. {
  323. bc (PORTD,5); // Alacsonyról magasra kell állítani, ezért a biztonság
  324. // kedvéért alacsonyra teszem.
  325. bs (PORTD,5); // Magas szintre teszem SH_CP - t így beolvassa DS értékét
  326. _delay_us(25); // Várok, hát ha túl gyors a proci
  327. bc (PORTD,5); // Visszaállítom SH_CP - t alacsonyba
  328. }
  329. //---Latch megrángatása, az adatot a kimenetre teszi---
  330. //----------------Kirakása a kimenetre-----------------
  331. void Hour_ST_CP (void)
  332. {
  333. bc (PORTD,4); // Alacsonyról magasra kell állítani, hogy kitegye a kimenetre,
  334. // ezért a biztonság kedvéért alacsonyra teszem.
  335. bs (PORTD,4); // Magas szintre teszem ST_CP - t így beolvassa DS értékét
  336. _delay_us(25); // Várok, hát ha túl gyors a proci
  337. bc (PORTD,4); // Visszaállítom ST_CP - t alacsonyba
  338. }
  339. /****************************************************************************************/
  340. /****************************************************************************************/
  341. /****************************************************************************************/
  342. //----------------Data kiküldése (0/1)-----------------
  343. void Min_sec_DS (int bit)
  344. {
  345. if (bit==0) bc (PORTC,0); // Adat láb értéke = 0
  346. if (bit==1) bs (PORTC,0); // Adat láb értéke = 1
  347. }
  348. //-------------Shift regiszter feltöltése--------------
  349. void Min_sec_SH_CP (void)
  350. {
  351. bc (PORTC,2); // Alacsonyról magasra kell állítani, ezért a biztonság
  352. // kedvéért alacsonyra teszem.
  353. bs (PORTC,2); // Magas szintre teszem SH_CP - t így beolvassa DS értékét
  354. _delay_us(25); // Várok, hát ha túl gyors a proci
  355. bc (PORTC,2); // Visszaállítom SH_CP - t alacsonyba
  356. }
  357. //---Latch megrángatása, az adatot a kimenetre teszi---
  358. //----------------Kirakása a kimenetre-----------------
  359. void Min_sec_ST_CP (void)
  360. {
  361. bc (PORTC,1); // Alacsonyról magasra kell állítani, hogy kitegye a kimenetre,
  362. // ezért a biztonság kedvéért alacsonyra teszem.
  363. bs (PORTC,1); // Magas szintre teszem ST_CP - t így beolvassa DS értékét
  364. _delay_us(25); // Várok, hát ha túl gyors a proci
  365. bc (PORTC,1); // Visszaállítom ST_CP - t alacsonyba
  366. }

A programkódot itt is vastagon kommenteztem, remélem, hogy érthető, de azért 1 - 2 dolgot részletesebben is elmagyarázok.

Az órajelet egy 16 bites megszakítás vektor szolgáltatja (65536 - onként van overflow):

14745600/65536 = 225 (órajel frekvenica / overflow) 

És ha osztunk még  225-el, és akkor máris 1 sec-et kapunk.

  1. if(++prescale == 225){prescale = 0;sec++;};

Ebben a megszakításban növelem a másodperceket, perceket, órákat. Ha ez mechanikus óra lenne fogaskerekekkel, akkor azt lehetne mondani, hogy ez az óra rugója és áttételszerkezete. Itt kezelem még a nyomógombokat is. Azért itt, mert hogy ha megnyomjuk a gombot akkor itt az másodpercenként 254x van megvizsgálva és nem kell várni a gombnyomásnál, hanem azonnal végrehajtja.

A main ciklusban csak a kijelzés fut. Ez nem annyira időkritikus, csak kijelzési funkciói vannak. Annyi a feladata, hogy az óra, perc, másodperc értékét megjelenítse a LED-sorokon. A csavart az adja, hogy egy LED-sor van a perc és másodperc megjelenítésére is. A megoldás amennyire egyszerű annyira sok fejtörést okozott.

Azért kell kivonni 60-at a feltételeknél, mert a shift regiszterek feltöltését az "59"-es másodperctől kezdjük óra mutató járásának ellentétesen és ha egyből betöltenénk a shift regiszterekbe a sec és min értékeit akkor egy "inverz" óránk lenne, "ami visszafelé jár".

Lényegében az időből kell olyan 60 bitnyi bináris adatot csinálni. Ezt legegyszerűbben úgy lehet megoldani, hogy ha felállítunk feltételeket, hogy ha a percek és másodpercek értékei egyenlőek valamilyen értékkel, akkor "1" -est ír a memóriába, bármelyik másik esetben "0"-át.

Így lehet azt megoldani, hogy "körbemenjen" a másodperceket jelző LED, mint valami mutató. Működése: egy segédváltozót létrehozunk, amit együtt növelünk a sec változóval és ebből kivonunk 60-at és hogy ha a szám értéke és a sec értéke megegyezik, "1"-eset írok be, hogy ha nem akkor "0"-át. Lássunk erre egy példát: sec=34mp, sec_a-60=34mp ---> beírok "1"-et a memóriába. Hogy ha nem akkor "0" át.

A kijelzés úgy működik, hogy világít minden 5. LED, jelezve, hogy "5 perc", "10 perc", "15 perc"... kivéve azt ami az " 5 perces körzetében van a percmutató LED - nek". Egyszerűbben szólva a perc mutató előtti "5 perces jelzések" nem világítanak. Erre azért van szüksége, mert hogy ha mondjuk 3óra 10 perc van akkor "eltűnik" a perc mutató a szemünk elől, de így látható, hogy éppen hol jár. Mindeközben másodpercet jelző "LED mutató" is folyamatosan jár körbe-körbe a percmutatóval együtt és amikor 59 percről átugrik a "0" percre (egész óra) akkor lép a következő órára az óramutató LED.


A cikk még nem ért véget, lapozz!
Következő: »»   8 / 10
Értékeléshez bejelentkezés szükséges!
Bejelentkezés

Belépés

Hirdetés
XDT.hu
Az oldalon sütiket használunk a helyes működéshez. Bővebb információt az adatvédelmi szabályzatban olvashatsz. Megértettem