Например, неправильный startup файл. Проверьте в list действительно ли обработчик прерывания таймера линкуется и отображается в векторах прерываний.
А вообще, причин может быть немало.
_________________ Платы для HLDI - установки лазерной засветки фоторезиста. ФоторезистыOrdyl Alpha 350 и AM 140. Жидкое олово для лужения плат (видео) - самое лучшее и только у меня. Паяльная маска XV501T-4 и KSM-S6189 (5 цветов). Заказ печатных плат - pcbsmac@gmail.com
_________________ Репозиторий STM32: https://cloud.mail.ru/public/2i19/Y4w8kKEiZ Актуальность репозитория: 6 декабря 2025 года Если чего-то не хватает с сайта st.com - пишите, докачаю.
Спасибо, так и есть. Не все прочитал, еще меньше понял. Еще и счетчик включить нужно, сначала думал что он и обновляется и запускается сам.
Добавлено after 6 hours 21 minute 50 seconds: Re: Микроконтроллеры STM32 - тонкости работы, отладочные платы Не могу сообразить еще одно. Таймер настроен на 1 МГц, т. е. 1000 в TIM3_CNT = 1 мсек. Старт-бит у моего пульта 4,5 мсек. импульс + 4,5 мсек. пауза. Должно ведь быть в регистре ТМ3_ССР1 = 9000? А там 18000, ну и все остальные импульсы так же. Если таймер настраивать для отсчета времени, то все совпадает, а почему в этом режиме нет?
Зависит от настроек каптуры. А ещё, смотрите что от пульта приходит, иногда несущая не фильтруется.
_________________ Репозиторий STM32: https://cloud.mail.ru/public/2i19/Y4w8kKEiZ Актуальность репозитория: 6 декабря 2025 года Если чего-то не хватает с сайта st.com - пишите, докачаю.
В общем я глянул на блок диаграмму в даташите, а там не указано что на таймеры стоит умножитель частоты. В общем все правильно- частота 84 МГц а не 42 МГц.
Иногда проще в кубике посмотреть, что там на шинах получается. Ведь на какой шине какое устройство известно же (через тот же RCC при активации тактов, например).
_________________ Репозиторий STM32: https://cloud.mail.ru/public/2i19/Y4w8kKEiZ Актуальность репозитория: 6 декабря 2025 года Если чего-то не хватает с сайта st.com - пишите, докачаю.
Заголовок сообщения: Re: Микроконтроллеры STM32 - тонкости работы, отладочные пла
Добавлено: Чт окт 30, 2025 12:03:36
Вымогатель припоя
Зарегистрирован: Пт май 20, 2022 12:28:46 Сообщений: 604
Рейтинг сообщения:-1
Господа, есть кубический вопрос
В проекте я использую специфический синтаксис с++. Собсно, настроил Сubeide как в мануале, плюс переименовал main.c в main.cpp (как предлагали на форуме STM) всё отлично компилируется.
Но если я пользуюсь визуальным конфигуратором (.ioc который), он вновь создает пустой файл main.c, который потом приходится мержить с проектом руками. Подскажите плиз, есть ли какой-нибудь способ заставить создавать (вернее вносить правки) файл с нужным расширением?
Чтобы не мержить нужно вставлять свой код в аккурат между комментами типа "Place your code here/End of user code". И тогда он, по идее, перенесёт код в новую версию.
_________________ Репозиторий STM32: https://cloud.mail.ru/public/2i19/Y4w8kKEiZ Актуальность репозитория: 6 декабря 2025 года Если чего-то не хватает с сайта st.com - пишите, докачаю.
Подскажите плиз, есть ли какой-нибудь способ заставить создавать (вернее вносить правки) файл с нужным расширением?
А в чём сложность? Не понял.
Код:
/* Initialize all configured peripherals */ MX_GPIO_Init(); MX_ADC1_Init(); /* USER CODE BEGIN 2 */
my_cpp_main();
/* USER CODE END 2 */
/* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */
/* USER CODE BEGIN 3 */ } /* USER CODE END 3 */
Добавлено after 6 minutes 55 seconds: Re: Микроконтроллеры STM32 - тонкости работы, отладочные платы
Silicoid писал(а):
Но если я пользуюсь визуальным конфигуратором (.ioc который), он вновь создает пустой файл main.c, который потом приходится мержить с проектом руками.
То, что вы хотите получить, полная чушь. Если используете МХ для настройки периферии, то тогда пишите на С, ну а коли решили использовать С++, то пишите работу с периферией сами, иначе ваша программа будет вызывать рвотный рефлекс как у адептов С, так и плюсовиков. Не знаю, как сейчас, но раньше С++ тошнило от кода МХ вплоть до ошибок компиляции. Так что следуйте совету из старого анекдота: "Абрам Моисеевич, вы или крестик снимите, или трусы наденьте!"
Заголовок сообщения: Re: Микроконтроллеры STM32 - тонкости работы, отладочные пла
Добавлено: Чт окт 30, 2025 14:37:03
Вымогатель припоя
Зарегистрирован: Пт май 20, 2022 12:28:46 Сообщений: 604
Рейтинг сообщения:0
tonyk писал(а):
А в чём сложность? Не понял.
Сложности нет. неудобство присутствует.
Тут штука в том, что визуально гораздо понятнее с какими ногами работаем. Когда у вас 64 ноги и на 58 из них что-то висит и самое плохое, что это что-то иногда еще и переползает с ноги на ногу, то держать в голове (или notepad++) где что подключено, ну очень неудобно. А тут хоть можно подписать какой вывод за что отвечает. Ну а когда всё устаканится, то перепишу. да.
Когда у вас 64 ноги и на 58 из них что-то висит и самое плохое, что это что-то иногда еще и переползает с ноги на ногу, то держать в голове (или notepad++) где что подключено, ну очень неудобно.
Для этого калокуб не нужен, достаточно лишь конфигуратор использовать. Из него же удобно выбрать наиболее подходящий МК по требованиям к периферии. А потом составляем табличку - что на какой ноге - и начинаем рисовать. По мере трассировки платы, естественно, будет возникать желание что-то куда-то передвинуть. Тут тоже вполне конфигуратор поможет. Подправляем свою табличку с ногами в Readme.md, и рисуем дальше. Ну, а по готовой печатной плате уже сформируется окончательная табличка, глядя на нее и напишем инициализацию периферии. И это будет красиво и удобно, а не блевотное дерьмище, которое генерирует калокуб.
Кстати, если уж знаете С++, то калокуб там вообще ни к черту: ведь благодаря "плюсовским" шаблонам можно очень красивый HAL сделать. Который не будет вырвиглазным блевотным кодом и реально позволит легко портировать код между семействами (кал от ST на самом деле этого не позволяет). Еще одним плюсом является то, что g++ все эти шаблоны свернет в итоге в одну операцию. И будет у вас что-то вроде REG = VAL, а не как у индусов от ST, когда 100500 раз идет REG |= FLAGS; REG &= ~FLAGS; … Видел я, как красиво можно под STM32 писать на С++. Жаль, я его осилить не могу, поэтому пишу на С, выдумывая всякие макросы, и получается вроде такого:
// bxCAN1 { "bxCAN1-TX", GPIOB, BIT_9, AF09, ALTFUNC, NO_PULL, PUSH_PULL, HIGH_SPEED }, { "bxCAN1-RX", GPIOB, BIT_8, AF09, ALTFUNC, PULL_UP, PUSH_PULL, HIGH_SPEED }, { 0 } // the end of the map marker #endif // __NUCLEO_F446RE__ };
Ещё нюанс. Потом переписать не получится. Вы же собираетесь использовать прерывания? Тогда нужно создать механизм для их обработки в стиле С++, а сие лучше сделать в стартапе, который тоже придётся переписать, и, желательно, на С++. Тогда появится возможность сделать обработчик прерывания виртуальным методом класса.
Код:
class HW_Cnt32 : public HW_Timer_base, protected IRQ { .... protected:
[quote="Silicoid"]Ещё нюанс. Потом переписать не получится. Вы же собираетесь использовать прерывания? Тогда нужно создать механизм для их обработки в стиле С++, а сие лучше сделать в стартапе, который тоже придётся переписать, и, желательно, на С++. Тогда появится возможность сделать обработчик прерывания виртуальным методом класса.
Вот это совсем не нужно и даже вредно в случае линковки с какими-либо библиотеками написанными на Си. А это хоть те же стандартные библиотеки. Куда проще обработчику прерывания добавить extern "C" и дёрнуть из него нужные методы класса.
Вот это совсем не нужно и даже вредно в случае линковки с какими-либо библиотеками написанными на Си. А это хоть те же стандартные библиотеки
Какая связь между вызовом обработчика прерывания как виртуального метода и стандартными библиотеками?
VladislavS писал(а):
Куда проще обработчику прерывания добавить extern "C" и дёрнуть из него нужные методы класса.
Как раз наоборот, проще через виртуальный метод. Обработкой прерывания занимается тот объект, которому это нужно. В случае с extern "C" разрывается логическая связь между объектом и обработчиком. Ну и раз уж мы используем ООП, то не будем уподобляться Абраму Моисеевичу из известного анекдота и чётко определимся, что нам следует надеть, трусы или крестик.
Прерывания принадлежат не объекту, а контрполлеру прерываний и процессору. Вот пример, не STM32, но суть понятна. Данные приходят из RS485, USB или Ethernet и обрабатываются одним и тем же протокольным классом, которому всё равно откуда свалились данные. Спойлер
Тогда нужно создать механизм для их обработки в стиле С++, а сие лучше сделать в стартапе, который тоже придётся переписать, и, желательно, на С++. Тогда появится возможность сделать обработчик прерывания виртуальным методом класса.
Почему именно нужно "переписывать стартап в стиле си++"? Чем ассемблерный стартап не подходит?
Тут штука в том, что визуально гораздо понятнее с какими ногами работаем. Когда у вас 64 ноги и на 58 из них что-то висит и самое плохое, что это что-то иногда еще и переползает с ноги на ногу, то держать в голове (или notepad++) где что подключено, ну очень неудобно. А тут хоть можно подписать какой вывод за что отвечает.
А в чём проблема описать все ноги в .h-файле? Вот один мой проект. Он может компилиться для 3-х разных плат (с по-разному распределённой периферией/цепями, даже компоненты некоторые отличаются). Соответственно - в составе исходников есть 3 файла "board_xxx.h" с содержимымм подобным:
Код:
#ifndef BOARD_..._H #define BOARD_..._H
#define CLKIN_XTAL 24000000 //[Hz] frequency of external main crystal or oscillator #define CLKIN_OSCHP 1 //==1 - generator on XTAL1 (Direct Input Mode); ==0 - quartz on XTAL1/2 (Crystal Mode) #define CLKIN_RTCX 32768 //[Hz] external frequency for RTC
//Allocation USIC-s #define nUSIC_df 2, 1 //USIC/channel's number for SPI-FLASH #define nUSIC_rf 0, 1 //USIC/channel's number for RF-unit #define nUSIC_service 0, 0 //USIC/channel's number for log-UART #define nUSIC_term 2, 0 //USIC/channel's number for UART of terminal //Allocation CCU-timers/slices #define nCCU_intmon 40, 0 //timer/slice numbers for monitoring of duration of interrupts bans (for debug) #define nCCU_dac_trig 40, 1 //timer/slice numbers for trigger-signals for DAC #define nCCU_dac_exe 40, 2 //timer/slice numbers for interrupt generation in middle/end of DMA-block of DAC #define nCCU_adc_trig 41, 0 //timer/slice numbers for trigger-signals for ADC #define nCCU_adc_res 41, 1 //timer/slice numbers #define nCCU_buzzer 40, 3 //timer/slice numbers for buzzer
#define PIN_SERV_RX 1, 4 //RX nUSIC_service #define PIN_SERV_TX 1, 5 //TX nUSIC_service #define PIN_TERM_RX 5, 1 //RX nUSIC_term #define PIN_TERM_TX 5, 0 //TX nUSIC_term #define PIN_LED1 5, 9 //LED1; bool."1" - is lighting #define PIN_LED2 3, 14 //LED2; bool."1" - is lighting #define PIN_LED3 6, 0 //LED3; bool."1" - is lighting #define PIN_BUZZER 0, 12 //==1 - buzzer enable #define PIN_DAC_GEN 14, 8 //generator's output #define PIN_DF_SCLK 4, 2 //SCLK for nUSIC_df #define PIN_DF_MOSI 4, 7 //MOSI for nUSIC_df #define PIN_DF_MISO 4, 6 //MISO for nUSIC_df #define PIN_DF_CS 4, 3 //CS for N25Q032A on nUSIC_df #define PIN_DF_WP 4, 5 //WP for N25Q032A #define PIN_DF_HOLD 4, 4 //HOLD for N25Q032A #define PIN_A_IN1 14, 0 //analog input 1 #define PIN_A_IN2 14, 1 //analog input 2 #define PIN_RF_SCLK 3, 0 //SCLK for nUSIC_rf #define PIN_RF_MOSI 3, 13 //MOSI for nUSIC_rf #define PIN_RF_MISO 4, 0 //MISO for nUSIC_rf #define PIN_RF_CS 3, 1 //CS for RF-unit #define PIN_RF_RST 3, 12 //NRESET for RF-unit; active - bool.0, >=100mcs, >=5ms - startup time #define PIN_RF_BOOST 0, 13 //BOOST switch control #define PIN_RF_LF 0, 14 //antenna switch control LF #define PIN_RF_HF 0, 15 //antenna switch control HF #define PIN_DIAG 2, 2 //thermal protection input from generator
//Allocation GPDMA lines (DMALINEx_...) for DLR. Channels are allocated similarly. #define nDMALINE_dac 1 #define nDMALINE_df_RX 8 #define nDMALINE_df_TX 9 //Allocation of Service Requests for all CCUs. Each element also needs to be added to the list CHK_SRCCU! #define nCCU_SR_intmon 0, nCCU_intmon //SR for nCCU_intmon #define nCCU_SR_dac_trig 1, nCCU_dac_trig //SR for DAC-triggering #define nCCU_SR_dac_exe 2, nCCU_dac_exe //SR generating an interrupt in middle/end of a block of samples transmitted to the DAC #define nCCU_SR_adc_trig 2, nCCU_adc_trig //SR for ADC-triggering #define nCCU_SR_adc_res 1, nCCU_adc_res //SR reading result from ADC #define nCCU_SR_buzzer 3, nCCU_buzzer //SR interrupt for buzzer control //Allocation of Service Requests for all USICs. Each element also needs to be added to the list CHK_SRUSIC! #define nUSIC_SR_serv_RX 3, nUSIC_service #define nUSIC_SR_serv_TX 4, nUSIC_service #define nUSIC_SR_serv_ERR 5, nUSIC_service #define nUSIC_SR_term_RX 3, nUSIC_term #define nUSIC_SR_term_TX 4, nUSIC_term #define nUSIC_SR_term_ERR 5, nUSIC_term #define nUSIC_SR_df_RX 0, nUSIC_df #define nUSIC_SR_df_TX 1, nUSIC_df #define nUSIC_SR_df_ERR 2, nUSIC_df #define nUSIC_SR_rf_RX 0, nUSIC_rf #define nUSIC_SR_rf_ERR 1, nUSIC_rf
#endif
А в остальном коде вычисления всех ног, портов, DMA-каналов, АЦП-каналов и т.п. - выполняются при помощи макросов на основе этих define-ов. И ни одного выражения с магическим номером типа UART1 в коде нет. Такой код очень легко перебрасывать в другой проект, с другой платой (но таким же МК).
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 27
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения