AnsweredAssumed Answered

Multiple USART (USART1 and USART6) on STM DISCO

Question asked by nilsson.henrik.002 on Nov 4, 2015
Latest reply on Nov 4, 2015 by Clive One

I am trying to set up two USART on my STM32F4 DISCOVER.

 

I have used the example as described in Examples/USART/USART_HyperTerminal.

 

I have manage to get the example working and can communicate using COM1 with PC Hyperterminal. Now I want to add a second USART (COM2) and use USART6 for that.

I have decided to use pin PG14 for Tx from Discovery and PG9 for Rx.

 

Attached are the code I have changed:

 

********** main.h ************

#if defined (USE_STM324x9I_EVAL)

  #define USART1_IRQHANDLER   USART1_IRQHandler

//Henrik

  #define USART6_IRQHANDLER   USART6_IRQHandler

//Henrik

 

 

********** main.c ************

 

/* Includes ------------------------------------------------------------------*/

#include "main.h"

 

/** @addtogroup STM32F4xx_StdPeriph_Examples

  * @{

  */

 

/** @addtogroup USART_HyperTerminal

  * @{

  */

 

/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/

/* Private macro -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/

extern uint8_t ubNbrOfDataToTransfer;

extern uint8_t ubNbrOfDataToRead;

extern __IO uint8_t ubTxCounter;

extern __IO uint16_t uhRxCounter;

 

//Henrik

extern uint8_t ubNbrOfDataToTransfer_COM2;

extern __IO uint8_t ubTxCounter_COM2;

//Henrik

 

/* Private function prototypes -----------------------------------------------*/

static void NVIC_Config(void);

static void USART_Config(void);

 

/* Private functions ---------------------------------------------------------*/

 

/**

  * @brief  Main program

  * @param  None

  * @retval None

  */

 

int main(void)

{

  /*!< At this stage the microcontroller clock setting is already configured,

       this is done through SystemInit() function which is called from startup

       files (startup_stm32f40_41xxx.s/startup_stm32f427_437xx.s/startup_stm32f429_439xx.s)

       before to branch to application main.

       To reconfigure the default setting of SystemInit() function, refer to

       system_stm32f4xx.c file

     */  

             

  /* NVIC configuration */

  NVIC_Config();

 

  /* USART configuration */

  USART_Config(); 

                            

 

  /* Enable the EVAL_COM1 Transmit interrupt: this interrupt is generated when the

     EVAL_COM1 transmit data register is empty */ 

  USART_ITConfig(EVAL_COM1, USART_IT_TXE, ENABLE);

 

//Henrik

  /* Enable the EVAL_COM2 Transmit interrupt: this interrupt is generated when the

     EVAL_COM2 transmit data register is empty */ 

  USART_ITConfig(EVAL_COM2, USART_IT_TXE, ENABLE);

//Henrik

 

 

  /* Wait until EVAL_COM1 send the TxBuffer */

  while(ubTxCounter < ubNbrOfDataToTransfer)

  {}

 

  /* The software must wait until TC=1. The TC flag remains cleared during all data

     transfers and it is set by hardware at the last frame’s end of transmission*/

  while (USART_GetFlagStatus(EVAL_COM1, USART_FLAG_TC) == RESET)

  {}

 

  /* Enable the EVAL_COM1 Receive interrupt: this interrupt is generated when the

     EVAL_COM1 receive data register is not empty */

  USART_ITConfig(EVAL_COM1, USART_IT_RXNE, ENABLE);

 

  /* Wait until EVAL_COM1 receive the RxBuffer */

  while(uhRxCounter < ubNbrOfDataToRead)

  {}

                                                         

 

//Henrik

 

  /* Wait until EVAL_COM2 send the TxBuffer */

  while(ubTxCounter_COM2 < ubNbrOfDataToTransfer_COM2)

  {}

 

  /* The software must wait until TC=1. The TC flag remains cleared during all data

     transfers and it is set by hardware at the last frame’s end of transmission*/

  while (USART_GetFlagStatus(EVAL_COM2, USART_FLAG_TC) == RESET)

  {}

 

                             /* Enable the EVAL_COM1 Receive interrupt: this interrupt is generated when the

     EVAL_COM1 receive data register is not empty */

  USART_ITConfig(EVAL_COM1, USART_IT_RXNE, ENABLE);

 

//Henrik

 

                             while (1)

  {

  }

 

}

 

/**

  * @brief  Configures the USART Peripheral.

  * @param  None

  * @retval None

  */

 

 

/**

  * @brief  Configures the USART Peripheral.

  * @param  None

  * @retval None

  */

static void USART_Config(void)

{

  USART_InitTypeDef USART_InitStructure;

 

/* USARTx configuration ------------------------------------------------------*/

  /* USARTx configured as follows:

        - BaudRate = 9600 baud 

        - Word Length = 8 Bits

        - Two Stop Bit

        - Odd parity

        - Hardware flow control disabled (RTS and CTS signals)

        - Receive and transmit enabled

  */

  USART_InitStructure.USART_BaudRate = 9600 * 25 / 8;

  USART_InitStructure.USART_WordLength = USART_WordLength_8b;

  USART_InitStructure.USART_StopBits = USART_StopBits_2;

  USART_InitStructure.USART_Parity = USART_Parity_Odd;

  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

 

  STM_EVAL_COMInit(COM1, &USART_InitStructure);

 

//Henrik

/* USARTx configuration ------------------------------------------------------*/

  /* USARTx configured as follows:

        - BaudRate = 9600 baud 

        - Word Length = 8 Bits

        - Two Stop Bit

        - Odd parity

        - Hardware flow control disabled (RTS and CTS signals)

        - Receive and transmit enabled

  */

  USART_InitStructure.USART_BaudRate = 9600 * 25 / 8;

  USART_InitStructure.USART_WordLength = USART_WordLength_8b;

  USART_InitStructure.USART_StopBits = USART_StopBits_2;

  USART_InitStructure.USART_Parity = USART_Parity_Odd;

  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

 

  STM_EVAL_COMInit(COM2, &USART_InitStructure);

//Henrik

}

 

/**

  * @brief  Configures the nested vectored interrupt controller.

  * @param  None

  * @retval None

  */

static void NVIC_Config(void)

{

  NVIC_InitTypeDef NVIC_InitStructure;

                            

  /* Enable the USARTx Interrupt */

  NVIC_InitStructure.NVIC_IRQChannel = EVAL_COM1_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

 

//Henrik

  /* Enable the USARTx Interrupt */

  NVIC_InitStructure.NVIC_IRQChannel = EVAL_COM2_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

//Henrik           

}

 

********** stm324x9i_eval.h ************

/** @addtogroup STM324x9I_EVAL_LOW_LEVEL_COM

  * @{

  */

#define COMn                             2

 

/**

 * @brief Definition for COM port1, connected to USART1

 */

#define EVAL_COM1                        USART1

#define EVAL_COM1_CLK                    RCC_APB2Periph_USART1

#define EVAL_COM1_TX_PIN                 GPIO_Pin_9

#define EVAL_COM1_TX_GPIO_PORT           GPIOA

#define EVAL_COM1_TX_GPIO_CLK            RCC_AHB1Periph_GPIOA

#define EVAL_COM1_TX_SOURCE              GPIO_PinSource9

#define EVAL_COM1_TX_AF                  GPIO_AF_USART1

#define EVAL_COM1_RX_PIN                 GPIO_Pin_10

#define EVAL_COM1_RX_GPIO_PORT           GPIOA

#define EVAL_COM1_RX_GPIO_CLK            RCC_AHB1Periph_GPIOA

#define EVAL_COM1_RX_SOURCE              GPIO_PinSource10

#define EVAL_COM1_RX_AF                  GPIO_AF_USART1

#define EVAL_COM1_IRQn                   USART1_IRQn

 

// Henrik

/**

 * @brief Definition for COM port2, connected to USART6

 */

#define EVAL_COM2                        USART6

#define EVAL_COM2_CLK                    RCC_APB2Periph_USART6

#define EVAL_COM2_TX_PIN                 GPIO_Pin_14

#define EVAL_COM2_TX_GPIO_PORT           GPIOG

#define EVAL_COM2_TX_GPIO_CLK            RCC_AHB1Periph_GPIOG

#define EVAL_COM2_TX_SOURCE              GPIO_PinSource14

#define EVAL_COM2_TX_AF                  GPIO_AF_USART6

#define EVAL_COM2_RX_PIN                 GPIO_Pin_9

#define EVAL_COM2_RX_GPIO_PORT           GPIOG

#define EVAL_COM2_RX_GPIO_CLK            RCC_AHB1Periph_GPIOG

#define EVAL_COM2_RX_SOURCE              GPIO_PinSource9

#define EVAL_COM2_RX_AF                  GPIO_AF_USART6

#define EVAL_COM2_IRQn                   USART6_IRQn

//Henrik

 

 

********** stm32f4xx_it.c ************

 

/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/

#define TXBUFFERSIZE   (countof(aTxBuffer) - 1)

#define RXBUFFERSIZE   0x20

 

//Henrik

#define TXBUFFERSIZE_COM2 (countof(aTxBuffer_COM2) - 1 )

#define RXBUFFERSIZE_COM2 0x20

//Henrik

 

/* Private macro -------------------------------------------------------------*/

#define countof(a)   (sizeof(a) / sizeof(*(a)))

 

/* Private variables ---------------------------------------------------------*/

uint8_t aTxBuffer[] = "\n\rUSART Hyperterminal Interrupts Example: USART-Hyperterminal\

 communication using Interrupt\n\r";

uint8_t aRxBuffer[RXBUFFERSIZE];

uint8_t ubNbrOfDataToTransfer = TXBUFFERSIZE;

uint8_t ubNbrOfDataToRead = RXBUFFERSIZE;

__IO uint8_t ubTxCounter = 0;

__IO uint16_t uhRxCounter = 0;

 

//Henrik

uint8_t aTxBuffer_COM2[] = "COM2COM2COM2";

uint8_t aRxBuffer_COM2[RXBUFFERSIZE_COM2];

uint8_t ubNbrOfDataToTransfer_COM2 = TXBUFFERSIZE_COM2;

uint8_t ubNbrOfDataToRead_COM2 = RXBUFFERSIZE_COM2;

__IO uint8_t ubTxCounter_COM2 = 0;

__IO uint16_t uhRxCounter_COM2 = 0;

//Henrik

 

 

 

/**

  * @brief  This function handles USARTx global interrupt request.

  * @param  None

  * @retval None

  */

 

 

void USART1_IRQHANDLER(void)

{

  if(USART_GetITStatus(EVAL_COM1, USART_IT_RXNE) != RESET)

  {

    /* Read one byte from the receive data register */

    aRxBuffer[uhRxCounter++] = (USART_ReceiveData(EVAL_COM1) & 0x7F);

 

//Henrik: Echo of characters from Tera Term

                                                          USART_SendData(EVAL_COM1, aRxBuffer[uhRxCounter - 1]);

//                                                      USART_SendData(EVAL_COM2, aRxBuffer[uhRxCounter - 1]);

//Henrik

    if(uhRxCounter == ubNbrOfDataToRead)

    {

      /* Disable the EVAL_COM1 Receive interrupt */

      USART_ITConfig(EVAL_COM1, USART_IT_RXNE, DISABLE);

    }

  }

 

  if(USART_GetITStatus(EVAL_COM1, USART_IT_TXE) != RESET)

  {  

    /* Write one byte to the transmit data register */

    USART_SendData(EVAL_COM1, aTxBuffer[ubTxCounter++]);

    if(ubTxCounter == ubNbrOfDataToTransfer)

    {

      /* Disable the EVAL_COM1 Transmit interrupt */

      USART_ITConfig(EVAL_COM1, USART_IT_TXE, DISABLE);

    }

                             }

}

 

//Henrik

void USART6_IRQHANDLER(void)

{

  if(USART_GetITStatus(EVAL_COM2, USART_IT_RXNE) != RESET)

  {

    /* Read one byte from the receive data register */

    aRxBuffer_COM2[uhRxCounter_COM2++] = (USART_ReceiveData(EVAL_COM2) & 0x7F);

 

// Fredrik M specialare: Echo of characters from Tera Term

                                                          USART_SendData(EVAL_COM2, aRxBuffer_COM2[uhRxCounter_COM2 - 1]);

// Fredrik M specialare

    if(uhRxCounter_COM2 == ubNbrOfDataToRead_COM2)

    {

      /* Disable the EVAL_COM2 Receive interrupt */

      USART_ITConfig(EVAL_COM2, USART_IT_RXNE, DISABLE);

    }

  }

 

  if(USART_GetITStatus(EVAL_COM2, USART_IT_TXE) != RESET)

  {  

    /* Write one byte to the transmit data register */

    USART_SendData(EVAL_COM2, aTxBuffer_COM2[ubTxCounter_COM2++]);

 

    if(ubTxCounter_COM2 == ubNbrOfDataToTransfer_COM2)

    {

      /* Disable the EVAL_COM2 Transmit interrupt */

      USART_ITConfig(EVAL_COM2, USART_IT_TXE, DISABLE);

    }                                                   

                             }

}

//Henrik

 

********** stm32f4x9i_eval.c ************

 

//Henrik

USART_TypeDef* COM_USART[COMn] = {EVAL_COM1, EVAL_COM2};

 

GPIO_TypeDef* COM_TX_PORT[COMn] = {EVAL_COM1_TX_GPIO_PORT, EVAL_COM2_TX_GPIO_PORT};

 

GPIO_TypeDef* COM_RX_PORT[COMn] = {EVAL_COM1_RX_GPIO_PORT, EVAL_COM2_RX_GPIO_PORT};

 

const uint32_t COM_USART_CLK[COMn] = {EVAL_COM1_CLK, EVAL_COM2_CLK};

 

const uint32_t COM_TX_PORT_CLK[COMn] = {EVAL_COM1_TX_GPIO_CLK, EVAL_COM2_TX_GPIO_CLK};

 

const uint32_t COM_RX_PORT_CLK[COMn] = {EVAL_COM1_RX_GPIO_CLK, EVAL_COM2_RX_GPIO_CLK};

 

const uint16_t COM_TX_PIN[COMn] = {EVAL_COM1_TX_PIN, EVAL_COM2_TX_PIN};

 

const uint16_t COM_RX_PIN[COMn] = {EVAL_COM1_RX_PIN, EVAL_COM2_RX_PIN};

 

const uint16_t COM_TX_PIN_SOURCE[COMn] = {EVAL_COM1_TX_SOURCE, EVAL_COM2_TX_SOURCE};

 

const uint16_t COM_RX_PIN_SOURCE[COMn] = {EVAL_COM1_RX_SOURCE, EVAL_COM2_RX_SOURCE};

 

const uint16_t COM_TX_AF[COMn] = {EVAL_COM1_TX_AF, EVAL_COM2_TX_AF};

 

const uint16_t COM_RX_AF[COMn] = {EVAL_COM1_RX_AF, EVAL_COM2_RX_AF};

 

//Henrik

 

Outcomes