Цель проекта: подключить ЖК-дисплей к 8051 в качестве внешнего устройства ввода-вывода с отображением памяти.
Проблема: Учитывая следующие детали, мой контроллер 8051 просто не генерирует внешнюю команду RD/WR, необходимую для работы остального кода.
Предыдущая работа: я использовал 3-контактный порт 8051 для генерации сигналов EN, R/W и RS и заставил его работать. Поэтому я знаю, что моя последовательность команд работает нормально. Однако это был действительно неэффективный способ использования ЖК-дисплея, потому что импульс включения генерировался путем установки и сброса вывода порта. Я хочу подключить ЖК-дисплей с помощью внешних сигналов WR/RD и отобразить его как устройство ввода-вывода с отображением памяти. Я проработал временные диаграммы, и общая блок-схема прилагается здесь. Как вы можете видеть (на блок-схеме), линия R/W ЖК-дисплея активируется с использованием старших 6 контактов порта 2, поэтому ЖК-дисплей активируется только по правильным адресам памяти. Эта операция (реализованная в SPLD) также служит для обеспечения требуемой задержки на ЖК-дисплее для обеспечения минимального времени настройки после того, как контакты 0,1 порта 2 используются для установки входов на сигналы R/W и RS ЖК-дисплея.
Дополнительная информация об оборудовании: я прикрепил диаграмму специй, чтобы показать, как подключена остальная часть моего 8051. Единственное, что там не включено, это: «Я использую кнопку мгновенного действия и подтягивающий резистор для / PSEN и удерживаю эту кнопку при выходе из сброса, чтобы принудительно запустить загрузчик; затем, после запуска загрузчика, Я отпускаю эту кнопку, чтобы устранить проблемы с дисками на линии /PSEN.Я использую заголовок/перемычку для входа /EA, чтобы обеспечить высокий уровень.Обратите внимание, что если вы используете эти аппаратные условия для входа в загрузчик при выходе из сброса , то загрузчик Atmel вводится вне зависимости от значений BLJB, BSB и SBV."
Используемое программное обеспечение: я использую paulmon2 для тестирования своего кода. Программирование осуществляется с помощью утилиты Flip: Flip 3.4.7 через последовательный порт. Программа последовательного эмулятора (TeraTerm) используется для связи с микроконтроллером. Микроконтроллер сначала выполняет код paulmon, а также его дополнительные команды, которые были запрограммированы в нем перед текущим кодом пользователя по адресу 0x2000. Дополнительная команда позволяет пользователю перейти к этому коду с помощью команды «J», а затем указать адрес памяти: 0x2000. Это вызывает текущую программу и выполняет ее. Здесь находится и выполняется мой код.
Адреса, используемые для отображения LCD, следующие:
LCD_INSTR_WR: 0xA8FF ---> Used to write commands to LCD controller.
This includes all initialization and setup and management commands.
LCD_INSTR_RD: 0xA9FF ---> Used to read command. Done only to read the busy
flag or the current address counter. This is valid only for a single
instruction on the LCD.
LCD_DATA_WR: 0xAAFF ---> Used to write Data to the current address which has
been set either in DDRAM or CGRAM given the LCD_INSTR_WR above.
LCD_DATA_RD: 0xABFF ----> Used to read Data from the current address which
has been set either in DDRAM or CGRAM given the LCD_INSTR_WR above.
Фрагмент кода, который я пишу на C для записи внешней памяти:
//Global variables
volatile unsigned char xdata *LCD_INSTR_WR = (char xdata *) 0xA8FF;
volatile unsigned char xdata *LCD_INSTR_RD = (char xdata *) 0xA9FF;
volatile unsigned char xdata *LCD_DATA_WR = (char xdata *) 0xAAFF;
volatile unsigned char xdata *LCD_DATA_RD = (char xdata *) 0xABFF;
/// More code
//Write command example
lcdbusywait();
* LCD_DATA_WR = cc;
Предыдущие тесты, чтобы выяснить проблему:
- Я попытался записать в ячейки памяти выше 2000, используя инструкции по редактированию памяти paulmon, и они хорошо записывают ячейки памяти. Как видно, в этом случае генерируется даже команда /WR (но я не правильно измерил/подсчитал доступы и изменения края /WR.
- Я использовал логический анализатор, чтобы убедиться, что адрес (и, следовательно, RS и RW) и данные (команда 0x30H в начале) поступают на порты, как и ожидалось. ALE генерируется.
- Я проверил, что бит регистра AUXR EXTRAM установлен (AUXR = 0x0E). Кроме того, поскольку EXTRAM установлен по умолчанию, я попытался полностью удалить свой код инициализации для AUXR, но это тоже не сработало.
- Я не был уверен, что код C, который я написал для доступа к адресам XRAM, верен. Тем не менее, я проверил файл .asm и (если только я не пренебрегаю чем-то очень мелким) сгенерированный ассемблерный код присваивает значение 0x30h в качестве непосредственных данных регистру A и использует инструкцию «MOVX @dptr,A» для записать это значение во внешнюю память.
Наконец, это мой первый пост на Stack Overflow, поэтому форматирование может быть отключено, и я понимаю, что это очень длинный пост. Извинения за это. Дайте мне знать, если вам нужно увидеть файлы кода или скомпилированный шестнадцатеричный файл или другие подробности. Вся ваша помощь очень ценится.