Problema al configurar los GPIO en STM32F103 utilizando ensamblador
Mi objetivo es escribir un código de ensamblaje de metal desnudo para STM32F103 que encienda el LED PB1.
Los pasos que sigo se enumeran a continuación:
1. Habilitar el bit IOPB 3 en el registro RCC_APB2ENR, que tiene una dirección de 0x18, restablecido desde la dirección base de RCC, 0x40021000. (El valor de reinicio de este registro es 0x00000000)
2. Habilitar los bits CNF1 (00): 7-6 y MODE1 (10): 5-4 para PB1 en el registro GPIO_CRL, cuyos valores de reinicio son 0x44444444 y su dirección es un desplazamiento de 0x0 desde la dirección base de GPIO_BASE, 0x40010C00. Esta configuración establece el puerto como salida de propósito general de empuje-pull con una velocidad máxima de 2 MHz.
3. Configurar el bit 1 – ODR1 en el registro GPIOx_ODR, que es un desplazamiento de 0x0C desde GPIO_BASE y su valor de reinicio es 0x00000000.
stack_size EQU 0x400 ; 0x400 = 1024 byte = 1kB
stack_start EQU 0x20000000 + stack_size
gpiob_base EQU 0x40010C00
rcc_base EQU 0x40021000
rcc_apb2enr EQU rcc_base+0x18
gpio_crl EQU gpiob_base
gpiob_odr EQU gpiob_base+0x0C
PRESERVE8
THUMB
AREA RESET, DATA, READONLY
DCD stack_start
DCD __mainCode
AREA |.text|, CODE, READONLY
ENTRY
__mainCode PROC
LDR R0, =rcc_apb2enr
LDR R1, [R0]
LDR R2, =0x4
ORR R1, R2
STR R1, [R0]
; Configure GPIO_CRL
LDR R0, =gpio_crl
LDR R1, [R0]
LDR R2, =0xFFFFFF00
AND R1,R1,R2
ORR R1, R1, #0x20
STR R1, [R0] ; Reset register
; Configure GPIOB_ODR
LDR R0, =gpiob_odr
LDR R1, [R0]
ORR R1, #0x2
STR R1, [R0]
NOP
ENDP
ALIGN
END
Desafortunadamente, el código no enciende el LED. He depurado el código y notado lo siguiente:
1. Después de restablecer, el valor de GPIO_CRL debería ser 0x44444444, pero es 0x44444844.
- El valor del registro GPIO_ODR debe ser 0x00000000, pero también es 0x00000001. Después de realizar la operación ORR con 0x2 y querer almacenarlo de nuevo en la dirección de registro 0x40010C0C, su valor permanece sin cambios (0x00000001).
Por favor, aconseje qué está mal en mi código y cómo puedo solucionarlo?
davy.ai
Posibles errores en el código:
gpio_crl EQU gpiob_base+0x00
ORR R1, R1, #(0b0010<<4) ; configurar MODE1 en modo de salida
ORR R1, R1, #(0b00<<6) ; configurar CNF1 en push-pull
Alternativamente, los valores pueden ser definidos como constantes:
mode_output EQU 0b0010
cnf_pushpull EQU 0b00
...
ORR R1, R1, #(mode_output<<4)
ORR R1, R1, #(cnf_pushpull<<6)
gpiob_odr EQU gpiob_base+0x0C
Soluciones sugeridas en el código: