#define F_CPU 7372800UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "bcd_7segment.h"
uint8_t position = 4;
uint8_t myValue = 0;
ISR(TIMER0_OVF_vect) {
PORTH ^= _BV(PH1);
position--;
load_digit_paterns(position % 4, myTable[myValue % 4]);
myValue++;
}
int main(void)
{
init_7_segment();
timer0_init();
sei();
// used for LED7
DDRH = _BV(PH1);
float myFloat = 0.001;
display_7_segment(myFloat, 4);
while(1)
{
myFloat = myFloat + 0.001;
// prepare array
display_7_segment(myFloat, 4);
_delay_ms(300);
}
}
#include <avr/io.h>
#include <stdio.h>
#include "bcd_7segment.h"
const uint8_t patterns[] = {
0xfc, 0x60, 0xda, 0xf2, 0x66, 0xb6, 0xbe, 0xe0,
0xfe, 0xf6, 0xee, 0x3e, 0x9c, 0x7a, 0x9e, 0x8e };
void load_shift_register(uint8_t pattern) {
uint8_t value;
uint8_t count = 8;
do {
value = pattern;
value = value & 0b00000001;
if(value == 0) {
PORTB &= ~(1 << DS);
}
else {
PORTB |= 1 << DS;
}
pattern = pattern >> 1;
// pulse SHCP
PORTB |= 1 << SHCP;
asm("nop");
asm("nop");
PORTB &= ~(1 << SHCP);
// 8 bits
count--;
} while (count > 0);
}
void load_digit_paterns(uint8_t digit, uint8_t pattern) {
load_shift_register(pattern);
PORTL = 0x00;
// strobe storage register
PORTK |= 1 << STCP;
asm("nop");
asm("nop");
PORTK &= ~(1 << STCP);
digit = digit % 4;
PORTL |= 1 << digit;
}
// snprintf: flags for linker:
// -Wl,-u,vfprintf -lprintf_flt -lm
void display_7_segment(float value, uint8_t no_of_decimals) {
char myStrTable[20];
// convert from float to string
snprintf(myStrTable, 20, "%f", value);
uint8_t j;
uint8_t k = 0;
static uint8_t myPointer;
static uint8_t myValue;
for (j = 0; j < 5; j++) {
// is it a dot?
if (myStrTable[j] == 0x2e) {
// take the previous digit
j--;
k--;
myPointer = myStrTable[j] - 0x30;
myValue = patterns[myPointer];
// add a dot (DP is LSB)
myTable[k] = myValue + 1;
j++;
k++;
}
else {
// 0x30: from ascii to decimal
myPointer = myStrTable[j] - 0x30;
myValue = patterns[myPointer];
// update the BCD-table
myTable[k] = myValue;
k++;
}
}
}
void timer0_init() {
// turns on the interrupts
TIMSK0 = (1 << TOIE0);
TIFR0 |= (1 << TOV0);
TCNT0 = 0x0000;
// start timer0 with /256 prescaler (p. 161)
TCCR0B |= (1 << CS02);
TCCR0B &= ~(1 << CS01);
TCCR0B &= ~(1 << CS00);
}
void init_7_segment() {
DDRB = (1 << SHCP) | (1 << DS) | (1 << MR);
DDRK = 1 << STCP;
DDRL = (1 << A) | (1 << B) | (1 << C) | (1 << D);
// reset 74595
PORTB &= ~(1 << MR);
asm("nop");
asm("nop");
asm("nop");
PORTB |= 1 << MR;
}