В последнее время среди велоаксессуаров получили распространение так называемые цифровые велосипедные спидометры (велокомпьютеры).
Эти устройства способны измерять множество параметров, основными из которых являются скорость и расстояние.
Принцип измерения скорости основан на расчете периода вращения колеса, а расстояние рассчитывается на основе измерения количества таких оборотов.
Часто датчик скорости колеса представляет собой геркон в сочетании с магнитом на спице колеса.
В зависимости от функционала цена таких устройств варьируется в широких пределах.
Самый дешевый велосипедный спидометр можно приобрести примерно за 500 рублей.
У меня всегда было желание иметь такое устройство.
При этом я сформулировал ряд собственных требований, которым оно должно удовлетворять.
Прежде всего, мне очень хотелось, чтобы по мере моего движения на дисплее рисовался график изменения скорости в зависимости от расстояния или времени, накопленный за небольшой период. А также записывать (журналировать) измерения на запоминающее устройство для дальнейшей передачи статистических данных на компьютер и более детального их просмотра.
Дешевые модели не полностью отвечают моим требованиям, а переплачивать за дорогие модели не хочется.
На основании вышеизложенного я решил создать свой велоспидометр на базе микроконтроллера ATmega8. Было много вопросов, в частности по поводу используемой периферии.
Случайно наткнулся на статьи об использовании дисплея некогда популярного мобильного телефона Nokia 3310. Прочитав к нему даташит и убедившись в простоте его управления, я не сомневался, что велоспидометр будет выполнен в корпусе вышеупомянутого телефона с собственным дисплеем.
Корпус вполне хороший, да и само устройство найти не сложно.
В качестве ПЗУ для записи статистики измерений я решил установить классический ПЗУ 24ХХ512 (512 Кбит), управляемый по интерфейсу I2C. Я не стал использовать карту памяти SD/MMC. Еще одна важная функция в устройстве – часы.
Они служат для привязки некоторых измеряемых конкретных параметров (например, максимальной скорости) к дате и времени, а также необходимы для записи временных меток в статистику.
В качестве часов я использовал отдельный от микроконтроллера чип часов реального времени (RTC), который питается независимо от аккумулятора, а также общается с контроллером по I2C. Дополнительные мелкие требования в функционале устройства я реализовал на этапе написания программы.
Сюда входят всевозможные организационные вопросы: количество задействованных кнопок, расположение тех или иных элементов на дисплее, навигация по интерфейсу и так далее.
В плане навигации я заранее решил не усложнять программу, например не реализовывать меню настроек, в частности настройки даты и времени.
Часы устанавливаются только один раз.
Часы «тикают» независимо в самом чипе RTC благодаря кварцу 32,768 кГц и батарее, которой хватает на долгое время.
Установка даты и времени осуществляется через UART-интерфейс велоспидометра, подключаемого к COM-порту компьютера, в один клик.
Через этот же интерфейс предполагалось считывать данные статистики из ПЗУ в компьютер.
Для всего этого нужно написать соответствующую программу для компьютера.
Однако, как показала дальнейшая практика, от последнего пришлось отказаться.
Во-первых, возникла проблема с реализацией приема данных от контроллера к компьютеру на этапе написания компьютерной программы.
И, что еще более существенно, увеличился объем программы для контроллера.
Гораздо интереснее было разместить ПЗУ (в SMD корпусе SOIC-8) на съемной платформе, сравнимой с SIM-картой, и использовать соответствующий свободный слот мобильного телефона.
Для этого необходимо изготовить устройство чтения ПЗУ на базе устройства чтения SIM-карт, используя одну из известных схем I2C-программатора ПЗУ.
Как выяснилось позже, это решение не доставило лишних неудобств.
Еще одним важным вопросом является вывод символьной (в том числе цифровой) информации на графический дисплей.
Для этого необходима графическая информация о конкретном символе.
Эта информация тесно связана с таким параметром, как размер отображаемого шрифта.
Для отображения основного параметра – скорости движения – для наглядности желательно использовать крупный шрифт. Однако, как будет показано далее, такая графическая информация о десяти цифрах не поместится в память МК, а использование того же внешнего, более емкого ПЗУ замедлит скорость отрисовки шрифта.
Я решил использовать шрифт размером 8 пунктов как самый крупный.
Графическую информацию для этого шрифта я вытащил из файла «8X8.FNT» какой-то программы MS DOS, предварительно разгадав его структуру и проделав дальнейшую обработку.
Как позже выяснилось на практике, этого размера вполне достаточно для демонстрации скорости.
Я выбрал 3x5 в качестве размера дополнительного шрифта и сам нарисовал графику для чисел этого размера.
Эти небольшие цифры отображают дополнительные параметры: дату/время, среднюю и максимальную скорость, путь.
Графическая информация обоих шрифтов хранится в неких двумерных массивах.
Каждый элемент массива размером в 1 байт указывает на распределение пикселей в определенном столбце определенной цифры.
Для крупного шрифта под каждую цифру отводится 8 столбцов, а для мелкого - 3. Для такого же мелкого шрифта размером 3Х5 формальная высота составляет не 5, а 8 пунктов (округляя до одного байта).
Это позволяет заранее определить размещение 5-позиционного шрифта внутри 8-позиционной зоны по вертикали одним из 4 возможных способов.
Эти факты хорошо иллюстрируются на рисунке ниже, где показано графическое моделирование первых двух цифр этого шрифта.
Известная программа Excel отлично подходит для моделирования.
Исходными данными является расстановка «единиц» в соответствующих полях для требуемых графиков.
Из них по формулам вычисляются значения массивов, вплоть до кода языка Си, которые в дальнейшем можно скопировать в текст программы для микроконтроллера.
Теперь поговорим об особенностях управления используемым дисплеем.
Этот дисплей монохромный, его размеры составляют 84 на 48 пикселей.
Управление дисплеем осуществляется с МК через интерфейс SPI. Передаваемые по SPI байты интерпретируются на дисплее в двух режимах: байты для отображения и байты команд конфигурации.
Эти режимы задаются самим МК с помощью определенного вывода дисплея (D/C).
Полный список команд приведен в даташите на дисплее.
Некоторые из этих команд используются в моем устройстве, и служат для первоначальной инициализации дисплея при подаче питания на устройство: температурный коэффициент, контрастность, режим последовательного рисования (горизонтальный или вертикальный) и т.д. Сразу отмечу, что режим горизонтального рисования используется.
Это означает, что при передаче байта в режиме отображения адрес автоматически увеличивается на единицу по строкам справа.
Когда строка заканчивается, адрес позиции перемещается в начало следующей строки.
Вам просто нужно сначала отправить на дисплей специальную команду позиционирования по определенному адресу строки и столбца (начальная позиция), а затем последовательно один за другим отправить байты данных для отображения графики.
Стоит отметить особенность адресного пространства и интерпретации графики в зависимости от принимаемых дисплеем байт. Обратите внимание, что для монохромной графики один байт содержит информацию сразу о восьми пикселях.
Рассматриваемый дисплей разделен по вертикали на 6 горизонтальных зон по 8 строк в каждой (6*8=48).
Каждому столбцу каждой зоны будет соответствовать определенный байт, который передается с адресом соответствующего столбца (0.83) и номером зоны (0.5).
Адрес считается не с единицы, а с нуля.
Например, если вы расположитесь по адресу (34;2) и отправите байт данных 255 (в двоичном виде «11111111»), то загорятся все 8 пикселей с 16 по 23 по вертикали и в 35-м столбце по горизонтали.
Из этой особенности, на мой взгляд, вытекает один из недостатков: невозможность контролировать состояние каждого пикселя в отдельности на аппаратном уровне.
Байт — это минимальный фрагмент данных для графики.
Когда байт отправляется на текущий адрес, все 8 соответствующих пикселей в текущей зоне обновляются.
Дисплей не поддерживает чтение отображаемой в данный момент графической информации в микроконтроллер.
Поэтому при необходимости нужно заранее сохранять выходную информацию в МК в специально отведенном буфере, а для изменения состояния каких-либо пикселей (битов) использовать битовые маски для байтов из этого буфера и передавать их на дисплей.
снова.
Моделирование и продумывание расположения этой или графической информации на дисплее осуществлялось с учетом вышеперечисленных особенностей.
Это сделано для упрощения кода при написании программы.
И не случайно размер шрифта рассматривался из разряда 8, 16, 24, т. е.
кратный 8. По аналогии с дисплеем я также разделил графическую информацию на 6 горизонтальных зон.
В первой зоне мелким шрифтом отображаются абсолютные и текущие (с момента включения устройства) значения оборотов.
Во второй зоне — абсолютные и текущие значения пути (в километрах, округленные до сотых).
В третьей зоне – средняя скорость.
В четвёртом - максимальная скорость и крупным шрифтом - текущая скорость.
В пятой зоне отображаются два индикатора выполнения, указывающие заполненность ПЗУ и объем перезаписи.
В шестой и последней зоне находится дата и время.
Исключением является пятая зона, когда по вертикали любого заданного столбца находятся пиксели, относящиеся к различной информации.
Поэтому эта информация собирается в буфер с помощью битовых масок, содержимое которых затем отображается на дисплее в этой пятой зоне.
Также в зонах 3-5 имеется информация для обрамления отображаемого значения скорости.
В последней зоне каждый первый (младший) бит во всех столбцах устанавливается на «1» для рисования разделительной линии (40-я строка).
Для такого моделирования и наглядности адресов я изобразил все вышеперечисленное в ячейках Excel.
Именно так выглядит первое окно дисплея.
Всего два окна.
Во втором окне отображается график (гистограмма) движения.
Он имеет 5 зон (40 строк) по вертикали и все 84 столбца по горизонтали.
Шестая зона с часами одинакова для обоих окон.
При программировании я решил не прибегать к использованию какой-либо библиотеки для работы с этим дисплеем.
Лично мне проще разобраться в даташите и реализовать часть функций самому, чем разбираться в библиотеке.
Более того, в этом были определенные преимущества.
Недавно, скачав одну из библиотек, я все-таки разобрался с ее функциональными особенностями.
Он универсален; его можно использовать для индивидуального управления пикселями и позиционирования их по реальному адресу пикселя.
Но библиотека использует буфер размером 84*6 Байт, и этот буфер периодически по таймеру отправляется на дисплей, обновляя графику.
Таким образом, таймер и часть памяти МК заняты.
В моем конкретном случае нет необходимости использовать библиотеку, так как при моделировании я заранее позаботился о максимальном разделении информации на отображаемые зоны, которые были заданы в полном соответствии с зонами отображения.
И нет необходимости периодически обновлять информацию на дисплее: информация обновляется только тогда и только в том месте, когда она меняется (при каждом обороте колеса, при каждом нажатии кнопки и т. д.).
Таким образом, еще раз подчеркиваю: в зависимости от поставленной задачи вы можете отказаться от использования каких-либо библиотек.
Для работы с чипом часов и ПЗУ я также не прибегал к использованию библиотек: все функции достаточно простые и реализовал их после изучения даташитов на эти компоненты.
Теперь посмотрим на электрическую схему устройства.
Схема велосипедного спидометра относительно проста.
Помимо всего вышеперечисленного, в схеме присутствует элемент IC5 MAX756, служащий преобразователем питания с 3 на 5 Вольт для надежного питания от оригинального аккумулятора мобильного телефона Nokia 3310. Схему для питания 3-В я не реализовал из-за отсутствия соответствующего МК и периферии.
В настоящее время я еще не приобрел MAX756, и вся схема по-прежнему питается от внешней батареи «Крона» с помощью регулятора LM7805 (не совсем оптимальный вариант).
Он подключается к разъему для наушников в нижней части телефона.
Геркон SF1, являющийся датчиком вращения колеса, подключается к порту прерывания INT0 МК (вывод 32).
Он надежно подключается снизу телефона к порту зарядки.
Функциональные кнопки S1-S3 подключаются к произвольным портам (контакты 23, 27, 28), которые совпадают с кнопками «1», «2», «3» мобильного телефона.
Кнопка S4 подключена к пину 29 сброса МК, который совпадает с верхней торцевой кнопкой включения мобильника.
Я сделал это именно так.
Само устройство не имеет режима ожидания и включается при подаче питания.
Дисплей IC2 и разъем для прошивки X1 подключаются к порту SPI контроллера (контакты 15-17).
С разъемом, который я хотел сделать на основе имеющихся на оригинальной плате «пятен» для интерфейса с ПК (там же), возникла небольшая загвоздка, и в будущем я перенесу его в другое место.
В этом же разъеме имеется UART-интерфейс для подключения пользователя к компьютеру, через который настраиваются дата и время на устройстве (контакты 30-31, RX/TX).
Дисплей подключен к контроллеру через резисторные делители, служащие для снижения напряжения, так как дисплей работает при напряжении 3,3 В.
Кроме того, выводы дисплея D/C (данные/команда), SCE (стробоскоп) и RES (сброс дисплея) подключаются к произвольным портам МК PB0, PB1 и PB2 соответственно (контакты 12-14).
Питание дисплея осуществляется через диоды D1-D3 и резистор R6, служащие для снижения напряжения с 5 до 3,3 В, позволяющие избежать использования линейного стабилизатора.
Кварц Cr1, тактирующий МК, номиналом 4,5 МГц был выбран случайно, но сознательно.
Я случайно наткнулся на это и решил использовать.
Транзисторы Q1 и Q2 подключены к портам МК PD4 и PD5 (выводы 2 и 9), на которые нагружена светодиодная подсветка дисплея и клавиатуры.
Контроллер обеспечивает возможность индивидуального управления подсветкой, как это предусмотрено оригинальной схемой мобильного телефона (это было на аппаратном уровне, а не на уровне пользователя), хотя на практике в этом нет необходимости.
Шина I2C подключается к портам PC2-PC3 (контакты 25-26) и для простоты реализуется программно с помощью соответствующей библиотеки (хотя и подключается к аппаратным портам TWI).
На шине находится ПЗУ IC3 и часы реального времени (RTC) IC4. Сразу оговорюсь, чтобы не было критики в комментариях: я знаю, что DS1307 не является решением, но на момент разработки схемы не знал о существовании DS3231. ПЗУ расположено на съемном разъеме, похожем на SIM-карту.
Дополнительный порт контроллера PC1 (вывод 24) используется для приема импульсов частотой 1 Гц от часов реального времени, обновляющих время на дисплее.
Все пассивные компоненты обвесов - согласно даташитам на каждый активный актив.
Рассмотрим математические соображения для расчета некоторых параметров.
Как уже было сказано вначале, принцип измерения скорости основан на расчете периода вращения колеса, а расстояние рассчитывается на основе измерения количества таких оборотов.
Контроллер измеряет время между предыдущим и вновь поступающим импульсом от геркона.
Результат измерения преобразуется в значение скорости путем деления периметра колеса на период вращения, и это значение обновляется на дисплее при каждом импульсе (вращении колеса).
Здесь стоит отметить, что с точки зрения физики средняя скорость велосипеда рассчитывается на участке пути, соответствующем периметру колеса.
Отдельно рассчитывается количество импульсов, которое затем преобразуется в значение расстояния.
Контроллер использует собственный таймер для измерения периода вращения колеса.
ATmega8 имеет 8-битные и 16-битные варианты таймера.
Динамический диапазон измерения зависит от разрядности таймера.
В моем случае используется 16-битный таймер, так как 8 бит (256 градаций счета) совершенно недостаточно.
Максимальный период измерения (до переполнения таймера) будет соответствовать минимальной измеренной скорости.
Можно ввести так называемый программный таймер, который позволит измерять длительные периоды времени.
Однако для упрощения программы я этого не делал.
При используемом кварце на 4,5 МГц и максимальном значении делителя 1024 в конфигурации таймера имеем: (1/(4500000/1024)) = 0,000227556 сек.
Это значение соответствует минимальному периоду счета.
А максимальный период счета составит 0,000227556*65536 = 14,913 секунды.
Максимальная измеренная скорость, соответствующая минимальному измеренному периоду, составит около 30 000 км/ч.
Об этом даже и говорить не стоило, «запас выше» просто огромен.
Но минимальная измеренная скорость, соответствующая максимальному измеренному периоду, составит 2,26/14,913/1000*3600 = 0,54 км/ч.
Здесь 2,26 — это периметр велосипедного колеса (в метрах) в моем случае.
Меня вполне устраивает это минимальное измеренное значение.
Если велосипед движется со скоростью менее 0,54 км/ч, велоспидометр зафиксирует отсутствие движения (и переполнение таймера).
С этим кварцем 4,5 МГц интерфейс UART прекрасно работает на скорости 2400 бод с допустимой погрешностью.
Этой скорости тоже вполне достаточно, тем более, что я использую UART для единоразовой настройки часов с компьютера (для копирования даты и времени с компьютера на устройство).
Если взять кварц на более высокую частоту, то минимальная измеряемая скорость увеличится, что для меня будет неприемлемо, и возникнет необходимость использования программного таймера.
А если брать ниже, то снижается производительность устройства в целом.
Поэтому я решил оставить это, это.
Замечу, что значения периода и скорости обратно пропорциональны, а таймер микроконтроллера измеряет период дискретно.
В нашем случае на диапазон измерения равномерно наносят 65535 точек (0,000227556…14,913), разделяя его на множество равных интервалов.
И эти точки соответствуют всевозможным измеряемым значениям.
Применяя интервальное преобразование времени в скорость, данная интервальная система преобразуется из равномерной в обратно пропорциональную.
Следовательно, диапазон скоростей, который можно измерить, разбивается на неравномерные интервалы.
Длина этих интервалов увеличивается с увеличением скорости.
Учитывая этот факт, огромный «запас сверху», о котором я писал чуть выше, лишним не будет. На практике в качестве максимальной измеряемой скорости велосипеда будет вполне достаточно принять значение 100 км/ч.
Это хотя бы для того, чтобы не вводить новую цифру (сотни) и не увеличивать ширину отображаемого параметра на дисплее.
Рассчитаем длину интервала между соседними возможными значениями при скорости в районе, например, 90 км/ч.
Используя обратные формулы или подбор, нетрудно подсчитать, что для значения таймера 397 (из 65536 возможных) измеренная скорость соответствует 90,06 км/ч.
А при следующем значении таймера 398 – 89,83 км/ч.
А разница скоростей составляет 0,23 км/ч, что более чем приемлемо.
А на более низких скоростях эта разница будет еще меньше.
На дисплее отображается значение скорости с точностью до сотых.
Однако на практике обычно бывает достаточно округления до ближайшего целого числа или десятых.
Из всего сказанного можно сделать вывод: неравномерностью «сетки» скоростей можно пренебречь, так как вызванная ею погрешность измерения не превышает допустимой погрешности.
Чтобы рассчитать расстояние, просто умножьте количество импульсов (оборотов) на периметр колеса.
В этом случае, конечно, расстояние рассчитывается с точностью до периметра колеса, что вполне приемлемо.
Текущая средняя скорость рассчитывается как отношение текущего пройденного расстояния к значению времени с момента включения.
Контроллер вычисляет это время, подсчитывая количество импульсов, поступающих раз в секунду от часов реального времени.
Средняя скорость на дисплее обновляется вместе с обновлением времени (раз в секунду).
Все остальные параметры обновляются при каждом вращении колеса.
Теперь о мелких особенностях интерфейса.
Первая кнопка используется для переключения режимов (графический режим или режим отображения значений).
Вторая кнопка предназначена для отображения абсолютной (за все время) максимальной скорости вместо относительной при ее удерживании.
Также вместо текущих даты и времени отображается дата и время достижения этой скорости.
А также вместо значения относительной скорости (для управления) отображается значение текущего адреса ПЗУ.
Это значение можно оценить по горизонтальной полосе прогресса на 38-й строке дисплея.
Это ПЗУ емкостью 65536 байт (512 кбит) записывает измеряемые параметры.
Как будет сказано далее, достаточно записать первоначально измеренный параметр (период вращения колеса) с отметкой времени начала.
Все остальные параметры легко рассчитываются компьютерной программой на этапе сканирования ПЗУ.
Третья кнопка предназначена для управления подсветкой.
В отличие от эскиза экрана выше, позже я удалил несущественные нули из второстепенных параметров, чтобы отобразить их более четко.
В графическом режиме слева направо рисуется гистограмма скорости движения, которая наглядно демонстрирует процесс изменения скорости на небольшом расстоянии в 84 оборота колеса.
Значение гистограммы представляет собой скорость в масштабе 1 пиксель на 1 км/ч.
Если скорость движения превышает 40 км/ч, масштаб изображения уменьшается по вертикали в 2 раза во избежание выхода за масштаб.
Подробное поведение устройства здесь описывать нет необходимости.
Стоит отметить одно из характерных отличий моего велосипедного спидометра от дешевых магазинных.
Она заключается в скорости обновления показаний скорости на дисплее.
В моем аппарате оно обновляется сразу, как посчитано, при каждом обороте колеса.
В купленных устройствах обновляется с некоторой задержкой.
Эта задержка может быть связана с попыткой отфильтровать шум измерений (например, с помощью метода скользящего среднего), чтобы стабилизировать показания скорости на дисплее и обеспечить более детальную видимость.
Или, возможно, отображение полностью обновляется через определенные промежутки времени (например, два раза в секунду).
Возможно это и удобно, но мне хотелось реализовать обновление скорости при каждом повороте колеса.
Печатная плата изготовлена методом ЛУТ по форме оригинальной платы используемого мобильного телефона.
При изготовлении платы я использовал программу SLayout. При этом я заранее сфотографировал оригинальную плату с обеих сторон с помощью сканера и поместил изображения в SLayout в качестве шаблона.
Это нужно для того, чтобы нарисовать области подключения дисплея, кнопок и разъемов именно в нужных местах.
При изготовлении платы произошла погрешность около 0,5 мм.
Эта погрешность оказалась допустимой с точки зрения соосности контактных площадок и элементов.
Однако эта ошибка сказалась на качестве подсветки: запаянные светодиоды смещались на доли миллиметров и не попадали в фокус светорассеивающих оправок.
Из-за этого снизилась яркость подсветки, снизив эффективность.
На рисунках ниже показана плата в SLayout вместе с тремя небольшими платами для ПЗУ в виде SIM-карты.
Также с обеих сторон показаны сканы оригинальной печатной платы.
Некоторые элементы (кнопки, разъемы) соединены между собой тонкими проволочными перемычками из-за отсутствия возможности прокладки дорожек.
Имеется резерв для всех доступных кнопок, т.е.
можно использовать любую доступную кнопку.
Возможно, было бы удобно сделать большую кнопку в центре кнопкой переключения режимов отображения.
В левом верхнем углу платы находится 3-вольтовая батарейка RTC. В целом все элементы на плате размещены правильно, сопоставляя свои размеры с размерами корпуса.
В отличие от позолоченного оригинала, самодельная плата покрыта обычным припоем.
Как показала первоначальная практика, контакт с дисплеем и другой периферией не теряется.
Программа для МК оказалась довольно большой и занимает значительную часть памяти.
Кроме того, в программе предусмотрено использование собственной энергонезависимой памяти контроллера (EEPROM) для записи и сохранения необходимой информации.
Ниже представлена таблица распределения этой информации по адресам EEPROM.
Адрес | Размер | Данные |
0 | 4 | п (для S) |
4 | 2 | t_min (для v_max) |
6 | 6 | Дата t_min |
12 | 2 | Адрес EEPROM |
14 | 1 | Количество записей EEPROM |
128 | 80 | Цифры 8X8 |
208 | 30 | Цифры 3X5 |
Я специально выбрал для этой переменной 32-битный целочисленный тип, поскольку на практике значения пути относительно велики.
Например, целочисленная 16-битная переменная может хранить максимум 65536 оборотов (около 148 км), что естественно мало.
Далее следуют два байта для хранения абсолютной максимальной скорости.
Фактически сохраняется минимальное время вращения колеса.
Переменная занимает два байта, поскольку ее значение является результатом измерения 16-битного таймера.
Следующие 6 байтов — это дата и время достижения указанной максимальной скорости.
Данные представлены именно в том формате, в котором они читаются с чипа RTC (без учета номера дня недели).
Далее идут два байта, в которых хранится значение текущего адреса внешнего ПЗУ.
Это своего рода указатель, который необходим для того, чтобы иметь возможность продолжить запись статистики в ПЗУ после очередного включения устройства.
Микроконтроллер должен знать, на какой позиции адресного пространства внешнего ПЗУ он остановился в последний раз.
С этой позиции МК продолжит запись.
Этому значению отведено 2 байта, поскольку адресное пространство внешнего ПЗУ 16-битное.
Это следует из размера ПЗУ 64 КБ.
Далее идет однобайтовая переменная, хранящая значение количества перезаписей ПЗУ.
Перезаписью считается случай, когда вышеописанный указатель достигает максимального значения и переходит в ноль.
В этом случае вновь поступающая информация на ПЗУ начнет записываться с самого начала, стирая на нем старую информацию.
Однобайтовая целочисленная переменная может хранить максимум 256 значений.
Напомню, значения индикатора адреса ПЗУ и количества перезаписей визуально обозначаются двумя индикаторами выполнения на дисплее.
Далее, после большого резервного места в EEPROM МК, начиная с адреса 128, сохраняется графическая информация размером 8х8 цифр.
Для него отведено 80 Байт (по 8 Байт на каждую цифру, как говорилось ранее).
И, наконец, начиная с адреса 208, 30 байт хранятся для графической информации о небольших цифрах 3х5 (по три байта на цифру).
Помимо основной программы для микроконтроллера я написал еще три вспомогательные программы для компьютера, о которых пойдет речь ниже.
Все программы не имеют графического интерфейса и работают из командной строки Windows XP. Первая программа позволяет скопировать дату и время с компьютера на спидометр велосипеда через COM-порт. Велосипедный спидометр подключается к компьютеру через микросхему MAX232. Используя WinAPI, программа получает текущую дату и время в специальную переменную структуры типа SYSTEMTIME. Из этой переменной извлекаются текущий день, месяц, год, день недели, часы, минуты, секунды в десятичном формате.
Все эти числа, за исключением года, не превышают двух десятичных знаков (менее 100) и лежат в пределах одного байта.
Значение года преобразуется в двузначное число путем вычитания из него числа 2000 — значения текущего тысячелетия.
Каждое из этих двухзначных десятичных чисел преобразуется в формат BCD, специфичный для чипа RTC. В этом формате двузначное число также занимает один байт. Старшие 4 бита кодируют цифру десятков, а младшие 4 бита кодируют цифру единиц.
В дальнейшем из этих чисел формируется пакет размером 13 Байт, по заранее заданному мной протоколу.
Первые пять байтов представляют слово «TIME=" в соответствии со стандартной кодировкой ASCII. Затем следуют секунды, минуты, часы, день недели, день, месяц, год. Последний байт представляет собой символ «#» как символ конца сообщения.
Этот пакет отправляется с компьютера на устройство через COM-порт. Программа микроконтроллера получает сообщение и проверяет его на корректность согласно приведенному выше формату.
Если первые пять байтов — «TIME=», а последний — «#», отправка считается корректной, а байты внутри интерпретируются в соответствующем порядке.
Не меняя эту цепочку байтов, контроллер отправляет ее на чип RTC по шине I2C, настраивая на текущую дату и время.
Замечу, что данная микросхема поддерживает счет дней недели от 1 до 7, хотя как таковая она не является календарем, определяющим соответствие даты и дня недели.
Я не вывел на дисплей информацию о дне недели в своем устройстве.
Вторая программа предназначена для обработки данных из содержимого внешнего ПЗУ.
Изначально предполагалось, что это содержимое следует переписать из ПЗУ в образ файла с помощью какой-нибудь известной программы, работающей с известными программистами МК и ПЗУ (например, «icprog»).
Однако более подробно изучив принцип работы I2C, я смог реализовать этот функционал и включил его в свою программу.
Схема ROM-программатора этой серии, который я использовал в устройстве, представлена на рисунке ниже.
ПЗУ подключается к COM-порту компьютера, который используется не как средство обмена информацией по RS-232 (где достаточно использовать выводы TX, RX, GND), а как средство произвольного ввода/вывода.
вывод логических сигналов.
Вывод TX обеспечивает питание ПЗУ, которое стабилизируется до 5 В регулятором 78L05. Управляя выводом TX с компьютера, мы можем включать или выключать микросхему ПЗУ.
Однонаправленная линия синхронизации SCL сосредоточена на выводе RTS разъема COM-порта, а двунаправленная линия данных SDA сосредоточена на двух выводах: CTS (прием данных) и DTR (передача данных).
Резисторы и стабилитроны D1 и D2 служат для ограничения уровня сигнала до ТТЛ, при котором работает ПЗУ.
Этот стандартный программатор я сделал для своего частного случая, где вместо гнезда ПЗУ я использовал SIM-ридер от сломанного мобильника.
С помощью WinAPI программа обращается к контактам COM-порта компьютера и устанавливает необходимые
Теги: #atmega8 #nokia 3310 #pcd8544 #велокомпьютер #C++ #математика #Программирование микроконтроллеров
-
Чем Хорош Gentoo: Мифы И Реальность
19 Oct, 24