Guest User

carlhako

a guest
Jan 16th, 2010
442
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // led_blink.c
  2. // for 7 segment led digit display
  3.  
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6.  
  7. #define F_CPU 14745600
  8.  
  9. #include <avr/io.h>
  10. #include <inttypes.h>
  11. #include <avr/interrupt.h>
  12.  
  13. #include "../libnerdkits/delay.h"
  14.  
  15.  
  16.  
  17. // PIN DEFINITIONS:
  18. /*
  19.  
  20. MCU - PIN - SEG
  21. ------------
  22. PC0 - 1 - E
  23. PC1 - 2 - D
  24. PC2 - 4 - C
  25. PC3 - 6 - B
  26. PC4 - 7 - A
  27. PC5 - 9 - F
  28. PB5 - 10 - G
  29.  
  30. PD6 - Button 1
  31.  
  32. Letters to binary register
  33. --------------------------
  34. E - 00000001 - 1
  35. D - 00000010 - 2
  36. C - 00000100 - 4
  37. B - 00001000 - 8
  38. A - 00010000 - 16
  39. F - 00100000 - 32
  40. G - 00100000 - 32
  41.  
  42. Segments
  43. --------
  44. A
  45. F B
  46. G
  47. E C
  48. D
  49.  
  50. Which segments make up numbers
  51. ------------------------------
  52. # - SEG DDRC PB5
  53. 0 - ABCDEF 63
  54. 1 - BC 12
  55. 2 - ABGED 27 on
  56. 3 - ABGCD 30 on
  57. 4 - FGBC 44 on
  58. 5 - AFGCD 54 on
  59. 6 - AFEDCG 55 on
  60. 7 - ABC 28
  61. 8 - AFGEDCB 63 on
  62. 9 - ABFGC 60 on
  63.  
  64. E - AFGED 51 on
  65.  
  66.  
  67. */
  68.  
  69.  
  70. void realtimeclock_setup() {
  71. // setup Timer0:
  72. // CTC (Clear Timer on Compare Match mode)
  73. // TOP set by OCR0A register
  74. TCCR0A |= (1<<WGM01);
  75. // clocked from CLK/1024
  76. // which is 14745600/1024, or 14400 increments per second
  77. TCCR0B |= (1<<CS02) | (1<<CS00);
  78. // set TOP to 143
  79. // because it counts 0, 1, 2, ... 142, 143, 0, 1, 2 ...
  80. // so 0 through 143 equals 144 events
  81. OCR0A = 143;
  82. // enable interrupt on compare event
  83. // (14400 / 144 = 100 per second)
  84. TIMSK0 |= (1<<OCIE0A);
  85. }
  86.  
  87. // the_time will store the elapsed time
  88. // in hundredths of a second.
  89. // (100 = 1 second)
  90. //
  91. // note that this will overflow in approximately 248 days!
  92. //
  93. // This variable is marked "volatile" because it is modified
  94. // by an interrupt handler. Without the "volatile" marking,
  95. // the compiler might just assume that it doesn't change in
  96. // the flow of any given function (if the compiler doesn't
  97. // see any code in that function modifying it -- sounds
  98. // reasonable, normally!).
  99. //
  100. // But with "volatile", it will always read it from memory
  101. // instead of making that assumption.
  102. volatile int16_t the_time;
  103.  
  104. SIGNAL(SIG_OUTPUT_COMPARE0A) {
  105. // when Timer0 gets to its Output Compare value,
  106. // one one-hundredth of a second has elapsed (0.01 seconds).
  107. the_time++;
  108. }
  109.  
  110.  
  111. int main() {
  112.  
  113. realtimeclock_setup();
  114.  
  115. // turn on interrupt handler
  116. sei();
  117.  
  118. DDRB |= (1<<PB1); //pins used to switch between screen 1,2,3,4
  119. DDRB |= (1<<PB2); // set to high to supply current
  120. DDRB |= (1<<PB3);
  121. DDRB |= (1<<PB4);
  122.  
  123. DDRD &= ~(1<<PC5); // set PC5 as input
  124.  
  125.  
  126.  
  127. volatile int8_t min = 0; // var used for minute
  128. volatile int8_t sec = 0; // var used for seconds
  129.  
  130.  
  131. //int8_t i;
  132.  
  133. while(1) {
  134.  
  135. if (the_time > 100) {
  136. sec++;
  137. the_time -= 100;
  138. }
  139. if (sec > 60) {
  140. min++;
  141. sec -= 60;
  142. }
  143.  
  144.  
  145. //PORTB &= ~((1<<PB1) | (1<<PB2) | (1<<PB3) | (1<<PB4)); // turn all displays off
  146. PORTB |= (1<<PB4); // turn on seconds display
  147. display(sec % 10); // display remainder of seconds after / 10
  148. PORTB &= ~(1<<PB4); // turn off seconds display
  149.  
  150. PORTB |= (1<<PB3); // turn on tens seconds display
  151. display(sec / 10); // display seconds / 10
  152. PORTB &= ~(1<<PB3); // turn off tens seconds display
  153.  
  154. if (min > 0) { // if mins is 0 nothing will be displayed, instead of 0
  155. PORTB |= (1<<PB2); // turn on minuts display
  156. display(min % 10); // display remainder of min after / 10
  157. PORTB &= ~(1<<PB2); // turn off minuts display
  158. }
  159.  
  160. if (min > 9) { // mins needs to be > 10 for this display to show anything
  161. PORTB |= (1<<PB1);// turn on 2nd minuts display
  162. display(min / 10); // display mins / 10
  163. PORTB &= ~(1<<PB1);// turn off 2nd minuts display
  164. }
  165.  
  166. }
  167.  
  168. return 0;
  169. }
  170.  
  171.  
  172. void display(uint8_t num) {
  173.  
  174. switch(num) { // switch pins to output based on variable num
  175. case 0:
  176. DDRC = 63; //set pins as output, once set as output default is set to low which is what we want.
  177. break;
  178.  
  179. case 1:
  180. DDRC = 12;
  181. break;
  182.  
  183. case 2:
  184. DDRC = 27;
  185. DDRB |= (1<<PB5); //1 segment is on PB also use of bitshift here or pins that power displays will be set to high impendence causing no power.
  186. break;
  187.  
  188. case 3:
  189. DDRC = 30;
  190. DDRB |= (1<<PB5);
  191. break;
  192.  
  193. case 4:
  194. DDRC = 44;
  195. DDRB |= (1<<PB5);
  196. break;
  197.  
  198. case 5:
  199. DDRC = 54;
  200. DDRB |= (1<<PB5);
  201. break;
  202.  
  203. case 6:
  204. DDRC = 55;
  205. DDRB |= (1<<PB5);
  206. break;
  207.  
  208. case 7:
  209. DDRC = 28;
  210. break;
  211.  
  212. case 8:
  213. DDRC = 63;
  214. DDRB |= (1<<PB5);
  215. break;
  216.  
  217. case 9:
  218. DDRC = 60;
  219. DDRB |= (1<<PB5);
  220. break;
  221.  
  222. default: // if invalid number is passed to function E is displayed.
  223. DDRC = 51;
  224. DDRB |= (1<<PB5);
  225.  
  226. }
  227.  
  228. delay_ms(1); // leave leds lit for 1ms, without this leds are dull;
  229.  
  230. DDRC &= ~((1<<PC0)|(1<<PC1)|(1<<PC2)|(1<<PC3)|(1<<PC4)|(1<<PC5)); // set all pins to high impedence or input to clear display
  231. DDRB &= ~(1<<PB5);
  232. }
  233.  
RAW Paste Data