afz писал(а):Так, что спокойно переносим выдачу через SPI в прерывания, свободная сотня тактов на любые действия останется. То есть сотню или чуть больше тактов занимаемся своими делами, 20-30 тактов тратим на прерывание от SPI и связанные с ним дела.
Да, но при таком подходе всё равно нужен какой-то буфер в ОЗУ, из которого "параллельный поток кода" на базе прерываний будет брать очередной байт для записи в дисплей, в идеале - те же 1КиБ на хранение всего кадра.
Поэтому такой подход, равно как и мой, относительно равнозначны. Разница в том, что у меня - максимально быстрый обмен (по SPI, либо параллельный режим - не так важно), а необходимые 50мкс обеспечены прерыванием от таймера, а у Вас - более медленный аппаратный SPI, обеспечивающий те же 50мкс уже своим прерыванием.
Но опять же, без некоего буфера оба эти подхода не имеют смысла.
afz писал(а):Я сравнил этот подход со своим. Как я понимаю, вся разница в том, что у меня прерывания получаются втрое чаще - с параллельным интерфейсом байт передается за один прием, а в последовательной передаче - в три приема, для программы на Си это, скорее всего, существенно. Зато проводов меньше...
Ну так-то да. Но я не заморачивался с SPI, поскольку проект поддерживает ещё и KS0108 (да и начинался с него). Поэтому смысла городить SPI не было, т.к. всё равно ноги D0-D7 заняты дисплеем, а параллельный интерфейс всё же максимально быстрый.
Кстати, вполне можно Ваш подход и мой совместить. Идея следующая:
а) Раз в 50 мкс таймер вырабатывает прерывание - как у меня и было.
б) По прерыванию от этого таймера у меня в параллельном режиме в это время берётся очередной байт (данных или команды - не важно) и пишется (стробируется) в дисплей. В случае SPI нужно по прерыванию от таймера этот байт просто разложить на три части, включить прерывание SPI и стартовать передачу по SPI первой части
по прерыванию SPI стартовать передачу второй части
по прерыванию SPI стартовать выключить прерывание SPI и начать передачу последней трети
Если SPI настроить на максимальную частоту (8МГц при 16МГц), получится, вся передача по SPI займёт около 5мкс (3мкс на три байта плюс небольшие накладные расходы на обработку прерывания), остальные 45мкс контроллер будет делать полезную работу. Да и между прерываниям SPI будет ещё некоторое "полезное" время. То есть, выглядеть это во времени будет как-то так:
Код: Выделить всё
___|Thh__Shh__Shh________~_______|Thh__Shh__Shh________~_______|Thh__Shh__Shh________
| 5us | 45us | 5us | 45us | 5us |
(здесь T,S - прерывания от таймера и SPI, hh - время нахождения в обработчиках прерывания, ___ - полезная работа контроллера. ~ - просто "разрыв" временной шкалы)
В принципе, можно особо и не заморачиваться, и делать по-вашему:
Код: Выделить всё
___|Shh____________Shh____________Shh___________|Shh____________Shh____________Shh___________|Shh____________Shh____
| 17us | 17us | 17us | 17us | 17us | 17us | 17us |
, но не забывать отслеживать, какую именно треть данных сейчас передаём, и когда переходить к следующей (у меня это однозначно определяется таймером)
shads писал(а):Как я понял - это KS0108? или все таки ST7920? просто обычно у ST7920 - экран синий...
Это именно
ST7920.