Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // led_blink.c
- // for 7 segment led digit display
- #include <stdio.h>
- #include <stdlib.h>
- #define F_CPU 14745600
- #include <avr/io.h>
- #include <inttypes.h>
- #include <avr/interrupt.h>
- #include "../libnerdkits/delay.h"
- // PIN DEFINITIONS:
- /*
- MCU - PIN - SEG
- ------------
- PC0 - 1 - E
- PC1 - 2 - D
- PC2 - 4 - C
- PC3 - 6 - B
- PC4 - 7 - A
- PC5 - 9 - F
- PB5 - 10 - G
- PD6 - Button 1
- Letters to binary register
- --------------------------
- E - 00000001 - 1
- D - 00000010 - 2
- C - 00000100 - 4
- B - 00001000 - 8
- A - 00010000 - 16
- F - 00100000 - 32
- G - 00100000 - 32
- Segments
- --------
- A
- F B
- G
- E C
- D
- Which segments make up numbers
- ------------------------------
- # - SEG DDRC PB5
- 0 - ABCDEF 63
- 1 - BC 12
- 2 - ABGED 27 on
- 3 - ABGCD 30 on
- 4 - FGBC 44 on
- 5 - AFGCD 54 on
- 6 - AFEDCG 55 on
- 7 - ABC 28
- 8 - AFGEDCB 63 on
- 9 - ABFGC 60 on
- E - AFGED 51 on
- */
- void realtimeclock_setup() {
- // setup Timer0:
- // CTC (Clear Timer on Compare Match mode)
- // TOP set by OCR0A register
- TCCR0A |= (1<<WGM01);
- // clocked from CLK/1024
- // which is 14745600/1024, or 14400 increments per second
- TCCR0B |= (1<<CS02) | (1<<CS00);
- // set TOP to 143
- // because it counts 0, 1, 2, ... 142, 143, 0, 1, 2 ...
- // so 0 through 143 equals 144 events
- OCR0A = 143;
- // enable interrupt on compare event
- // (14400 / 144 = 100 per second)
- TIMSK0 |= (1<<OCIE0A);
- }
- // the_time will store the elapsed time
- // in hundredths of a second.
- // (100 = 1 second)
- //
- // note that this will overflow in approximately 248 days!
- //
- // This variable is marked "volatile" because it is modified
- // by an interrupt handler. Without the "volatile" marking,
- // the compiler might just assume that it doesn't change in
- // the flow of any given function (if the compiler doesn't
- // see any code in that function modifying it -- sounds
- // reasonable, normally!).
- //
- // But with "volatile", it will always read it from memory
- // instead of making that assumption.
- volatile int16_t the_time;
- SIGNAL(SIG_OUTPUT_COMPARE0A) {
- // when Timer0 gets to its Output Compare value,
- // one one-hundredth of a second has elapsed (0.01 seconds).
- the_time++;
- }
- int main() {
- realtimeclock_setup();
- // turn on interrupt handler
- sei();
- DDRB |= (1<<PB1); //pins used to switch between screen 1,2,3,4
- DDRB |= (1<<PB2); // set to high to supply current
- DDRB |= (1<<PB3);
- DDRB |= (1<<PB4);
- DDRD &= ~(1<<PC5); // set PC5 as input
- volatile int8_t min = 0; // var used for minute
- volatile int8_t sec = 0; // var used for seconds
- //int8_t i;
- while(1) {
- if (the_time > 100) {
- sec++;
- the_time -= 100;
- }
- if (sec > 60) {
- min++;
- sec -= 60;
- }
- //PORTB &= ~((1<<PB1) | (1<<PB2) | (1<<PB3) | (1<<PB4)); // turn all displays off
- PORTB |= (1<<PB4); // turn on seconds display
- display(sec % 10); // display remainder of seconds after / 10
- PORTB &= ~(1<<PB4); // turn off seconds display
- PORTB |= (1<<PB3); // turn on tens seconds display
- display(sec / 10); // display seconds / 10
- PORTB &= ~(1<<PB3); // turn off tens seconds display
- if (min > 0) { // if mins is 0 nothing will be displayed, instead of 0
- PORTB |= (1<<PB2); // turn on minuts display
- display(min % 10); // display remainder of min after / 10
- PORTB &= ~(1<<PB2); // turn off minuts display
- }
- if (min > 9) { // mins needs to be > 10 for this display to show anything
- PORTB |= (1<<PB1);// turn on 2nd minuts display
- display(min / 10); // display mins / 10
- PORTB &= ~(1<<PB1);// turn off 2nd minuts display
- }
- }
- return 0;
- }
- void display(uint8_t num) {
- switch(num) { // switch pins to output based on variable num
- case 0:
- DDRC = 63; //set pins as output, once set as output default is set to low which is what we want.
- break;
- case 1:
- DDRC = 12;
- break;
- case 2:
- DDRC = 27;
- 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.
- break;
- case 3:
- DDRC = 30;
- DDRB |= (1<<PB5);
- break;
- case 4:
- DDRC = 44;
- DDRB |= (1<<PB5);
- break;
- case 5:
- DDRC = 54;
- DDRB |= (1<<PB5);
- break;
- case 6:
- DDRC = 55;
- DDRB |= (1<<PB5);
- break;
- case 7:
- DDRC = 28;
- break;
- case 8:
- DDRC = 63;
- DDRB |= (1<<PB5);
- break;
- case 9:
- DDRC = 60;
- DDRB |= (1<<PB5);
- break;
- default: // if invalid number is passed to function E is displayed.
- DDRC = 51;
- DDRB |= (1<<PB5);
- }
- delay_ms(1); // leave leds lit for 1ms, without this leds are dull;
- DDRC &= ~((1<<PC0)|(1<<PC1)|(1<<PC2)|(1<<PC3)|(1<<PC4)|(1<<PC5)); // set all pins to high impedence or input to clear display
- DDRB &= ~(1<<PB5);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement