Ruslan-maniak 0 14 мая, 2017 Опубликовано 14 мая, 2017 (изменено) · Жалоба Приветствую, коллеги. Пытаюсь реализовать на STM32F103 поддержку RGB интерфейса (DATA[24], DataCLK, VSYNC, HSYNC, DataEN) для передачи изображения на матрицу матрицу hsd050idw1-a20. Изображение нужно только черно-белое (не градиент, а именно только черное и только белое), поэтому пытаюсь сделать аналогично данной статье. Также использую SPI для формирования сигналов DATA[24] и DataCLK. Остальные сигналы реализуются просто на GPIO. Длительность этапов отправки данных формируются размером ДМА. То есть сформировал сигналы задал размер дма и запустил его, в прерывании завершения отправки дма переключаю сигналы в новое положение, задаю новый размер дма и запускаю отправку. и т.д. Естественно при каждом таком переходе образуется небольшая пауза в тактировании DataCLK. Собственно код прерывания дма следующий : void LcdSpiHandler (void) { while(SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_TXE) == RESET); while(SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_BSY) == SET); switch(lcd->vState) { case(eLcdState_PULSE): { switch(lcd->hState) { case(eLcdState_PULSE): { GPIOSet(lcd->gpioHSync); lcd->hState = eLcdState_BACK_PORCH; DMASetCurrDataCounter(5, lcd->spi->dmaTx); DMACmd(ENABLE, lcd->spi->dmaTx); break; } case(eLcdState_BACK_PORCH): { lcd->hState = eLcdState_DATA; DMASetCurrDataCounter(100, lcd->spi->dmaTx); DMACmd(ENABLE, lcd->spi->dmaTx); break; } case(eLcdState_DATA): { lcd->hState = eLcdState_FRONT_PORCH; DMASetCurrDataCounter(5, lcd->spi->dmaTx); DMACmd(ENABLE, lcd->spi->dmaTx); break; } case(eLcdState_FRONT_PORCH): { if(lcd->hNumber == 2) { GPIOSet(lcd->gpioVSync); GPIOReset(lcd->gpioHSync); lcd->vState = eLcdState_BACK_PORCH; lcd->hState = eLcdState_PULSE; lcd->hNumber = 0; DMASetCurrDataCounter(6, lcd->spi->dmaTx); DMACmd(ENABLE, lcd->spi->dmaTx); } else { GPIOReset(lcd->gpioHSync); lcd->hNumber++; DMASetCurrDataCounter(6, lcd->spi->dmaTx); lcd->hState = eLcdState_PULSE; DMACmd(ENABLE, lcd->spi->dmaTx); } break; } } break; } case(eLcdState_BACK_PORCH): { switch(lcd->hState) { case(eLcdState_PULSE): { GPIOSet(lcd->gpioHSync); lcd->hState = eLcdState_BACK_PORCH; DMASetCurrDataCounter(5, lcd->spi->dmaTx); DMACmd(ENABLE, lcd->spi->dmaTx); break; } case(eLcdState_BACK_PORCH): { lcd->hState = eLcdState_DATA; DMASetCurrDataCounter(100, lcd->spi->dmaTx); DMACmd(ENABLE, lcd->spi->dmaTx); break; } case(eLcdState_DATA): { lcd->hState = eLcdState_FRONT_PORCH; DMASetCurrDataCounter(5, lcd->spi->dmaTx); DMACmd(ENABLE, lcd->spi->dmaTx); break; } case(eLcdState_FRONT_PORCH): { if(lcd->hNumber == 28) { GPIOReset(lcd->gpioHSync); lcd->vState = eLcdState_DATA; lcd->hState = eLcdState_PULSE; lcd->hNumber = 0; DMASetCurrDataCounter(6, lcd->spi->dmaTx); DMACmd(ENABLE, lcd->spi->dmaTx); } else { GPIOReset(lcd->gpioHSync); lcd->hNumber++; DMASetCurrDataCounter(6, lcd->spi->dmaTx); lcd->hState = eLcdState_PULSE; DMACmd(ENABLE, lcd->spi->dmaTx); } break; } } break; } case(eLcdState_DATA): { switch(lcd->hState) { case(eLcdState_PULSE): { GPIOSet(lcd->gpioHSync); lcd->hState = eLcdState_BACK_PORCH; DMASetCurrDataCounter(5, lcd->spi->dmaTx); DMACmd(ENABLE, lcd->spi->dmaTx); break; } case(eLcdState_BACK_PORCH): { GPIOSet(lcd->gpioDe); lcd->hState = eLcdState_DATA; DMASetCurrDataCounter(100, lcd->spi->dmaTx); DMACmd(ENABLE, lcd->spi->dmaTx); break; } case(eLcdState_DATA): { GPIOReset(lcd->gpioDe); lcd->hState = eLcdState_FRONT_PORCH; DMASetCurrDataCounter(5, lcd->spi->dmaTx); DMACmd(ENABLE, lcd->spi->dmaTx); break; } case(eLcdState_FRONT_PORCH): { if(lcd->hNumber == 479) { GPIOReset(lcd->gpioHSync); lcd->vState = eLcdState_FRONT_PORCH; lcd->hState = eLcdState_PULSE; lcd->hNumber = 0; DMASetCurrDataCounter(6, lcd->spi->dmaTx); DMACmd(ENABLE, lcd->spi->dmaTx); } else { GPIOReset(lcd->gpioHSync); lcd->hNumber++; DMASetCurrDataCounter(6, lcd->spi->dmaTx); lcd->hState = eLcdState_PULSE; DMACmd(ENABLE, lcd->spi->dmaTx); } break; } } break; } case(eLcdState_FRONT_PORCH): { switch(lcd->hState) { case(eLcdState_PULSE): { GPIOSet(lcd->gpioHSync); lcd->hState = eLcdState_BACK_PORCH; DMASetCurrDataCounter(5, lcd->spi->dmaTx); DMACmd(ENABLE, lcd->spi->dmaTx); break; } case(eLcdState_BACK_PORCH): { lcd->hState = eLcdState_DATA; DMASetCurrDataCounter(100, lcd->spi->dmaTx); DMACmd(ENABLE, lcd->spi->dmaTx); break; } case(eLcdState_DATA): { lcd->hState = eLcdState_FRONT_PORCH; DMASetCurrDataCounter(5, lcd->spi->dmaTx); DMACmd(ENABLE, lcd->spi->dmaTx); break; } case(eLcdState_FRONT_PORCH): { if(lcd->hNumber == 12) { GPIOReset(lcd->gpioVSync); GPIOReset(lcd->gpioHSync); lcd->vState = eLcdState_PULSE; lcd->hState = eLcdState_PULSE; lcd->hNumber = 0; DMASetCurrDataCounter(6, lcd->spi->dmaTx); DMACmd(ENABLE, lcd->spi->dmaTx); } else { GPIOReset(lcd->gpioHSync); lcd->hNumber++; DMASetCurrDataCounter(6, lcd->spi->dmaTx); lcd->hState = eLcdState_PULSE; DMACmd(ENABLE, lcd->spi->dmaTx); } break; } } break; } } } Но к сожалению так оно не взлетает. может есть способ как-то поумнее управлять сигналами управления, а не просто переключать в прерывании. К сожалению в вышеприведенной статье об этом не упоминается. Подскажите кто что думает. Изменено 14 мая, 2017 пользователем IgorKossak [codebox] для длинного кода, [code] - для короткого! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Eddy_Em 1 14 мая, 2017 Опубликовано 14 мая, 2017 (изменено) · Жалоба А если FSMC использовать? Или на крайняк ногодрыг через DMA? И да, для начала попробуйте просто повыкидывать все библиотечные функции из тела обработчика прерывания. Переключайте напрямую регистрами. Я с этой проблемой столкнулся, когда 1-wire делал. Если вызывать функции (я тогда opencm3 пользовался), то получались заметные выбросы, а если делать по-человечески, все было четко. Изменено 14 мая, 2017 пользователем Эдди Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ruslan-maniak 0 15 мая, 2017 Опубликовано 15 мая, 2017 · Жалоба И да, для начала попробуйте просто повыкидывать все библиотечные функции из тела обработчика прерывания. Переключайте напрямую регистрами. Переход на работу с регистрами к сожалению не исправил положение. FSMC тоже вряд ли поможет, там ведь также придется отдельно работать с сигналами управления. Остается попробовать ногодрыг через дма. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ruslan-maniak 0 15 мая, 2017 Опубликовано 15 мая, 2017 · Жалоба А может кто-нибудь поделиться примером ногодрыга из дма по таймеру? Адекватных работающих примеров я не нагуглил. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ruslan-maniak 0 16 мая, 2017 Опубликовано 16 мая, 2017 (изменено) · Жалоба Соорудил все на ногодрыге из дма по таймеру. Но все равно матрица ничего не выдает. Такое ощущение что она вообще не воспринимает сигналы с стм. То есть без разницы включаю я питание и подаю сигналы или просто включаю питание логики без сигналов - реакция матрицы идентична: появляются некоторые вертикальные цветные линии. К сожалению нет под рукой логического анализатора, но то что можно увидеть по осцилографу - все как по даташиту матрицы. Изменено 16 мая, 2017 пользователем Ruslan-maniak Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 16 мая, 2017 Опубликовано 16 мая, 2017 · Жалоба В коде из первого сообщения неверная полярность DE - он должен быть в '1' при активных данных. HS и VS вообще не нужны, работайте в DE-mode. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ruslan-maniak 0 17 мая, 2017 Опубликовано 17 мая, 2017 (изменено) · Жалоба В коде из первого сообщения неверная полярность DE - он должен быть в '1' при активных данных. HS и VS вообще не нужны, работайте в DE-mode. В коде с полярностью все верно. По DE подается именно '1' когда передаются данные. Спасибо что натолкнули на DE mode. Не знал про него. Только в даташите на матрицу не указаны параметры для реализации этого режима. Изменено 17 мая, 2017 пользователем Ruslan-maniak Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 17 мая, 2017 Опубликовано 17 мая, 2017 · Жалоба Только в даташите на матрицу не указаны параметры для реализации этого режима. Переведите HS и VS в третье стостояние, а DE управляйте как обычно - это и будет DE-mode. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ruslan-maniak 0 17 мая, 2017 Опубликовано 17 мая, 2017 · Жалоба Переведите HS и VS в третье стостояние, а DE управляйте как обычно - это и будет DE-mode. Третье состояние - это оставить в воздухе? Все так и сделал. Глянул осцилом - все как надо. Но все равно результат не изменился. Надо искать логический анализатор. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ruslan-maniak 0 17 мая, 2017 Опубликовано 17 мая, 2017 · Жалоба Оказалось что сигнал клока не заходил в шлейф. Исправил. Теперь в DE mode все работает как надо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться