Автор Тема: Часы на семисегментнике и AVR  (Прочитано 27179 раз)

aleksunches

  • Jr. Member
  • **
  • Сообщений: 61
    • Просмотр профиля
Re:Часы на семисегментнике и AVR
« Ответ #80 : Февраль 09, 2012, 20:39:05 »
mim пишет:
Цитировать

Из нас двоих - честный это я!
Я обещал тобой заниматься - я выполняю обещание...

Согласен, но я как увидел такие красивые часы мне сразу захотелось взглянуть)
Незнаю, может опять пишу лабуду, но всё что мне понятно на данный момент это то, что если регистры TCCR0B и TCCR0А = 0x00 - это останавливает таймер или счётчик. Если TCCR0B = 0x04 то это запускает таймер, но как непонятно. Прошу сильно не бить, и если лабуда - то ткнуть куда надо!
www.gaw.ru/html.cgi/txt/doc/micros/avr/arh128/16_3.htm ни тут, ни в дате 0х04 не видал.
И что же с этим кодом?
TCCR0A = 0x00;
TCCR0B = 0x04; //запускаем таймер
Это правильный пример или нет?

Taska

  • Hero Member
  • *****
  • Сообщений: 1801
    • Просмотр профиля
Re:Часы на семисегментнике и AVR
« Ответ #81 : Февраль 09, 2012, 20:50:21 »
Если 0х04 перевести в двоичную систему получится 0b00000100, смотри эти биты регистра TCCR0B.
TCCR0A - пока не трогай.

mim

  • Hero Member
  • *****
  • Сообщений: 2700
    • Просмотр профиля
Re:Часы на семисегментнике и AVR
« Ответ #82 : Февраль 09, 2012, 20:51:57 »
У меня дежавю? Или HIMIK вернулся???
Восьмиразрядный таймер/счетчик

Taska

  • Hero Member
  • *****
  • Сообщений: 1801
    • Просмотр профиля
Re:Часы на семисегментнике и AVR
« Ответ #83 : Февраль 09, 2012, 21:00:11 »
b]mim пишет:[/b]
Цитировать
У меня дежавю? Или HIMIK вернулся???

1. Сосмневаюсь. :smile:
2. Просто совпадение, очень похожая ситуация :smile:


Вот еще подсказка.
 

aleksunches

  • Jr. Member
  • **
  • Сообщений: 61
    • Просмотр профиля
Re:Часы на семисегментнике и AVR
« Ответ #84 : Февраль 09, 2012, 21:36:37 »
Ура! Это выбор прескалера 256. 256 это делитель. От него зависит сколько раз в секнду будет перепонлятся счётчик. TCNT0 обнуляем так: TCNT0=0x00 Спасибо Максиму! Если б не подсказл 0b00000100 так бы ещё неделю и не понятно было!

aleksunches

  • Jr. Member
  • **
  • Сообщений: 61
    • Просмотр профиля
Re:Часы на семисегментнике и AVR
« Ответ #85 : Февраль 11, 2012, 21:32:20 »
http://naukoved.ru/content/view/823/33/ прочитал, но думал будет интересней...  :smile:

mim

  • Hero Member
  • *****
  • Сообщений: 2700
    • Просмотр профиля
Re:Часы на семисегментнике и AVR
« Ответ #86 : Февраль 12, 2012, 08:30:44 »
Aleksunches пишет:
Цитировать
http://naukoved.ru/content/view/823/33/ прочитал, но думал будет интересней...  :smile:


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

Ладно... к вечеру кое что выложу.

aleksunches

  • Jr. Member
  • **
  • Сообщений: 61
    • Просмотр профиля
Re:Часы на семисегментнике и AVR
« Ответ #87 : Февраль 12, 2012, 09:31:21 »
mim пишет:
Цитировать

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

Ладно... к вечеру кое что выложу.

Ну я то вроде понял, а вот правильно сформировать и выложить мысль не могу.
Ну если я студент девятого класа то пусть будет так  :))

С нетерпением жду.

mim

  • Hero Member
  • *****
  • Сообщений: 2700
    • Просмотр профиля
Re:Часы на семисегментнике и AVR
« Ответ #88 : Февраль 12, 2012, 15:10:50 »
Aleksunches пишет:
Цитировать

Ну если я студент девятого класа то пусть будет так  :))

Бывают и вечные студенты, как и халявщики... Не стремись к этому.

Едем дальше.

Это общая для приведенных программ схема
 

Clock_OK.fcf_avr
 
Счетчик секунд.
Принцип подсчета такой же, как и у счетчика витков, только от таймера.
Счетчик намоточного станка
Счет накапливается в переменной – count. Для отображения на сегментах переменная count раскладывается на знакоместа
digit4 = count/1000
digit3 = count/100 - digit4 * 10
digit2 = count/10 - digit3 * 10 - digit4 * 100
digit1 = count - digit2 * 10 - digit3 * 100 - digit4 * 1000

Предварительная установка значения счета делается так же, как в счетчике витков, поэтому оставлена функция гашения не значащих (нулевых разрядов).
Выбор знака при установке подсвечивается точкой.
После установки предварительного значения, переменная count собирается из значений знакомест в единое число по формуле (см. макрос BUT)count = digit4*1000+digit3*100+digit2*10+digit1.
Таким образом, после запуска, счет продолжается от установленного значения.
Опция включения и отключения таймера основана но свойствах Таймера0 (TCNT0).
Включение. Если в регистр TCCR0B записать любое значение прескаллера (в нашем случае это 4 – деление на 256), то на вход таймера0 (TCNT0) начнут поступать импульсы от генератора МК (от внешнего или внутреннего). При наличии единицы в бите TOIE0 в регистре TIMSK (разрешить прерывание) начнут происходить прерывания, с частотой, которую мы установили. И наша программа начнет подсчет секунд.
Отключение. Чтобы отключить подсчет секунд нужно остановить таймер0 (TCNT0). Для этого в регистре TCCR0B нужно обнулить биты прескаллера. Поскольку кроме прескаллера мы ничего в этом регистре не используем, можно в TCCR0Bзаписать ноль напрямую TCCR0B=0; После такой записи Таймер0 остановится и счет секунд прекратится.
Если процесс счета не требует продолжения счета таймера0, то одновременно с TCCR0B=0; рекомендуется таймер0 обнулить TCNT0=0; (см. вставки на Си).
Как делается установка секунд понятно из программы (см. макрос BUT).


Clock_OK_v1.fcf_avr
 
Счетчик секунд и минут.
Реализован подсчет секунд и минут. С этой целью введены две переменные SEC и MIN.
Для отображения на сегментах переменные раскладываются на знакоместа
digit2 = SEC/10
digit1 = SEC%10
digit4 = MIN/10
digit3 = MIN%10

Установка предварительных значении ничем не отличается от предыдущей версии. После установки значения собираются (см. макрос BUT).
SEC = digit2*10+digit1
MIN = digit4*10+digit3

Гашение незначащих нулей в данной версии не целесообразно и оно убрано.
Все остальное реализовано также как и в Clock_OK.fcf_avr.

Clock_OK_v2.fcf_avr
 
По функциям такая же как Clock_OK_v1.fcf_avr отличие в реализации подсвета знакомест - оптимизировано использование переменной show_digit. Сравните как организована работа переменной show_digit в предыдущих программа и в этой.


Clock_OK_v3.fcf_avr
 
Написана на основе Clock_OK_v2.fcf_avr, но подсвет выбора знака осуществляется не точкой, а мерцанием самого знака. При старте программы внутренний таймер отключен. Для организации мерцания знака запускается таймер, после окончания установки таймер останавливается, поэтому после выхода из установки часы нужно перезапускать. Я просто не стал заморачиваться с отдельной переменной для мерцания. Желающие, переделают как хотят.


Clock_OK_v4.fcf_avr
 
Тоже самое что Clock_OK_v3.fcf_avr, но прерывание написано для режима сравнения (см. пример Максима в этой теме). Таким образом, установлено точное прерывание с частотой 125 Гц вместо 122,07 Гц.
Поскольку в предыдущих версиях частота прерывания стоит не точная (не целая, потому что программы для обучения). Рекомендую в предыдущих версиях программ установить такое прерывание, и изменить условие в прерывании на TIME>124, вместо TIME>121.



Поскольку чип attiny2313 – один из популярнейших чипов, то для тех, кто читает все темы подряд, это будет подарком.
Правленый файл ATTINY2313_A.fcd
 
В файле ATTINY2313_A.fcd добавлены расширенные режимы работы прерывания по таймерам, фактически все режим работы таймеров (за исключение PWM).

Clock_OK_v3_A.fcf_avr
 
Развитее версии Clock_OK_v3.fcf_avr. Для работы программы Clock_OK_v3_A.fcf_avr нужно скопировать файл ATTINY2313_A.fcd в директорию FCD ФК.
В программе установлен режим прерывания от таймера1 по совпадению и установлена частота прерывания 1 Гц. Для такой реализации изменена подпрограмма прерывания (см. программу).
Мерцание знакомест организовано по другому. В предыдущей версии переменная TIME изменялась в прерывании от 0 до 122 (или 125) и мы использовали это для задания времени мерцания. В этой версии переменная TIME читает регистр тамера1 непосредственно  - FCV_TIME=TCNT1>>8;. В остальном все тоже.

Интересности еще будут... Это выучить наизусть.

mim

  • Hero Member
  • *****
  • Сообщений: 2700
    • Просмотр профиля
Re:Часы на семисегментнике и AVR
« Ответ #89 : Февраль 13, 2012, 19:21:18 »
Продолжаем тему.

Clock_OK_v4_seg.fcf_avr
 
Схема та же.
Программа основана на версии Clock_OK_v4.fcf_avr. Поскольку Часы – это последовательный счетчик, то есть счет идет равномерно с инкрементом в единицу (резких изменений значения нет), то можно делать подсчет сразу в переменные digit1, digit2, digit3, digit4. Такой способ подсчета взят из примера ChasikiV1.fcf_avr (в этой теме см макрос UPDATE_VALUES)
При таком способе пересчет значений по принципу
SEC = digit2*10+digit1
MIN = digit4*10+digit3 не нужен.

В программе я специально оставил места от программы Clock_OK_v4, обойдя их GOTO. Оставлен и макрос прерывания int. Эти обходы и int можно удалить. Это сделано для сравнения (заменяя одно другим и наоборот). Если сравнить программы, то хорошо видно, что объем уменьшился, а скорость выполнения возросла (при одинаковых задержках частота подсвета увеличилась). Проведите эксперимент с заменой реализаций – это полезно для понимания.


Clock_OK_v4_1_seg.fcf_avr
 
Модернизация Clock_OK_v4_seg.fcf_avr
В программе изменен макрос Cod_to_port и способ формирования отображения точки.

Clock_OK_v4_seg_massiv.fcf_avr
 
Модернизация Clock_OK_v4_seg.fcf_avr
В программе удален макрос Cod_to_port. Коды сегментов размещены в массиве COD_7[]. Выдача кодов производится в условии (в переключателе) Switch прямо в порт.

Clock_OK_v4_seg_2massiv.fcf_avr
 
Модернизация Clock_OK_v4_seg_massiv.fcf_avr. Добавлен массив кодов знакомест COMM[]. Это привело к изменению цикла отображения знакомест (остался только один цикл), изменился способ изменения переменной show_digit (изменение по маске, в диапазоне от 0 до 3) – для выбора кода знакоместа.
Таким образом, программа содержит два массива данных – этот способ используют Матриксы в своих Макросах.

Теперь возьмемся за Макросы Матриксов.

Возможно описание, как работает динамическая индикации, нужно было привести раньше, но так уж сложилось… Лучше позже, чем никогда.
На примере с ОК (с ОА все тоже только сигналы инверсные).
Все сегменты нужно подключить к соответствующим портам, если на сегменте установить высокий уровень, то для того чтобы сегмент засветился, общий электрод (в данном случае Катод) нужно посадить на землю (установить низкий уровень). Последовательность работы индикатора такова. Установить на общих электродах (катодах) высокий уровень (это отключит все знакоместа). Установить на сегментах низкий уровень, это очистит порт сегментов. Установить на сегментах код знака (установить на соответствующих портах высокий уровень). Установить низкий уровень на общем электроде (катоде), который соответствует нужному знакоместу, это включит подсветку означенных сегментов только в одном знакоместе. Выдержать паузу. Повторить процедуру, но уже подключить следующее знакоместо. И так все в цикле.

Макрос Led7seg4

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

//display the digit
#if (%n == 0)
// вместо единицы нужно поставить НОЛЬ.
//common anode
…………………
#else
//common cathode
…………………
#endif


Clock_OK_v4_seg_macro4.fcf_avr
 
Применение макроса Led7seg4. Основа программы рассматривалась выше. Но это пример как не нужно писать если применять макрос Led7seg4.

Clock_OK_v4_1_seg_macro4.fcf_avr
 
Модернизация программы Clock_OK_v4_seg_macro4.fcf_avr
Поскольку значение переменной show_digit меняется от 0 до 3, и это соответствует номеру Макроса, то программу можно упростить. Макросы Led7seg4 выносим из переключателя Switch и используясь свойства параметров (переменные которые передают значения в подпрограмму Led7seg4) оставляем только один Макрос.

Clock_OK_v4_2_seg_macro4.fcf_avr
 
Продолжаем усовершенствование Clock_OK_v4_1_seg_macro4.fcf_avr. Благодаря тому, что Макрос остался один, появилась возможность вместо переменных digit1, digit2, digit3, digit4 ввести массив DIGIT[4] и значения этих переменных хранить в нем. Для извлечения значений их массива DIGIT[4] применяем переменную show_digi или N_digit (см. программу). Для ограничения верхнего порога ввода значений введен массив LIM[].
Посмотрите в макросе BUT как изменилось редактирование цифр.

Clock_OK_v4_macro1.fcf_avr
 
Показано применение Макроса Led7seg в приложении к нашей задаче.

В этих двух постах есть все ответы на все вопросы по всем принципам динамической индикации!