8051 Внешний сигнал /WR не генерируется при использовании загрузчика UART после сброса

Цель проекта: подключить ЖК-дисплей к 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;

Предыдущие тесты, чтобы выяснить проблему:

  1. Я попытался записать в ячейки памяти выше 2000, используя инструкции по редактированию памяти paulmon, и они хорошо записывают ячейки памяти. Как видно, в этом случае генерируется даже команда /WR (но я не правильно измерил/подсчитал доступы и изменения края /WR.
  2. Я использовал логический анализатор, чтобы убедиться, что адрес (и, следовательно, RS и RW) и данные (команда 0x30H в начале) поступают на порты, как и ожидалось. ALE генерируется.
  3. Я проверил, что бит регистра AUXR EXTRAM установлен (AUXR = 0x0E). Кроме того, поскольку EXTRAM установлен по умолчанию, я попытался полностью удалить свой код инициализации для AUXR, но это тоже не сработало.
  4. Я не был уверен, что код C, который я написал для доступа к адресам XRAM, верен. Тем не менее, я проверил файл .asm и (если только я не пренебрегаю чем-то очень мелким) сгенерированный ассемблерный код присваивает значение 0x30h в качестве непосредственных данных регистру A и использует инструкцию «MOVX @dptr,A» для записать это значение во внешнюю память.

Наконец, это мой первый пост на Stack Overflow, поэтому форматирование может быть отключено, и я понимаю, что это очень длинный пост. Извинения за это. Дайте мне знать, если вам нужно увидеть файлы кода или скомпилированный шестнадцатеричный файл или другие подробности. Вся ваша помощь очень ценится.


person Farah    schedule 13.11.2017    source источник
comment
Доступно много вариантов Atmel 8051, какой из них вы используете? Некоторые из них поставляются с внутренней XRAM.   -  person Turbo J    schedule 19.11.2017
comment
@TurboJ Я использую AT89C51. Приносим извинения за поздний ответ. Мне удалось заставить работать сигналы /WR, /RD. Я считаю, что ранее проблема была связана с тем, как я инициализировал регистр AUXR. Мое начальное значение было немного отключено, и я этого не осознавал.   -  person Farah    schedule 26.11.2017


Ответы (1)


volatile unsigned char xdata *LCD_INSTR_WR = (char xdata *) 0xA8FF;

Я предполагаю, что LCD_INSTR_WR должно иметь значение address0xA8FF.

Вы можете попробовать, используя

#define LCD_INSTR_WR  XBYTE[0xA8FF]

а потом

LCD_INSTR_WR  = cc;

or

char xdata LCD_INSTR_WR  _at_ 0xA8FF;  //This will declare the LCD_INSTR_WR at location 0xA8FF-

Возможно, вам придется заглянуть в техпаспорт микроконтроллера, как настроить внешнюю память.

LCD_INSTR_WR = cc;
person Sudhee    schedule 04.12.2017
comment
Спасибо за ответ, Судхи. Как я уже говорил ранее, мне пришлось переделывать весь код, добавляя одну за другой функции для отладки. В конце концов, проблема оказалась в том, как я инициализировал свой регистр AUXR. Проблему было трудно отследить, потому что я почти исчерпал свое внутреннее использование ОЗУ, а указатель неправильно обращался. Короче говоря, это не было связано с указателями, на которые вы ссылаетесь в своем комментарии. Еще раз спасибо за ваше время и помощь. - person Farah; 09.12.2017