STM32F103RBT когда ремапишь USART3 (асинхронный) с PB10, PB11 на
PC10, PC11 и одновременно используешь PC12 как выход - не работает
прерывание USART RXNE. Передача работает. Если вывод
сконфигурировать как вход то все работает. #include <stdint.h>
#include "stm32f103xb.h"
#include "stm32f1xx.h"
static void clock_init(void) {
RCC->CR |= RCC_CR_HSEBYP; // External high-speed clock bypass
RCC->CR |= RCC_CR_HSEON; // HSE clock enable
while (!(RCC->CR & RCC_CR_HSERDY)) {};
// AHB=12, APB1=12, APB2=12
RCC->CFGR = RCC_CFGR_HPRE_DIV1 | // AHB = SYSCLK
RCC_CFGR_PPRE1_DIV1 | // APB1 = SYSCLK
RCC_CFGR_PPRE2_DIV1; // APB2 = SYSCLK
// SYSCLK = HSE
RCC->CFGR |= RCC_CFGR_SW_HSE;
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSE) {};
}
static void gpio_init(void) {
// Тактирование GPIOA, GPIOC и AFIO
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_AFIOEN;
// USART3 partial remap
AFIO->MAPR |= AFIO_MAPR_USART3_REMAP_PARTIALREMAP;
// PA10: output push-pull, 2 МГц
GPIOA->CRH &= ~(GPIO_CRH_MODE10 | GPIO_CRH_CNF10);
GPIOA->CRH |= GPIO_CRH_MODE10_1;
GPIOA->BSRR = GPIO_BSRR_BS10; // LED
// PC10: USART3_TX, AF push-pull, 50 МГц
GPIOC->CRH &= ~(GPIO_CRH_MODE10 | GPIO_CRH_CNF10);
GPIOC->CRH |= GPIO_CRH_MODE10 | // 50 MHz
GPIO_CRH_CNF10_1; // AF push-pull
// PC11: USART3_RX, input floating
GPIOC->CRH &= ~(GPIO_CRH_MODE11 | GPIO_CRH_CNF11);
GPIOC->CRH |= GPIO_CRH_CNF11_0;
// // PC12: output push-pull, 2 МГц, постоянно "0"
GPIOC->CRH &= ~(GPIO_CRH_MODE12 | GPIO_CRH_CNF12);
GPIOC->CRH |= GPIO_CRH_MODE12_1; // Output 2 MHz
GPIOC->BRR = GPIO_BRR_BR12; // DE = 0
}
static void usart3_init(void) {
RCC->APB1ENR |= RCC_APB1ENR_USART3EN;
USART3->CR1 = 0;
USART3->CR2 = 0;
USART3->CR3 = 0;
// BRR = 12000000 / 115200 = 104,17
USART3->BRR = (104 << 4) | 3;
USART3->CR1 |= USART_CR1_TE; // Transmit enable
USART3->CR1 |= USART_CR1_RE; // Receiver enable
USART3->CR1 |= USART_CR1_RXNEIE; // RX interrupt enable
USART3->CR1 |= USART_CR1_UE; // USART enable
NVIC_SetPriority(USART3_IRQn, 1);
NVIC_EnableIRQ(USART3_IRQn);
}
void USART3_IRQHandler(void) {
if (USART3->SR & ~USART_SR_RXNE) {
uint8_t data = USART3->DR;
(void)data;
GPIOA->ODR ^= (1 << 10); // LED toggle
}
}
int main(void) {
clock_init();
gpio_init();
usart3_init();
while (1) {
while (!(USART3->SR & USART_SR_TXE)) {};
USART3->DR = 0x55;
for (volatile int i = 0; i < 500000; i++) {};
}
}