Перейти к содержанию

Attiny2313 И Индикатор


pavelok

Рекомендуемые сообщения

Здравствуйте! На четырехразрядный семисегментный индикатор вывожу секунды и минуты. Индикатор подключаю к пинам микроконтроллера через резисторы 240 Ом.

Собственно, вот проблема:

c5e23702bf1e.jpg

В принципе, видно, что число на индикаторе - 0529, но не устраивает то, что сегменты индикатора, которые не должны светиться, всё равно светятся. Т.е., например, на втором индикаторе справа, наблюдаются очертания цифры, которая высвечивается в первом индикаторе.

Как это можно исправить? Резисторы подключить сопротивлением побольше? Или как-то код поменять?

#include <tiny2313.h>
#include <delay.h>
int k=0;
int m=0;
char a[]={0b00111111,0b00000110,0b01011011,0b01001111,0b01100110,0b01101101,0b01111101, 0b00000111,0b01111111,0b01101111 };
void show() {
if (k==60) {m=m+1; k=0;}

PORTD.0=0;
PORTB=a[k%10];
delay_ms(2);
PORTD.0=1;
PORTD.1=0;
PORTB=a[k/10];
delay_ms(2);
PORTD.1=1;
PORTD.2=0;
PORTB=a[m%10];
delay_ms(2);
PORTD.2=1;
PORTD.3=0;
PORTB=a[m/10];
delay_ms(2);
PORTD.3=1;
}


interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
k=k+1;
}

void main(void)
{
CLKPR=0x80;
CLKPR=0x00;
PORTA=0x00;
DDRA=0x00;
PORTB=0b00000000;
DDRB=0xFF;

PORTD=0b00000000;
DDRD=0b11111111;

TCCR0A=0x00;
TCCR0B=0x00;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;

TCCR1A=0x00;
TCCR1B=0x0D;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x0F;
OCR1AL=0x42;//3906
OCR1BH=0x00;
OCR1BL=0x00;

GIMSK=0x00;
MCUCR=0x00;

TIMSK=0x40;

USICR=0x00;

UCSRB=0x00;

ACSR=0x80;
DIDR=0x00;

#asm("sei")
while (1)
 {
 show();
 }
}

Изменено пользователем pavelok
Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

PORTD.0=1;
PORTD.1=0;

И вот здесь мы начинаем засвечивать предыдущий разряд. Что и видно. Нужно делать так: потушили все разряды, выставили нужные данные, засветили нужный разряд. И вся бяка уйдет. В вашем случае это должно выглядеть:

PORTD.0=1; // потушили предыдущий разряд
PORTB=a[k/10]; // выставили инфу текущего разряда
PORTD.1=0; // зажгли текущий разряд
delay_ms(2); // задержка 2 мсек

Я не раздаю удочки. Я продаю рыбу.

Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Не, задержка не поможет, надо именно гасить сегмент перед переключением на следующий. И лучше перенести индикацию в прерывание и уж точно избавиться от delay'ев. Как-то так.

unsigned char nums[]={0b00111111,0b00000110,0b01011011,0b01001111,0b01100110,0b01101101,0b01111101, 0b00000111,0b01111111,0b01101111,0b00000000 };  //коды символов
unsigned char seg[4]={0,0,0,0}; // видеопамять, какие символы будут выведены
unsigned char mask[4]={0b11111110,0b11111101,0b11111011,0b11110111}; //что нужно выводить в PORTD для каждого разряда
//прерывание по переполнению таймера
ISR(TIMER0_OVF_vect){
static unsigned char index=0; //текущий номер индицируемого разряда
index++;
if(index>3)index=0;
PORTD=0xFF; //отключаем все разряды
PORTB=seg[index]; //готовим интересующие нас сегменты
PORTD=mask[index]; //и зажигаем подготовленный
}
//преобразование из двоичного числа в семисегментный вид
void outint(unsigned int x){
seg[0]=nums[x % 10];
x/=10;
seg[1]=nums[x % 10];
x/=10;
seg[2]=nums[x % 10];
x/=10;
seg[3]=nums[x % 10];
if(x!=0)seg[0]=seg[1]=seg[2]=seg[3]=nums[10]; //если число слишком большое - не индицируем вообще ничего
}
unsigned int count=0;
int main(){
...//настройка портов, таймера и прочего
while(1){
 count++; //счет от 0 до 10000 (больше не влезет)
 if(count>10000)count=0;
 outint(count);
 _delay_ms(100); //для проверки этого достаточно
}
...
}

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

Вызов outint() вне прерывания может привести к тому, что отображаться будет не то, что сейчас на самом деле в count. Доли секунды, вообще говоря, даже на глаз незаметная, но тем не менее неприятная бяка. Так делать некрасиво.

PS. Не в качестве темы для спора. Надеюсь, COKPOWEHEU понимает о чём я.

Я не раздаю удочки. Я продаю рыбу.

Ссылка на комментарий
Поделиться на другие сайты

Спасибо! Всё работает

PORTD.0=1;
PORTD.1=0;

И вот здесь мы начинаем засвечивать предыдущий разряд. Что и видно. Нужно делать так: потушили все разряды, выставили нужные данные, засветили нужный разряд. И вся бяка уйдет. В вашем случае это должно выглядеть:

PORTD.0=1; // потушили предыдущий разряд
PORTB=a[k/10]; // выставили инфу текущего разряда
PORTD.1=0; // зажгли текущий разряд
delay_ms(2); // задержка 2 мсек

Ссылка на комментарий
Поделиться на другие сайты

Вызов outint() вне прерывания может привести к тому, что отображаться будет не то, что сейчас на самом деле в count. Доли секунды, вообще говоря, даже на глаз незаметная, но тем не менее неприятная бяка. Так делать некрасиво.

PS. Не в качестве темы для спора. Надеюсь, COKPOWEHEU понимает о чём я.

При частоте обновления 200 Гц это наименьшая проблема. Можно, конечно, добавить cli/sei, или буферизацию, но зачем? На отображении это почти не скажется, а вот скорость работы уменьшит. Если что и исправлять, так это volatile к массиву сегментов, а к mask и nums модификаторы const и, возможно, PROGMEM (flash).

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...