Advertisement
Guest User

Untitled

a guest
Apr 25th, 2018
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.16 KB | None | 0 0
  1. /********************************************************************
  2. * Autor: Artur Cichowski *
  3. * Program demonstujący wykorzystanie przerwania od Timera, w którym *
  4. * obslugiwane są cztery przyciski. Program realizuje także obsługę *
  5. * w sposób cykliczny czterech wyświetlaczy siedmisegmentowych. *
  6. ********************************************************************/
  7.  
  8. #include <avr/interrupt.h> // funkcje sei(), cli()
  9. #include <util/delay.h>
  10. #include "main.h"
  11.  
  12. #define HAPSIM
  13.  
  14. volatile unsigned char kl_ENTER = 0; //przycisk ENTER (KEY0)
  15. volatile unsigned char kl_UP = 0; //przycisk UP (KEY1)
  16. volatile unsigned char kl_DOWN = 0; //przycisk DOWN (KEY2)
  17. volatile unsigned char kl_CANCEL = 0; //przycisk CANCELv(KEY3)
  18.  
  19. signed char cyfry[4]; //wartości tablicy modyfikowane są przyciskami
  20. signed char cyfry_kopia[4];
  21. signed int dzielnik_f=0;
  22. signed int miganie=0;
  23. static char menu=0x00;
  24.  
  25.  
  26. //deklaracje funkcji
  27. void init_TIMER0 (void);
  28. void init_pins (void);
  29. char BCD_to_7_seg(char cyfra);
  30. void display_7seg(void);
  31. void display_7seg_kopia(char menu, int miganie);
  32. int main(void);
  33.  
  34.  
  35. //Timer0 jest zainicjalizowany w celu generowania przerwań od jego przepełnienia.
  36. void init_TIMER0 (void) {
  37. #if HAPSIM
  38. TCCR0 = _BV(CS00); //fclk/1,
  39. #else
  40. TCCR0 = _BV(CS00)|_BV(CS01)|_BV(CS02); //fclk/1024,
  41. #endif
  42. TCNT0 = 0x00; //wartość zliczona przez licznik
  43. TIMSK = _BV(TOIE0); //selektywne zezwolenie na przerwania od przepełnienia licznika0 TOIE0=1, przepełnienie co 256*64us=16,38ms, dla HAPSIM co 0,128ms
  44. };
  45.  
  46. union { //do obsługi przycisków -> w przerwaniu ISR
  47. struct {
  48. unsigned char ENTER:1; //LSB
  49. unsigned char UP:1;
  50. unsigned char DOWN:1;
  51. unsigned char CANCEL:1;
  52. unsigned char ENTER_PREV:1;
  53. unsigned char UP_PREV:1;
  54. unsigned char DOWN_PREV:1;
  55. unsigned char CANCEL_PREV:1; //MSB
  56. } flags;
  57. char byte;
  58. } key;
  59.  
  60. union { //do obsługi przycisków -> w przerwaniu ISR
  61. struct {
  62. unsigned char ENTER:1; //LSB
  63. unsigned char UP:1;
  64. unsigned char DOWN:1;
  65. unsigned char CANCEL:1;
  66. unsigned char ENTER_PREV:1;
  67. unsigned char UP_PREV:1;
  68. unsigned char DOWN_PREV:1;
  69. unsigned char CANCEL_PREV:1;
  70. unsigned char ENTER_PREV1:1;
  71. unsigned char UP_PREV1:1;
  72. unsigned char DOWN_PREV1:1;
  73. unsigned char CANCEL_PREV1:1;
  74. unsigned char ENTER_PREV2:1;
  75. unsigned char UP_PREV2:1;
  76. unsigned char DOWN_PREV2:1;
  77. unsigned char CANCEL_PREV2:1; //MSB
  78. } flags;
  79. int word;
  80. } falling_slope;
  81.  
  82. ISR (TIMER0_OVF_vect) { //przerwanie wywoływane co ok. 16,4 ms
  83. key.byte=(key.byte<<4);// przesuwając w lewą stronę bity z dołu uzupełniane są zerami
  84. //ustawienie jedynek na pozycjach od 0 do 3 w przypadku odczytania zer z odpowiednich wejść KEYx
  85. key.byte|=((bit_is_clear(PINKEY,KEY0))|(bit_is_clear(PINKEY,KEY1) << 1)|(bit_is_clear(PINKEY,KEY2) << 2)|(bit_is_clear(PINKEY,KEY3) << 3));
  86. falling_slope.word=(falling_slope.word<<4);
  87.  
  88. if(key.flags.ENTER){ //czy wciśnięty jest przycisk ENTER?
  89. if(!key.flags.ENTER_PREV) falling_slope.flags.ENTER=1; //Czy wykryto zbocze opadające
  90. if(falling_slope.flags.ENTER_PREV2) kl_ENTER = 1; //Czy od chwili wykrycia zbocza opadającego upłynęły 3 przerwania z wciśniętym przyciskiem
  91. }
  92. else{
  93. falling_slope.word&=0xEEEE; //wyzerowanie flag dla przycisku ENTER potwierdzających wykrycie zbocza opadającego
  94. };
  95.  
  96.  
  97. if(key.flags.UP){ //czy wciśnięty jest przycisk UP?
  98. if(!key.flags.UP_PREV) falling_slope.flags.UP=1; //Czy wykryto zbocze opadające
  99. if(falling_slope.flags.UP_PREV2) kl_UP = 1; //Czy od chwili wykrycia zbocza opadającego upłynęły 3 przerwania z wciśniętym przyciskiem
  100. }
  101. else{
  102. falling_slope.word&=0xDDDD; //wyzerowanie flag dla przycisku UP potwierdzających wykrycie zbocza opadającego
  103. };
  104.  
  105. if(key.flags.DOWN){ //czy wciśnięty jest przycisk DOWN?
  106. if(!key.flags.DOWN_PREV) falling_slope.flags.DOWN=1; //Czy wykryto zbocze opadające
  107. if(falling_slope.flags.DOWN_PREV2) kl_DOWN = 1; //Czy od chwili wykrycia zbocza opadającego upłynęły 3 przerwania z wciśniętym przyciskiem
  108. }
  109. else{
  110. falling_slope.word&=0xBBBB; //wyzerowanie flag dla przycisku DOWN potwierdzających wykrycie zbocza opadającego
  111. };
  112.  
  113. if(key.flags.CANCEL){ //czy wciśnięty jest przycisk CANCEL?
  114. if(!key.flags.CANCEL_PREV) falling_slope.flags.CANCEL=1; //Czy wykryto zbocze opadające
  115. if(falling_slope.flags.CANCEL_PREV2) kl_CANCEL = 1; //Czy od chwili wykrycia zbocza opadającego upłynęły 3 przerwania z wciśniętym przyciskiem
  116. }
  117. else{
  118. falling_slope.word&=0x7777; //wyzerowanie flag dla przycisku CANCEL potwierdzających wykrycie zbocza opadającego
  119. };
  120. dzielnik_f++;
  121. if(dzielnik_f==15)
  122. {
  123. dzielnik_f=0;
  124. miganie=!miganie;
  125. }
  126. };
  127.  
  128.  
  129. void init_pins (void) {
  130. /*ustawienie odpowiednich pinów mikrokontrolera jako
  131. wyjść dla portu, do którego podłączono diody LED*/
  132. DIRLED |= (_BV(LED0)|_BV(LED1)|_BV(LED2)|_BV(LED3));
  133. /*ustawienie odpowiednich pinów mikrokontrolera jako
  134. wejść dla portu, do którego podłączono przyciski KEY*/
  135. DIRKEY &= ~(_BV(KEY0)|_BV(KEY1)|_BV(KEY2)|_BV(KEY3));
  136. /*ustawienie odpowiednich pinów mikrokontrolera jako
  137. wejść dla portu, do którego podłączono przełączniki SW*/
  138. DIRSWITCH &= ~(_BV(SW0)|_BV(SW1)|_BV(SW2)|_BV(SW3));
  139. /*ustawienie wyjść dla portu, do którego podłączono katody wyświetlacza*/
  140. DIRHEX = 0xFF;
  141. /*ustawienie odpowiednich pinów mikrokontrolera jako
  142. wyjść dla portu, do którego podłączono anody wyświetlacza*/
  143. DIRHEXA |= (_BV(HEXA0)|_BV(HEXA1)|_BV(HEXA2)|_BV(HEXA3));
  144. };
  145.  
  146. //funkcja transkodera kodu BCD na kod wyswietlacza siedmiosegmentowego
  147. char BCD_to_7_seg(char cyfra){
  148. char katody = 0xFF; //domyślnie wszystkie segmenty wyłączone
  149. switch(cyfra){
  150. case 0 : katody=0xC0; //0b11000000
  151. break;
  152. case 1 : katody=0xF9; //0b11111001
  153. break;
  154. case 2 : katody=0xA4; //0b10100100
  155. break;
  156. case 3 : katody=0xB0; //0b10110000
  157. break;
  158. case 4 : katody=0x99; //0b10011001
  159. break;
  160. case 5 : katody=0x92; //0b10010010
  161. break;
  162. case 6 : katody=0x82; //0b10000010
  163. break;
  164. case 7 : katody=0xF8; //0b11111000
  165. break;
  166. case 8 : katody=0x80; //0b10000000
  167. break;
  168. case 9 : katody=0x90; //0b10010000
  169. break;
  170. };
  171. return katody;
  172. };
  173.  
  174.  
  175. //funkcja obsługi wyswietlacza siedmiosegmentowego
  176. //funkcja uaktywnia cyklicznie poszczególne wyświetlacze
  177. void display_7seg(void)
  178. {
  179. static char select = 1; //zmienna o zakresie od 1 do 4
  180. PORTHEXA |= (_BV(HEXA0)|_BV(HEXA1)|_BV(HEXA2)|_BV(HEXA3)); //wyłączenie wszystkich wyświetlaczy
  181. select++; //wskazanie na kolejną cyfrę
  182. if(select>4) select=1;
  183. //cykliczne aktywowanie wyświetlaczy 7-seg
  184. switch(select)
  185. {
  186. case 1 :PORTHEX = BCD_to_7_seg(cyfry[0]); //wizualizacja cyfry[0]
  187. PORTHEXA &= ~_BV(HEXA0); //aktywacja 1 wyświetlacza
  188. break;
  189. case 2 :PORTHEX = BCD_to_7_seg(cyfry[1]); //wizualizacja cyfry[1]
  190. PORTHEXA &= ~_BV(HEXA1); //aktywacja 2 wyświetlacza
  191. break;
  192. case 3 :PORTHEX = BCD_to_7_seg(cyfry[2]); //wizualizacja cyfry[2]
  193. PORTHEXA &= ~_BV(HEXA2); //aktywacja 3 wyświetlacza
  194. break;
  195. case 4 :PORTHEX = BCD_to_7_seg(cyfry[3]); //wizualizacja cyfry[3]
  196. PORTHEXA &= ~_BV(HEXA3); //aktywacja 4 wyświetlacza
  197. break;
  198. };
  199. };
  200.  
  201. void display_7seg_kopia(char menu, int miganie)
  202. {
  203. static char select_kopia = 1; //zmienna o zakresie od 1 do 4
  204. PORTHEXA |= (_BV(HEXA0)|_BV(HEXA1)|_BV(HEXA2)|_BV(HEXA3)); //wyłączenie wszystkich wyświetlaczy
  205. select_kopia++; //wskazanie na kolejną cyfrę
  206. if(select_kopia>4) select_kopia=1;
  207. switch(select_kopia)
  208. {
  209. case 1 :PORTHEX = BCD_to_7_seg(cyfry_kopia[0]);
  210. if((miganie) && (menu == 0x10)) //wizualizacja cyfry_kopia[0]
  211. PORTHEXA &= ~_BV(HEXA0); //aktywacja 1 wyświetlacza
  212. break;
  213. case 2 :PORTHEX = BCD_to_7_seg(cyfry_kopia[1]);
  214. if((miganie) && (menu == 0x20)) //wizualizacja cyfry_kopia[1]
  215. PORTHEXA &= ~_BV(HEXA1); //aktywacja 2 wyświetlacza
  216. break;
  217. case 3 :PORTHEX = BCD_to_7_seg(cyfry_kopia[2]);
  218. if((miganie) && (menu == 0x30)) //wizualizacja cyfry_kopia[2]
  219. PORTHEXA &= ~_BV(HEXA2); //aktywacja 3 wyświetlacza
  220. break;
  221. case 4 :PORTHEX = BCD_to_7_seg(cyfry_kopia[3]);
  222. if((miganie) && (menu == 0x40)) //wizualizacja cyfry_kopia[3]
  223. PORTHEXA &= ~_BV(HEXA3); //aktywacja 4 wyświetlacza
  224. break;
  225. };
  226. };
  227. int main(void)
  228. {
  229. key.byte=0xFF; //inicjalizacja flag stanami nieaktywnymi
  230. falling_slope.word=0x0000; //inicjalizacja flag stanami nieaktywnymi
  231. PORTHEX = 0xFF; //wyłączenie wszystkich segmentów
  232. PORTHEXA |= (_BV(HEXA0)|_BV(HEXA1)|_BV(HEXA2)|_BV(HEXA3)); //wyłączenie wszystkich wyświetlaczy
  233. init_pins(); //inicjalizacja kierunkowości wyprowadzeń
  234. init_TIMER0(); //inicjalizacja Timera0
  235. sei(); //globalne zezwolenie na przerwania
  236. while(1) //nieskończona pętla
  237. {
  238. switch (menu)
  239. {
  240. case 0x00 :
  241. display_7seg();
  242. if(kl_ENTER == 1)
  243. {
  244. cyfry_kopia[0]=cyfry[0];
  245. cyfry_kopia[1]=cyfry[1];
  246. cyfry_kopia[2]=cyfry[2];
  247. cyfry_kopia[3]=cyfry[3];
  248. menu=0x10;
  249. kl_ENTER=0;
  250. };
  251. break;
  252. case 0x10 :
  253. display_7seg_kopia();
  254. if(kl_ENTER == 1)
  255. {
  256. menu=0x20;
  257. kl_ENTER=0;
  258. };
  259. if(kl_UP == 1)
  260. {
  261. cyrfy_kopia[0]++;
  262. if ( cyfry_kopia[0] > 9 )
  263. cyfry_kopia[0] = 0;
  264. kl_UP = 0;
  265. };
  266. if(kl_DOWN == 1)
  267. {
  268. cyfry_kopia[0]--;
  269. if ( cyfry_kopia[0] < 0 )
  270. cyfry_kopia[0] = 9;
  271. kl_DOWN = 0;
  272. };
  273. if(kl_CANCEL == 1)
  274. {
  275. menu=0x00;
  276. kl_CANCEL = 0;
  277. };
  278. break;
  279. case 0x20 :
  280. display_7seg_kopia();
  281. if(kl_ENTER == 1)
  282. {
  283. menu=0x30;
  284. kl_ENTER=0;
  285. };
  286. if(kl_UP == 1)
  287. {
  288. cyrfy_kopia[1]++;
  289. if ( cyfry_kopia[1] > 9 )
  290. cyfry_kopia[1] = 0;
  291. kl_UP = 0;
  292. };
  293. if(kl_DOWN == 1)
  294. {
  295. cyfry_kopia[1]--;
  296. if ( cyfry_kopia[1] < 0 )
  297. cyfry_kopia[1] = 9;
  298. kl_DOWN = 0;
  299. };
  300. if(kl_CANCEL == 1)
  301. {
  302. menu=0x00;
  303. kl_CANCEL = 0;
  304. }
  305. break;
  306. case 0x30 :
  307. display_7seg_kopia();
  308. if(kl_ENTER == 1)
  309. {
  310. menu=0x40;
  311. kl_ENTER=0;
  312. };
  313. if(kl_UP == 1)
  314. {
  315. cyrfy_kopia[2]++;
  316. if ( cyfry_kopia[2] > 9 )
  317. cyfry_kopia[2] = 0;
  318. kl_UP = 0;
  319. };
  320. if(kl_DOWN == 1)
  321. {
  322. cyfry_kopia[2]--;
  323. if ( cyfry_kopia[2] < 0 )
  324. cyfry_kopia[2] = 9;
  325. kl_DOWN = 0;
  326. };
  327. if(kl_CANCEL == 1)
  328. {
  329. menu=0x00;
  330. kl_CANCEL = 0;
  331. };
  332. break;
  333. case 0x40 :
  334. display_7seg_kopia();
  335. if(kl_ENTER == 1)
  336. {
  337. menu=0x00;
  338. kl_ENTER=0;
  339. cyfry[0]=cyfry_kopia[0];
  340. cyfry[1]=cyfry_kopia[1];
  341. cyfry[2]=cyfry_kopia[2];
  342. cyfry[3]=cyfry_kopia[3];
  343.  
  344. };
  345. if(kl_UP == 1)
  346. {
  347. cyrfy_kopia[3]++;
  348. if ( cyfry_kopia[3] > 9 )
  349. cyfry_kopia[3] = 0;
  350. kl_UP = 0;
  351. };
  352. if(kl_DOWN == 1)
  353. {
  354. cyfry_kopia[3]--;
  355. if ( cyfry_kopia[3] < 0 )
  356. cyfry_kopia[3] = 9;
  357. kl_DOWN = 0;
  358. };
  359. if(kl_CANCEL == 1)
  360. {
  361. menu=0x00;
  362. kl_CANCEL = 0;
  363. };
  364. break;
  365. };
  366.  
  367. }
  368.  
  369. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement