Страница 1 из 1

ATmega8 и восьмиразрядный семисегментный led индикатор

Добавлено: Пн июн 24, 2013 08:36:37
MrFarik
Здравствуйте, Коты и Кошки!

Начал недавно изучать МК. Хочу создать часы на восьмиразрядном дисплее, только на 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МГц нормально. В чем ошибка?
Можно ли вообще применить данную схему с использованием всех портов?

Есть советы по поводу схемы?

Re: ATmega8 и восьмиразрядный семисегментный led индикатор

Добавлено: Пн июн 24, 2013 15:08:16
MrFarik
И еще, я хочу прицепить выводы кнопок к PORTD, параллельно с разрядами. Каким куском кода можно организовать опрос кнопок с этого порта?

Re: ATmega8 и восьмиразрядный семисегментный led индикатор

Добавлено: Пн июн 24, 2013 15:49:05
vAv
1. 32768 используется для таймера, сам проц тактируется другой частотой. если 8 мгц нормально, то так и оставить, настроив фьюзы на внутренний генератор.
2. Про "все порты" что-то нифиг не понял.
3. Опрос можно организовать любым способом, но я ничего вообще в твоем коде не вижу про кнопки. И организовывать надо как угодно, только не так как у тебя на схеме. Зачем там резисторы 22к???

Re: ATmega8 и восьмиразрядный семисегментный led индикатор

Добавлено: Пн июн 24, 2013 18:51:10
MrFarik
1. Разве проц и таймер не тактируются от одного генератора? Как же тогда можно использовать внешний кварц для часов (таймера), а внутренний для программы? Извините за (может быть) глупый вопрос, но в ДШ я ничего подобного не нашел.
2. Я имел в виду использовать все порты на мк без исключения.
3. Резисторы по 2.2 к. А разве можно тупо кнопкой коротить вывод мк на землю? Наверное должен быть какой-то определенный уровень... Опрос кнопок пока не создал.

И еще вопрос. Как можно организовать опрос длинных и коротких нажатий клавиш программно?

Re: ATmega8 и восьмиразрядный семисегментный led индикатор

Добавлено: Пн июн 24, 2013 19:04:54
zero648
Я подозреваю, что при таком количестве разрядов с динамической индикацией, яркость будет недостаточной.

Re: ATmega8 и восьмиразрядный семисегментный led индикатор

Добавлено: Пн июн 24, 2013 19:08:55
MrFarik
Планирую добавить регулятор яркости... Кстати можно ли регулировать уровень напряжения на выходной ноге мк?

Re: ATmega8 и восьмиразрядный семисегментный led индикатор

Добавлено: Пн июн 24, 2013 19:16:30
zero648
MrFarik писал(а):Кстати можно ли регулировать уровень напряжения на выходной ноге мк?
Можно с помощью ШИМа.

Re: ATmega8 и восьмиразрядный семисегментный led индикатор

Добавлено: Пн июн 24, 2013 19:52:56
MrFarik
Спасибо! Надо освободить PORTB для ISP программирования. Куда можно подключить кнопки?

Re: ATmega8 и восьмиразрядный семисегментный led индикатор

Добавлено: Пн июн 24, 2013 20:04:37
zero648
MrFarik писал(а):Спасибо! Надо освободить PORTB для ISP программирования. Куда можно подключить кнопки?
Можно оставить так, кнопки не мешают программированию, просто их не нажимать во время прошивки и все.

Re: ATmega8 и восьмиразрядный семисегментный led индикатор

Добавлено: Вт июн 25, 2013 08:14:58
Engineer_Keen
Регулировать яркость ШИМом можно, но у вас и так динамическая индикация, а значит ток для нормальной яркости нужно будет выдавать побольше номинального (см. импульсный ток индикатора в даташите). Допустимый ток вывода контроллера 40мА, т.е. около 6мА на сегмент - это мало, нужно ставить транзисторы как минимум на общие катоды(или аноды), а ток ограничивать резисторами, ими можно регулировать яркость и не будет ее зависимости от количества включенных в цифре сегментов.

Re: ATmega8 и восьмиразрядный семисегментный led индикатор

Добавлено: Вт июн 25, 2013 08:29:09
uk8amk
MrFarik писал(а):1. Разве проц и таймер не тактируются от одного генератора? Как же тогда можно использовать внешний кварц для часов (таймера), а внутренний для программы?
TIMER/COUNTER2 в асинхронном режиме. Там целый раздел в даташите есть.
MrFarik писал(а):3. Резисторы по 2.2 к. А разве можно тупо кнопкой коротить вывод мк на землю?
Если этот вывод включен как вход с подтяжкой. Посмотрите, многие схемы используют подобное решение.

Re: ATmega8 и восьмиразрядный семисегментный led индикатор

Добавлено: Вт июн 25, 2013 10:01:15
MrFarik
40 мА на один вывод и не более 200мА на все выводы. Я добавлю транзисторы на общие аноды - по схеме на порт D. В таком случае можно регулировать яркость ШИМом? Подскажите пожалуйста, как рассчитать транзисторы и ограничительные сопротивления на сегменты, если известен ток потребления светодиодного дисплея.

Re: ATmega8 и восьмиразрядный семисегментный led индикатор

Добавлено: Вт июн 25, 2013 11:31:05
Engineer_Keen
Яркость ШИМом можно регулировать в любом случае, вопрос в том, как вы сможете это реализовать - либо программно, каким-либо образом прерывая динамическую индикацию, либо аппаратно, поставив дополнительный ключ на аноды или катоды и управляя им с одного вывода OCRx. Как рассчитать ограничительные резисторы есть спец. тема, только учесть, что на биполярном транзисторе упадет еще примерно 0,6В. Транзисторы подобрать по току коллектора (скорее всего любой подойдет). Если ставить коллектором на аноды (PNP), то нужно инвертировать сигнал на PORTD. Базовый резистор килоом на 10 (можно больше).

Re: ATmega8 и восьмиразрядный семисегментный led индикатор

Добавлено: Вт июн 25, 2013 11:47:37
SmarTrunk
Зачем ставить транзисторы? Современные сверхъяркие индикаторы очень экономичны. У меня 7 разрядов, высота цифр 12мм, при индикации восьмерок потребляют 80 мА суммарно.

Конечно я не знаю, какой индикатор используется, может быть в данном конкретном случае это и правильно.

Еще можно поставить MAX7219, MAX7220, и они будут делать все сами, но это дороже. Зато транзисторов точно не понадобится, и программа упростится.

Re: ATmega8 и восьмиразрядный семисегментный led индикатор

Добавлено: Вт июн 25, 2013 12:17:46
MrFarik
Планируется использовать четыре двухразрядных индикатора paralight a-562g. Максимальный ток потребления 100ма. Регулирование яркости хочу сделать программно, зачем при этом останавливать динамическую индикацию?

Re: ATmega8 и восьмиразрядный семисегментный led индикатор

Добавлено: Вт июн 25, 2013 12:33:15
Engineer_Keen
MrFarik писал(а):Регулирование яркости хочу сделать программно, зачем при этом останавливать динамическую индикацию?
Под остановкой я имел ввиду гашение цифры при совпадении уровня яркости со счетчиком ШИМ.

Re: ATmega8 и восьмиразрядный семисегментный led индикатор

Добавлено: Вт июн 25, 2013 17:03:29
MrFarik
Непонятна таблица в даташите...
Изображение

Неужели ток потребления данного индикатора 25мА (макс 100мА) на один сегмент? Не многовато?
И можно ли использовать ШИМ для моей схемы?

Re: ATmega8 и восьмиразрядный семисегментный led индикатор

Добавлено: Вт июн 25, 2013 17:44:53
Engineer_Keen
MrFarik писал(а):Неужели ток потребления данного индикатора 25мА (макс 100мА) на один сегмент? Не многовато?
Типовое значение тока индикаторного светодиода 20мА, так что это нормально.
MrFarik писал(а):И можно ли использовать ШИМ для моей схемы?
Я уже сказал что можно в любом случае.

Re: ATmega8 и восьмиразрядный семисегментный led индикатор

Добавлено: Вт июн 25, 2013 17:57:00
SmarTrunk
MrFarik
Это таблица МАКСИМАЛЬНО ДОПУСТИМЫХ параметров. А фактический ток будет зависеть от требуемой яркости. Очень может быть, что для одиночного индикатора будет нужен ток сильно меньше (порядка, скажем, 5мА), а вот при динамической индикации, с восемью индикаторами, где-нибудь 20-50мА. Это нужно экспериментально выяснять!

Кстати, для этих индикаторов, т.к. они имеют среднюю яркость и средние размеры, транзисторы ставить придется.

Программное изменение яркости, изменением длительности импульсов выбора разряда, при постоянной частоте сканирования, всегда возможно.