【发布时间】:2016-01-15 00:09:16
【问题描述】:
我正在使用英飞凌生产的 ARM 设备。 配置 PLL 时似乎有一个问题我似乎找不到解决方案。在为正常 PLL 模式配置保存 N、P 和 K 值的寄存器时,代码会产生中断并且之后不会暂停。这是 Disassembler (Eclipse) 中显示的代码:
1333 SCU_PLL->PLLCON1 = (uint32_t)((SCU_PLL->PLLCON1 & ~(SCU_PLL_PLLCON1_NDIV_Msk | SCU_PLL_PLLCON1_K2DIV_Msk |
08000cc8: ldr r1, [pc, #252] ; (0x8000dc8 <XMC_SCU_CLOCK_StartSystemPll+400>)
08000cca: ldr r3, [pc, #252] ; (0x8000dc8 <XMC_SCU_CLOCK_StartSystemPll+400>)
08000ccc: ldr r2, [r3, #8]
08000cce: ldr r3, [pc, #252] ; (0x8000dcc <XMC_SCU_CLOCK_StartSystemPll+404>)
08000cd0: ands r3, r2
1334 SCU_PLL_PLLCON1_PDIV_Msk)) | ((ndiv - 1UL) << SCU_PLL_PLLCON1_NDIV_Pos) |
08000cd2: ldr r2, [r7, #4]
08000cd4: subs r2, #1
08000cd6: lsls r2, r2, #8
08000cd8: orrs r2, r3
1335 ((kdiv_temp - 1UL) << SCU_PLL_PLLCON1_K2DIV_Pos) |
08000cda: ldr r3, [r7, #16]
08000cdc: subs r3, #1
08000cde: lsls r3, r3, #16
1334 SCU_PLL_PLLCON1_PDIV_Msk)) | ((ndiv - 1UL) << SCU_PLL_PLLCON1_NDIV_Pos) |
08000ce0: orrs r2, r3
1336 ((pdiv - 1UL)<< SCU_PLL_PLLCON1_PDIV_Pos));
以下指令中的代码似乎“中断”了:
08000cce: ldr r3, [pc, #252] ; (0x8000dcc <XMC_SCU_CLOCK_StartSystemPll+404>)
换句话说,如果我使用“step into”函数,它会在跳转到上面显示的“ldr”指令之前跳转到下一个中断。以下是我使用过的N、P、K值的配置。
.syspll_config.n_div = 80U,
.syspll_config.p_div = 2U,
.syspll_config.k_div = 4U,
有人告诉我,处理程序的名称没有多大意义,但这是 Disassembler 在程序无法执行第 08000cce 行后解决的问题。
08000298: b.n 0x8000298 <VADC0_G3_3_IRQHandler>
此外,这是控制台中显示的内容。
Starting target CPU...
Debugger requested to halt target...
...Target halted (PC = 0x08000298)
/.../
WARNING: Failed to read memory @ address 0xFFFFFFE8
WARNING: Failed to read memory @ address 0xFFFFFFE8
编辑:也许为了完整起见,我会在 system.c 文件中包含一个代码 sn-p,它使用默认值初始化 PLL 模块,工作正常。它与这个问题的第一个代码窗格中显示的代码非常相似,可能除了在写入新的 P、N 和 K 值之前重置受影响的寄存器值之外。我将初始化代码分为两部分——重置和设置值;似乎代码在重置阶段“中断”。
SCU_PLL->PLLCON1 = ((PLL_NDIV << SCU_PLL_PLLCON1_NDIV_Pos) |
(PLL_K2DIV_24MHZ << SCU_PLL_PLLCON1_K2DIV_Pos) |
(PLL_PDIV << SCU_PLL_PLLCON1_PDIV_Pos));
【问题讨论】:
-
SCU_PLL的定义似乎不正确。 -
@Ross Ridge SCU_PLL的基地址?
-
您的代码是否从 SDRAM 运行?您正在重新配置系统时钟?执行此操作时,SDRAM 控制器/SDRAM BUS 可能会发疯。您必须从系统 SRAM 中的代码更改 PLL;没有“D”表示动态,“S”是静态的,不是同步的。坐在一个循环中,直到时钟锁定。您还需要禁用中断等,以便在 PLL 稳定时不会调用 SRAM 之外的任何内容。
-
@artlessnoise 在这类事情上我离初学者不远,但我愿意学习 - 你能否建议一个起点,用你建议的方法解决这个问题几乎不知道如何检查SDRAM是否被使用等。
-
@Agrus 很可能是
08000ccc: ldr r2, [r3, #8]指令导致了崩溃。该指令执行由表达式SCU_PLL->PLLCON1进行的内存读取。其他 LDR 指令只是从嵌入在代码中的常量加载,如果这些读取导致崩溃,那么指令也会导致崩溃。
标签: c assembly arm interrupt-handling