Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: AT91SAM7SE, PIO и 8-bit параллельный интерфейс
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Artkop
Доброго времени суток! Необходимо соединить at91sam7se и дисплейный OLED модуль (контроллер SSD1305). Для этого надо написать софтверный протокол на PIO (8080 параллельный интерфейс). Разбираюсь.. Выяснил, что можно выставлять уровни ножек PIO (в моем случае PIOA) регистрами PIO_SODR и PIO_СODR. Но если делать это в программе, в ручную, то временные диаграммы получаются не пойми какими. Для синхронной записи используется PIO_ODSR, я правильно понимаю?

Делаю так:

//----------------------------------------------------------------------------------

volatile AT91PS_PIO pPIO = AT91C_BASE_PIOA;

volatile AT91PS_PMC pPMC = AT91C_BASE_PMC;
pPMC->PMC_PCER = (1<<AT91C_ID_PIOA);

pPIO->PIO_PER = AT91C_PIO_PA0 | AT91C_PIO_PA1 | AT91C_PIO_PA2 | AT91C_PIO_PA3 |
AT91C_PIO_PA4 | AT91C_PIO_PA5 | AT91C_PIO_PA6 | AT91C_PIO_PA7 |
AT91C_PIO_PA8 | AT91C_PIO_PA9 | AT91C_PIO_PA10 | AT91C_PIO_PA11 | AT91C_PIO_PA12 | AT91C_PIO_PA14 | AT91C_PIO_PA15;

pPIO->PIO_OER = AT91C_PIO_PA0 | AT91C_PIO_PA1 | AT91C_PIO_PA2 | AT91C_PIO_PA3 |
AT91C_PIO_PA4 | AT91C_PIO_PA5 | AT91C_PIO_PA6 | AT91C_PIO_PA7 |
AT91C_PIO_PA8 | AT91C_PIO_PA9 | AT91C_PIO_PA10 | AT91C_PIO_PA11 | AT91C_PIO_PA12 | AT91C_PIO_PA14 | AT91C_PIO_PA15;

pPIO->PIO_OWER = AT91C_PIO_PA0 | AT91C_PIO_PA1 | AT91C_PIO_PA2 | AT91C_PIO_PA3 |
AT91C_PIO_PA4 | AT91C_PIO_PA5 | AT91C_PIO_PA6 | AT91C_PIO_PA7;

pPIO->PIO_ODSR = 0xFF; //
pPIO->PIO_ODSR = 0x00; // Сформировал строб на 8битной шине

//------------------------------------------------------------------------------------------------------------------------------------

Но длительность импульса получилась 600 нс. Как ее уменьшить?
_dem
Нет.
Используйте SODR / CODR для установки / снятия уровня.

Во-вторых, SAM7, как и любой арм, дрыгает ногами весьма неохотно.
Посмотрите документацию на предмет синхронизации состояния PIO линий с тактовой частотой.
Artkop
Спасибо!
Буду смотреть.

Пока сделал так:

pPIO->PIO_CODR = 0x400;
pPIO->PIO_CODR = 0x1000;
pPIO->PIO_ODSR = 0xFF;
pPIO->PIO_ODSR = 0x00;
pPIO->PIO_SODR = 0x1000;
pPIO->PIO_SODR = 0x400;

CS (это который 0x1000) длительностью 2 мк сек получился...
Rst7
Цитата
Во-вторых, SAM7, как и любой арм, дрыгает ногами весьма неохотно.


Не так уж все и запущено именно на атмеловских армах. 3 такта на запись в порт (супротив двух при записи, например, в ОЗУ).

Тут решать надо по другому.
Код
#pragma optimize=no_inline
void Out8Bit(unsigned int d1, unsigned int d2, unsigned int d3, unsigned int d4)
{
pPIO->PIO_CODR = d1;
pPIO->PIO_CODR = d2;
pPIO->PIO_ODSR = d3;
pPIO->PIO_ODSR = d4;
pPIO->PIO_SODR = d2;
pPIO->PIO_SODR = d1;
}

и вызывать уже эту функцию, передавая ей в параметрах нужные биты.
Код
...
  Out8Bit(0x400,0x1000,0xFF,0x00);
...


Тогда будет достаточно быстро.
Genadi Zawidowski
volatile AT91PS_PIO pPIO = AT91C_BASE_PIOA;
volatile AT91PS_PMC pPMC = AT91C_BASE_PMC;

А зачем припсали выделенное ключевое слово? const ещё понимаю, а это-то зачем?

Тут в три такта не уложитесь никак... посмотрите что Вам нагенерировал компилятор.

У меня 62 наносекунды между соседними фронтами получалось (gcc, код для 32-бит ARM, из ОЗУ на 48 МГц, оптимизация -Os).
DmitryM
Хм, может не в теме, но зачем эмулировать паралельный интерфейс, если у SE серии есть EBI (8/16/32)
Почему просто через него не обращаться как к статической 8-разрядной памяти?
Artkop
DmitryM: Да, и правда можно! D[0..7], CS, Read и Write есть! Правда необходимо добавить еще 2 линии. Но эти линии (команда/данные и reset) можно и в ручную дергать.

Genadi Zawidowski: volatile используется для того, чтобы в обработчике прерываний изменять переменную. (я там запрещаю прерывание, типа такого (например для SPI) pSPI->SPI_IDR = AT91C_SPI_RDRF) Ну и компилятор не должен ее оптимизировать. Хотя вот написал это, а для PIOA никаких обработчиков еще нет, да и не будет наверное, и ничто параллельно выполнению основной задачи структуру PIO не изменит. И PMC я не правлю, только при включении и инициализации. Спасибо за наводки, будем думать!)
fantex
Цитата(Artkop @ Aug 21 2009, 09:44) *
DmitryM: Да, и правда можно! D[0..7], CS, Read и Write есть! Правда необходимо добавить еще 2 линии. Но эти линии (команда/данные и reset) можно и в ручную дергать.


Линию команда/данные можно завести на A0 и всё будет работать.
Genadi Zawidowski
Цитата(Artkop @ Aug 21 2009, 09:44) *
Ну и компилятор не должен ее оптимизировать.

Это и причина низкой скорости.

pSPI->SPI_IDR = AT91C_SPI_RDRF - в этом случае volatile у адреса не нужен, так как сами регистры периферии имеют такой атрибут:
typedef volatile unsigned int AT91_REG;

Вы же не переставляете в прерывани значение переменной pSPI - а именно у неё Вами добавлено volatile!
Artkop
Genadi Zawidowski: Без volatile (и соответственно с включенной оптимизацией по скорости) строб получился 100нс! В пять раз короче! (компилятор IARовский)
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.