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

Собрал спидометр на Atmega8

Добавлено: Пн июл 29, 2013 07:53:30
Inf1nity
Здравствуйте!
Вопрос по динамической индикации появился. Собрал спидометр по этой схеме:
Изображение
Работает правильно, но есть одна проблема - старший разряд всегда менее яркий, чем младший/младшие.
Вот так вот это выглядит:
http://youtu.be/RmW8iJPWKR4
http://youtu.be/YJwzmAXQdoE
Резисторы на сегменты по 270Ом, индикатор CA04-41GWA.
В "Вопросах по теории" решили, что время отображения старшего разряда меньше, чем остальных. Погуглил с пристрастием - действительно так.
Нашёл исходник от автора девайса:
Спойлер/*****************************************************
Chip type : ATmega8
Program type : Application
Clock frequency : 1,000000 MHz
Memory model : Small
External SRAM size : 0
Data Stack size : 256

*****************************************************/
#include <mega8.h>

unsigned char nom_temp;
unsigned int imp,kmh;

void init(void);
void display(unsigned char ch,unsigned char nom);

interrupt [EXT_INT0] void ext_int0_isr(void)
{
}

interrupt [EXT_INT1] void ext_int1_isr(void)
{
imp++;
}

interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
if (nom_temp<3) nom_temp++; else nom_temp=1;
switch (nom_temp)
{
case 1: {if (kmh>99) display((kmh/100)%10,3); break;}
case 2: {if (kmh>9) display((kmh/10)%10,2);break;}
case 3: {display(kmh%10,1);break;}
}
}

// Timer 1 output compare A interrupt service routine
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
kmh=imp*6/5;
//imp_s=imp;
imp=0;
TCNT1H=0x00;
TCNT1L=0x00;
}


void init(void)
{
PORTB=0x00;
DDRB=0xff;

PORTC=0x00;
DDRC=0xff;

// Port D initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=In Func2=Out Func1=Out Func0=Out
// State7=0 State6=0 State5=0 State4=0 State3=P State2=0 State1=0 State0=0
PORTD=0x08;
DDRD=0xF7;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 15,625 kHz
//TCCR0=0x03;

// Clock value: 125,000 kHz
TCCR0=0x02;
TCNT0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 3,906 kHz
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: On
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x04;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x07;
OCR1AL=0xA1;
OCR1BH=0x00;
OCR1BL=0x00;

// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Falling Edge
// INT1: On
// INT1 Mode: Falling Edge
GIFR=0x00;
MCUCR=0x0A;
GICR|=0xC0;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x51;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// Global enable interrupts
#asm("sei")

}

void display(unsigned char ch,unsigned char nom)
{
PORTD.0=0;PORTD.1=0;PORTD.2=0;
PORTB.0=1;PORTB.1=1;PORTB.2=1;PORTB.3=1;PORTB.4=1;PORTB.5=1;PORTB.6=1;

switch (ch)
{case 0: {PORTB.1=0;PORTB.2=0;PORTD.7=0;PORTD.6=0;PORTD.5=0;PORTB.0=0;PORTD.4=1;break;}
case 1: {PORTB.1=1;PORTB.2=0;PORTD.7=0;PORTD.6=1;PORTD.5=1;PORTB.0=1;PORTD.4=1;break;}
case 2: {PORTB.1=0;PORTB.2=0;PORTD.7=1;PORTD.6=0;PORTD.5=0;PORTB.0=1;PORTD.4=0;break;}
case 3: {PORTB.1=0;PORTB.2=0;PORTD.7=0;PORTD.6=0;PORTD.5=1;PORTB.0=1;PORTD.4=0;break;}
case 4: {PORTB.1=1;PORTB.2=0;PORTD.7=0;PORTD.6=1;PORTD.5=1;PORTB.0=0;PORTD.4=0;break;}
case 5: {PORTB.1=0;PORTB.2=1;PORTD.7=0;PORTD.6=0;PORTD.5=1;PORTB.0=0;PORTD.4=0;break;}
case 6: {PORTB.1=0;PORTB.2=1;PORTD.7=0;PORTD.6=0;PORTD.5=0;PORTB.0=0;PORTD.4=0;break;}
case 7: {PORTB.1=0;PORTB.2=0;PORTD.7=0;PORTD.6=1;PORTD.5=1;PORTB.0=1;PORTD.4=1;break;}
case 8: {PORTB.1=0;PORTB.2=0;PORTD.7=0;PORTD.6=0;PORTD.5=0;PORTB.0=0;PORTD.4=0;break;}
case 9: {PORTB.1=0;PORTB.2=0;PORTD.7=0;PORTD.6=0;PORTD.5=1;PORTB.0=0;PORTD.4=0;break;}
case 10: {PORTB.1=0;PORTB.2=1;PORTD.7=1;PORTD.6=1;PORTD.5=1;PORTB.0=1;PORTD.4=1;break;}
}
switch (nom)
{
case 1: {PORTD.0=1;PORTD.1=0;PORTD.2=0;break;}
case 2: {PORTD.0=0;PORTD.1=1;PORTD.2=0;break;}
case 3: {PORTD.0=0;PORTD.1=0;PORTD.2=1;break;}
}

}
void main(void)
{init();


while (1)
{
};

}
Возможно ли исправить данную "особенность" прошивки малой кровью?
Подозреваю, что надо что-то сделать с

Код: Выделить всё

case 1: {if (kmh>99) display((kmh/100)%10,3); break;}
  case 2: {if (kmh>9)  display((kmh/10)%10,2);break;}
  case 3: {display(kmh%10,1);break;
но, т.к. с программированием не дружу, то прошу помощи у Вас. :)

Re: Собрал спидометр на Atmega8

Добавлено: Пн июл 29, 2013 08:17:26
pyzhman
Нарушено время отображения разрядов, а они должны быть одинаковыми. Попробовать так:

Код: Выделить всё

case 1: {display((kmh/100)%10,3); break;}
case 2: {display((kmh/10)%10,2);break;}
case 3: {display(kmh%10,1);break;

Re: Собрал спидометр на Atmega8

Добавлено: Пн июл 29, 2013 21:27:04
vitalik_1984
Собрать по нормальной схеме и упростить код. Нужно считать один раз, а показывать 100, тогда , возможно, будет успевать все разряды показывать.
Считать можно в буфер и потом отображать из него по таймеру.
pyzhman писал(а):Попробовать так:
Мне кажется это ничего не даст. Ведь это обычное условие для того чтобы не показывать незначащие разряды.

Зато я не нашел в коде как прозрачно происходит пролистывание разрядов друг за другом.
Могу написать простой код индикации расчетом скорости по этому исходнику.
Тестить самостоятельно придется.

Re: Собрал спидометр на Atmega8

Добавлено: Пн июл 29, 2013 22:21:44
Inf1nity
pyzhman писал(а):Нарушено время отображения разрядов, а они должны быть одинаковыми. Попробовать так:

Код: Выделить всё

case 1: {display((kmh/100)%10,3); break;}
case 2: {display((kmh/10)%10,2);break;}
case 3: {display(kmh%10,1);break;
Попробовал, теперь вместо 0 отображается 000
vitalik_1984 писал(а):Могу написать простой код индикации расчетом скорости по этому исходнику.
Тестить самостоятельно придется.
Был бы очень признателен :)

Re: Собрал спидометр на Atmega8

Добавлено: Вт июл 30, 2013 00:12:20
vitalik_1984
Такой вариант устроит?
Speedometer.hex
(2.25 КБ) 396 скачиваний

Re: Собрал спидометр на Atmega8

Добавлено: Вт июл 30, 2013 05:27:46
Inf1nity
Проверил. Разности яркости нет. При включении отображается "001". Скорость считается десятками километров, т.е. 001-011-021-031 и т.д.

Re: Собрал спидометр на Atmega8

Добавлено: Вт июл 30, 2013 07:59:08
pyzhman
vitalik_1984 писал(а):это ничего не даст.
Это даст то, что времена отображения каждого разряда станут равными и, соответственно, яркость станет равной. А вот гашение незначащих разрядов упустил. Впрочем, думаю, у вас всё получится. :beer:

Re: Собрал спидометр на Atmega8

Добавлено: Вт июл 30, 2013 08:18:31
Inf1nity
pyzhman писал(а):
vitalik_1984 писал(а):это ничего не даст.
Это даст то, что времена отображения каждого разряда станут равными и, соответственно, яркость станет равной. А вот гашение незначащих разрядов упустил. Впрочем, думаю, у вас всё получится. :beer:
А давайте я и Ваш вариант попробую, процы у меня ещё есть, заодно хоть чему-нибудь научусь. Учиться-то никогда не поздно :)
Может есть где пример какой-нибудь, как гасить незначащие нули? Я бы как раз поразбирался, пока на работе свободное время есть

Re: Собрал спидометр на Atmega8

Добавлено: Вт июл 30, 2013 10:30:26
pyzhman
Так вы же уже
Inf1nity писал(а):Попробовал

Re: Собрал спидометр на Atmega8

Добавлено: Вт июл 30, 2013 13:20:05
vitalik_1984
Понял уже свою ошибку с нулями. Там это гашение есть, но я не додумал, что нужно немного по другому написать, я написал, что нужно присвоить 0 значению отображаемому, вот 0 и показывается. :))
Вот пробуйте

Re: Собрал спидометр на Atmega8

Добавлено: Вт июл 30, 2013 21:58:14
Inf1nity
Что-то не то :(
Изображение

Re: Собрал спидометр на Atmega8

Добавлено: Вт июл 30, 2013 22:19:46
Aмstroн
поменяй местами разряды, это 0v.

Re: Собрал спидометр на Atmega8

Добавлено: Вт июл 30, 2013 22:23:30
vitalik_1984
Нифига это не V вот код расчета:

Код: Выделить всё

 
  if (kmh>99){ind_speed[2]=((kmh/100)%10);}else ind_speed[2]=11;    //Считаем разряды: 3
  if (kmh>9){ind_speed[1]=((kmh/10)%10);}else ind_speed[1]=11;      // 2
              ind_speed[0]=(kmh%10);                                 // 1 
поправил в предыдущем сообщении код

Re: Собрал спидометр на Atmega8

Добавлено: Вт июл 30, 2013 22:38:37
Аlex
Aмstroн, схему нормальную покажите по которой собирали. Схема из 1-ого поста не соответствует программе, которую Вы выложили.

Re: Собрал спидометр на Atmega8

Добавлено: Вт июл 30, 2013 22:40:32
Aмstroн
if (kmh>99){ind_speed[2]=((kmh/100)%10);}else ind_speed[2]=11;
А что, компилятор это хавает.
А если так
if (kmh>99){ind_speed[2]=((kmh/100)%10);}else {ind_speed[2]=11;};
Aмstroн, схему нормальную покажите по которой собирали
Это не Я...

Re: Собрал спидометр на Atmega8

Добавлено: Вт июл 30, 2013 22:58:44
Аlex
Это не Я...
Тьфу, блин. Извиняюсь :)
Inf1nity, схему выложите нормальную.

Re: Собрал спидометр на Atmega8

Добавлено: Вт июл 30, 2013 23:49:21
vitalik_1984
Вроде эта схема, только почему то даже родная прошивка не работает как нужно. Похоже на то, что в каждом сегменте еще по транзистору или вообще непонятно что.
либо схема без транзисторов вообще.
Вот переделал вроде похоже на рабочую.
Так и не смог нормально сымитировать работу - не генерит импульсы генератор в схеме. Кнопкой до 2х поднимается адекватно.
Speedometer.hex
(2.28 КБ) 294 скачивания
Изображение
Aмstroн писал(а):if (kmh>99){ind_speed[2]=((kmh/100)%10);}else ind_speed[2]=11;
А что, компилятор это хавает.
А если так
if (kmh>99){ind_speed[2]=((kmh/100)%10);}else {ind_speed[2]=11;};
Правильно подметили - компилятор хавает ведь это соответствует стандарту.
А скобки используются когда команд, относящихся к esle несколько.

Re: Собрал спидометр на Atmega8

Добавлено: Ср июл 31, 2013 05:54:29
Inf1nity
Аlex писал(а):
Это не Я...
Тьфу, блин. Извиняюсь :)
Inf1nity, схему выложите нормальную.
Схема из первого поста, собирал точно по ней.
Модель в протеусе от автора схемы

Re: Собрал спидометр на Atmega8

Добавлено: Ср июл 31, 2013 11:32:45
Аlex
Ни с этим проектом, ни со своим, собранным по схеме из 1-ого поста, у меня не заработали прошивки от vitalik_1984. Странно.

Re: Собрал спидометр на Atmega8

Добавлено: Ср июл 31, 2013 20:57:45
vitalik_1984
А с этим проектом?
3_num_7_seg_speedometer.rar
(52.51 КБ) 262 скачивания
А родная прошивка заработала? я вот только убрав транзисторы нормальную картинку увидел
Особо ничего в программе не менял, только динамическую индикацию модифицировал. И подсчет для отображаемого массива убрал в главный цикл.
Лень было на два порта переделывать заново фактически. Проще когда все на одном порту, но опять же плату разводить неудобно.
Inf1nity писал(а):Схема из первого поста, собирал точно по ней.
У вас в приборе заработало или нет?