Los bits son altos en los pines deshabilitados (STM32)

Por alguna razón, tengo muchos bits con valor 1, incluso si se supone que deben estar apagados. Traté de depurarlo con algunos LED y el depurador Keil uVision. uC es STM32F103 La situación es:
tengo 2 pines configurados como salida y 1 como entrada.

GPIOA->CRL = 0x00000228;

Cuando trato de leer el registro IDR (que contiene valores de entrada, al que se accede con GPIOA->IDR) espero obtener algo como 0x00000001 o todos ceros si la entrada es baja. Pero por alguna razón, obtengo 0x0000BF01, lo que significa que tengo estas cosas en la entrada: 1011111100000001, que obviamente no tengo, ya que ni siquiera uso estos pines.

Lo que probé:
de la hoja de datos encontré que el estado de reinicio para los pines es 4 = 0100. así que lo intenté

GPIOA->CRL = 0x44444228;

Esto me dio valores en IDR 0x0000BFF8, aún werid.
Luego traté de restablecer también manualmente el registro CRH

GPIOA->CRH = 0x44444444;

Esto tampoco cambió nada.

A veces genera 0x0000B000... No sé, tal vez sea un poco aleatorio (¿captación de ruido?).

¿Cual puede ser el problema? ¿Asigno algo de manera incorrecta?

Básicamente, este es todo mi código principal, mientras que solo accedo a GPIO->IDR:

RCC->APB2ENR|=RCC_APB2ENR_IOPAEN; // Enable IOPA
GPIOA->CRL = 0x44444228;
GPIOA->CRH = 0x44444444;

Y sí, sé que puedo usar la biblioteca std_periph, mi pregunta es saber por qué suceden las cosas de esa manera, no encontrar una solución.

SOLUCIÓN
El siguiente texto es válido para stm32f103, no estoy seguro acerca de otros stm32.
Resultó que los pines 12,13,14,15 en el puerto A son para señales JTAG y CAN, por lo que están "reservados" y no se pueden usar, a menos que vuelva a asignar JTAG a otro lugar. Básicamente, simplemente no use el pin 12 a 15 en el puerto A, puede ignorarlo enmascarando el registro necesario o, en caso de que desee leer bits específicos, la biblioteca gpio std_peripgh tiene la función GPIO_ReadInputDataBit (GPIOx, uint16_t GPIO_Pin), donde también puede O el pin números juntos.
La forma en que lo descubrí es que siempre eran los mismos bits, simplemente borré todo el chip con la utilidad STM32 ST-LINK y verifiqué si estos bits estaban altos nuevamente, y de hecho estaban altos.
¡TAMBIÉN! Los pines 3 y 4 en el puerto B también están reservados para SWO y NJTRST y también están altos en el chip recién borrado, así que supongo que es mejor NO usar PB3 y PB4.

Podría ayudarnos si publica el programa completo y un enlace al hardware utilizado. Con lo que has presentado es difícil ayudar. Las sugerencias obvias son: los puertos no se están habilitando correctamente, y estos son valores aleatorios, el puerto se está sobrescribiendo, o alguna parte del software está configurando las resistencias pull-up de los puertos en 'encendido'. Además, el hardware puede tener pines vinculados a las señales, y una parte del software se está inicializando para eso.
Muy buen trabajo detectivesco. Estoy de acuerdo contigo sobre los pines JTAG (lo siento, no los había revisado), pero no estoy de acuerdo contigo sobre los pines CAN/USB. AFAIK, si CAN/USB y los otros periféricos (TIM1 USART1) no se usan, PA12 se puede usar para GPIO.

Respuestas (1)

Probablemente necesitemos más información para ayudar completamente. Sin embargo, ...

El 'valor de reinicio' de 0x44444444 es el valor en el que se establecen los registros cuando se reinicia el hardware. No es necesariamente el valor de configuración del puerto lo que necesita.

Consulte el manual de referencia de RM008... STM32F103xx... MCU avanzados de 32 bits basados ​​en ARM Sección 9.2

El código está configurando todos los pines del puerto en:
"CNFy: 01: entrada flotante (estado de reinicio)"
"MODEy: 00: modo de entrada (estado de reinicio)"

Entonces, todos los pines, excepto los tres inferiores, están configurados para la entrada, sin pull-up o pull-down específicos. Por lo tanto, un pin conectado a una señal o con una carga aleatoria podría estar en 0 o 1.

Es normal enmascarar los datos de los pines no utilizados de un puerto para que solo se utilicen los valores necesarios. Esto ayuda si, por ejemplo, se cambia su hardware y se activan nuevos pines para algún otro propósito.

Enmascaro el IDR, de modo que solo se use el valor de los pines que son entradas activas, antes de usar el valor de registro de datos de entrada de puerto.

Puede considerar configurar la resistencia desplegable en todos los demás pines para que sea más fácil ver lo que sucede con las entradas activas. Sin embargo, eso tiene algún riesgo; por ejemplo, si esos pines de entrada se conectan a una señal alta o Vcc.

Si observa el código fuente de la biblioteca de periféricos estándar, mostrará una secuencia de accesos a registros que la inicializan correctamente.

Eso podría proporcionarle suficiente información para que continúe con su aprendizaje.

Posiblemente más fácil de leer es la fuente libmaple de Leaflabs para la placa de desarrollo Maple STM32F103.

O busque en stm32duino.com, que están trabajando en su actualización de libmample.
O mire un puerto de libmaple por un ex miembro del personal de LeafLabs en rambutan.cc

EDITAR: cuando configuró los bits de CRL en '8 = 1000 (menú de entrada)', ¿también configuró el registro ODR en 0? De acuerdo con la tabla 20 en la sección 9.1, el ODR determina si el resistor es desplegable o desplegable.

EDIT2: ¡Bien hecho! Un buen trabajo de detective.
Los pines JTAG (PA13, PA14, PA15, PB3, PB4) se pueden liberar para el uso normal de GPIO configurando un valor en AFIO_MAPR, pero tendería a dejar esos pines como JTAG/SWJ-DP.
AFAIK PA11 y PA12 son pines ordinarios, por lo que si no se utilizan CAN, USB, TIM1 y USART1, están disponibles para GPIO normal.

Traté de poner todos los pines no utilizados en el estado 8 = 1000 (menú de entrada), no ayudó ... Gracias por los enlaces, revisaré el código fuente y aprenderé qué está pasando. Marcaré tu respuesta, pero publicaría la solución más tarde editando la publicación original.
Si alguien lee este comentario, lea la solución en la publicación original, tiene información útil.