Jump to content
    

Search the Community

Showing results for tags 'stm32'.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • Сайт и форум
    • Новости и обсуждения сайта и форума
    • Другие известные форумы и сайты по электронике
    • В помощь начинающему
    • International Forum
    • Образование в области электроники
    • Обучающие видео-материалы и обмен опытом
  • Cистемный уровень проектирования
    • Вопросы системного уровня проектирования
    • Математика и Физика
    • Операционные системы
    • Документация
    • Системы CAD/CAM/CAE/PLM
    • Разработка цифровых, аналоговых, аналого-цифровых ИС
    • Электробезопасность и ЭМС
    • Управление проектами
    • Neural networks and machine learning (NN/ML)
  • Программируемая логика ПЛИС (FPGA,CPLD, PLD)
    • Среды разработки - обсуждаем САПРы
    • Работаем с ПЛИС, области применения, выбор
    • Языки проектирования на ПЛИС (FPGA)
    • Системы на ПЛИС - System on a Programmable Chip (SoPC)
    • Methods and tools for FPGA/ASIC verification
  • Цифровая обработка сигналов - ЦОС (DSP)
    • Сигнальные процессоры и их программирование - DSP
    • Алгоритмы ЦОС (DSP)
  • Микроконтроллеры (MCU)
    • Cредства разработки для МК
    • ARM
    • RISC-V
    • AVR
    • MSP430
    • Все остальные микроконтроллеры
    • Отладочные платы
  • Печатные платы (PCB)
    • Разрабатываем ПП в САПР - PCB development
    • Работаем с трассировкой
    • Изготовление ПП - PCB manufacturing
  • Сборка РЭУ
    • Пайка и монтаж
    • Корпуса
    • Вопросы надежности и испытаний
  • Аналоговая и цифровая техника, прикладная электроника
    • Вопросы аналоговой техники
    • Цифровые схемы, высокоскоростные ЦС
    • RF & Microwave Design
    • Метрология, датчики, измерительная техника
    • АВТО электроника
    • Умный дом
    • 3D печать
    • Робототехника
    • Repair and debug
  • Силовая электроника - Power Electronics
    • Силовая Преобразовательная Техника
    • Обратная Связь, Стабилизация, Регулирование, Компенсация
    • Первичные и Вторичные Химические Источники Питания
    • Высоковольтные Устройства - High-Voltage
    • Электрические машины, Электропривод и Управление
    • Индукционный Нагрев - Induction Heating
    • Системы Охлаждения, Тепловой Расчет – Cooling Systems
    • Моделирование и Анализ Силовых Устройств – Power Supply Simulation
    • Компоненты Силовой Электроники - Parts for Power Supply Design
  • Интерфейсы
    • Форумы по интерфейсам
  • Поставщики компонентов для электроники
    • Поставщики всего остального
    • Компоненты
  • Майнеры криптовалют и их разработка, BitCoin, LightCoin, Dash, Zcash, Эфир
    • Обсуждение Майнеров, их поставки и производства
  • Дополнительные разделы - Additional sections
    • Встречи и поздравления
    • Ищу работу
    • Предлагаю работу
    • Куплю
    • Продам
    • Объявления пользователей
    • Общение заказчиков и потребителей электронных разработок

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


AIM


MSN


Сайт


ICQ


Yahoo


Jabber


Skype


Город


Код проверки


skype


Facebook


Vkontakte


LinkedIn


Twitter


G+


Одноклассники

  1. Продам отладочные платы разных производителей: 1. STM32F4 Discovery 2. STM32H743 Nucleo-144 3. OMAP-L138 Development Kit (LCDK) - полный комплект (плата, диск, кабеля, переходники) 4. Чипы OMAP-L138 (на 450 МГц) 5. Olinuxino A13 6. Модуль SOM A13 7. NRF PCA10040 8. NRF PCA10056 + штатная гибкая антенна 9. uBlox ATSAM3U2C + штатная печатная антенна + USB-кабель Фото ниже. Цена договорная. Рассылка по РФ. За подробностями пишите в личку или на почту repstosw2018 @ gmail . com
  2. В GD32F103RBT6 имеется Timer1. В Timer1 имеется 4 канала. Каждый канал можно настроить в режим захвата по фронту/срезу на пине контроллера и настроить соответствующие прерывания. Собственно я так и настроил. Функция обработки прерывания от Timer1 выглядит так: void TIMER1_IRQHandler (void) { uint32_t temp = 0; uint8_t ch = 0; // Переменная определяет номер канала. static uint16_t prev_tim_capture_reg_val [NUMBER_OF_DALI_CHANNELS] = {0}; // Предыдущее значение регистра захвата для каждого канала. //---If channel 0 capture/compare interrupt flag is set---// if (TIMER_INTF(TIMER1) & TIMER_INTF_CH0IF) // If channel 0 capture/compare interrupt flag is set. { //---Input capture event--------------------------------------------------------------// //-Clear capture/compare interrupt flag-// TIMER_INTF(TIMER1) &= (~TIMER_INTF_CH0IF); // NVIC_ClearPendingIRQ(TIMER1_IRQn); //--------------------------------------// ch = 0; // Выбор номера канала. temp = TIMER_CH0CV(TIMER1) & 0xFFFF; if (wait_start_bit_flag[ch] == RESET) { if (temp > prev_tim_capture_reg_val[ch]) PulseDuration[ch] = temp - prev_tim_capture_reg_val[ch]; else PulseDuration[ch] = 0xFFFF - prev_tim_capture_reg_val[ch] + temp; } else PulseDuration[ch] = 0; // Сброс счётчика длительности импульса. prev_tim_capture_reg_val[ch] = temp; if (TIMER_CHCTL2(TIMER1) & TIMER_CHCTL2_CH0P) // Если было настроено прерывание на срез... { CallbackInputPulse_ch0(DALI_BUS_LOG0, PulseDuration[ch]); // Раз словили срез, то надо начинать отслеживать stop, отслеживаем его после каждого среза. StopDuration[ch] = 0; // Для старта отслеживания stop-а, сбрасываем длительность стоп-интервала. Другой счётчик воспримет этот сброс как старт к подсчёту длительности. } else // Если было настроено прерывание на фронт... Для микроконтроллера посылка начинается с фронта на его пине, поэтому при приёме посылки, сначала придём сюда!!! { if (wait_start_bit_flag[ch]) // Если словили стартовый фронт... wait_start_bit_flag[ch] = RESET; else CallbackInputPulse_ch0(DALI_BUS_LOG1, PulseDuration[ch]); } TIMER_CHCTL2(TIMER1) ^= TIMER_CHCTL2_CH0P; // Change channel x capture/compare function polarity. DaliStates[ch] = (!DaliStates[ch]); // Присваиваем новое лог. значение установившееся на шине DALI. //------------------------------------------------------------------------------------// } //--------------------------------------------------------// //---If channel 1 capture/compare interrupt flag is set---// if (TIMER_INTF(TIMER1) & TIMER_INTF_CH1IF) // If channel 1 capture/compare interrupt flag is set. { //---Input capture event--------------------------------------------------------------// TIMER_INTF(TIMER1) &= (~TIMER_INTF_CH1IF); // Clear capture/compare interrupt flag. ch = 1; // Выбор номера канала. temp = TIMER_CH1CV(TIMER1) & 0xFFFF; if (wait_start_bit_flag[ch] == RESET) { if (temp > prev_tim_capture_reg_val[ch]) PulseDuration[ch] = temp - prev_tim_capture_reg_val[ch]; else PulseDuration[ch] = 0xFFFF - prev_tim_capture_reg_val[ch] + temp; } else PulseDuration[ch] = 0; // Сброс счётчика длительности импульса. prev_tim_capture_reg_val[ch] = temp; // i_ch1++; if (TIMER_CHCTL2(TIMER1) & TIMER_CHCTL2_CH1P) // Если было настроено прерывание на срез... { CallbackInputPulse_ch1(DALI_BUS_LOG0, PulseDuration[ch]); StopDuration[ch] = 0; // Для старта отслеживания stop-а, сбрасываем длительность стоп-интервала. Другой счётчик воспримет этот сброс как старт к подсчёту длительности. } else // Если было настроено прерывание на фронт... { if (wait_start_bit_flag[ch]) wait_start_bit_flag[ch] = RESET; else CallbackInputPulse_ch1(DALI_BUS_LOG1, PulseDuration[ch]); } TIMER_CHCTL2(TIMER1) ^= TIMER_CHCTL2_CH1P; // Change channel x capture/compare function polarity. DaliStates[ch] = (!DaliStates[ch]); // Присваиваем новое лог. значение установившееся на шине DALI. //------------------------------------------------------------------------------------// } //--------------------------------------------------------// //---If channel 2 capture/compare interrupt flag is set---// if (TIMER_INTF(TIMER1) & TIMER_INTF_CH2IF) // If channel 2 capture/compare interrupt flag is set. { //---Input capture event--------------------------------------------------------------// TIMER_INTF(TIMER1) &= (~TIMER_INTF_CH2IF); // Clear update interrupt flag. ch = 2; // Выбор номера канала. temp = TIMER_CH2CV(TIMER1) & 0xFFFF; if (wait_start_bit_flag[ch] == RESET) { if (temp > prev_tim_capture_reg_val[ch]) PulseDuration[ch] = temp - prev_tim_capture_reg_val[ch]; else PulseDuration[ch] = 0xFFFF - prev_tim_capture_reg_val[ch] + temp; } else PulseDuration[ch] = 0; // Сброс счётчика длительности импульса. prev_tim_capture_reg_val[ch] = temp; if (TIMER_CHCTL2(TIMER1) & TIMER_CHCTL2_CH2P) // Если было настроено прерывание на срез... { CallbackInputPulse_ch2(DALI_BUS_LOG0, PulseDuration[ch]); StopDuration[ch] = 0; // Для старта отслеживания stop-а, сбрасываем длительность стоп-интервала. Другой счётчик воспримет этот сброс как старт к подсчёту длительности. } else // Если было настроено прерывание на фронт... { if (wait_start_bit_flag[ch]) wait_start_bit_flag[ch] = RESET; else CallbackInputPulse_ch2(DALI_BUS_LOG1, PulseDuration[ch]); } TIMER_CHCTL2(TIMER1) ^= TIMER_CHCTL2_CH2P; // Change channel x capture/compare function polarity. DaliStates[ch] = (!DaliStates[ch]); // Присваиваем новое лог. значение установившееся на шине DALI. //------------------------------------------------------------------------------------// } //--------------------------------------------------------// //---If channel 3 capture/compare interrupt flag is set---// if (TIMER_INTF(TIMER1) & TIMER_INTF_CH3IF) // If channel 3 capture/compare interrupt flag is set. { //---Input capture event--------------------------------------------------------------// TIMER_INTF(TIMER1) &= (~TIMER_INTF_CH3IF); // Clear capture/compare interrupt flag. ch = 3; // Выбор номера канала. temp = TIMER_CH3CV(TIMER1) & 0xFFFF; if (wait_start_bit_flag[ch] == RESET) { if (temp > prev_tim_capture_reg_val[ch]) PulseDuration[ch] = temp - prev_tim_capture_reg_val[ch]; else PulseDuration[ch] = 0xFFFF - prev_tim_capture_reg_val[ch] + temp; } else PulseDuration[ch] = 0; // Сброс счётчика длительности импульса. prev_tim_capture_reg_val[ch] = temp; if (TIMER_CHCTL2(TIMER1) & TIMER_CHCTL2_CH3P) // Если было настроено прерывание на срез... { CallbackInputPulse_ch3(DALI_BUS_LOG0, PulseDuration[ch]); StopDuration[ch] = 0; // Для старта отслеживания stop-а, сбрасываем длительность стоп-интервала. Другой счётчик воспримет этот сброс как старт к подсчёту длительности. } else // Если было настроено прерывание на фронт... { if (wait_start_bit_flag[ch]) wait_start_bit_flag[ch] = RESET; else CallbackInputPulse_ch3(DALI_BUS_LOG1, PulseDuration[ch]); } TIMER_CHCTL2(TIMER1) ^= TIMER_CHCTL2_CH3P; // Change channel x capture/compare function polarity. DaliStates[ch] = (!DaliStates[ch]); // Присваиваем новое лог. значение установившееся на шине DALI. //------------------------------------------------------------------------------------// } //--------------------------------------------------------// } //------------------------------------------------------------------------------// Когда фронты/срезы поступают на один из 4 каналов, всё работает как надо и вопросов не возникает. Но если фронты/срезы будут поступать одновременно на два и более каналов, то вопросы возникают. Если слать фронты/срезы на канал 0 и канал 1, то на канале 1 будут пропуски в обработке прерываний. Выяснил это просто инкрементируя счётчики фронтов/срезов при обработке прерываний от каналов. Причём, если код как в посте, то пропуски будут на канале 1. Если в коде поменяю местами очерёдность обработки каналов (сначала канал 1, а потом канал 0), то пропуски всё равно будут на канале 1. Если уберу обработку канала 0, и буду слать фронты/срезы на каналы 1 и 2. То пропуски будут на канале 2. Вангую, что мне ответят: 1) читай Джозефа Ю.; 2) не нужно совать всю обработку события в функцию обработки прерывания. Нужно установить флаг события, а уж в основном цикле разбираться; 3) использовать другие таймеры - не могу, остальные все заняты; 4) в UserManualе ответа не нашёл, Erratы не нашёл на сайте производителя. Если есть у кого-нибудь другие комментарии, очень прошу подсказать. Как устранить или минимизировать пропуски? Сам пробовал увеличить стек - не помогло. Приоритет прерываний от Timer1 равен 7. Приоритеты остальных прерываний ниже (значение больше 7).
  3. Здравствуйте! Имеется разработанная плата с STM32F407VET6 и PHY DP83848 для реализации Ethernet-передачи(планируется TCP-клиент или сервер). STM32F407VET6 и DP83848 соединяются по MII-интерфейсу. Используется LWIP-стек. DP83848 тактируется от отдельного кварца на 25 МГц, микроконтроллер - также от отдельного на 25 МГц. Плата и ПК соединены напрямую по Ethernet-кабелю, без роутеров и маршрутизаторов. Проект был сгенерирован из CubeMx в Keil v5.27. Далее в цикл While() добавил MX_LWIP_Process(), скомпилировал, прошил. Основная проблема - МК не принимает данные от DP83848. Что было проверено/сделано: 1. Сверил все адреса регистров/значений из даташита на DP83848 с тем, что выдает CubeMx. Пришлось в некоторых местах исправить. 2. Проверил повторно схему, соответствие подключаемых выводов на обоих сторонах (STM32 и DP83848), еще раз сверился с требованиями по подключению DP83848 из даташита. 3. Проверил осциллографом сигналы на RXD0..RXD3 - имеются (т.е. DP83848 принимает сигналы с ПК, и передает затем STM32, но он их не воспринимает что-ли?), RX_CLK и TX_CLK - имеются, генерация от кварца есть. 4. Назначил IP адрес, маску и узел в настройках адаптера Ethernet на ПК. 5. Попытался понять, где же все-таки происходит "затык", прошелся последовательно по функциям: While() -> MX_LWIP_Process() -> ethernetif_input(&gnetif) -> low_level_input(netif) -> HAL_ETH_GetReceivedFrame(&heth). В функции HAL_ETH_GetReceivedFrame(&heth) есть условие: if(((heth->RxDesc->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET)), в него программа не заходит. Подумал, что возможно что-то с DMA, но так и не получилось понять. 6. Хотел проверить в RMII-режиме - схема и разводка платы не позволяет (P.S.- Хотя конечно, можно настроить "нестандартно" тактирование STM32, пустить 50 МГц с MCO на RX_CLK и X1 у DP83848 через доп.провода) После вышеописанных действий результата нет. Скриншоты с настройкой из CubeMx прикрепил. Также прикрепил пару скриншотов из WireShark, скриншоты "фейкового" пинга из командной строки и общих настроек LWIP. В WireShark видно, что ПК постоянно спрашивает "Who has 192.168.1.1.?", а плата шлет какие-то запросы (наверно связаны с автосогласованием при включении DP83848), но не слышит ПК. Я понимаю, что применять CubeMX не очень "рационально", но имеется потребность в кратчайшие сроки реализовать связь по Ethernet для передачи данных. Буду рад любым подсказкам.
  4. Продолжение моего прошлого вопроса. До этого хотел реализовать загрузчик с прошивкой в качестве hex-файла, теперь попытался с бинарным и возникла проблема. "Получать прошивку должен по UART. На данный момент загрузчик успешно выполняет передачу управления основной программе и стирает память по адресу, соответствующему программе, при получении прошивки." Отправляю bin-файл через TeraTerm, контроллер его вроде как получает, но пропускает цикл с записью прошивки, не могу понять почему. Проблема находится где-то в районе "strtoul". Пробовал конец строки, что в буфере, добивать нуль-терминирующим символом - безрезультатно. Прикладываю файл загрузчика, буду благодарен за любую помощь.main.c
  5. Ищу работу/подработку/стажировку, связанную с программированием микроконтроллеров AVR, STM32. Работа в программах AtmelStudio, Proteus, KeiluVision, CubeMX. Знание основ языка программирования С++. Желание развиваться в данном направлении. [email protected]
  6. Пишу загрузчик на stm32f103. Получать прошивку должен по UART. На данный момент загрузчик успешно выполняет передачу управления основной программе и стирает память по адресу, соответствующему программе, при получении прошивки. Застрял на моменте отправки hex-файла загрузчику - плохо понимаю как это реализовать. Со стороны компьютера должно быть приложение, позволяющее передать файл прошивки, на это выделено 10 секунд. Пробовал использовать Tera Term, но ничего не выходит. Не знаю, не позволяет приложение или криво написан код. Сам код с получением файла прошивки не мой, планирую сначала проверить его, а затем уже написать свой. Новичок в этом деле, так что прошу не судить строго. main.c
  7. Приветствую участников форума, В процессе изучения реального потребления в режиме Standby y HK32F030F4P6 на макетной плате собственной разработки обнаружилось, что вместо 1,64 мкА потребление составляет около 175 мкА. При этом все GPIO переключены в состояние входов, в цепи питания (где измеряется ток) есть только конденсаторы сам микроконтроллер. При старте никакие периферийные блоки, кроме GPIO, не настраиваются и не включаются. Для перехода в режим Standby используется следующий код: // Configure standby mode PWR->CR &= ~PWR_CR_LPDS; PWR->CR |= PWR_CR_PDDS | PWR_CR_CWUF | PWR_CR_CSBF; // PWR->CSR2 SHDS bit to 1 *((uint32_t*)(PWR_BASE + 0x30)) |= (1 << 7); // Set SLEEPDEEP in system control register SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; while (1) { __WFE(); } Пин BOOT0 подтянут с помощью резистора 100 кОм к земле, NRST подтянут с помощью 100 кОм к питанию. Линии SWD и NRST на время измерения отключаются от кабеля программирования. Поскольку у меня ранее не было нужды и опыта работы с аналогичными STM32 в режиме Standby я возможно упускаю какую-то необходимую настройку? Хотя с точки зрения описания на HK32 я всё сделал правильно, даже взвёл в 1 бит SHDS, отсутствующий у аналогичного STM32. Но тем не менее это не помогает. Был ли у кого-нибудь опыт работы с этими МК в режимах пониженного энергопотребления? Какие есть подводные камни при настройке?
  8. Куплю или приму в дар ссылку на магазин, где продается этот микроконтроллер)
  9. STM32CubeMonitor

    Использую эту штуку для отладки с st-link'ом. Возник простой вопрос: как поменять "проект" целиком? Я экспортировал все потоки в json-файл, но импортировать обратно можно только удаляя потоки поодиночке. Непонятно где хранятся свойства Dashboard. В общем, может ли кто пояснить, как мониторить другой проект? Или хотя бы как удалить всё и заново загрузить? Последний поток не удаляется.
  10. При использовании одного буфера на приём и передачу звука через DMA всё работает нормально, если использовать разные буферы на приём и передачу, появляются лишние шумы и записанного голоса почти не слышно, буфер заполняется при срабатывании callback
  11. Сначала суть проблемы, а потом собственно вопрос. Встал вопрос и переносе проекта с PIC18 на STM32 - основная причина - нехватка скорости АПЦ, скорости работы, плюс увеличение разрядности АПЦ с 10 до 12 бит. Раньше с STM32 почти не работал. Выбор пал на STM32F401CCU6. Тактовая устраивает, скорость АЦП тоже. Цена опять же вполне приемлемая. Начал изучать АПЦ - а там чудеса... Внутри не оказалось источника опорного напряжения, даже одного. В корпусах 48/64 вывода вывод Vref+ не выведен на ружу. Точнее он объединен с VDDA. Т.е. диапазон измеряемых напряжение от 0 до 3-х вольт (питания 3В). Vref- даже если в большом корпусе выведен отдельным выводом, он обязательно должен быть соединен с землей. Т.е. смещение шкалы АЦП такого вида не пройдет: на Vref- 0.4В, на Vref+ 2.2В. Измеряем в коридоре 1,8В. С PIC18 такое легко прокатывает. Собственно вопрос - есть ли среди STM32 камни с более развитым модулем АЦП? Чтобы можно было, бы хотя бы, просто на Vref+ подать 2В, не в монструозном корпусе.
  12. Всех приветствую. Предлагаю тут выкладывать найденные ошибки в библиотеках HAL. P.S. не нужно тут обсуждать применять или нет библиотеки. Итак. MCU - L433 библиотека - stm32l4xx_hal_i2c.c версия - STM32Cube_FW_L4_V1.17.2 (последняя на 23.06.2022) функция - I2C_IsErrorOccurred Причина: в цикле while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET) после условия выхода по таймауту if ((HAL_GetTick() - tickstart) > I2C_TIMEOUT_STOPF) нет выхода из цикла. Может остаться на очень долгое время. Решение: добавить break; после status = HAL_ERROR;
  13. Клоны STM32

    Поднимаю тему так как на рынке сейчас чехарда, а брэндовые stm32 по некоторым позициям подорожали в 6-10 раз. Пытался (и пытаюсь) пол года как уже объездить CH32F103C8T6 клон от китайской компании WCH Здесь буду описывать грабли, которые прошел лично с данными МК, дабы другие не налетали. В принципе, чипы рабочие, если как рыбу "фугу" уметь их готовить. Они дешевле оригинальных STM32 в несколько раз, имеют широкий диапазон питания по напряжению. Купить их можно только на Али либо в Китае. Даже на англоязычном сайте WCH они не упоминаются, только в китайской его части. Кто сталкивался или интересуется - прошу высказыватся.
  14. Продам мк stm32f030f4p6, оригинал, упаковка в ленте, в наличии 500 шт. Цена - 90р/шт При желании доставим в любой город РФ.
  15. День добрый. Задача... Нужна общая линия тревоги, устойчивая к помехам. К ней подключаются 1-10 блоков, каждый на расстоянии 1-5м друг от друга, соотв. максимальная длина линии 50 м. Любой блок может активировать линию (логическое "или") и каждый блок узнает, если линию активировал другой блок. Все блоки питаются 24в с общего БП. В каждом блоке STM32F103. Решение... Линию просаживаю биполярным транзистором с ОК, оптопарой слушал линию. Проблема... На столе работает как нужно. Любой блок может активировать линию, и все об этом узнают. НО когда имитирую работу в тяжелых (нормальных рабочих) условиях, проводами линии обвешиваю 3-х фазный электродвигатель - начинается произвольная активация линии. Предположил открывается транзистор, пытался менять номинал R5 - не помогло, хотя на 2к перестал открываться от касания пальцем. Предположил срабатывает светодиод оптопары, пытался "приглушить" номиналом R3 до 2к - нет разницы. Подскажите пожалуйста, как доработать мою схему (или может другой схемой), решить задачу. В электронике слаб, буду очень признателен, если поправите неправильные номиналы, подскажите что поменять. P.S. Возможна зацепка... При подключении 2-х блоков, наводки как буд-то сильнее и наводятся быстрее, чем если подключены 8 блоков. При 2 блоках светодиоды (имитируют вход МК) горят на 20%, МК активацию линии (лог 0) ловит практически сразу при включении электродвигателя. При 8 блоках светодиоды помаргивают еле еле, МК активацию линии ловит секунд через 10.
  16. Место работы - удаленно. Оплата труда - по договоренности. Сроки - как можно быстрее. Суть задачи. Имеется некая новая плата в составе большой установки, на этой плате установлен контроллер STM32F407ZGT6. Есть два импульсных входа, и вход по RS485 для связи с остальной инфраструктурой по протоколу Modbus. Есть служебный разъем для прошивания. По Модбасу приходит команда Start, начиная с этого момента запускается счет импульсов по первому входу, и от него запускается счет по второму входу. По команде Stop счет импульсов прекращается синхронно (первый затем второй). Затем накопленные данные должны быть переданы наверх по Модбасу. Телефон для связи в личке.
  17. Здравствуйте! Имеется отладочная плата с STM32F303. Задача: измерять импульсный сигнал длинной 100 мкс и частотой 1000 Гц и выводить измерения на ПК. Запускаю два таймера. Первый имитирует измеряемый сигнал. Второй "толкает" АЦП Измеряю через внутренний 12-битный АЦП с использованием ДМА и запуском по таймеру. и сохраняю измерения в массив. Затем этот массив через ДМА передаю ЮАРТУ и вывожу на ПК. На выходе получаю поток невнятных чисел. Помогите разобраться в чем ошибка.
  18. Приветствую, столкнулся с проблемой при записи данных с АЦП, посредством библиотеки FATFS на SD карту. Данные с АЦП формируются в массив, после чего последовательностью функций f_mount, f_open, f_write записываются на SD карту, однако иногда функция f_write возвращает результат FR_INVALID_OBJECT и запись прерывается. Копнув глубже увидел что такой статус появляется из за того, что функция HAL_SD_GetCardState возвращает странный статус HAL_SD_CARD_SENDING, который описан как sd card is sending operation information. Большего описания нигде не нашел. Проблема исчезает посредством увеличения делителя частоты тактирования SDIO, что в свою очередь значительно режет скорость передачи созданного файла с данными на пк посредством USB HS, с чем вроде можно и свыкнуться, но хотелось бы разобраться в чём причина. Возможно кто-то сталкивался с подобной проблемой и может помочь.
  19. Привет, народ! Заметил такую странность, которую не знаю как объяснить. Плата STM32F103C8T6 (Blue Pill) Я хотел сделать мигание светодиодом на ноге A0 при инициализации контроллера на 72MHz. Взял сделанный ранее проект и стал его упрощать. И вот когда оставил в проекте, по-сути, только: - инициализацию на 72Mhz - включение тактирования портов - настройку пина A0, то заметил, что код мигания стал работать медленнее! Т. е. мигание, сделанное в бесконечном цикле, стало в 1.5-2 раза медленнее, чем было до. Я стал разбираться, что могло на это повлиять. И вернул вызов ненужной функции, в которой инициализировались пины A8, A9, B3, B4, B6, B7. И о чудо, мигание стало опять быстрым! Повторюсь, в этой функции делается только инициализация пинов, и она вызывается один раз в начале программы, ничего более. Вот полный код: https://pastebin.com/Z7d0LZif А вот код функции, которая "разгоняет" выполнение кода: // Настройка пинов A8, A9, B3, B4, B6, B7 void otherPortInit(void) { // Для начала сброс конфигурации всех используемых портов в ноль GPIOA->CRH &= ~(GPIO_CRH_MODE8 | GPIO_CRH_CNF8); GPIOA->CRH &= ~(GPIO_CRH_MODE9 | GPIO_CRH_CNF9); GPIOB->CRL &= ~(GPIO_CRL_MODE3 | GPIO_CRL_CNF3); GPIOB->CRL &= ~(GPIO_CRL_MODE4 | GPIO_CRL_CNF4); GPIOB->CRL &= ~(GPIO_CRL_MODE6 | GPIO_CRL_CNF6); GPIOB->CRL &= ~(GPIO_CRL_MODE7 | GPIO_CRL_CNF7); uint32_t mode; uint32_t cnf; mode=0b11; // Режим выхода, с максимальной частотой 50 МГц cnf=0b00; // Режим push-pull GPIOA->CRH |= (mode << GPIO_CRH_MODE8_Pos) | (cnf << GPIO_CRH_CNF8_Pos); GPIOA->CRH |= (mode << GPIO_CRH_MODE9_Pos) | (cnf << GPIO_CRH_CNF9_Pos); mode=0b00; // Режим входа cnf=0b01; // Режим плавающего входа, подтяжки нет GPIOB->CRL |= (mode << GPIO_CRL_MODE3_Pos) | (cnf << GPIO_CRL_CNF3_Pos); GPIOB->CRL |= (mode << GPIO_CRL_MODE4_Pos) | (cnf << GPIO_CRL_CNF4_Pos); GPIOB->CRL |= (mode << GPIO_CRL_MODE6_Pos) | (cnf << GPIO_CRL_CNF6_Pos); GPIOB->CRL |= (mode << GPIO_CRL_MODE7_Pos) | (cnf << GPIO_CRL_CNF7_Pos); } Я не могу эту вещь объяснить. Почему настройки пинов, которые не используются в коде, так странно влияют на скорость выполнения программы контроллером? Мало того, в базовом проекте, на точно таком же коде я обнаружил обратный эффект: вызов этой функции инициализации портов замедляет мигание, а комментирование ее вызова - ускоряет. В общем, я в недоумении. Я вообще не ожидал, что такое поведение возможно. Это тормозит разработку домашнего проекта, потому то в нем критична реакция на сигналы длительностью ~500нс, и тут я вижу, что тупой бесконечный цикл работает с разной скоростью в зависимости от инициализации неиспользуемых портов. Вопрос 1: Как единственный вызов этой функции может влиять на скорость выполнения основного цикла? Вопрос 2: Почему вызов этой функции может давать строго обратный эффект?
  20. Привет, народ. Пытаюсь разобраться как прошивать плату STM32F103C8T6 (Blue Pill) по miniUSB-кабелю. Свои изыскания я записываю здесь: Как прошивать Blue Pill STM32 F103 через обычный USB-кабель в Linux Затык происходит на том, что я прошиваю DFU-бутлоадер в плату, плата становится видна по USB: [25760.232130] usb 2-2: new full-speed USB device number 7 using xhci_hcd [25760.385437] usb 2-2: New USB device found, idVendor=1eaf, idProduct=0004, bcdDevice= 2.00 [25760.385444] usb 2-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0 [25760.385447] usb 2-2: Product: Maple [25760.385449] usb 2-2: Manufacturer: LeafLabs [25760.424009] cdc_acm 2-2:1.0: ttyACM0: USB ACM device [25760.424307] usbcore: registered new interface driver cdc_acm [25760.424310] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters Однако утилита dfu-util (версии 0.9) ни одной платы не видит. И версия 0.8 тоже не видит: > dfu-util --list dfu-util 0.9 Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc. Copyright 2010-2016 Tormod Volden and Stefan Schmidt This program is Free Software and has ABSOLUTELY NO WARRANTY Please report bugs to http://sourceforge.net/p/dfu-util/tickets/ Пробовал давать команду с указанием id-шников устройства: dfu-util -d 1eaf:0004 --list так тоже DFU-устройство не обнаруживается. Пробовал и под рутом, и от обычного пользователя, хотя DBUS правило для доступа пользователем прописывается при установке пакета dfu-util (Debian Linux 11). Что еще нужно донастроить, чтобы увидеть DFU-устройство?
  21. Продаются оказавшиеся лишними новые компоненты: STM32L151CCT6 80 шт - по 1000 р STM32L151C6U6A 29 шт - по 500 р atmega328pb 7 шт по 600 р Резисторы SQP 10 Вт 36 Ом 200 шт по 20 р BD244C TO-220 100 шт по 80 р itcrs собак sibnet.ru Возможны различные варианты как по оплате так и по доставке.
  22. Привет, народ. Купил себе на пробу STM32F103C8T6 (BluePill) с программатором STLink-V2. Вот что о нем рассказывает st-info --probe: Found 1 stlink programmers serial: 132014026315303030303032 openocd: "\x13\x20\x14\x02\x63\x15\x30\x30\x30\x30\x30\x32" flash: 65536 (pagesize: 1024) sram: 20480 chipid: 0x0410 descr: F1 Medium-density device Установил среду STM32CubeIDE Version: 1.8.0 Build: 11526_20211125_0815 (UTC). И попытался собрать и запустить программку мигания светодиодом. Сделал новый проект для STM32F103C8Tx, настройки брал из вот этого видео: https://www.youtube.com/watch?v=e_NSqz5P8Qk По-сути сгенерировался дефолный проект для STM32F103C8Tx, частота настроена на 72MHz, активирован пин PC13 на режим Output. В коде в бесконечный цикл вписаны команды: while (1) { HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13); HAL_Delay(500); } По ходу попыток запуска, вначале STM32CubeIDE сказал, что прошивка устарела, и надо обновить. Я согласился, но пришлось пару раз вставить-вытащиить программатор в USB, так как была ошибка: st-link is not in the DFU mode. Please restart it. Прошивка залилась, а в сети нашел инфу что если обновление прошивки предваряется такой ошибкой, то это нормально. Потом пришлось подредактировать файл stm32f1x.cfg, так как при запуске была ошибка: linux gdb ST-LINK: Could not verify ST device! Abort connection. Эту ошибку убрал по инструкции: https://stackoverflow.com/questions/58783393/atollic-couldnt-verify-st-device, заодно отладку переключил с STLink GDB Server на STLink OpenOCD (сам GDB, естественно, установлен и работает, обычный C/C++ код через него отлаживается). В результате, после устранения предыдущей ошибки, стали появляться другие ошибки: Error: STM32F103C8Tx.cpu -- clearing lockup after double fault Polling target STM32F103C8Tx.cpu failed, trying to reexamine Насколько я понял, эти ошибки возможны из-за того, что программа либо не запускается, либо крашится уже на самом микроконтроллере по причине неправильной настройки диапазонов адресного пространства или какой-то периферии. Тогда я решил снова сделать новый проект, все повторил заново, и на этот раз почти получилось. Во всяком случае, явных ошибок в логе запуска нет. Но светодиод не мигает, отладка не работает: Open On-Chip Debugger 0.11.0+dev-00438-ga75fc63 (2021-11-03-15:26) Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html Info : Listening on port 6666 for tcl connections Info : Listening on port 4444 for telnet connections Info : STLINK V2J39S7 (API v2) VID:PID 0483:3748 Info : Target voltage: 2.427853 Info : Unable to match requested speed 8000 kHz, using 4000 kHz Info : Unable to match requested speed 8000 kHz, using 4000 kHz Info : clock speed 4000 kHz Info : stlink_dap_op_connect(connect) Info : SWD DPIDR 0x2ba01477 Info : STM32F103C8Tx.cpu: Cortex-M3 r2p1 processor detected Info : STM32F103C8Tx.cpu: target has 6 breakpoints, 4 watchpoints Info : starting gdb server for STM32F103C8Tx.cpu on 3333 Info : Listening on port 3333 for gdb connections Info : accepting 'gdb' connection on tcp/3333 Info : device id = 0x20036410 Info : flash size = 64kbytes undefined debug reason 8 - target needs reset O.K. O.K.:0xE00FFFD0 undefined debug reason 8 - target needs reset shutdown command invoked Info : dropped 'gdb' connection Я пробовал собрать и запуститься в режиме релиза (переткнул и конфигурацию и билд на Release), но почему-то при запуске RUN все равно IDE пытается запустить дебаггер, ей это не удается, лог запуска все тот же. Дальше я уже не знаю что делать. Прошу посоветовать что где еще надо докрутить, чтобы помигать светодиодом. * * * UPD: Иногда запуск почему-то происходит по-другому, хотя ничего ни в коде ни в конфигурации не меняю. Запуск сопровождается появлением окна с ошибкой: Could not verify STM device! Хотя, как написано выше, такая ошибка была, и верификация устройства отключена (в начало файла stm32f1x.cfg добавлена строка set CPUTAPID 0). Выхлоп запуска при этом немного другой, строки с Info те же самые, но в конце такие ошибки: undefined debug reason 8 - target needs reset O.K. O.K.:0xE00FFFD0 Error: Failed to read memory at 0xfffffffe Error: Failed to read memory at 0xfffffffe undefined debug reason 8 - target needs reset shutdown command invoked Info : dropped 'gdb' connection Вот как выглядит скриншот: https://ibb.co/JvyD2HK
  23. Добрый вечер, настроена база для передачи информации по сети CAN. не работает простой колбек (помигать светодиодом при получении сообщения) . Если смотреть при отладке код вылетает из if как я понял в моменте проверки на наличие инфы в FIFO. Rx data после отправки сообщения остается пустым. Буду благодарен за любой совет, готов ответить на конкретизирующие вопросы. /* Private variables ---------------------------------------------------------*/ ADC_HandleTypeDef hadc; CAN_HandleTypeDef hcan; TIM_HandleTypeDef htim1; /* USER CODE BEGIN PV */ CAN_TxHeaderTypeDef TxHeader; CAN_RxHeaderTypeDef RxHeader; uint32_t TxMailbox = 0; uint8_t TxData[8] = {0,}; uint8_t RxData[8] = {0,}; CAN_FilterTypeDef sFilterConfig; /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_ADC_Init(void); static void MX_CAN_Init(void); static void MX_TIM1_Init(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_ADC_Init(); MX_CAN_Init(); MX_TIM1_Init(); /* USER CODE BEGIN 2 */ HAL_TIM_Base_Start(&htim1); HAL_CAN_Start(&hcan); TxHeader.ExtId = 0; TxHeader.RTR = CAN_RTR_DATA; TxHeader.IDE = CAN_ID_STD; TxHeader.DLC = 8; TxHeader.TransmitGlobalTime = ENABLE; HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING | CAN_IT_ERROR | CAN_IT_BUSOFF | CAN_IT_LAST_ERROR_CODE); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { if(HAL_CAN_GetTxMailboxesFreeLevel(&hcan) > 0) { TxHeader.StdId = 0x0378; for (uint8_t i = 0; i < 8; i++) { TxData[i] = i; } } HAL_CAN_AddTxMessage(&hcan, &TxHeader, TxData, &TxMailbox); HAL_Delay(500); HAL_CAN_GetRxMessage(&hcan, CAN_RX_FIFO0, &RxHeader, RxData); if(HAL_CAN_GetRxMessage(&hcan, CAN_RX_FIFO0, &RxHeader, RxData) == HAL_OK) { HAL_GPIO_WritePin(Led2_GPIO_Port,Led2_Pin, GPIO_PIN_SET); HAL_Delay(50); HAL_GPIO_WritePin(Led2_GPIO_Port,Led2_Pin, GPIO_PIN_RESET); } HAL_Delay(500); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } ....описание функицй static void MX_CAN_Init(void) { /* USER CODE BEGIN CAN_Init 0 */ /* USER CODE END CAN_Init 0 */ /* USER CODE BEGIN CAN_Init 1 */ /* USER CODE END CAN_Init 1 */ hcan.Instance = CAN; hcan.Init.Prescaler = 4; hcan.Init.Mode = CAN_MODE_NORMAL; hcan.Init.SyncJumpWidth = CAN_SJW_1TQ; hcan.Init.TimeSeg1 = CAN_BS1_8TQ; hcan.Init.TimeSeg2 = CAN_BS2_7TQ; hcan.Init.TimeTriggeredMode = DISABLE; hcan.Init.AutoBusOff = DISABLE; hcan.Init.AutoWakeUp = DISABLE; hcan.Init.AutoRetransmission = DISABLE; hcan.Init.ReceiveFifoLocked = DISABLE; hcan.Init.TransmitFifoPriority = DISABLE; if (HAL_CAN_Init(&hcan) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN CAN_Init 2 */ sFilterConfig.FilterBank = 0; sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; sFilterConfig.FilterIdHigh = 0x0000; sFilterConfig.FilterIdLow = 0x0000; sFilterConfig.FilterMaskIdHigh = 0x0000; sFilterConfig.FilterMaskIdLow = 0x0000; sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0; sFilterConfig.FilterActivation = ENABLE; sFilterConfig.SlaveStartFilterBank = 14; /* USER CODE END CAN_Init 2 */ } void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) { if(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, RxData) == HAL_OK) { HAL_GPIO_WritePin(Led2_GPIO_Port,Led2_Pin, GPIO_PIN_SET); HAL_Delay(50); HAL_GPIO_WritePin(Led2_GPIO_Port,Led2_Pin, GPIO_PIN_RESET); HAL_Delay(50); } }
  24. Разработка электроники. Полное ведение проекта, от проработки устройства, написания софта и firmware до отладки образца. FPGA Xilinx - проекты любой сложности. Опыт больше 20 лет. STM32 - включая BLE устройства. Большой опыт разработки для разных заказчиков. Altium Designer - разработка печатных плат. Опыт работы с JKLC PCB. Сделаны многие проекты. Написание приложений под ОС Android. ADC приложения и ЦОС (DSP). Почта для связи [email protected]
  25. Всем добрый день! На работе поручили заняться разработкой нового прибора на микроконтроллере STM32 (исходя из технической задачи мой выбор пал на STM32F407VE) с обязательным условием - использование ОСРВ FreeRTOS. С микроконтроллерами знаком, разрабатывал на их основе пару приборов, но с данной ОСР не работал никогда, и поэтому хочу попросить здесь совета. Работаю в STM32CubeIDE. Одна из возможностей моего девайся - это ручное управление коллекторным двигателем. В проекте я настроил две ножки на внешние прерывания GPIO_EXTI_3 и GPIO_EXTI_4. Включена подтяжка по питанию и срабатывание прерывания по любому изменению фронта сигнала (прибор должен реагировать на нажатие/отпускание кнопок. Пока одна из кнопок нажата - крутим вверх или вниз, а если отпустили, то остановка). Схемотехнически нажатие кнопки коммутирует вход МК с землёй. Программно я себе это представлял так: Срабатывание прерывания на одном из входов -> В перывании определяем, какой именно фронт пришёл -> Если фронт низкий, то крутим двигатель || Если фронт высокий, то останавливаемся. Вставлять в прерывание функцию вращения двигателем я, разумеется не стал. Вместо этого я решил в зависимости от статуса кнопки пересылать в функцию управления двигателем семафор. Условно говоря, код выглядит так: void EXTI3_IRQHandler(void) //Кнопка вращения двигателя вверх { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_3); if(HAL_GPIO_ReadPin(GPIOD,GPIO_PIN_3) == GPIO_PIN_SET) //Если на входе высокий уровень, то пока ничего не делаем { asm("nop"); } else //Если уровень изменился, то { xSemaphoreGiveFromISR(sem_curr_upHandle,NULL); //Даём семафор из прерывания } } // void EXTI4_IRQHandler(void) //Кнопка вращения двигателя вниз { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4); if(HAL_GPIO_ReadPin(GPIOD,GPIO_PIN_4) == GPIO_PIN_SET) //Если высокий уровень, то ничего не делаем { asm("nop"); } else //В противном случае выдаём семафор { xSemaphoreGiveFromISR(sem_curr_downHandle,NULL); } } Задача, в которой я собираюсь вращать двигателем, выглядит так: void poll_button(void const * argument) { for(;;) { if(xSemaphoreTake(sem_curr_upHandle,portMAX_DELAY) == pdPASS) //Если семафор на вращение вверх принят функцией и равен одному (время ожидания семафора максимальное) { HAL_GPIO_WritePin(GPIOA,GPIO_PIN_9,GPIO_PIN_SET); } else if(xSemaphoreTake(sem_curr_downHandle,portMAX_DELAY) == pdPASS) //Если семафор на вращение вниз принят функцией и равен одному (время ожидания семафора максимальное) { HAL_GPIO_WritePin(GPIOA,GPIO_PIN_10,GPIO_PIN_SET); } } } В качестве отлаживающего механизма использую светодиоды (их и пытаюсь зажечь на отладочной плате в зависимости от полученного семафора), но после прошивки платы ничего не происходит. Я понимаю, что код ещё не дописан, так как после отжатия кнопки мне надо вернуть семафор обратно (правильно ли - "вернуть"?), но по идее данная конструкция уже должна его "выдать", а задача - "принять", и в соответствии с этим что-то сделать. Поэтому мои вопросы заключаются в следующем: 1. Правильна ли моя идея с использованием семафоров в принципе для данной ситуации? В любом случае, эту ОСРВ мне надо изучать по работе; 2. После отдачи семафора по нажатию кнопки - как его вернуть обратно после её отжатия? 3. Задача poll_button не реагирует на полученный семафор. Если в одном из условий изменить "== pdPass" на "!= pdPass", то светодиод будет гореть, но если так сделать в двух условиях, то всё равно будет гореть только один светодиод, будто бы задача по какой-то причине зависает. Что это может быть? Заранее всех благодарю за ответы.
×
×
  • Create New...