Перейти к содержанию
    

auric

Участник
  • Постов

    99
  • Зарегистрирован

  • Посещение

Репутация

0 Обычный

Информация о auric

  • Звание
    Частый гость
    Частый гость

Посетители профиля

Блок последних пользователей отключён и не показывается другим пользователям.

  1. upd: кстати чистить хвосты командой SPI_I2S_ReceiveData(SPI2)); после записи байта (после проверки SPI_SR_BSY) не помогло. Кстати какая частота шины SPI доступна, не пойму? По таймингам клока SPI вроде около 5МГц. У меня SPI на 2,5МГц настроен, запас вроде есть, на этой настройке достаточно медленный TM1638 работает и ничего не выкаблучивается, в паузы вклиниваюсь я с EEPROM.
  2. Работаю с EEPROM m95160, вроде все работает, но такое ощущение, что на костылях. Сразу скажу, я не работал со внешними EEPROM, тк устраивал внутренний FLASH у STM32, но тут решил поставить, тк надо чуть ли не по одному байту писать, жалко память. Короче, пишу я разрешение на запись, а судя по документации это должно выглядеть примерно так: EEPROMState m95160_WriteEnable(void){ u8 cmd[] = {M95160_WREN}; //#define M95160_WREN (0x06) // write enable u8 TryCount = 0; while ( M95160_WIP & m95160_ReadStatus() ) { if (TryCount > 60000) return EEPROM_STATUS_PENDING; TryCount++; } EEPROM_Write(cmd,1); return EEPROM_STATUS_COMPLETE; } сама запись байте по SPI условно такая while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET); //Detect SPI send flag bit (send buffer empty) SPI_I2S_SendData(SPI2, data); //Send data via SPI2 peripheral while(SPI2->SR & SPI_SR_BSY); // Wait for end of Busy flag далее читаю статус уже в ожидании бита WEL (ну статус я читаю и перед отправкой команды M95160_WREN, жду свободного бита WIP "запись идет", хотя если честно может и нет там смысла, но на всякий случай воткнул проверку, число попыток от балды, просто большое, считаем что частота проца 72МГц, ну там порядка 3 мс думаю будет задержка ожидания - не вникал). Но факт я не от балды посылаю команду когда захотел. u8 m95160_ReadStatus(void) { u8 cmd[] = {M95160_RDSR, 0xFF}; //#define M95160_RDSR (0x05) // read status register u8 status[] = {0xFF, 0xFF}; EEPROM_Write_Read(cmd, status, 2); return status[1]; } запись и чтение такое: while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET); //Detect SPI send flag bit (send buffer empty) SPI_I2S_SendData(SPI2, data); //Send data via SPI2 peripheral while (SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE) == RESET); // Wait for end of data receive return ((unsigned char)SPI_I2S_ReceiveData(SPI2)); // Return the received byte from RX Buffer Короче загвоздка в том, что на отладке иногда у меня такая вот процедура выходит по ошибке превышения числа попыток: while ( !(M95160_WEL & m95160_ReadStatus()) ) { if (TryCount > 60000) return EEPROM_STATUS_ERROR; // m95160_WriteEnable(); //включить бит WEL TryCount++; } Если раскоментировать дополнительную посылку команды, то все хорошо, но если оставить только одну команду до этой проверки (а внутри цикла команда остается закомментированной), то в отладке пошагово !!! ИНОГДА!!! я все-таки на второй третьей итерации в цикле попыток прохожу этот While, а если отладку запустить непрерывно до следующей точке останова за циклом, то я выхожу из функции раньше точки останова после цикла стабильно. Отсюда вопрос: Это надо долго ждать (кстати если ставить delay, то хоть 10мс - только хуже работает) или я что-то не так проверяю перед отправкой M95160_WREN ? Короче кто что подскажет? Или нормально так зацикливать что уходит туча команд, какая-нибудь завершится успехом? Опять же смущает момент, что команда M95160_WREN не требует забирать из DR байт данных - я и не делаю этого, а потом читаю статус и забираю соответствующие байты, по идее могу нарваться на то, что принимая байт при чтении, я могу ложно принять старый байт (пока не уверен что это вообще возможно, просто предположил). Может есть смысл пересмотреть процедуру чтения и/или записи без чтения, чтобы хвосты эти чистить?
  3. 🙂 да DWT, использовал такой код для подсчета времени цикла: #define DWT_CYCCNT *(volatile uint32_t*)0xE0001004 #define DWT_CONTROL *(volatile uint32_t*)0xE0001000 #define SCB_DEMCR *(volatile uint32_t*)0xE000EDFC //разрешаем использовать DWT и обнуляем значение SCB_DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;// разрешаем использовать DWT DWT_CONTROL|= DWT_CTRL_CYCCNTENA_Msk; // включаем счётчик DWT_CYCCNT = 0;// обнуляем счётчик if (DWT_CYCCNT > count_tic_old) cycle_time = (DWT_CYCCNT - count_tic_old)/7200; // кол-во тактов count_tic_old = DWT_CYCCNT; // обновляем кол-во тактов
  4. честно в моем случае это был вопрос менее одной минуты (осцил и так висел на нужной ножке), не надо искать код для WDT, хотя я его знаю и использовал в других задачах, так что каждому свое...гадать что у меня я и не просил, читайте первый пост...для меня важно понять в первом приближении - проблема встречалась ли и насколько часто...если честно больше кажется то, что никто вообще не заморачивается временем выхода в прерывание, если задача и так решается...
  5. да так все и было, начал в нем, зато бесплатный, устраивает на все сто, зато не надо гоняться за кряками итп кейлов всяких, перенести хоть в кейл, хоть в иар не проблема, работал и в них, не нашел ничего особенного, чтобы на них перейти.
  6. SysTick есть на миллисекунду, не думаю что он. может, но смущает порядок разницы, ведь другие процессы медленные по сравнению с этим (уставку специально сделал меньше микросекунды для проверки) и их не настолько много. Попробую когда время будет повторить тест вообще с одним таймером. Здесь же хотел понять, был ли кто-то из участников так сказать так же заинтересован и замерял выход в прерывание? Есть ли какая-то практическая статистика? Или только теория...
  7. Искал но не нашел темы достаточно объемной и так сказать подходящей, кроме как на радиокоте (хотя объемной ее назвать сложно). Если верить https://www.radiokot.ru/forum/viewtopic.php?p=2444545 то время выхода в прерывание (так сказать накладные расходы) составляет12 тактов. Хочу понять что не так у меня, если я взводя таймер всего на один такт меньше 1 мкс получаю больше 3-х мкс задержки выхода в прерывание (сперва взводил на 4мкс, а получал 7)? Как проверял, взводил бит перед включением таймера и сбрасывал в прерывании, смотрел осциллом. Короче вижу, что достаточно много уходит на накладные расходы, пусть даже замер велся очень примерно. Частота 72МГц, то есть такты явно на порядки отличаются. Написано в Cocox, компилятор GNU, оптимизацию не включал, тк она мешает отладке, но опять же не думаю, что это может так влиять, ну блин порядки целые разница, не разы. Ну естественно гадать на кофейной гуще не предлагаю, просто хочу уточнить если кто-то заморачивался по данному вопросу, у кого какие получались задержки и может кто-то проводил действия по уменьшению этого времени.
  8. Ну да - канал, отвечающий за DMA_RX занят USART-ом (так получилось, недоглядел, плату переделывать не очень хотелось). В принципе не критично, тк прием нужен не во всех пакетах. Но все равно такая схема удобнее поллинга флагов внутри основной/фоновой программы. пока не понял как это должно работать, вроде пин SCLK при работе с периферией SPI назначается как AFIO (если конечно работа SPI не делается так сказать "вручную").
  9. Интересное наблюдение за TM1638, команда описанная как "DispMode" код 0x40 видимо у них в даташите лишняя в описании под диаграммами запросов-ответов (хотя может такой даташит попался, в другой уже не было этой строки), короче следом должна идти "Data instruction", если адрес фиксированный шлем команду 0х44, если инкремент - 0x40, что собственно повторяет DispMode (кстати нормально он работает прибавляет ровно 1 к адресу, то есть если работать по регистрам, отвечающим за GRID - разряд/символ, которых 8 штук, то придется не забыть заполнить данные и для нечетных адресов 9,10 сегменты SEG, тк они тоже будут заполняться в перемешку с четными адресами сегментов 1-8, но в моем случае все наоборот было, мне все равно надо было заполнять все адреса, тк у меня сегменты управлялись с GRID, а разряды с SEG для охвата большего числа разрядов - 10). "Display control command" тоже оказалась не обязательным элементом в цикле, один раз конечно ее надо запустить в начале, но потом в работе, если не менять в процессе работы яркость (не использовать команду "Display control command"), то данные можно вообще упрощенно отправлять одним пакетом "Data instruction" и CS переключать всего один раз в начале и один раз в конце пакета, то есть полностью положиться на DMA. Очень удобно и просто и не затратно практически - не то что делать это "ногодрыгом". Вот такая недокументированная особенность.
  10. в итоге сделал переключение CS на прерываниях (полностью на DMA повесить управление SPI не получилось), но в итоге если работать с односторонней передачей, то проще действительно использовать таймер, тем более мне он пригодился для дополнительных пауз, тк нужно выдерживать задержку от конца последнего CLK импульса до поднятия /CS. А в случае использования еще и приема от периферии (у меня канал DMA на прием как назло оказался занят) подошел и IE_RXNE флаг вполне, что собственно и писали тоже в советах но только задержки надо контролировать, чтобы не было все быстро (кстати по поводу задержек уже другая история).
  11. Если что так чисто для рассуждений...5 вольт питания на TM1638 попробовал на макетке - работает даже с МК на 3,3В, да в конечном итоге на ножках вместо 5В при высоком уровне 3,4-3,5В, видимо этого достаточно чтобы на границе возможностей связь по SPI шла (5В*0,7=3,5В). Но интересно было и с 3,3 Вольта питания на TM1638 - тоже отработала (причем не заметил уменьшения яркости по сравнению с 5В), правда индикатор зеленый (который новомодный Pure) да красный, синего нет, наверное с ним бы не прокатило. По току пока не готов анализ проводить, тем более он в импульсном режиме, но ничего пока не сгорело )) и режим яркости был на полной. Схема согласования полнопроводной SPI и трехпроводной с объединенной MOSI/MISO с 1К резистором как указано выше работает, ну видимо как раз защищает резистор от высокого уровня сигнала на MOSI во время приема от Slave. Отработало даже не смотря на то, что выходы slave открытый коллектор с подтяжкой к питанию резисторами 10К. Особенно мне мозг конечно заколебала особенность 1638 - требует дрыгать ножкой STB как бы синхронизируя команды, то есть перед и после каждой команды, хотя все как бы есть в документации - даже графики и требования по командам, все было, просто это не акцентировано, хотелось попроще, микруха команды жрет, но выдает символы как у "Хищника" на руке были в фильме со Шварцем )), пока не сделал как надо не заработало. Я почему-то думал, что будет достаточно один раз в начале выбрать и в конце отключить CS. Ну и с библиотеками из тырнета чет нифига не совпало, ну это как обычно... Оставшиеся вопросы: Как обычно организуется выходы Slave Output устройств на шине SPI? Если как открытый коллектор, то требуется подтяжка, не всегда вижу (судя по EEPROM), если занимают высокоимпедансное состояние, то тоже не совсем понятно, а есть ли на входах защитные диоды, короче если кто б накидал свои наблюдения практические, было б может полезно многим, потому как иногда вот рассуждения заходят в сторону согласования питаний итп (ведь MISO сидят все на одной шине) и в итоге как бы хочется учесть особенности всех slave устройств, а не всегда есть понимание, даже несмотря на то, что есть даташит. Кто как согласует линии 5В и 3,3? транзисторами (биполярники или полевики)? С инверсией? Делителями, если с высокой стороны? Или есть более лаконичное решение?
  12. Все верно, но у них же предложена альтернативная схема для 10 индикаторов с общим анодом. Вот с ней не все так просто, потому обсуждаю.
  13. Вопрос, вот понравился мне TM1638, хочу подключить десять семисегментных индикаторов (10 разрядов). TM1638 тянет 8 по стандартной схеме подключения, где сегменты цепляются на SEG выходы, а разрядные общие точки (кстати обычно эта схема для общего катода, если правильно понял) цепляются на GRID. Если с точки зрения программы вроде как проблем больших не вижу, регистры вот так представлены: Да надо перерабатывать каждый байт данных и раскидывать побитно в разные регистры для каждого разряда исходных данных, но в принципе реально. Смущает другое... Во первых давайте разберемся, что пишут даташиты: Segment output, P pipe open-drain output, если перевести на русский я так понял это P-канальный полевик, правда пишут что с "открытым коллектором" или стоком, если брать терминологию полевиков, но если вспомнить, что изначально TM1638 идут для общего катода, то SEG выходы получается должны иметь "открытый исток", то есть выдают вытекающий ток. Grid output, N pipe open-drain output, тут вроде понятно - N-канальный полевик. цепляется на общий катод "открытым истоком" (коллектором, кому как понятнее), должен выдерживать достаточную токовую нагрузку, тк ток с сегментов суммируется. Вот выдержка из их даташита для общего анода. Первое что смутило - токи, для выходов типа SEG указан максимальный ток -50 mA, для выходов типа GRID +200 mA, даже знаком показали вытекающий ток. Так вот вопрос к тем, кто работал с TM1638 - хватает ли этого тока, чтобы запитать целый индикатор? Ведь TM1638 используется без ограничительных резисторов и как он там подбирает ток мне не понятно, может требуется изначально занизить яркость? Второй момент - питания, драйвер может работать и с 3,3В, но по даташиту всячески намекают брать питание 5В, может ему проще работается так...но для светодиодов типа синих, у которых напряжение включения больше других, говорят может не хватить 3,3В питания, ведь часть потеряется на ключе, плюс для разных светодиодов это значение может быть и побольше...в общем прошу отписаться тех, кто работал например с синими на низком напряжении - стоит или нет оставаться на 3,3В. Почему такой вопрос, потому как если использовать 5В, надо думать про согласование уровня, а это уже следующий вопрос, по нему ниже. В третьем вопросе хочется обсудить выбор напряжения и схему согласования, в том числе по шине SPI. Стандартно предлагается подтянуть к питанию ножки STB (chip select), CLK (clock), DIO (объединенная slave input/output) резистором 10кОм (от 1кОм до 10, но рекомендуют 10) и поставить фильтр-конденсатор на 100pF, если с DIO все понятно - там выход открытый коллектор (открытый сток), то по остальным ножкам не понятно зачем. Вопрос: а если я не буду этого делать, какие могут быть ньюансы? Пока это я обсуждаю вариант, если питание одинаковое и у МК и у драйвера. Если брать вариант, где питания МК 3,3В, а у драйвера 5В, начинается веселье: допустим ножки процессора толерантны к 5В (хотя даже если не торлерантны, но имеют защитные диоды, ограничивающие вход/выход питанием+-0,5В) имея подтяжку 10кОм ток будет незначительным и не должен диод вывести из строя, но напряжение на линии не поднимется до 5В, тк максимальное напряжение будет 3,3В за счет схемы с диодом. Что вход что выход, а напряжения включения на входах драйвера 1638 (который кстати тоже имеет защитные диоды судя по диапазону напряжения Logic input voltage -0.5 ~ VDD + 0.5 из даташита) составляет 0.7 VDD минимум и 0.3 VDD максимум (тут я боюсь опечатка, думаю 0.3 VDD минимум, иначе они не гарантируют вообще выключение, как и включение если брать там максимум - тоже опечатались). Короче кто работал с TM1638 (может 1637 или аналогичными от этого производителя) как решили вопрос с согласованием напряжения. Отдельно стоит поговорить о том, как организуется подключение SPI, точнее согласование объединенного DIO и резделных MOSI и MISO? Стандартно многие предлагают использовать такие схемы для объединения стандартной SPI и трехпроводной (с объединенным I/O): https://arduino.stackexchange.com/questions/23684/stpm10-using-arduino-spi-communication https://microdigisoft.com/tm1638-8-bit-button-digital-led-seven-segment-display-module/ а так же https://web.archive.org/web/20230418064003/https://os.mbed.com/components/TM1638-LED-controller-80-LEDs-max-Keyboa/ и некоторые ныне недоступные в свободном доступе типа Texas Instr Вопрос: что нам дает этот резистор/резисторы? Тем более что у нас на входе DIO будет стоять подтягивающий резистор 10кОм. Есть какие-то особенности работы ножки MOSI в режиме полудуплекса, раз ее так отсекают? Разве она не должна переходить в высокий импеданс?
  14. Буду благодарен, если поделитесь, а то, что находил мне как-то не приглянулось - как мне показалось там тупо все в структуру помещали, так я и так на отладчике вижу и стек могу разглядеть, другое дело, я ожидал более очевидного деления сообщений причин попадания. Понимаю вопрос я поверхностно разобрал, просто не так часто с HF приходится взаимодействовать, да и зачастую находится быстро.
  15. Для меня это не так очевидно как вам это кажется, я читал как по регистрам отследить появление HF, но к сожалению при 0xFFFFFFF9 в LR вроде как отсыл был к неправильной адресации - для меня не особо говорит, что и где искать...
×
×
  • Создать...