-
Постов
204 -
Зарегистрирован
-
Посещение
Весь контент AlanDrakes
-
Наталкивался на похожее поведение, когда память не успевала считывать данные из себя при слишком быстром тактировании ядра. Проверьте, что латентность Flash'а соответствует скорости ядра.
-
Push-Pull. На ведомых устройствах это всегда вход, так что можно не бояться выставлять на нём любой логический уровень. Если вниз (5 -> 3.3) - резисторный делитель 1к/2к Если вверх (3.3 -> 5) - Mosfet (тот же N7002) и пара резисторов. Эпизодически, когда лень заморачиваться с количеством резисторов, ставлю с инверсией: В особо замороченых случаях, когда требуется сделать более "силовой" плюс - ставлю пару N + P. N-канальный тянет затвор P-канального к нулю, P-канальный подключает сток к питанию. Из минусов - требуется резистор подтяжка уже для P-канального.
-
STM32F103..., SPI передача через DMA, проблема с CS
AlanDrakes ответил auric тема в STM
На F103 успешно работает вот такая конструкция ожидания завершения передачи последнего* байта: *(volatile uint8_t *)&(SPI2->DR) = Data; // Складываем байт while (!(SPI2->SR & SPI_SR_TXE)); // Ждём, пока не станет "Свободно" в буфере передатчика (иначе можно проскочить) while (SPI2->SR & SPI_SR_BSY); // Только после этого дожидаемся снятия флага "ЗАНЯТО, Л-Л-ЛЯ!" После этого данные гарантированно переданы и можно поднимать ножку. С DMA - можно использовать те же проверки, предварительно отключив сам DMA канал. -
ST-LINK/V2 ISOL делает мОзги
AlanDrakes ответил LAS9891 тема в STM
Из простейшего (так как отображает, что чип видит): 1. Попробуйте снизить частоту тактирования до 1МГц (возможно слишком длинные провода, или что-то ещё в схеме) и слишком высокая скорость обмена его в итоге и ломает. 2. Попробуйте поменять опции подключения к чипу: Connect -> Under reset / With Pre-reset (должен быть подключен пин сброса). Reset -> Hardware reset. В некоторых случаях желательно подтягивать пин сброса чипа к напряжению питания (3.3В) дополнительным резистором на 1-4кОм. Пин VTarget желательно подключать. От него питаются выходные шинные буферы (в варианте STLink'а на Discovery - нет, но там напряжение должно быть близким, иначе тоже возникают разные интересные сбои). -
А ещё можно вызывать __INLINE__ функции. И даже функции описывать так же. Да в конце концов! static inline __attribute__((always_inline)) void stop(void) { PORTD &=~(1<<PIND7); PORTB &= ~(1<<PINB0); } И вызывать в коде "stop();". В результате на место вызова функици будет вставлено её развёрнутое тело - обе операции с портами.
-
Макрос пытается выполнить два действия с портами? Может в этом случае изменить его на однострочный? #define stop PORTD &=~(1<<PIND7); PORTB &= ~(1<<PINB0) В таком случае будет производиться подстановка, условно, двух команд. А та конструкция должна вызывать у компилятора вопрос "Тут же всегда будет TRUE. Оптимизировать, что ли?"
-
Кнопка "Изменить" внизу сообщения. А с ассемблером внутри ОС - довольно сложно. Если мне не изменяет память, то можно выделить переменные статически (внутри программы) через db - посмотрите хотя бы здесь. Либо же использовать вызовы ОС, в частности malloc / free для работы с виртуальной памятью. Либо же собирать bare-metal приложение, без всех возможностей ОС. Я так пытаюсь лениво подступиться к одному китайскому SoC кристаллу.
-
Работать с локальными переменными на ассемблере - та ещё морока. А в среде операционной системы - так вообще. Самое простое объяснение - память, которую видит программа (адресное пространство) никак не связана с реальным адресным пространством, потому что MMU в уже запущеной ОС работает с таблицами адресов (в простейшем случае) и при обращении к памяти по адресу 0xDEADBEEF (допустим), в начале идёт поиск по таблицам адресов, затем выбирается блок памяти, на который диапазон ссылается, после чего идёт попытка обращения к этой памяти (например получилась страница в 4к по адресам 0xFOODC000 ~ 0xFOODCFFF). Вам... действительно нужен ассемблер? Проще же написать программу на Си под малинку. Компилятор сделает большую часть работы за вас. Лично я ассемблером наигрался на AVR'ках. Больше не хочется писать ВЕСЬ код на нём.
-
У меня имеется подозрение, что писать в адрес 0x100 не удаётся и именно это вызывает исключение.
-
В базе знаний описан процесс запуска контроллера и подготовки его к шифрованию. https://docs.espressif.com/projects/esp-idf/en/latest/esp32/security/flash-encryption.html В общем случае контроллер может работать в трёх режимах - обычный (flash не зашифрован), комплект разработчика (во flash записывается расшифрованная прошивка, которую после шифрует загрузчик) и release - готовое устройство. Прошивка на внешней флешке должна быть зашифрована (либо в устройстве). Зашить во FUSE блок ключ можно с помщью команды: espefuse.py --port port burn_key flash_encryption abc/key.bin Проверить состояние: espefuse.py --port port summary Если ключ в области FUSE забит вопросами: значит ключ есть и после перезагрузки содержимое внешней флешки будет зашифровано. Ну и процесс обновления по воздуху описан там же
-
CC = c99
AlanDrakes ответил addi II тема в Программирование
c99 - это стандарт. Компилятор, как правило, gcc В зависимости от архитектуры может быть с преффиксами, а может быть дефолтным. В моём случае, c99 находится в /usr/bin/c99, является алиасом на /etc/alternatives/c99, который является bash-скриптом, запускающим gcc с ключом -std=c99 Сделайте sudo apt-get install gcc -
ChaN пишет, что в самой FAT прописывается размер сектора и Windows* системы его поддерживают, но некоторые драйверы используют зашитое значение в 512. http://elm-chan.org/docs/fat_e.html А тут пробуют отформатировать обычную карту памяти под сектор с размером 4к. Вроди бы даже успешно. Но имеются ограничения - минимальное количество кластеров для файловой системы. https://askubuntu.com/questions/983546/trying-to-format-a-64gb-microsdxc-card-with-4096-bytes-per-sector Плюс, дескрипторы USB - нужно сообщать, что размер сектора не 512 байт, а 4к. Но вам это виднее - я только пару раз прикрутил пример от ST к проекту и оно даже заработало... как-то. Ужасно медленно и в режиме только чтения. И естественно, на 512-байтных секторах.
-
Для одного проекта наваял простенький самописный загрузчик, прикрутил к нему UART и x-modem, чтобы каждый раз не разбирать устройство и не обновлять прошивку программатором. В какой-то момент, обновляя прошивку, случайно указал .elf файл вместо .bin и заметил это только когда залилось уже 190кБ из 96 😕 В общем, счётчик страниц на STM32F103C8T6 успешно крутанулся и записал в загрузчик мусор. Хотя вроди бы всё проверял перед записью. Оказалось, что нет. Так что от ошибок программиста никто не застрахован. И самое печальное, когда от своих ошибок не застрахован.
-
SPI нужно ли выравнивание длины?
AlanDrakes ответил catBasilio тема в Интерфейсы
Упс. А слово-то я перепутал, да 😞 На тех кристаллах, с которыми я имел дело, обычно интерфейс выведен плотненько в 4 пина. Так почему бы не вести их рядом? А потом на месте перекинуть как требуется для другого чипа. =] -
SPI нужно ли выравнивание длины?
AlanDrakes ответил catBasilio тема в Интерфейсы
На однослойке проблемно. На двух слоях ещё можно. Просто все 4 дорожки вести группой, и уже по месту как-то менять их положение (перекидывать через резисторы-перемычки, например). -
SPI нужно ли выравнивание длины?
AlanDrakes ответил catBasilio тема в Интерфейсы
Это не те частоты, на которых нужно заморачиваться ТАКОЙ магией. С дорожками до 10 см и разнице длин до 2-3 см это будет работать и так. Выравнивание нужно для синфазных пар. Но хорошим тоном будет вести дорожки рядом. -
STM32F427VG FMC 16 bit LCD ST7796 проблемы с чтением
AlanDrakes ответил Mysteo тема в STM
TE - Tearing Effect - специальный пин, который взводится в 1 в тот момент, когда контроллер дисплея обновляет на матрице определённую строку. Ищите по даташиту соответствующий регистр. Возможно по "Tearing line" или похожему сочетанию. Используется для синхронизации вывода изображения из контроллера в память экрана для устранения эффекта полукадра. Регистр 0x44 - STE (Set Tear ScanLine ) - устанавливает линию, на которой будет генерироваться прерывание. Про эффект разрыва - смотрите пункт 10.8.3 Example 1: MPU Write is faster than panel read. В даташите, который имеется у меня, изображение-пример с данными кадра относится к 10.8.4 Example 2: MPU write is slower than panel read Не с именно этим контроллером, но похожую ситуацию ловил на ILI9341 Лично мне пришлось немного ухудшать тайминги работы с дисплеем перед чтением. Попробуйте вот такой код: -
stm32l0 отдельные старт, передача данных и стоп в i2c
AlanDrakes ответил Mark16 тема в STM
Вы правы, я что-то не те функции взял. И, да. У 401 как раз старый блок I2C. Но фукнкции таки работают. Исправлюсь. Тут проект был меньше и в основном читает данные с датчиков. Собирается как раз под L051. I2C_ReadArray - читает как есть - это работает с AHT10. ИМХО - забавный датчик. Отправляем команду через запись трёх байт, ждём, читаем тупо массивом. I2C_ReadArray_from8 - аналогично EEPROM'у. Уже нормально работает с BMP(BME)280. Вычитывает массив, начиная с адреса [Addr] и складывает в память. ЗЫ: Вообще не люблю шину I2C. Кроме экономии проводов даёт только проблемы. То после подачи питания контроллер слишком быстро начинает работу с шиной (а некоторые хитро вы.... сделанные микросхемы ещё не очухались), то какой-то чип воспринял переходный процесс как START, то ещё что... Уууууу. То подтяжки слабые, то подтяжки сильные... И гнать шину нельзя. Хотя пара MAX17043 + M24C02 на шине пока что уживаются хорошо. -
STM32 нужна помощь с кнопками
AlanDrakes ответил MaximDV тема в ARM, 32bit
Резистор-подтяжка какого номинала? Я бы выбрал около 1к, исходя из ваших замеров. Получаем: Кнопки отпущены - цепь разомкнута: Vadc = 3.3V (если питается от 3.3V). Нажата кнопка 1 [3к]: Получаем делитель напряжения 1:3; Vadc ~= 0.75*3.3V ~= 2.475V. [центральное] Нажата кнопка 2 [1k]: Получаем делитель напряжения 1:1; Vadc ~= 0.5*3.3V ~= 1.65V. [центральное] Нажаты кнопки 1+2 [3k || 1k]: Получаем делитель напряжения 1:0.77; Vadc ~= 1.27V [центральное] Нажата кнопка 3 [0]: Получаем... замыкание цепи АЦП на землю и напряжение около нуля. Читаем напряжение на пине каждые 10-20мс, фильтруем значения, усредняем пару-тройку выборок. Если напряжение более 0.2с стабильно в вышеописанных диапазонах (даём допуск 5-10%), то принимаем решение о том, что кнопка нажата. Если снова 3.3V - кнопки отпущены. Всё довольно просто. В теории. PS: Не забудьте добавить конденсатор фильтра на вход АЦП. Для такого делителя можно взять от сотен пикофарад до десятков нанофарад. -
stm32l0 отдельные старт, передача данных и стоп в i2c
AlanDrakes ответил Mark16 тема в STM
Я подключал этот дисплей на шину SPI и отправлял данные блоками по 128 байт (дополнительно обрамляя их командами записи в определённые ячейки памяти, ибо похожий контроллер SH1106 не умел переходить на следующую строку - приходилось самому. А SSD1306 умеет, но команда ему не мешает - так что оставил как есть). И, да. Присоединяюсь к рекомендации Obam - слать блоками по 128 байт. Вообще, перепишите функцию отправки. У вас исходник под AVR, а тут всё же более продвинутая периферия - можно много чего сделать удобнее. VladislavS привёл в пример готовый код. Если хотите максимально просто - приложу свой. Не использует плюсы, всё на регистрах. Заточено под F401 (но I2C периферия в L05x не особенно отличается - проверил по референсу). У меня НЕ обрабатываются пограничные случаи, как отправка OVER 255 байт в устройство (т.к. столько не требовалось, да и микросхема EEPROM, под которую писал код, всего на 256 байт. Функции в случае ошибки при передаче возвращают -1 (0xFF), в случае успеха - 0. -
Синхронный запуск таймеров.
AlanDrakes ответил dOb тема в ARM
Посмотрите в сторону синхронного запуска через TIMx->SMCR - Slave mode control register. В reference manual'е как раз указывается, что данный регистр может использоваться для вашей задачи. -
stm32l0 отдельные старт, передача данных и стоп в i2c
AlanDrakes ответил Mark16 тема в STM
Кто как, а у меня на L051 работает вот такой запуск I2C: I2C1->CR2 = (I2C_CR2_AUTOEND | DevAddr << 1 | I2C_CR2_RD_WRN | (DataToRead<<16) | I2C_CR2_START); Сразу пишем в регистр и адрес ведомого и автостоп (после нужного количества байт) и всё прекрасно срабатывает. Ещё раз убеждаюсь, что в L05x перенесли блок I2C от F030, а не из F407, где всё делалось через тыканье битов на каждое действие: Отправили старт? Шлём адрес. Отправили? Отлично. Ошибка?! Ах ты ж... ну ладно. Или Закончили отправлять байт? Отлично, продолжаем. Ошибка линии? Ну вот опять 😞 А тут? Стартуем на адрес XXXX, отправлять будем YYYY байт! После отправки - стоп. И всё! Знай только байты подкладывай. И иногда следи за флагами состояний. -
STM32 и аналоговый сигнал на вход ADC
AlanDrakes ответил reg33 тема в ARM, 32bit
Отсюда АЦП на STM32 работает по принципу уравновешивания заряда, а не уравновешиванию токов, как АЦП на AVR чипах (во всяком случае тех, с которыми я работал). Если оставить пин АЦП болтающимся в воздухе, или же прицепить к нему конденсатор относительно небольшой ёмкости (сотни-тысячи пикофарад), то значения АЦП будут тянуться к середине шкалы (2047/4097), но и реагировать на наводки на этот самый пин. При большой частоте измерений ток, вытекающий из АЦП будет довольно значительным для резистора в 1МОм на вашей схеме. Я бы уменьшил его номинал до десятков кОм, либо поставил промежуточный буферный ОУ между C52-R88 и собственно АЦП. -
1. Не делайте очистку проекта перед сборкой. 2. Не добавляйте файлы исходников (и заголовочников). 3. Не меняйте опции сборки через make menuconfig. И тогда проект будет собираться в режиме сборки изменений, а не в режиме полной сборки. Если не выполняется хоть одно условие - чаще всего в каталог в проектом был добавлен новый файл, либо удалён существующий - происходит полная перекомпиляция ВСЕГО. Да, бесит, особенно на слабых компах.
-
У меня энкодер работает следующим образом: // TIM3 SMCR -> SMS = 011 // TIM3 CCER -> CC1P + CC2P TIM3->ARR = 402; TIM3->SMCR = (TIM_SMCR_SMS_1 | TIM_SMCR_SMS_0); TIM3->CCER = (TIM_CCER_CC2P | TIM_CCER_CC1P); TIM3->CNT = 200; TIM3->CR1 = TIM_CR1_CEN; EncVal = (TIM3->CNT >> 2); <...> if (EncVal != (TIM3->CNT >> 2)) { if (EncVal < (TIM3->CNT >> 2)) { OnKeyDown(9); // ENC- } else { OnKeyDown(10); // ENC+ }; EncVal = (TIM3->CNT >> 2); }; В общем, мне попались энкодеры, которые за один клик дают фактически два импульса (фронт на первом канале и спад на втором). С одной стороны - хорошо, с другой - интересная особенность. Потому значение делится на два. Случай переполнения цинично игнорируется (код тестовый).