Я создаю проект Keil для своего микроконтроллера STM32F103 с помощью STM32CubeMx.
Моя цель - использовать канал 2 TIM1 для управления зуммером. Я хочу генерировать ШИМ на частоте 4 кГц через канал 2 TIM1. Я настроил с помощью STM32CubeMx TIM1_Channel2 как «Генератор ШИМ CH2».
Проблема касается сеанса отладки. В частности, когда я запускаю сеанс отладки и когда MCU выполняет макрос "__HAL_AFIO_REMAP_TIM1_ENABLE()", происходит сбой сеанса отладки.
Это код инициализации таймера, сгенерированный STM32CubeMx:
void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(htim->Instance==TIM1)
{
/* USER CODE BEGIN TIM1_MspPostInit 0 */
/* USER CODE END TIM1_MspPostInit 0 */
/**TIM1 GPIO Configuration
PE11 ------> TIM1_CH2
*/
GPIO_InitStruct.Pin = GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
__HAL_AFIO_REMAP_TIM1_ENABLE();
/* USER CODE BEGIN TIM1_MspPostInit 1 */
/* USER CODE END TIM1_MspPostInit 1 */
}
}
Эта проблема связана с полным переназначением контакта Timer1.
У кого-нибудь есть такая же проблема?
Спасибо!
=== ОБНОВЛЕНИЕ ===
Наконец-то я нашел время протестировать решение, предложенное @SamGibson, и оно работает! И спасибо @Rafiq Rahman за его код!
Спасибо, ребята, за ваше время!
Это код, который я использовал для переназначения TIM1 и сохранения возможности генерировать код с помощью Stm32CubeMX.
if(htim->Instance==TIM1)
{
/* USER CODE BEGIN TIM1_MspPostInit 0 */
#undef __HAL_AFIO_REMAP_TIM1_ENABLE
#define __HAL_AFIO_REMAP_TIM1_ENABLE() (0)
/* USER CODE END TIM1_MspPostInit 0 */
/**TIM1 GPIO Configuration
PE11 ------> TIM1_CH2
*/
GPIO_InitStruct.Pin = GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
__HAL_AFIO_REMAP_TIM1_ENABLE();
/* USER CODE BEGIN TIM1_MspPostInit 1 */
/* Make a copy of AFIO register */
volatile uint32_t afioRegisterCopy = AFIO->MAPR;
/* Clear Timer1 remap bits and + JTAG/SWD bits */
afioRegisterCopy &= ~((7 << 24) + (3 << 6));
/* To perform a full remap Timer1, bit 6-7 of
AFIO->MAPR must be set. Mask is 3 (11b) */
afioRegisterCopy |= (3 << 6);
/* Apply the new register configuration*/
AFIO->MAPR = afioRegisterCopy;
/* USER CODE END TIM1_MspPostInit 1 */
}
STM32F103 [...] STM32CubeMx [...] когда я запускаю сеанс отладки и когда MCU выполняет макрос "__HAL_AFIO_REMAP_TIM1_ENABLE()", происходит сбой сеанса отладки.
Я не использую STM32CubeMX HAL, но могу объяснить проблему и обходной путь.
Проблема в том, что серия STM32F1 имеет один регистр AFIO_MAPR
, который содержит настройки для переназначения различных периферийных устройств и для включения/отключения соединения JTAG/SWD с вашим отладчиком. И чтобы сделать это еще более сложным, биты в этом регистре, которые включают/отключают настройки JTAG/SWD ( bits 24-26
), доступны только для записи, поэтому их текущее состояние не может быть прочитано .
См. этот отрывок из справочного руководства STM32F1 :
Это означает, что любая попытка изменить настройки различных битов «переназначения периферийных устройств» путем выполнения последовательности «чтение-изменение-запись» в этом регистре может привести к считыванию других значений вместо реальных текущих значений в битах JTAG/SWD. Затем, когда запись в регистр завершена, ваш доступ к отладчику прекращается, потому что все, что было прочитано из этих битов JTAG/SWD, записывается обратно в них. (Сообщалось и о других эффектах, но я не буду сейчас вдаваться в подробности).
Из того, что я смог найти без установки HAL, используются следующие макросы:
#define __HAL_AFIO_REMAP_TIM1_ENABLE() MODIFY_REG(AFIO->MAPR, AFIO_MAPR_TIM1_REMAP, AFIO_MAPR_TIM1_REMAP_FULLREMAP)
и MODIFY_REG
это:
#define MODIFY_REG(REG, CLEARMASK, SETMASK) WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK)))
Итак, как вы видите, MODIFY_REG
выполняется чтение-изменение-запись, и вы не знаете, какие значения он будет считывать из JTAG/SWD bits 24-26
и, следовательно, какие значения он будет записывать туда! Значения, считанные из этих битов, являются «неопределенными» (цитируя ST), и я знаю, что читал разные значения с одного и того же STM32F1 в разное время.
«Исправление», которое я использовал с SPL, состоит в том, чтобы изменить любой код переназначения, чтобы специально установить биты JTAG/SWD, которые вы хотите, всякий раз, когда вы записываете в регистр AFIO_MAPR
. Вам нужно будет выяснить, как вы хотите сделать то же самое с кодом HAL. Один из способов — использовать временную переменную, чтобы из памяти последовательность выглядела так:
К счастью, ST изменился на лучшее расположение регистров в более поздних моделях STM32 (например, STM32F4).
Вот рабочий фрагмент кода, иллюстрирующий шаги, предложенные @SamGibson. Это работает для меня как шарм. Первое, что нужно сделать, это закомментировать файл __HAL_AFIO_REMAP_TIM1_ENABLE();
stm32f1xx_hal_msp.c и заполнить его кодом переназначения следующим образом:
//__HAL_AFIO_REMAP_TIM1_ENABLE();
/* USER CODE BEGIN TIM1_MspPostInit 1 */
volatile uint32_t map_copy = AFIO->MAPR;
map_copy &= ~((7 << 24) + (3 << 6)); // Clear desired bitfields + debug bits
// 5(101b) shifted left 24 for CoreSight SW-DP (What Keil Ulink2 and St-LinkV2
//use for debugging in either Keil IDE or SW4STM32 IDE)
// The (3 << 6) is me wanting to fully remap the TIM1 AF pins for
//Complementary PWM Generation
map_copy |= (5 << 24) + (3 << 6);
AFIO->MAPR = map_copy;
/* USER CODE END TIM1_MspPostInit 1 */
Просто следите за другими вызовами MspPostInit...
Ваше здоровье.
Федерико