在一个最小的STM32应用程序中,我写过将字符写入USART1,当我尝试同时启用我需要的所有时钟时,USART似乎不起作用:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA
| RCC_APB2Periph_AFIO
| RCC_APB2Periph_USART1, ENABLE);
但是,当我一次启用一个时钟时,它可以工作:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
这是为什么?是否有特定的顺序必须启用这些时钟? (如果是这样,这在哪里记录?)
(我已经遗漏了之后的所有代码,初始化GPIO引脚,设置USART,并开始发送内容,因为它在每个应用程序中都是相同的。如果相关,请告诉我,我将包括它)。
我正在使用的设备是STM32F103VET6。
由于对所涉及的组件有一些兴趣,这里就是。对于所有三个时钟:
00000000 <main>:
0: b590 push {r4, r7, lr}
2: b089 sub sp, #36 ; 0x24
4: af00 add r7, sp, #0
6: f244 0014 movw r0, #16389 ; 0x4005
a: 2101 movs r1, #1
c: f7ff fffe bl 0 <RCC_APB2PeriphClockCmd>
一次一个时钟:
00000000 <main>:
0: b590 push {r4, r7, lr}
2: b089 sub sp, #36 ; 0x24
4: af00 add r7, sp, #0
6: 2004 movs r0, #4
8: 2101 movs r1, #1
a: f7ff fffe bl 0 <RCC_APB2PeriphClockCmd>
e: 2001 movs r0, #1
10: 2101 movs r1, #1
12: f7ff fffe bl 0 <RCC_APB2PeriphClockCmd>
16: f44f 4080 mov.w r0, #16384 ; 0x4000
1a: 2101 movs r1, #1
1c: f7ff fffe bl 0 <RCC_APB2PeriphClockCmd>
...
这里是RCC_APB2PeriphClockCmd
:
00000000 <RCC_APB2PeriphClockCmd>:
0: 4b04 ldr r3, [pc, #16] ; (14 <RCC_APB2PeriphClockCmd+0x14>)
2: 699a ldr r2, [r3, #24]
4: b109 cbz r1, a <RCC_APB2PeriphClockCmd+0xa>
6: 4310 orrs r0, r2
8: e001 b.n e <RCC_APB2PeriphClockCmd+0xe>
a: ea22 0000 bic.w r0, r2, r0
e: 6198 str r0, [r3, #24]
10: 4770 bx lr
12: bf00 nop
14: 40021000 .word 0x40021000
0x40021000
是RCC外设的基地址; #24
偏移量指向RCC_APB2ENR
寄存器,该寄存器对于每个启用的时钟都有一位。 (有关详细信息,请参阅RM0008的第109页。)
答案 0 :(得分:4)
嗯,我想我弄明白了,结果却不是硬件问题......我的工具链配置存在很多问题:
我正在设置-nostdlib
。这导致一些全局初始化代码无法生成。我不确定这有多重要,但其他问题包括:
我没有将-mthumb
和其他CPU选项传递给链接器。这导致一些生成的启动代码变成垃圾。
我的启动文件未包含对__libc_init_array
的调用。这导致在链接时删除一些更多的初始化代码。
我仍然不确定为什么要拆分周边时钟初始化设法解决这个问题。也许代码数量的变化会使某些东西碰到正确的对齐?无论如何,到目前为止,解决潜在的问题似乎已经修补了一些问题(尽管我仍然对一些剩余的启动代码持怀疑态度。)
答案 1 :(得分:1)
您可能想让我们确切地知道您正在使用哪种设备和/或查看该设备的勘误表。例如,STM32L100x6 / 8 / B-A(和其他)设备的勘误表具有以下内容(http://www.st.com/web/en/resource/technical/document/errata_sheet/DM00097022.pdf):
2.6.1 RCC外设时钟使能后的延迟
描述
RCC外设时钟使能与有效之间的延迟 应考虑外围设备以便进行管理 外设读/写寄存器。
此延迟取决于外围设备的映射:
- 如果外围设备映射在AHB上:延迟应该等于2个AHB周期。
- 如果外设映射到APB:延迟应该等于1 +(AHB / APB预分频器)周期。
变通方法
- 使用DSB指令停止Cortex-M CPU管道,直到指令完成。
- 插入&#34; n&#34; RCC之间的NOP使能位写入和外设寄存器写入(对于AHB外设,n = 2,n = 1 + AHB / APB APB外设的预分频器。)
醇>
这听起来并不像你的问题,但它可能是相关的(也许一次一个启用会引入一个必要的延迟)。