0
\$\begingroup\$

I have been trying to get the usart working on the stm32f3 discovery board for a while. I am using a 3.3V FTDI basic from sparkfun for the purpose. So far, I haven't got a peep from the program.

The program is given below:

    /* Includes ------------------------------------------------------------------*/
#include <stm32f30x.h>
#include <stm32f30x_rcc.h>
#include <stm32f30x_rcc.c>
#include <stm32f30x_gpio.h>
#include <stm32f30x_gpio.c>
#include <stm32f30x_misc.h>
#include <stm32f30x_misc.c>
#include <stm32f30x_tim.h>
#include <stm32f30x_tim.c>
#include <stm32f30x_usart.h>
#include <stm32f30x_usart.c>
//#include <arm_math.h>

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
volatile int ms;

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

/* Private functions ---------------------------------------------------------*/
void SysTick_Handler(void)
{
  ms++;
    if (ms>99){
        USART_SendData(USART1,'S');
        while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET){}
        ms=0;
    }
}

/**
  * @brief  Main program.
  * @param  None
  * @retval None
  */
int main(void)
{
  GPIO_InitTypeDef GPIO_InitStruct;
    USART_InitTypeDef USART_InitStruct;

    /*GPIO configuration for indicator LED*/
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOE,ENABLE);

    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;

    GPIO_Init(GPIOE,&GPIO_InitStruct);

    //Turn LED on
    GPIO_SetBits(GPIOE,GPIO_Pin_8);

    /*GPIO configuration for USART. PA2 = USART2_TX, PA3 = USART2_RX*/
    //Enable clock for GPIOA
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE);

    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN;

    GPIO_Init(GPIOA,&GPIO_InitStruct);

    //AF configuration
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_7);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_7);

    /*USART configuration*/
    USART_Cmd(USART2, ENABLE);

    USART_InitStruct.USART_BaudRate = 9600;
  USART_InitStruct.USART_WordLength = USART_WordLength_8b;
  USART_InitStruct.USART_StopBits = USART_StopBits_1;
  USART_InitStruct.USART_Parity = USART_Parity_No;
  USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

  USART_Init(USART2, &USART_InitStruct);

    //Enable RXNE interrupt
    USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);
    //Enable USART global interrupt
    NVIC_EnableIRQ(USART2_IRQn);

    if (SysTick_Config(SystemCoreClock / 1000))
  { 
    /* Capture error */ 
    while (1);
  }

  while (1)
  {

  }
}

void USART2_IRQHandler(void){
    /*RXNE handler*/
    if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET){
        /*If recieved 't', toggle LED, transmit 'T'*/
        if((char)USART_ReceiveData(USART2) == 't'){
            /*Toggle LED*/
            if (GPIO_ReadOutputDataBit(GPIOE,GPIO_Pin_8)){
                GPIO_ResetBits(GPIOE,GPIO_Pin_8);
            }
            else{
                GPIO_SetBits(GPIOE,GPIO_Pin_8);
            }

            /*USART_SendData(USART1,'T');
            while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET){}*/
        }
    }
}

I am using the Keil uvision 5 IDE.

Thank you.

EDIT: The current code is given below:

/* Includes ------------------------------------------------------------------*/
#include <stm32f30x.h>
#include <stm32f30x_rcc.h>
#include <stm32f30x_rcc.c>
#include <stm32f30x_gpio.h>
#include <stm32f30x_gpio.c>
#include <stm32f30x_misc.h>
#include <stm32f30x_misc.c>
#include <stm32f30x_tim.h>
#include <stm32f30x_tim.c>
#include <stm32f30x_usart.h>
#include <stm32f30x_usart.c>
//#include <arm_math.h>

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
volatile int ms;

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

/* Private functions ---------------------------------------------------------*/
void SysTick_Handler(void)
{
  ms++;
    if (ms>99){
        USART_SendData(USART1,'S');
        while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET){};
        if (GPIO_ReadOutputDataBit(GPIOE,GPIO_Pin_12)){
                GPIO_ResetBits(GPIOE,GPIO_Pin_12);
        }
        else{
                GPIO_SetBits(GPIOE,GPIO_Pin_12);
        }
        ms=0;
    }
}

/**
  * @brief  Main program.
  * @param  None
  * @retval None
  */
int main(void)
{
  GPIO_InitTypeDef GPIO_InitStruct;
    USART_InitTypeDef USART_InitStruct;

    /*GPIO configuration for indicator LED*/
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOE,ENABLE);

    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;

    GPIO_Init(GPIOE,&GPIO_InitStruct);

    //Turn LED on
    GPIO_SetBits(GPIOE,GPIO_Pin_8|GPIO_Pin_12);

    /*GPIO configuration for USART. PA2 = USART2_TX, PA3 = USART2_RX*/
    //Enable clock for GPIOA
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE);

    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN;

    GPIO_Init(GPIOA,&GPIO_InitStruct);

    //AF configuration
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_7);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_7);

    /*USART configuration*/
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
    USART_Cmd(USART2, ENABLE);

    USART_InitStruct.USART_BaudRate = 9600;
  USART_InitStruct.USART_WordLength = USART_WordLength_8b;
  USART_InitStruct.USART_StopBits = USART_StopBits_1;
  USART_InitStruct.USART_Parity = USART_Parity_No;
  USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

  USART_Init(USART2, &USART_InitStruct);

    //Enable RXNE interrupt
    USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);
    GPIO_SetBits(GPIOE,GPIO_Pin_9);
    //Enable USART global interrupt
    NVIC_EnableIRQ(USART2_IRQn);
    GPIO_SetBits(GPIOE,GPIO_Pin_10);

    if (SysTick_Config(SystemCoreClock / 1000))
  { 
    /* Capture error */ 
    while (1);
  }
    GPIO_SetBits(GPIOE,GPIO_Pin_11);

  while (1)
  {

  }
}

void USART2_IRQHandler(void){
    /*RXNE handler*/
    if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET){
        /*If recieved 't', toggle LED, transmit 'T'*/
        if((char)USART_ReceiveData(USART2) == 't'){
            /*Toggle LED*/
            if (GPIO_ReadOutputDataBit(GPIOE,GPIO_Pin_8)){
                GPIO_ResetBits(GPIOE,GPIO_Pin_8);
            }
            else{
                GPIO_SetBits(GPIOE,GPIO_Pin_8);
            }

            /*USART_SendData(USART1,'T');
            while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET){}*/
        }
    }
}

There is no response from the program at this time. (TX is constant at 3.3V, RX is at 0v).

UPDATE: I have tried using USART1 instead, and I still get no response. The other changes include moving the transmission part of the code to the while loop, and trying with GPIO_PuPd_UP, GPIO_PuPd_DOWN and GPIO_PuPd_NOPULL, with no result. Currently, when using USART2, the TX (PA2) is at a constant 3.3V, and RX(PA3) at 0v. On moving it to USART1, both(PC4,PC5) seem to be at a constant 3.3V.

UPDATE: The TX of the USART is working now, I had to enable the USART after initialising it, not before, as discussed here: https://community.st.com/thread/47271-usart-stm32f3-discovery

\$\endgroup\$
9
  • 1
    \$\begingroup\$ What do you mean by "Haven't got a peep out of?" No receive interrupt? What does your scope say the signal looks like going into the Rx pin? We need a schematic too. If you're using Keil, you have a good debugger. Have you set a breakpoint at the end of your UART init to see whether the registers are set as you think they should be? \$\endgroup\$
    – DiBosco
    Feb 6, 2018 at 9:26
  • \$\begingroup\$ you havent enabled Peripheral clock for USART2 \$\endgroup\$
    – Abel Tom
    Feb 6, 2018 at 13:00
  • \$\begingroup\$ if my answer worked for you, could you please mark it as accepted. \$\endgroup\$
    – Abel Tom
    Feb 6, 2018 at 13:59
  • 2
    \$\begingroup\$ It seems a little odd that you are #includeing .c files along with the .h files. You should only have to include the .h file. \$\endgroup\$
    – Ron Beyer
    Feb 6, 2018 at 17:20
  • 1
    \$\begingroup\$ Yes, but the linker fails if I don't. I'm not sure why. \$\endgroup\$
    – 884-15-X-C
    Feb 6, 2018 at 17:37

1 Answer 1

4
\$\begingroup\$

you need to enable Peripheral clock for USART2 explicitly, using this call

RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

before enabling USART2 with USART_Cmd(USART2, ENABLE);

Also make sure your startup_xx.s file knows the USART2_IRQ_Handler

\$\endgroup\$
13
  • \$\begingroup\$ I enabled the peripheral clock, and the startup_stm32303xc.s does have USART2_IRQ_Handler. The program doesn't work yet. I have used the LEDs on the board for making sure that the program runs. The program initialises completely, and sysTick_Handler works without a problem (that LED keeps blinking - I have set it to toggle after the USART_SendData command). Regardless, there is no output on the TX Pin (PA2) - the oscilloscope shows that this pin at a constant 3.3V. \$\endgroup\$
    – 884-15-X-C
    Feb 6, 2018 at 15:53
  • \$\begingroup\$ Does it come inside the ISR? you also need to clear the pending interrupt bit i.e USART_ClearITPendingBit(USART2, USART_IT_RXNE); inside the ISR. \$\endgroup\$
    – Abel Tom
    Feb 6, 2018 at 16:35
  • \$\begingroup\$ No, I didn't check inside the ISR. Still (correct me if I am wrong), I believe the program should be transmitting even if the ISR is never called (i.e., I don't send anything to the board). \$\endgroup\$
    – 884-15-X-C
    Feb 6, 2018 at 16:56
  • \$\begingroup\$ Its a little unconventional i would say, but you are trying to send data in Systick handler even before USART1 module is initialized. I would start by commenting everything inside systick and put that Send routine in main--> while(1) loop \$\endgroup\$
    – Abel Tom
    Feb 6, 2018 at 16:59
  • 1
    \$\begingroup\$ @NipuniPerera If this is not solving your problem, you should not have marked it as an "answer" as it will deter further answers from being posted. \$\endgroup\$
    – Ron Beyer
    Feb 6, 2018 at 17:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.