我正在尝试为 PC13 上的 LED 设置 STM32F103C8T6 的 ADC,其所需的行为是以与 PA0 处电位计电阻成比例的频率闪烁(一种 arm 组装 hello-world 自学项目)。 IE。较低的电阻=>较高的频率,反之亦然。除了根据参考手册设置所有必要的时钟外,我还将 PA0 设置为模拟输入:
// Enabling PA0 as analog input (used below by ADC)
LDR r0, =0x40010800 // GPIOA_CRL, sets up low pins; GPIOA starts from 0x40010800 (Reference Manual, p. 51)
LDR r1, [r0]
BIC r1, 0xF << 0 // Clear MODE0 and CNF0 bits for PA0 -> setting analog mode
STR r1, [r0]
...以及通过 ADON 位打开 ADC1:
// Configuring ADC1
LDR r0, =0x40012400 + 0x08 // ADC_CR2 register for ADC1 (Reference Manual, p. 240)
LDR r1, [r0]
ORR r1, 1 << 0 // ADON bit - power on ADC1
STR r1, [r0]
下面的主循环本身就是我的第一个“hello-world”代码的修改版本,其中 PC13 上的 LED 每秒闪烁几次(我已经在参考手册中写下了我用来修改它的页面):
main_loop:
// ADC conversion
LDR r0, =0x40012400 + 0x08
LDR r1, [r0]
ORR r1, 1 << 22 // SWSTART bit - starts conversion
STR r1, [r0]
wait_adc:
LDR r0, =0x40012400 // ADC_SR register for ADC1 (Reference Manual, p. 237)
LDR r1, [r0]
TST r1, 1 << 1 //
BEQ wait_adc
LDR r0, =0x40012400 + 0x4C // ADC_DR - regular data register (Reference Manual, p. 251)
LDR r2, [r0]
LDR r3, =1000000
MUL r0, r2, r3
MOV r4, r0
// Loop for waiting:
delay_loop:
SUBS r4, #1
BNE delay_loop
// toggle PC13
LDR r0, =0x40011000 + 0x0c // GPIOC_ODR
LDR r1, [r0]
EOR r1, 1 << 13 // ODR 13 - port 13
STR r1, [r0]
B main_loop
结果,感兴趣的 LED 只是发光,而不对电位计切换的位置做出反应(10 KOhm,通过中间引脚连接到 A0,以及通过其他两个引脚连接到 GND 和 +3.3)。所有电气连接均已检查没有损坏。
使用的链接器是GNU ld。 该板是带有 Cortex-M3 的 STM32F103C8T6。 启用拇指模式,组装说明取自arm的官方网站。 参考手册为 RM0008,修订版 21。
我正在尝试“从下面”学习 arm 架构,并且非常感谢您帮助理解此失败的原因。
我在STM官方论坛上得到了一个解决方案:为了让ADC由SWSTART启动,需要将CR2的EXTTRIG位设置为1,并将EXTSEL[2:0]位设置为0b111(0x7)。该信息包含在参考手册(RM0008,修订版 21)第 14 页中。 240. 现在 PC13 上的 LED 闪烁并符合要求,有关 ADC 转换的解决方案如下所示:
LDR r0, =0x40012400 + 0x08 // ADC_CR2 register for ADC1 (Reference Manual, p. 240)
LDR r1, [r0]
ORR r1, 1 << 20 // EXTTRIG bit - enables conversion on external trigger (ibid)
ORR r1, 0x7 << 17 // EXTSEL[2:0] bits - should be set to 0b111 (0x7) to start conversion with SWSTART further (ibid)
ORR r1, 1 << 22 // SWSTART bit - starts conversion (ibid)
STR r1, [r0]