Cannot set up ADC for proportionally frequent LED blinking in STM32F103C8T6
Hello everyone,
I'm new to embedded development, and I'm trying to implement a kind of hello-world-level project to get acquainted with STM32 MCU architecture using arm assembly. In particular, I'm trying to set up ADC at STM32F103C8T6 Blue Pill board for a LED at PC13, which desired behaviour is blinking with frequency proportional to an external potentiometer's resistance at PA0. In other words, the lower is potentiometer resistance - the higher is blinking frequency and vice versa. Besides having set up all necessary clocks according to the Reference Manual (RM0008, Rev 21), I have also set up PA0 as analog input:
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]
...as well as put ADC1 on through ADON bit:
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]
The main loop below represents itself a modified version of my first successful "hello-world" code, where the LED at PC13 just blinked several times per second, but now with attempts to start single ADC conversion per iteration and read input values on PA0:
main_loop: // ADC conversion: LDR r0, =0x40012400 + 0x08 LDR r1, [r0] ORR r1, 1 << 22 // SWSTART bit - starts conversion STR r1, [r0]
// Waiting for the convresion to end: wait_adc: LDR r0, =0x40012400 // ADC_SR register for ADC1 (Reference Manual, p. 237) LDR r1, [r0] TST r1, 1 << 1 // Checking the EOC flag - end of conversion (Reference Manual, p. 237) BEQ wait_adc LDR r0, =0x40012400 + 0x4C // ADC_DR - regular data register (Reference Manual, p. 251) LDR r2, [r0] LDR r3, =1000000 // Base blink length, about 300+ ms MUL r0, r2, r3 // Trying to multiply the value from ADC by the base blink length, not sure if it is correct MOV r4, r0 // Waiting: delay_loop: SUBS r4, #1 BNE delay_loop // Toggling PC13: LDR r0, =0x40011000 + 0x0c // GPIOC_ODR (Reference Manual, p. 173) LDR r1, [r0] EOR r1, 1 << 13 // ODR 13 STR r1, [r0] B main_loop
As a result, the LED of interest just continuously glows, without reacting to the position of the potentiometer toggle (10 KOhm, connected to A0 with its middle pin, as well as to GND and +3.3 with two other pins). All electrical connections have been checked for not being damaged.
So far I have managed to figure out that `wait_adc` loop is endless, i.e. EOC flag seems to never be set. As far as I understand, this means that conversion actually never ends.
I have also tried adding a small delay loop right before `wait_adc` to wait for the ADC to stabilize (if I understand its timing correctly, according to the diagram in the Reference Manual, p. 220, Fig. 23), but that did not help.
Linker used is GNU ld. Thumb mode enabled, assembly instructions verified through manuals at arm's official website.
I would be thankful for your help with understanding the reasons of this failure.
