ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Пятница
20 марта
1576972 Топик полностью
_werwolf_ (Сегодня, 11:40, просмотров: 181)
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++) {};
    }
}