Статья из цикла посвященных отладочной плате для COF дисплеев.
Предыдущие статья:
Первое, что необходимо для работы с контроллером T5L, это правильно задать начальную конфигурацию и организовать взаимодействие между двух ядер.
Из документации в файл T5LRegisterMap.h скопированы все регистры дисплея. Список их достаточно большой, поэтому описание будет идти по ходу написания статей, регистры которые будут задействованы, будут описаны.
Необходим файл с системными переменными, инициализацией ядра и функциями общения между ядрами (SYSTEM.c SYSTEM.h).
Определяем стандартное написание типов переменных в привычный вид:
Добавим константные значения адресов:
Константные значения частоты (FOSC) для дальнейших расчётов и настройки частоты для системного таймера с частотой 1 мс (T1MS).
Далее в SYSTEM.h необходимо определить прототипы функций которые в дальнейшем придется описать:
ReadDgus - считывает 16-битную переменную из адресов DGUS.
WriteDgus - записывает 16-битную переменную из адресов DGUS.
ReadDgusVp- последовательно считывает данные в память DGUS.
WriteDgusVp- последовательно записывает данные в память DGUS.
InitCPU - содержит настройки контроллера для корректного запуска.
GetPageID - считать номер текущей страницы.
PageChange - перейти на заданную страницу.
Теперь необходимо создать сами функции в си файле.
Начнем файл с инициализации:
EA - регистр включения и выключения прерываний, 0 выключает прерывание, 1 включает прерывание.
Перед инициализацией переводим прерывания в выключенное состояние.
Первичная инициализация указана в "T5L_ASIC Development Guide" сейчас ничего изменяться не будет, следуем инструкции не отклоняясь от неё.
Также очищаем все регистры прерываний. Необходимые прерывания будут включены вместе с функциональными блоками.
Приступаем к функциям обмена данных
Первым шагом будет изучение регистров отвечающих за этот функционал:
В таблице имеется 9 регистров
Регистр управления доступа к интерфейсу памяти переменных DGUS RAMMODE = 0xF8;
sbit APP_REQ = RAMMODE^7; //1 — запрос занятия DGUS памяти для чтения/записи, должен быть сброшен при отсутствии занятия.
sbit APP_EN = RAMMODE^6; //1 — инициировать однократное чтение/запись, сбрасывается после выполнения аппаратно.
sbit APP_RW = RAMMODE^5; //1 — чтение переменной памяти, 0 — запись переменной памяти.
sbit APP_ACK = RAMMODE^4; //Ответ DGUS ядра на запрос 8051: 1 — OK, 0 — BUSY.
sfr ADR_H = 0xF1; //Старшие 8-бит адреса DGUS памяти (A23:A16).
sfr ADR_M = 0xF2; //Средние 8-бит адреса DGUS памяти (A15:A8).
sfr ADR_L = 0xF3; //Младшие 8-бит адреса DGUS памяти (A7:A0).
sfr ADR_INC = 0xF4; //Бит автоматического увеличения адреса после чтения/записи. Новый адрес = ADR_H:M:L + ADR_INC.
sfr DATA3 = 0xFA; //Считанный третий байт;
sfr DATA2 = 0xFB; //Считанный второй байт;
sfr DATA1 = 0xFC; //Считанный первый байт;
sfr DATA0 = 0xFD; //Считанный нулевой байт;
Память переменных DGUS использует собственную модель адресации и не совпадает с адресным пространством микроконтроллера C8051. Доступ к переменным осуществляется не по одному 16-битному слову, а блоками по 4 байта. Каждый такой блок содержит две 16-битные переменные с последовательными логическими адресами.
По этой причине логический адрес DGUS-переменной перед передачей в регистры `ADR_H/M/L` делится на два. В результате вычисляется адрес 4-байтного блока, в котором расположена требуемая переменная. После чтения блока выбор нужного 16-битного значения выполняется в зависимости от чётности исходного адреса: для чётных адресов используется первая половина блока, для нечётных — вторая.
Таким образом, деление адреса и раздельная обработка чётных и нечётных адресов обусловлены блочной организацией доступа к памяти DGUS, а не разрядностью самих переменных. Логическая адресация DGUS остаётся 16-битной, тогда как аппаратный интерфейс доступа оперирует 32-битными (4-байтными) блоками данных.
Описываем функцию считывания переменной DGUS:
Функция записи значения в переменную DGUS:
Функция пакетного считывания значений переменных DGUS:
Функция пакетной записи значений переменных DGUS:
Для проверки функционала сделаем функции считывания текущей страницы и переход на новую страницу.
Считывание текущей страницы:
Переход:
С файлами SYSTEM.c и SYSTEM.h закончили. Далее создаём файл APP.c, из него в main.c будет добавлена инициализация и процесс. файл main в своих проекта я оставляю минималистичным.
Всё что будет в файле main.c
Для удобства проверки в APP.c будут добавлены функции, которые пока что не описаны, чтобы не перегружать статьи. Это функции таймера и uart2, чтобы с ПК можно было считать и записать данные для проверки работы функций.
Uptime инкрементируется раз в секунду и раз в секунду будут переключаться страницы дисплея. Если дисплей считает с регистра страницу номер 1, то переключиться на страницу 0, а если считает 0, то на страницу 1. Если страница будет отличная от 1 и 0, то переключится на вторую.
Далее в DGUS формируем 3 страницы на которых написано: Page 0, Page 1 и Page 3.
Загружаем всё на uSD карту и проверяем работу UART 2:
Ответ есть, значит UART2 работает корректно.
На дисплее происходит выше описанный алгоритм, переключение страниц с 0 на 1 и обратно, любая другая страница заставляет оставаться на странице 2.
Далее разберем ADC и GPIO используя периферию платы.
Традиционно все исходники лежат на гите.
Вопрос к читателям, удобно смотреть в таком формате код? Или лучше текстом писать? Не могу понять как будет удобнее на дзене, код корректно выделять не даёт, возможно будет лучше дублировать на хабру?
Telegram Канал:
https://t.me/DWIN_LCD
Контакты для обратной связи:
Email: rvb@dwin-global.ru
VK: https://vk.com/radchenko_vb
Telegram: https://t.me/Radchenko_VB
Сообщество VK https://vk.com/public208909284
Русскоязычный сайт: https://dwin-global.ru/