简体   繁体   English

USART3 初始化 STM32F103RB

[英]USART3 Initilization STM32F103RB

I'm a beginner when it comes to using STM chips, and I have a project where I have to use all three USART terminals in Uvision.在使用 STM 芯片方面,我是初学者,我有一个项目,我必须在 Uvision 中使用所有三个 USART 终端。

I am using an STM32F103RB chip, and I already got the first two USART_init functions working, but I can't get the third one to work for some reason.我正在使用 STM32F103RB 芯片,我已经让前两个 USART_init 函数工作,但由于某种原因我无法让第三个工作。 I would really appreciate any help Here are my USART_init functions:我非常感谢任何帮助这是我的 USART_init 函数:

/*----------------------------------------------------------------------------
  Initialize UART pins, Baudrate
 *----------------------------------------------------------------------------*/
void USART1_Init (void) {
  int i;

  RCC->APB2ENR |=  (   1UL <<  0);        /* enable clock Alternate Function  */
  AFIO->MAPR   &= ~(   1UL <<  2);        /* clear USART1 remap               */

  RCC->APB2ENR |=  (   1UL <<  2);        /* enable GPIOA clock               */
  GPIOA->CRH   &= ~(0xFFUL <<  4);        /* clear PA9, PA10                  */
  GPIOA->CRH   |=  (0x0BUL <<  4);        /* USART1 Tx (PA9) output push-pull */
  GPIOA->CRH   |=  (0x04UL <<  8);        /* USART1 Rx (PA10) input floating  */

  RCC->APB2ENR |=  (   1UL << 14);        /* enable USART#1 clock             */

  USART1->BRR   = 0x0271;                 /* 115200 baud @ PCLK2 72MHz        */
  USART1->CR1   = ((   1UL <<  2) |       /* enable RX                        */
                   (   1UL <<  3) |       /* enable TX                        */
                   (   0UL << 12) );      /* 1 start bit, 8 data bits         */
  USART1->CR2   = 0x0000;                 /* 1 stop bit                       */
  USART1->CR3   = 0x0000;                 /* no flow control                  */
  for (i = 0; i < 0x1000; i++) __NOP();   /* avoid unwanted output            */

  USART1->CR1  |= ((   1UL << 13) );      /* enable USART                     */
}

/*----------------------------------------------------------------------------
  Initialize UART2 pins, Baudrate
 *----------------------------------------------------------------------------*/
void USART2_Init (void) {

  RCC->APB2ENR |= 1;                                    // enable clock for AF
    AFIO->MAPR |= 1<<3;                                 // set USART2 remap
    RCC->APB2ENR |= 1<<5;                           // enable clock for GPIOD
    GPIOD->CRL &= ~(0xFF << 20);                // Clear PD5, PD6
    GPIOD->CRL |= (0x0B << 20);                 // USART2 Tx (PD5) output push-pull
    GPIOD->CRL |= (0x04 << 24);                 // USART2 Rx (PD6) input floating
    RCC->APB1ENR |= 1<<17;                          // enable clock for USART2
    USART2->BRR = 0x138;                                // set baudrate -115.2kB from 36MHz
    USART2->CR1 &= ~(1<<12);                        // force 8 data bits
    USART2->CR2 &= ~(3<<12);                        // force 1 stop bit
    USART2->CR3 &= ~(3<<8);                         // force no flow control
    USART2->CR1 &= ~(3<<9);                         // force no parity
    USART2->CR1 |= 3<<2;                                // RX, TX enable
    USART2->CR1 |= 1<<5;                                // Rx interrupts if required
    NVIC->ISER[1] = (1 << 6);                   // enable interrupts if required
    USART2->CR1 |= 1<<13;                           // USART enable
    
}

/*----------------------------------------------------------------------------
  Initialize UART3 pins, Baudrate
 *----------------------------------------------------------------------------*/
void USART3_Init (void) {

  RCC->APB2ENR |= 1;                                    // enable clock for AF
    AFIO->MAPR |= 1<<3;                                // set USART3 remap
    RCC->APB2ENR |= 1<<4;                               // enable clock for GPIOC
    
  GPIOC->CRH   &= ~(0xFFUL <<  4);        /* clear PC10, PC11                  */
    GPIOC->CRH   |=  (0x04UL <<  8);        /* USART3 Rx (PC10) input floating  */
  GPIOC->CRH   |=  (0x01UL <<  8);        /* USART3 Tx (PC11) output push-pull */
    RCC->APB1ENR |=  1<<20;                                 // enable clock for USART3
    
    USART3->BRR = 0x138;                                // set baudrate -115.2kB from 36MHz; USART3    
                                                    //should have the same baudrate as USART2
    USART3->CR1 &= ~(1<<12);                        // force 8 data bits
    USART3->CR2 &= ~(3<<12);                        // force 1 stop bit
    USART3->CR3 &= ~(3<<8);                         // force no flow control
    USART3->CR1 &= ~(3<<9);                         // force no parity
    USART3->CR1 |= 3<<2;                                // RX, TX enable
    USART3->CR1 |= 1<<5;                                // Rx interrupts if required
    NVIC->ISER[1] = (1 << 6);                   // enable interrupts if required
    USART3->CR1 |= 1<<13;                           // USART enable
    
}

Your first line for the USART3 initialization is wrong:-)您的 USART3 初始化的第一行是错误的:-)

RCC->APB2ENR |= 1; // enable clock for AF

must be (without a clock the USART doesn't work)必须是(没有时钟 USART 不起作用)

RCC->APB1ENR |= (1<<18); // enable clock for USART

And as an additional hint, do not use all these magic numbers for the bits.作为附加提示,不要将所有这些幻数用于位。 This is much more readable (and the needed defines are already done in the CMSIS:这更具可读性(并且所需的定义已经在 CMSIS 中完成:

RCC->APB1ENR |= RCC_APB1ENR_USART3EN; // enable clock for USART

After some research, I found there were more problems than just the clock not being enabled.经过一番研究,我发现问题不仅仅是没有启用时钟。 Below is the complete code of the initialization for UART3 using an STM32F103RB chip下面是使用STM32F103RB芯片初始化UART3的完整代码

/*----------------------------------------------------------------------------
  Initialize UART3 pins, Baudrate
 *----------------------------------------------------------------------------*/
void USART3_Init (void) {

    RCC->APB2ENR |= 1;                                  // enable clock for AF
    AFIO->MAPR |= AFIO_MAPR_USART3_REMAP_PARTIALREMAP;  // set USART3 to partical remap to use PC10 and PC11
    RCC->APB2ENR |= 1<<4;                               // enable clock for GPIOC
    
    // since our pins are above 8, we use H instead of L
    // since we are using 10 & 11 we will be using bits 8-15 in the CRH register
    /* USART3 Tx (PC10) output push-pull */             
    GPIOC->CRH   &= ~(0xFFUL <<  8);        
  GPIOC->CRH   |=  (0x0BUL <<  8);       
    /* USART3 Rx (PC11) input floating  */
    GPIOC->CRH   |=  (0x04UL <<  12);     
    
    RCC->APB1ENR |=  RCC_APB1ENR_USART3EN; /* enable clock for USART3         */
    USART3->BRR = 0x138;                  /* set baudrate -115.2kB from 36MHz */
    
    USART3->CR1   = ((   1UL <<  2) |     /* enable RX                        */
                   (   1UL <<  3) |       /* enable TX                        */
                   (   0UL << 12) );      /* 1 start bit, 8 data bits         */
    
  USART3->CR2   = 0x0000;                 /* 1 stop bit                       */
  USART3->CR3   = 0x0000;                 /* no flow control                  */
    
    USART3->CR1 |= 1<<13;                 /* USART3 enable                    */
    
    //Configure and enable USART3 interrupt
    NVIC->ICPR[USART3_IRQn/32] = 1UL << (USART3_IRQn%32);   // clear any previous pending interrupt flag
    NVIC->IP[USART3_IRQn] = 0x80;                           // set priority to 0x80
    NVIC->ISER[USART3_IRQn/32] = 1UL << (USART3_IRQn%32);   // set interrupt enable bit
    USART3->CR1 |= USART_CR1_RXNEIE;                        // enable USART3 receiver not empty interrupt
}

and the interrupt I used to prove this works looks like this我用来证明这个工作的中断看起来像这样

// UART3 Interupt Handler
void USART3_IRQHandler (void) {

    uint8_t inKey3 = (int8_t) (USART3->DR & 0x1FF);
    SendCharTo3(inKey3);
    if(inKey3 == 0x0D) {
        SendCharTo3('\n');
    }
}

/*----------------------------------------------------------------------------
  SendChar
  Write character to Serial Port. for UART 3
 *----------------------------------------------------------------------------*/
int SendCharTo3 (uint8_t ch)  {

  while (!(USART3->SR & USART_SR_TXE));
  USART3->DR = ((uint16_t)ch & 0x1FF);

  return (ch);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM