带有 STM32 的 SEGGER:无法连接到目标。未检测到 idcode
Posted
技术标签:
【中文标题】带有 STM32 的 SEGGER:无法连接到目标。未检测到 idcode【英文标题】:SEGGER with STM32: Failed to connect to target. No idcode detected 【发布时间】:2021-08-28 11:17:32 【问题描述】:我一直在尝试在 STM32H7B3 板上设置 PLL 时钟频率,我可以通过在下面的代码中设置 DIVN 乘法器 (RCC_PLL1DIVR_N1) 来实现。上次我能够成功执行此操作是将乘数设置为 1。当我尝试下载乘数设置为 0x18F (= 399) 的代码时,我收到了上述错误消息。我现在意识到,由于 sys_ck 规范,我应该尝试的最大值可能是 DIVN = 280,但尽管如此,错误发生在下载代码时,而不是运行它。我尝试使用重置按钮,但无济于事。我现在无法连接到开发板,我不知道还能尝试什么。
RCC -> CFGR &= 0; // Reset register
int32_t cfgr = RCC -> CFGR;
int32_t sws_pll1 = RCC_CFGR_SWS_PLL1;
int32_t status = cfgr & sws_pll1;
while (!status)
cfgr = RCC -> CFGR;
sws_pll1 = RCC_CFGR_SWS_PLL1;
status = cfgr & sws_pll1;
// System clock switch status: Wait until PLL1 is system clock; TODO: hangs*/
// RCC source control register
RCC->CR |= RCC_CR_HSION; // HSI clock enable
while (!(RCC->CR & RCC_CR_HSIRDY)); // Wait until HSI clock is ready
/* -------- PLL Config -------- */
// RCC PLLs clock source selection register
RCC -> PLLCKSELR |= RCC_PLLCKSELR_PLLSRC_HSI; // Select HSI as PLL clock source (hsi_ck)
// Note: Must have PLL1ON = 0 for modifying prescaler
RCC -> PLLCKSELR &= ~RCC_PLLCKSELR_DIVM1; // Reset prescaler for PLL1 to disabled
RCC -> PLLCKSELR |= RCC_PLLCKSELR_DIVM1_5; // Set prescaler for PLL1 to divsion by 32
// RCC PLL1 fractional divider register
RCC -> PLL1FRACR = 0; // Set FRACN to 0
// RCC PLLs configuration register
RCC -> PLLCFGR |= RCC_PLLCFGR_PLL1FRACEN; // PLL1 franctional latch enable
RCC -> PLLCFGR &= ~RCC_PLLCFGR_PLL1VCOSEL; // Select PLL1 output frequency range: wide VCO range from 128 to 560 MHz
RCC -> PLLCFGR |= RCC_PLLCFGR_PLL1RGE_3; // Select PLL1 input reference frequency range: between 8 and 16 MHz
// Note: Must have PLL1ON = 0 and PLL1RDY = 0 for enabling divider output
RCC -> PLLCFGR |= RCC_PLLCFGR_DIVP1EN; // PLL1 DIVP divider output enable
RCC -> PLLCFGR |= RCC_PLLCFGR_DIVQ1EN; // PLL1 DIVQ divider output enable
RCC -> PLLCFGR |= RCC_PLLCFGR_DIVR1EN; // PLL1 DIVR divider output enable
// RCC PLL1 dividers configuration register
// Note: Must have PLL1ON = 0 and PLL1RDY = 0 for writing bits
RCC -> PLL1DIVR &= 0; // Reset register
RCC -> PLL1DIVR |= (0x1 << RCC_PLL1DIVR_N1_Pos) & RCC_PLL1DIVR_N1; // DIVN = 0x18F = 399
RCC -> PLL1DIVR |= (0x1 << RCC_PLL1DIVR_P1_Pos) & RCC_PLL1DIVR_P1; // DIVP = 1
RCC -> PLL1DIVR |= (0x1 << RCC_PLL1DIVR_Q1_Pos) & RCC_PLL1DIVR_Q1; // DIVQ = 1
RCC -> PLL1DIVR |= (0x1 << RCC_PLL1DIVR_R1_Pos) & RCC_PLL1DIVR_R1; // DIVR = 1
// RCC source control register
RCC -> CR |= RCC_CR_PLL1ON; // PLL1 enable
//while((RCC -> CR & RCC_CR_PLL1RDY) == 0); // Wait until PLL1 clock is ready; TODO: hangs
更新:我运行了 JLinkSTM32,但它打印了以下内容:
Connecting to J-Link via USB...O.K.
Using SWD as target interface.
Target interface speed: 1000 kHz.
VTarget = 3.299V
Reset target...O.K.
Reset option bytes to factory settings...
Option bytes reset to factory settings.
Resetting option bytes failed.
Press any key to exit.
【问题讨论】:
虽然我通常不喜欢它,但 STM32CubeMX 工具有一个时钟树工具,可以根据所需的系统时钟、I2S、USB、AHB 等时钟速率等约束条件为您确定 PLL 和分频器设置。如果您手动使用它,它将突出显示冲突。您不必使用其生成的代码,只需将设置复制到您自己的代码中即可。鉴于各种 STM32 部件上时钟树的差异和复杂性,我推荐它。一些较旧的部件为此提供了电子表格,但您必须设法让 Excel 运行宏才能使其正常工作。 这个乘数对我来说似乎很疯狂。上次我做 PLL 时,我使用了 mul 8 div 2 之类的东西。我同意 @Clifford 使用我的时钟树来降低值。 @Sorenp 我使用 DIVM 除以 32,使用 DIV(P/Q/R) 除以 2,因此 64 MHz HSI 时钟变为 1 MHz,然后乘以 DIVN 的值。它可能高于应有的水平,但低于 2 倍。 @Sorenp 我认为他指的是那里的 DIVNx 值,而不是乘数。 STM32 PLLS 和时钟树非常灵活和复杂,H7 是一个 280MHz 的部分,可以使用 4MHz 外部晶振或振荡器运行,并具有三个独立的 PLLS。 【参考方案1】:运行命令行JLinkSTM32.exe
实用程序(随 J-Flash 工具一起安装),选择选项 9(对于 STM32H7xxxx)并希望(需要几秒钟的时间)。
如果成功,它可能会批量擦除闪存,并将重置整个芯片的选项字节。它让我摆脱了许多无法通过 J-Flash GUI 工具恢复的莫名其妙的锁定情况。
【讨论】:
我尝试运行它似乎有重置选项字节的问题。输出如上所示。 顺便说一下,这是我能够为 H7 系列选择的两个选项: [9] STM32H743_53_50 [10] STM32H745_47_55_57 我都试过了。这些是否与 H7B3I 兼容? @FranciscoSkrobola 好问题,我认为它们是较新的部件。你有最新的 J-Flash 代码吗?我显然没有。您在 J-Flash 中编程时选择了什么器件? 我刚刚下载了它,所以我应该有最新的。 @FranciscoSkrobola 奇怪的自动更正!我无法想象“我的心”应该是什么!如果我不得不猜测我会选择 H743。以上是关于带有 STM32 的 SEGGER:无法连接到目标。未检测到 idcode的主要内容,如果未能解决你的问题,请参考以下文章