Share Pastebin
Guest
Public paste!

carlhako

By: a guest | Jan 16th, 2010 | Syntax: None | Size: 4.83 KB | Hits: 215 | Expires: Never
Copy text to clipboard
  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. }