#include <avr/io.h>
unsigned char Hex_Data [] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D,
0x07, 0x7F, 0x67, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71};
void timer1_init() {
TCCR1B |= (1 << WGM12); // Configure timer 1 for CTC mode
TCCR1B |= (1 << CS11) | (1 << CS10); // Set prescaler to 64
OCR1A = 249; // Set CTC compare value for 1ms at 16MHz with prescaler of 64
}
void my_delay_ms(unsigned int msecs) {
while (msecs--) {
TCNT1 = 0; // Reset timer count to 0
TIFR1 |= (1 << OCF1A); // Clear any existing compare match flag
while (!(TIFR1 & (1 << OCF1A))); // Wait for compare match flag to set
}
}
void adc_init() {
// ADC Initialization
ADMUX |= (1 << REFS0); // AVCC with external capacitor at AREF pin
ADCSRA |= (1 << ADEN) | (1 << ADPS1) | (1 << ADPS0); // Enable ADC and set prescaler to 8
}
unsigned int adc_read(unsigned char ch) {
ADCSRA |= (1 << ADIF); // Clear ADIF by writing one to it
ADCSRA |= (1 << ADSC); // Start Single conversion
while(ADCSRA & (1 << ADSC)); // Wait for conversion to complete
return (ADC);
}
int main(void) {
unsigned char output;
DDRB &= ~0x0C; // Set PORTB 0-1 as inputs
PORTB |= 0x03; // Enable pull-ups
DDRD |= 0xFC; // Set PORTD 2-7 as outputs
DDRB |= 0x03;
timer1_init(); // Initialize Timer1 for precise timing
adc_init(); // Initialize the ADC
int index = 0;
while (1) {
if (PINB & ~(0x08)) {
if (PINB & 0x04) { // Potentiometer mode
unsigned int adc_value = adc_read(0); // Read from ADC channel 0 (A0)
unsigned char hex_index = (adc_value) / 64; // Map ADC value (0-1023) to 0-15
PORTD = ~(Hex_Data[hex_index] << 2);
PORTB = ~(Hex_Data[hex_index] >> 6);
my_delay_ms(100); // Short delay to stabilize output
}
else {
unsigned int adc_value = adc_read(0); // Read from ADC channel 0 (A0)
unsigned char hex_index = ((adc_value) / 64); // Map ADC value (0-1023) to 0-15
PORTD = ~(Hex_Data[index]<<2);
PORTB = ~(Hex_Data[index]>>6);
my_delay_ms(1505-((hex_index) * 67 + 250));
index++;
if (index >= 16)
{(index = 0);
}
}
} else
if (index >= 0) {
PORTD = ~(Hex_Data[index]<<2);
PORTB = ~(Hex_Data[index]>>6);
my_delay_ms(1000);
index++;
if (index >= 16)
{(index = 0);
}
}
}
}