Начал недавно изучать МК. Хочу создать часы на восьмиразрядном дисплее, только на atmega8. Прилагаю схему и код программы на CodeVisionAVR. Пока что это набросок для протеуса. Поэтому некоторых элементов не хватает...
Схема:
Текст программы:
Спойлер
#include <mega8.h>#include <delay.h>
#define dl 500
#define A PORTC.0
#define B PORTC.1
#define C PORTC.2
#define D PORTC.3
#define E PORTC.4
#define F PORTC.5
#define G PORTB.0
#define DP PORTB.1
int hours, minutes, seconds, day, month, year;
int mode;
// Timer1 output compare A interrupt service routine
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
TCNT1H = 0;
TCNT1L = 0;
seconds++;
}
// Declare your global variables here
void InitMC(void)
{
// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=Out Func4=In Func3=In Func2=In Func1=Out Func0=Out
// State7=T State6=T State5=0 State4=T State3=T State2=T State1=1 State0=1
PORTB=0x03;
DDRB=0x23;
// Port C initialization
// Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State6=1 State5=1 State4=1 State3=1 State2=1 State1=1 State0=1
PORTC=0x7F;
DDRC=0x7F;
// Port D initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=1 State6=1 State5=1 State4=1 State3=1 State2=1 State1=1 State0=1
PORTD=0xFF;
DDRD=0xFF;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0=0x00;
TCNT0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 0,032 kHz
// Mode: Normal top=0xFFFF
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: On
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x05;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x20;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
MCUCR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x10;
// USART initialization
// USART disabled
UCSRB=0x00;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
// ADC initialization
// ADC disabled
ADCSRA=0x00;
// SPI initialization
// SPI disabled
SPCR=0x00;
// TWI initialization
// TWI disabled
TWCR=0x00;
// Global enable interrupts
#asm("sei")
}
// Процедура вывода на 7ми сегментный дисплей
void LedOn(int digit, int dot)
{
//A=1; B=1; C=1; D=1; E=1; F=1; G=1;
switch(digit)
{
case 0: {A=0; B=0; C=0; D=0; E=0; F=0; G=1; break;} // 0
case 1: {A=1; B=0; C=0; D=1; E=1; F=1; G=1; break;} // 1
case 2: {A=0; B=0; C=1; D=0; E=0; F=1; G=0; break;} // 2
case 3: {A=0; B=0; C=0; D=0; E=1; F=1; G=0; break;} // 3
case 4: {A=1; B=0; C=0; D=1; E=1; F=0; G=0; break;} // 4, Ч
case 5: {A=0; B=1; C=0; D=0; E=1; F=0; G=0; break;} // 5
case 6: {A=0; B=1; C=0; D=0; E=0; F=0; G=0; break;} // 6, Б
case 7: {A=0; B=0; C=0; D=1; E=1; F=0; G=1; break;} // 7
case 8: {A=0; B=0; C=0; D=0; E=0; F=0; G=0; break;} // 8, В
case 9: {A=0; B=0; C=0; D=0; E=1; F=0; G=0; break;} // 9
case 10: {A=1; B=1; C=1; D=1; E=1; F=1; G=0; break;} // -
case 11: {A=0; B=0; C=0; D=1; E=0; F=0; G=1; break;} // П
case 12: {A=1; B=0; C=0; D=1; E=0; F=0; G=0; break;} // Н
case 13: {A=0; B=0; C=0; D=1; E=1; F=1; G=1; break;} // Т
case 14: {A=0; B=1; C=1; D=0; E=0; F=0; G=1; break;} // С
case 15: {A=0; B=0; C=1; D=1; E=0; F=0; G=0; break;} // Р
}
if(dot) DP = 0; else DP = 1;
}
// Вывод данных на дисплей
void DispData(void)
{
int i, dp, j=0;
int digit[8];
switch (mode)
{
case 1: // Вывод времени чч-мм-сс
{
digit[0] = hours/10;
digit[1] = hours-10*(hours/10);
digit[2] = 10;
digit[3] = minutes/10;
digit[4] = minutes-10*(minutes/10);
digit[5] = 10;
digit[6] = seconds/10;
digit[7] = seconds-10*(seconds/10);
for (i=1; i<256; i*=2)
{
PORTD = i;
LedOn(digit[j], 0);
j++;
delay_us(dl);
}
break;
}
case 2: // Вывод даты дд.мм.гггг
{
digit[0] = day/10;
digit[1] = day-10*(day/10);
digit[2] = month/10;
digit[3] = month-10*(month/10);
digit[4] = (year % 100-(year % 10))/10;
digit[5] = year % 10;
for (i=1; i<256; i*=2)
{
PORTD = i;
if (j==1 || j==3) dp=1; else dp=0;
LedOn(digit[j], dp);
j++;
delay_us(dl);
}
break;
}
case 3: // Вывод даты
{
for (i=1; i<256; i*=2)
{
PORTD=i;
LedOn(digit[j], 0);
j++;
delay_us(dl);
}
}
}
}
// MAIN
void main(void)
{
InitMC();
// Проверка дисплея (прогон всех символов)
/*PORTC = 0b111111;
for (mode=0; mode<18; mode++)
{
LedOn(mode, 1);
delay_ms(100);
} */
// Инициализация переменных
hours = 20;
minutes = 15;
seconds = 0;
day = 28;
month = 12;
year = 2013;
mode = 1;
while (1)
{
// Условия времени
if (seconds == 60)
{
minutes++;
seconds = 0;
if (minutes == 60)
{
hours++;
minutes = 0;
if (hours == 24)
{
day++;
hours = 0;
}
}
}
// Опрос кнопок
// Вывод данных на дисплей
DispData();
}
}
Хочу собрать такую схему без дополнительных микросхем...
А вот вопросы:
Не могу настроить нормальную динамическую индикацию на частоте 32768Гц, на 8МГц нормально. В чем ошибка?
Можно ли вообще применить данную схему с использованием всех портов?
Есть советы по поводу схемы?