Содержание
Урок 1. Первый проект
Урок 2. Управление кнопками
Урок 3. Подключение LCD
Урок 4. Использование ШИМ
Урок 5. Таймеры
Урок 6.1. Статическая индикация
Урок 6.2. Динамическая индикация
Урок 7.1. Генерация звука
Урок 7.2. Генерация звука. Продолжение
Урок 8.1. Передача данных через UART
Урок 8.2. Передача данных через UART. Продолжение»
Урок 9. Передача данных через SPI
Урок 10. Изучение АЦП. Простой вольтметр
Урок 11. Получение синуса при помощи ШИМ
Урок 12. Измерение температуры
Урок 13. Внешние прерывания.
Урок 14. Использование отладчика
Урок 15.1. Управление инкрементальным энкодером
Урок 15.2. Управление громкостью, при помощи энкодера
Урок 16. Управление RGB светодиодом
Урок 17. Использование ИК
Урок 18.1. Знакомство с графическим дисплеем
Урок 18.2 Вывод изображения на графический дисплей
Урок 18.3 Вывод русскоязычного текста
Урок 19. Формирование сигнала, при помощи ЦАП (R2R)
Урок 20. Опрос матричной клавиатуры
Урок 21. Сторожевой таймер
Урок 22.1 Воспроизведение wav. Введение.
Урок 22.2 Воспроизведение wav. Продолжение.
Урок 23.1 Работа с внешней памятью
Урок 23.2 Работа с файловой системой Fat

seglogoВ продолжение урока, рассмотрим динамическую индикацию. Если вы внимательно изучили статическую индикацию, то знаете, что сегментный индикатор это набор светодиодов. Для того, чтобы подключить индикатор, нужно 7 ножек микроконтроллера. Но, вдруг нам понадобилось использовать несколько индикаторов, например 2, 3, 4…

Тогда нам понадобится уже 14, 21, 28 ножек, а ножек итак мало… Тут нам на помощь приходит динамическая индикация. Основная задача динамической индикации — снизить количество используемых ножек микроконтроллера. Обратите внимание на схеме задействовано 9, а не 14 ножек. Ножки управления все подключены параллельно.
sch2

В общем смысле работает данная конструкция следующим образом: вначале выводится конфигурация первого числа на общую шину и включаем PB1. Первый индикатор загорается, с нужным числом. Затем его гасим, выводим конфигурацию второго числа на шину данных, зажигаем второй индикатор, выключаем.

Более детально. В первый момент времени все выключено PORTB=0x00; PORTD=0xFF; так как схема с общим «+», анодом. Далее на PORTD посылается конфигурация первого числа, например «0». Из статической индикации мы помним:

case 0:
{
  PORTD=0xC0; 
  break;
}

Но обратите внимание, «+» подключен к PORTB.1, т.е. чтобы зажечь сегмент нужно включить ножку PORTB.1=1; 

Во второй момент времени, снова все выключаем, посылаем конфигурацию второго числа и включаем, на этот раз, второй индикатор. Далее повторяем.

При высоких частотах, человеческий глаз не способен разглядеть эти переключения, и кажется что индикатор горит постоянно. Рекомендуется не использовать частоты кратные 50Гц. В своем тестовом проекте я использовал 120Гц. Таймер настроен на частоту 1МГц. Код обрабатывается в прерывании таймера1. Прерывание вызывается 240 раз в секунду, потому что индикаторов два, поэтому 1000 000/240=4166 или 0x1046 пихаем в регистр сравнения. Протеус подружить с динамическим индикатором не удалось, зато на железе заработало сразу.

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

Для схемы с общим анодом

sch4

Для схемы с общим катодом

sch3

В качестве тестовой прошивки использовал таймер из предыдущего проекта.

Видео работы прошивки

140 комментариев: Урок 6.2 Динамическая индикация в AVR микроконтроллерах

  • я выводил на lcd и включал stdio.h.

  • ещё один вопрос на as7 hex меньше будет на 7 сегментном индикаторе.Чем на LCD?

  • последний вопрос не понятен

  • в яких межах рекомендований опір резисторів? (студент прост)

  • я имею ввиду что у меня вывод на экран результата на лсд занимает 11 кбайт.с ацп я использую мегу16

  • можно написать код так что и на сегментнике будет все плохо. теоретически работа с дисплеем займет больше места.

  • как мне вывести результат с ацп на индикатор?

  • дайте напутствие.Не во всех примерах получается.

  • возьмите индикатор на али с max7219 http://avr-start.ru/?p=3788

  • Здравствуйте, а как можно реализовать регулировку яркости свечения. Как в мигающем сегменте(динамическая индикация) мигать для скважности (шим)

  • на общий провод поставить транзистор и менять на нем шимом скважность

  • Как разложить число?
    Допустим в переменную записано число 123456
    В первый индикатор вывести 6
    Во второй 5
    Третий 4
    И.т.д

    Пробовал через%10 остаток, в первый индикатор
    Второй /10%10
    Третий/100%10

    Можно ли как-нибудь по-другому раскладывать?

  • наговнякал такую функцию (как можно её оптимизировать)

    void ledprint(unsigned int Number) //функция разложения числа на сегменты
    {
    Seg0= Number%10;
    Seg1= Number/100%10;
    Seg2= Number/1000%100;
    Seg3= Number/10000%1000;
    Seg4= Number/100000%10000;
    Seg5= Number/100000;
    }

  • это самый простой способ

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

  • добрый вечер
    админ подскажите пожалуйста как отсчитывать в обратном порядке?
    кнопкой «+» насчитал до 450, кнопкой «-» отсчитать в обратном порядке не получается, уже несколько дней пытаюсь, не получается, уже не знаю как быть. помогите……..

  • не понятно что из чего вы отсчитываете

  • доброе утро
    прошу прощения, видимо не правильно сформулировал вопрос
    надо собрать электронный регулятор скорости
    собрать на lcd проблем нету, уже собирал..
    при нажатии кнопки + мк считал от 0 до 100,
    а при нажатии кнопки — в обратном порядке не отсчитывал
    с этим вроде разобрался
    while (1)
    {
    if(PINB.0==0) // «+» 0…100
    {
    while(2)
    {
    if(n0==10)
    {
    n0=0;
    n1++;
    }
    if(n1==10)
    {
    n1=0;
    n2++;
    }
    delay_ms(150);
    n0++;
    if(n2==1)
    {
    n0=0;
    }
    if(PINB.0==1)
    {
    break;
    }
    }
    }

    if(PINB.1==0) // «-» 100…0
    {
    while(2)
    {
    if((n0<=0)&(n1==0)&(n2==0))
    {
    n0=0;
    }
    else
    {
    if(n0==0)
    {
    n0=10;
    }
    }

    if(n0==10)
    {
    n2=0;
    }

    if((n2==0)&(n0==10))
    {
    if(n1==0)
    {
    n1=10;
    }
    n1—;
    }
    if((n1==0)&(n0==10))
    {
    n1=0;
    n0—;
    }

    delay_ms(150);
    n0—;

    if(PINB.1==1)
    {
    break;
    }
    }

    }

    }
    есть более простой способ?
    буду пытаться связать с шимом и сохранять в eeprom
    спасибо Вам за ваши уроки и Вашу помощь начинающим программистам

  • По всей видимости вы пытаетесь в этом обработчике запихнуть логику разрядов. Как по мне, не стоит так делать. У вас есть переменная, которая содержит число от 0 до 100 вот ее и увеличивайте и уменьшайте. Перевод числа для дисплея должен быть там, где оно выводится на дисплей. Если у вас механические кнопки, то нужен антидребезг. while и delay тут тоже не нужны, нужно чтобы цикл крутился постоянно, опрашивайте по таймеру, есть флаг — зашли проверили состояние кнопки.

  • Здравствуйте! Как реализовать обратный отсчёт?

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Последние комментарии
  • Загрузка...
Счетчик
Яндекс.Метрика