Не опять, а снова!

Меню навигации для мобильных

Последние сообщения

#1
Цифровая техника / Re: Светодиодные матрицы
Последний ответ от zenon - Вчера в 21:53
Случайно удалил свой пост.
Предделитель для 1Гц будет такой:
72000000/7200 = 10000Гц
Предзагрузка 10000.
Прерывание по переполнению счётчика:

↓ спойлер ↓
void TIM13_init(void){
  RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; // разрешить тактирование таймера
  TIM3->PSC = 7200 - 1; // предделитель
  TIM3->ARR = 10000 - 1; // предзагрузка
  TIM3->DIER |= TIM_DIER_UIE; // прерывания будем ловить по переполнению счетчика
  TIM3->CR1 |= TIM_CR1_CEN;
  NVIC_EnableIRQ(TIM3_IRQn);
}

void TIM3_IRQHandler (void) {
  if ((TIM3->SR & TIM_SR_UIF) == TIM_SR_UIF) { //  проверяем, что прерывание произошло по событию переполнения счетчика stm32f10x.h
    TIM3->SR &= ~TIM_SR_UIF; // флаг сбросить, иначе при выходе из обработчика прерываний мы тут же попадем туда снова
    LEDTOGGLE; // моргаем
  }
}
[свернуть]
---
Но, у нас ещё есть собственное прерывание на SPI: void SPI1_IRQHandler() :)
#2
Цифровая техника / Re: Светодиодные матрицы
Последний ответ от Slabovik - Вчера в 19:14
Это немного другая организация процесса, но в принципе подходит. Основной цикл крутит круги, в которых вызываются все процедуры. А процедуры уже смотрят, пора им или ещё нет. Тут проблема может быть в том, что вдруг возможен какой-то длительный процесс/процедура, а эта штука его прерывать не сможет. Прерывания помогают отделить процессы друг от друга.
#3
Цифровая техника / Re: Светодиодные матрицы
Последний ответ от zenon - Вчера в 18:38
Ну у меня же есть SySTick, он же подходит?, - зашли, проверили миллисекунды, - надо выполнили задачу, нет - вышли.
Можно и меньше 1 мсек его настроить.
#4
Неплохая подборка производителей.
Статья на Хабре: https://habr.com/ru/articles/808465/
#5
Цифровая техника / Re: Светодиодные матрицы
Последний ответ от Slabovik - Вчера в 12:12
Скорее пока буду смотреть на исходное изображение



Сигналы 'A' и 'B' - выбор строки. Фактически - это разряды двоичного числа в диапазоне 0-3 (A - разряд 0, B - разряд 1)
Несмотря на то, что строк на дисплее 16 длиной по 32 пикселя, электрически их только 4 длиной по 128 пикселей, что составляет 16 байт.

Электрически сигналы 'A' и 'B' не зависят ни от чего и могут меняться в любое время, однако для правильной работы индикатора устанавливать их надо непосредственно перед отображением новой строки.

Сигнал 'OE' (Output Enable) - включение отображения строки (или индикатора). Активный уровень - высокий. Может использоваться для управления яркостью индикатора при помощи ШИМ.

'R' - информационные биты, отображаемые строкой. Инвертированные: '0' - точка горит, '1' - точка погашена. Биты задвигаются в регистры строки в количестве, соответствующем физической длине строки (т.е. 128 бит или 16 байт для нашего случая).

'CKL' - строб (Clock, CLK и т.п.) для данных 'R'. Активный переход от низкого уровня к верхнему - в этот момент то, что было на 'R' попадёт в сдвиговый регистр строки. CKL - наверное опечатка

'SCLK' - строб для переноса накопленных в сдвиговом регистре данных на выход (он же Rdy, DataReady, Sync и т.п.) Активный переход от низкого уровня к верхнему
↓ спойлер ↓
тут могут быть нюансы т.к. микросхем с аналогичных функционалом много и бывает, что у некоторых типов на выходе использован не регистр-защёлка, а регистр хранения - у него при низком уровне сигнала данных на выходе 'хранятся', а при высоком он 'прозрачен', т.е. на его выходах ровно то же, что и на входах

Вот как-то было: https://anklab.ru/forum/index.php?msg=220
[свернуть]

Синонимы.
'A','B' = A0, A1, SA0, SA1...
'CLK' = Clk, Clock, BitLock, BitShift, Shift...
'SCLK' = Ready, Rdy, DataLock, DataReady...
'R' = Data, DataBit, DB...
'OE' = On...

Думаю, сейчас можно будет понимать, о чём речь при любом раскладе (я не всегда имею картинку перед глазами).

Самое главное. Как работать.
Развёртка индикатора должна быть весьма пунктуальна. Поэтому не обойтись без хардверной синхронизации от таймера. В самом простом случае, вывод на индикатор делается внутри прерывания от таймера - см. картинку. Это не очень хорошо т.к. последовательный вывод отнимает много времени, но для учебной цели пойдёт
↓ спойлер ↓
в более серьёзном проекте в прерывании от таймера необходимо делать только включение вывода новой строки (OE и RDY) и можно расчёт байт новой строки, а затем выход и запуск SPI со своими прерываниями - так не надо будет мудрить с вложенными прерываниями и не будет блокировки прерываний надолго (что и есть не очень хорошо)[/b] Ну а пока одно прерывание, SPI можно сделать софтверный
[свернуть]

Циклограмма-вывода-на-светодиодные-матрицы.png
картинка очень широкая, поэтому лучше правым кликом мыши...

В прерывании первое - опускаем OE
Второе - устанавливаем AB текущей строки
Третье - поднимаем RDY (SCLK)
Четвёртое - рассчитываем биты/байты следующей (!) строки, складываем в буфер (ОЗУ)

Пятое - опускаем RDY (SCLK), передаём  рассчитанные биты/байты следующей строки.
Выходим из прерывания.

Повторюсь - пятое не обязательно делать внутри прерывания по таймеру (лучше не делать). Если используется хардверный SPI, то подготовленный на четвёртом буфер должен быть доступен и процедуре обработки SPI, а пятый пункт заключается в запуске прерываний SPI, после чего выход из прерываний по таймеру.
По прерыванию от SPI смотрим на буфер и засовываем в SPI следующий из буфера байт. Если байта нету - останавливаем SPI.

Вот, нарисовал то, что я бы сам делал, будь у меня только проц и ни одной микросхемой более

Циклограмма-вывода-правильная.png

Такое построение позволяет не сидеть долго в прерывании, блокируя их (это моветон, почему - узнаете, когда жахнет).
2,5 мс между строками - это соответствует 100 Гц развертки на экране. Нормально, чтобы не обращать внимание на мерцания.

Лучше всего выделить ОЗУ, в которой формировалось бы изображение, выводимое на экран.
Изменять изображение программе разрешить только когда будут показаны все строки, например, формировать сигнал после вывода 4-й строки, запуская процедуру обновления. Иначе будут видны "перекосяки". Процедура обновит содержимое экранного ОЗУ и новый кадр пойдёт уже обновлённым.

Да, скорость SPI слишком задирать не надо. Например, при 1МГц вывод 128 бит будет всего по длительности ~0,13мс, так что времени довольно много. Другое дело, если экран будет большим, но там просто посчитать.

Надо будет оценить (тем же осциллограформ), сколько по времени займёт исполнение прерывания от таймера, но не думаю, что много. Особенно, если изображение уже в "экранной" области ОЗУ, то оно уже готово, надо только выбрать нужную строчку. Если выводить из памяти программ, то там конечно дольше выходит т.к. каждый раз каждую строчку считать по-новой. Это непроизводительно.

А, да. RDY, OE, AB сделать программно управляемыми (ногодрыг). Data, CLK - хардверными, пусть блок SPI ими дрыгает. По циклограмме вроде понятно, в каком порядке всем этим дрыгать. AB если назначить на биты 0 и 1 какого-нибудь порта, будет проще их туда выгонять (хотя...)
#6
Цифровая техника / Re: Светодиодные матрицы
Последний ответ от zenon - Вчера в 00:25
Давай называть пины так, как я их задефайнил, а то запутаемся.
nOE, PinA, PinB, SCLK - ногодрыг и SPI ноги - CLK, MOSI (PA5/PA7).
У F103 камня управление третьей ногой SS аппаратное реализовано как-то не верно, никто им не пользуется, только две ноги хардварного SPI у всех, не вдавался в подробности почему.
В принципе и у F0 делал также.
#7
Цифровая техника / Re: Светодиодные матрицы
Последний ответ от Slabovik - 01 Май, 2024, 23:02
nOE... я забыл про него.
RDY - это не оно. Это строб, по фронту которого происходит перезапись данных из регистра сдвига в выходной регистр.
Тогда да, nOE пусть остаётся как есть. Потому что выход надо "погасить" перед подъёмом RDY и "зажечь" после выставления строки AB.

Гм, оборванный вывод? Это вполне проблема, да... Жаль, что у STM даташиты такие разбросанные. Не случилось ли какой рестрикции из-за конфигов. Но это читать много надо, так не помню, практиковался совсем мало  :-\

Ну трындец какой-то. Я тутпро RDY вещаю, а на входе матрицы этой фигни нет. В общем, RDY - это ST на микросхемах, формируется как-то автоматом. Давай я завтра, как время будет, возьму и на основе уже этой схемы нарисую циклограммы, как там вообще должно быть. А то я по памяти всё, и... промахиваюсь...

и,да... OE по схеме не задействован, так что совсем печалька...
#8
Цифровая техника / Re: Светодиодные матрицы
Последний ответ от zenon - 01 Май, 2024, 22:36
RDY это nOE? Который шимить можно?
Тут понял что у меня происходит, PA15, я его и так и эдак - не вижу, как был высоким так и остаётся высоким....
... ну и перекиул сначала на PA6, - и сразу увидел его анализатором, завёл на enable, вижу оба состояния.
перекинул инит на PB15, чтобы себя проверить, не напутал ли я что-то с кодом, нет всё ок, рабодает.
В что с PA15 не пойму, те же манипуляции с ним - не реагирует никак, козы на плате нет, до своей ноги звонится.
Может и до этого была проблема из-за него.
#9
Цифровая техника / Re: Светодиодные матрицы
Последний ответ от Slabovik - 01 Май, 2024, 21:30
При инициализации устанавливаем RDY (OE? не помню, как там на картинке) в 1, Clk тоже в 1

При передаче
1. Опускаем RDY
2. запускаем SPI (для одной строки 32x16 надо передать (32/8)*(16/4)=16 байт. Если передать меньше, то строка не обновится полностью - переданное ранее просто сместится далее по регистрам. Байты можно придумать разные, хоть 1-2-3-4-5...
3.a Поднимаем RDY
3.б Выставляем строку AB

Эти два действия надо сделать с минимальным интервалом времени, причём порядок даже не важен. Если разнести во времени, то между этими действиями выведенные данные  светятся на "чужой" строке, а это нам сейчас не надо (можно загонять конечно между делом 16 нулей, либо "жать резет", но это не сейчас).

Далее перво-наперво, посмотри осциллографом, как выглядит Clk.
Далее можно зацепить каналы на Rdy и Data. Синхронизацию на Rdy прицепить по спаду - на экране будет начало посылки. Прицепить по подъёму - будет конец посылки. Ну там разберёшься...
#10
Цифровая техника / Re: Светодиодные матрицы
Последний ответ от zenon - 01 Май, 2024, 20:57
Да, вероятно скорость выше, анализатор обычный на стм-ке 24МГц может максимум.
---
У меня таки оно ожило, но пока не так как надо, потому что метод не тот, ну и передаю я всего одну посылку 8-бит, а надо 16.
Сейчас над распутать алгоритм передачи.
Из вышеупомянутой ссылки он такой:
Цитата1. Выдаём по SPI данные для сдвиговых регистров.
2. Устанавливаем лог. 0 на ножке nOE.
3. Устанавливаем лог. уровни на ножках A и B в соответствии с обновляемой группой светодиодов (одной из четырёх).
4. Выдаём на ножку SCLK короткий положительный импульс.
5. Устанавливаем лог. 1 на ножке nOE.
Для переключения PinA-PinB сделал функцию:
void PINAB_change(uint8_t col){
  switch (col) {
    case 0: {PinA0; PinA0;};
    case 1: {PinA0; PinA1;};
    case 2: {PinA1; PinA0;};
    case 3: {PinA1; PinA1;};
  }
}

дальше вопрос в SPI, настроил на 8-ми битный режим, main такой:
do {
  uint8_t _data = 0; // то, что запишем в SPI
  for (col = 0; col < 4; col++) {
    SPI1_send(_data); // 1. передаём данные
    nOE0; // 2. Устанавливаем лог. 0 на ножке nOE
    PINAB_change(col); //  лог. уровни на ножках A и B
    SCLK1; // 3. выдаём на ножку SCLK короткий положительный импульс
    dummy_loop(10);
    SCLK0;
    nOE1;
  }
  delay_ms(10);
  } while (1);
}
Результат происходящего:
https://youtu.be/fBkpjaoDfQo

:: добавлено 01 Май, 2024, 20:07
ы. Да, без RDY (MISO) каша, надо попробовать третий провод и нормально посмотреть.