Estoy intentando configurar manualmente un USART en un Nucleo F401RE para transmitir a través del puerto COM virtual USB, lo que significa usar USART2 en PA2 (TX) y PA3 (RX). No solo no estoy recibiendo ningún carácter, sino que el pin TX nunca es alto, lo que creo que debería estar cuando está inactivo.
Esto es lo que he hecho:
PLL se está ejecutando a 84MHz (confirmado usando MCO), y el prescaler APB1 se establece en / 2:
RCC_CFGR =
(2 << RCC_CFGR_SW_BIT) // Use PLL as clock source
| (0b100 << RCC_CFGR_PPRE1_BIT) // Prescale APB1 clock /2
;
El reloj periférico GPIOA está habilitado:
// Enable GPIOA peripheral clock
RCC_AHB1ENR = RCC_AHB1ENR_GPIOAEN;
Luego la configuración de USART:
GPIOA_MODER |= 0b1010 << 4; // PA2, PA3 to AF
GPIOA_OSPEEDR |= 0b1111 << 4; // PA2, PA3 to high speed
GPIOA_AFRL |= (7 << 8) | (7 << 12); // Set PA2, PA3 to AF7 (USART2)
RCC_APB1ENR |= RCC_APB1ENR_USART2EN; // Enable peripheral clock for USART2
// Baud rate 115k2 with SYSCLK 84MHz (BRR = 45.5625)
USART2_BRR = (45 << 4) | 9;
USART2_CR1 = USART_CR1_UE | USART_CR1_TE;
Creo que en este punto, TX debería ser alto, pero no lo es. Lo envío con:
while ((USART2_SR & USART_SR_TXE) == 0);
USART2_DR = c;
Al encender el LED dentro de while
se muestra que el búfer de transmisión está inicialmente lleno. Al encenderlo después de que while
muestra que se vacía con éxito. El uso de TC
en lugar de TXE
muestra que se considera que se transmitió con éxito.
¿Qué me he perdido?
Todo el código está aquí: enlace
* Por favor, no intentes convencerme de que use CMSIS o mbed; Es un ejercicio de aprendizaje.