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

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
Inf1nity
Родился
Сообщения: 10
Зарегистрирован: Вт июл 31, 2012 07:42:04
Откуда: Екатеринбург

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

Сообщение 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;
но, т.к. с программированием не дружу, то прошу помощи у Вас. :)
Реклама
Аватара пользователя
pyzhman
Друг Кота
Сообщения: 7016
Зарегистрирован: Вс июл 12, 2009 19:15:29
Откуда: Ижевск
Контактная информация:

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

Сообщение pyzhman »

Нарушено время отображения разрядов, а они должны быть одинаковыми. Попробовать так:

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

case 1: {display((kmh/100)%10,3); break;}
case 2: {display((kmh/10)%10,2);break;}
case 3: {display(kmh%10,1);break;
Docendo discimus
Реклама
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

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

Сообщение vitalik_1984 »

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

Зато я не нашел в коде как прозрачно происходит пролистывание разрядов друг за другом.
Могу написать простой код индикации расчетом скорости по этому исходнику.
Тестить самостоятельно придется.
Аватара пользователя
Inf1nity
Родился
Сообщения: 10
Зарегистрирован: Вт июл 31, 2012 07:42:04
Откуда: Екатеринбург

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

Сообщение 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 писал(а):Могу написать простой код индикации расчетом скорости по этому исходнику.
Тестить самостоятельно придется.
Был бы очень признателен :)
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

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

Сообщение vitalik_1984 »

Такой вариант устроит?
Speedometer.hex
(2.25 КБ) 396 скачиваний
Реклама
Аватара пользователя
Inf1nity
Родился
Сообщения: 10
Зарегистрирован: Вт июл 31, 2012 07:42:04
Откуда: Екатеринбург

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

Сообщение Inf1nity »

Проверил. Разности яркости нет. При включении отображается "001". Скорость считается десятками километров, т.е. 001-011-021-031 и т.д.
Реклама
Аватара пользователя
pyzhman
Друг Кота
Сообщения: 7016
Зарегистрирован: Вс июл 12, 2009 19:15:29
Откуда: Ижевск
Контактная информация:

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

Сообщение pyzhman »

vitalik_1984 писал(а):это ничего не даст.
Это даст то, что времена отображения каждого разряда станут равными и, соответственно, яркость станет равной. А вот гашение незначащих разрядов упустил. Впрочем, думаю, у вас всё получится. :beer:
Docendo discimus
Аватара пользователя
Inf1nity
Родился
Сообщения: 10
Зарегистрирован: Вт июл 31, 2012 07:42:04
Откуда: Екатеринбург

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

Сообщение Inf1nity »

pyzhman писал(а):
vitalik_1984 писал(а):это ничего не даст.
Это даст то, что времена отображения каждого разряда станут равными и, соответственно, яркость станет равной. А вот гашение незначащих разрядов упустил. Впрочем, думаю, у вас всё получится. :beer:
А давайте я и Ваш вариант попробую, процы у меня ещё есть, заодно хоть чему-нибудь научусь. Учиться-то никогда не поздно :)
Может есть где пример какой-нибудь, как гасить незначащие нули? Я бы как раз поразбирался, пока на работе свободное время есть
Аватара пользователя
pyzhman
Друг Кота
Сообщения: 7016
Зарегистрирован: Вс июл 12, 2009 19:15:29
Откуда: Ижевск
Контактная информация:

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

Сообщение pyzhman »

Так вы же уже
Inf1nity писал(а):Попробовал
Docendo discimus
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

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

Сообщение vitalik_1984 »

Понял уже свою ошибку с нулями. Там это гашение есть, но я не додумал, что нужно немного по другому написать, я написал, что нужно присвоить 0 значению отображаемому, вот 0 и показывается. :))
Вот пробуйте
Вложения
Speedometer.hex
(2.37 КБ) 398 скачиваний
Последний раз редактировалось vitalik_1984 Вт июл 30, 2013 22:20:55, всего редактировалось 1 раз.
Аватара пользователя
Inf1nity
Родился
Сообщения: 10
Зарегистрирован: Вт июл 31, 2012 07:42:04
Откуда: Екатеринбург

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

Сообщение Inf1nity »

Что-то не то :(
Изображение
Aмstroн
Встал на лапы
Сообщения: 107
Зарегистрирован: Сб июл 27, 2013 10:52:37
Откуда: Украина

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

Сообщение Aмstroн »

поменяй местами разряды, это 0v.
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

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

Сообщение 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 
поправил в предыдущем сообщении код
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

Сообщение Аlex »

Aмstroн, схему нормальную покажите по которой собирали. Схема из 1-ого поста не соответствует программе, которую Вы выложили.
Aмstroн
Встал на лапы
Сообщения: 107
Зарегистрирован: Сб июл 27, 2013 10:52:37
Откуда: Украина

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

Сообщение 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н, схему нормальную покажите по которой собирали
Это не Я...
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

Сообщение Аlex »

Это не Я...
Тьфу, блин. Извиняюсь :)
Inf1nity, схему выложите нормальную.
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

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

Сообщение 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 несколько.
Аватара пользователя
Inf1nity
Родился
Сообщения: 10
Зарегистрирован: Вт июл 31, 2012 07:42:04
Откуда: Екатеринбург

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

Сообщение Inf1nity »

Аlex писал(а):
Это не Я...
Тьфу, блин. Извиняюсь :)
Inf1nity, схему выложите нормальную.
Схема из первого поста, собирал точно по ней.
Модель в протеусе от автора схемы
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

Сообщение Аlex »

Ни с этим проектом, ни со своим, собранным по схеме из 1-ого поста, у меня не заработали прошивки от vitalik_1984. Странно.
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

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

Сообщение vitalik_1984 »

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

Вернуться в «AVR»