STM32 Toggle PIN при остановке цели

Я использую микроконтроллеры серии STM32F7, и было бы очень полезно иметь какое-то значение изменения GPIO (переключение, импульс, высокий z, ...) всякий раз, когда ядро ​​останавливается отладчиком, подключенным к интерфейсу JTAG. Кто-нибудь знает о такой функции?


person Arne    schedule 04.10.2017    source источник
comment
IMO это невозможно сделать, так как остановка ядра не должна изменять состояние uC. Может быть, у некоторых датчиков есть штырь, который сигнализирует об этом - но я не знаю.   -  person 0___________    schedule 05.10.2017


Ответы (1)


Есть регистры DBGMCU, которые могут выборочно останавливать определенные периферийные устройства (в основном таймеры) при остановке ядра.

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

Сконфигурируйте TIM3 для вывода сигнала ШИМ с очень высоким коэффициентом заполнения, начиная с низкого уровня в течение двух циклов, а затем переходя в высокий уровень в течение оставшегося периода продолжительностью 65536 циклов. Подчините его TIM2, который работает с периодом в 2 цикла и сбрасывает TIM3 при переполнении счетчика. Таким образом, TIM3 принудительно устанавливается на постоянный низкий уровень, пока работает TIM2, но он будет выдавать сигнал PWM с высоким уровнем 99,997%, когда TIM2 остановлен. Затем TIM2 настроен на остановку, когда ядро ​​останавливается отладчиком, но TIM3 продолжает работать.

RCC->AHBENR |= RCC_AHBENR_GPIOBEN; // enable peripheral clocks, that might be different on your board
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN | RCC_APB1ENR_TIM3EN;

// consult your datasheet for the right AF value
GPIOB->AFR[0] = (GPIOB->AFR[0] & ~GPIO_AFRL_AFRL0) | 2; // set PB0 to Alternate Function 2, TIM3
GPIOB->MODER = (GPIOB->MODER & ~GPIO_MODER_MODER0) | GPIO_MODER_MODER0_1; // set PB0 to Alternate Function

DBGMCU->APB1FZ |= DBGMCU_APB1_FZ_DBG_TIM2_STOP; // stop TIM2 when core is stopped
DBGMCU->APB1FZ &= ~DBGMCU_APB1_FZ_DBG_TIM3_STOP; // but don't stop TIM3

TIM2->ARR = 1;                  // master timer period
TIM2->CR2 = TIM_CR2_MMS_1;      // master mode selection MMS=010 Update event
TIM2->CR1 = TIM_CR1_CEN;        // enable timer 2

TIM3->ARR = 65535;              // PWM period
TIM3->CCR3 = 2;                 // channel 3 PWM duty cycle
TIM3->CCMR2 = TIM_CCMR2_OC3M;   // set channel 3 to PWM mode 2
TIM3->CCER = TIM_CCER_CC3E      // enable channel 3 compare output
        /* | TIM_CCER_CC3P */;  // it's possible to invert output polarity
TIM3->SMCR = TIM_SMCR_TS_0      // trigger selection TS=001 ITR1 = TIM2 is master
        | TIM_SMCR_SMS_2;       // slave mode SMS=100 reset mode
TIM3->CR1 = TIM_CR1_CEN;        // enable timer 3

У меня нет F7, он работает на моей STM32L151 плате, на которой есть светодиод на PB0, TIM3 канале 3. Светодиод красиво загорается, когда я нажимаю кнопку приостановки в отладчике, низкий импульс - нет. невооруженным глазом заметно. Примените внешний фильтр нижних частот RC, чтобы он исчезал, когда он мешает любому компоненту. это связано с. Возможно, удастся вывести чистый сигнал с помощью одноимпульсного режима повторного запуска расширенных таймеров TIM1 или TIM8, но у меня нет опыта работы с ними.

person followed Monica to Codidact    schedule 05.10.2017
comment
два таймера для этой задачи (включая драгоценный 32-битный tim2), это перебор. - person 0___________; 05.10.2017
comment
Конечно, он будет работать с любой возможной парой таймеров главный-подчиненный. - person followed Monica to Codidact; 05.10.2017
comment
Но я не понимаю зачем? Для остановки очередного микропроцессора в многопроцессорной среде jtag имеет специальные механизмы. - person 0___________; 05.10.2017
comment
Возможно, это какой-то тупой компонент, который станет слишком горячим или переместится слишком далеко, когда контроллер не сможет его контролировать. - person followed Monica to Codidact; 06.10.2017