Skip to main content
chrispadbury
Associate III
March 26, 2012
Question

F4Discovery using UART1

  • March 26, 2012
  • 20 replies
  • 4233 views
Posted on March 26, 2012 at 16:03

Hi, I not having much success with using the UART (USART1) on my F4Discovery board (STM32F407). I am pretty new to STM32 and Keil (the IDE I am using). Here's my code:

&sharpinclude ''stm32f4_discovery.h''

&sharpinclude ''stm32f4xx_usart.h''

&sharpinclude ''stm32f4xx.h''

void usartSetup(void);

void USART_PutChar(uint8_t ch);

int main (void) {

    usartSetup();

    USART_PutChar(0);   //I realise this won't send a 0

    USART_PutChar(8);   //I realise this won't send an 8

    USART_PutChar(255);   //I realise this won't send a 255

    while (1) {

        //loop forever

    }

}

void usartSetup (void) {

    USART_InitTypeDef USART_InitStructure;

    //USART_StructInit(&USART_InitStructure);

    USART_InitStructure.USART_BaudRate = 9600;

    USART_InitStructure.USART_WordLength = USART_WordLength_8b;

    USART_InitStructure.USART_StopBits = USART_StopBits_1;

    USART_InitStructure.USART_Parity = USART_Parity_No;

    USART_InitStructure.USART_HardwareFlowControl =  USART_HardwareFlowControl_None;

    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

    USART_Init(USART1, &USART_InitStructure);

    USART_Cmd(USART1, ENABLE);

}

void USART_PutChar(uint8_t ch) {

    USART_SendData(USART1, (uint16_t) 0x49);

    while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);

    USART_SendData(USART1, (uint16_t) 0x49);

}

 I'd be very grateful if someone could help. It never sends the 0x49 out of the UART1 TX (have checked pin PA9 and PB6) and then gets endlessly stuck on the while(USART_GetFlagStatus...). I am observing using the Keil debugger and see it get stuck in the while. I also have a scope probe on the TX pin and never see anything.

I am including the stm32f4xx_usart.c driver into the project.

Thanks!

#rs232-uart-usart-f4discover-407 #uart #stm32f4discovery
This topic has been closed for replies.

20 replies

Tesla DeLorean
Guru
March 26, 2012
Posted on March 26, 2012 at 16:20

Problems there with failing to enable clocks, or configure GPIO pins.

// STM32 USART1 (Tx PA.9, Rx PA.10) STM32F4 Discovery - sourcer32@gmail.com
#include ''stm32f4_discovery.h''
/**************************************************************************************/
void RCC_Configuration(void)
{
/* --------------------------- System Clocks Configuration -----------------*/
/* USART1 clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
/* GPIOA clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
}
/**************************************************************************************/
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*-------------------------- GPIO Configuration ----------------------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Connect USART pins to AF */
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1); // USART1_TX
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1); // USART1_RX
}
/**************************************************************************************/
void USART1_Configuration(void)
{
USART_InitTypeDef USART_InitStructure;
/* USARTx configuration ------------------------------------------------------*/
/* USARTx configured as follow:
- BaudRate = 9600 baud
- Word Length = 8 Bits
- One Stop Bit
- No parity
- Hardware flow control disabled (RTS and CTS signals)
- Receive and transmit enabled
*/
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
USART_Cmd(USART1, ENABLE);
}
/**************************************************************************************/
int main(void)
{
RCC_Configuration();
GPIO_Configuration();
USART1_Configuration();
while(1)
{
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); // Wait for Empty
USART_SendData(USART1, 0x49); // Send 'I'
}
while(1); // Don't want to exit
}

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
chrispadbury
Associate III
March 26, 2012
Posted on March 26, 2012 at 16:43

Thanks for this, I didn't think you'd have to configure the GPIO if you were using just the UART (i.e. truning on the UART functionality I presumed would turn off the GPIO on the same pins).

I see a very gruesome trace out of PA9:

0690X00000605TqQAI.png

I get the same track with either the MAX3232 chip connected or not. The PC interprets it a E9 (233).

Tesla DeLorean
Guru
March 26, 2012
Posted on March 26, 2012 at 16:58

Dunno, is USART1 viable on the STM32F4 Discovery on these pins? Check the schematic.

Always assume the hardware isn't going to magically configure itself. Review some of the peripheral examples to get a feeling for how it's done, the API documentation mostly describes the functions, the reference manuals are the best place to understand the hardware. I've been using USART3, I had to mod this example to get you USART1. Here's a build using PB6,7 as the USART1 pins

// STM32 USART1 (Tx PB.6, Rx PB.7) STM32F4 Discovery - sourcer32@gmail.com
#include ''stm32f4_discovery.h''
/**************************************************************************************/
void RCC_Configuration(void)
{
/* --------------------------- System Clocks Configuration -----------------*/
/* USART1 clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
/* GPIOB clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
}
/**************************************************************************************/
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*-------------------------- GPIO Configuration ----------------------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Connect USART pins to AF */
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1); // USART1_TX
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1); // USART1_RX
}
/**************************************************************************************/
void USART1_Configuration(void)
{
USART_InitTypeDef USART_InitStructure;
/* USARTx configuration ------------------------------------------------------*/
/* USARTx configured as follow:
- BaudRate = 9600 baud
- Word Length = 8 Bits
- One Stop Bit
- No parity
- Hardware flow control disabled (RTS and CTS signals)
- Receive and transmit enabled
*/
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
USART_Cmd(USART1, ENABLE);
}
/**************************************************************************************/
int main(void)
{
RCC_Configuration();
GPIO_Configuration();
USART1_Configuration();
while(1)
{
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); // Wait for Empty
USART_SendData(USART1, 0x49); // Send 'I'
}
while(1); // Don't want to exit
}

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
chrispadbury
Associate III
March 26, 2012
Posted on March 26, 2012 at 17:22

It works with the alternate pins (PB6 as TX). PA9 is connected to an LED which is why it is capacitively slowed and creates a nasty trace (might work at 1200baud :-).

Thank you for your help!

danielczigany9
Visitor II
March 27, 2012
Posted on March 27, 2012 at 09:29

Hello,

you can see on STMF4 Discovery user manual (page 34): on the PA9 there is a 4.7uF capacitor. If you want to use UART1 TX then you must remove this component and you must care about PC0, you must keep it HIGH.

I suggest use UART6, the pins for UART6 is near to UART1 on the header. (PC6 Tx, PC7 Rx).

cd334

chrispadbury
Associate III
March 27, 2012
Posted on March 27, 2012 at 12:59

Hi

I am now trying to use PortE GPIO output, but it isn't doing as expected.

// STM32 USART1 (Tx PB.6, Rx PB.7) STM32F4 Discovery - sourcer32@gmail.com 
#include ''stm32f4_discovery.h'' 
void Delay(int ms); 
/**************************************************************************************/ 
void RCC_Configuration(void) 
{ 
/* --------------------------- System Clocks Configuration -----------------*/ 
/* USART1 clock enable */ 
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); 
/* GPIOB clock enable */ 
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); 
} 
/**************************************************************************************/ 
void GPIO_Configuration(void) 
{ 
GPIO_InitTypeDef GPIO_InitStructure; 
/*-------------------------- GPIO Configuration ----------------------------*/ 
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; 
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; 
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
GPIO_Init(GPIOB, &GPIO_InitStructure); 
/* Connect USART pins to AF */ 
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1); // USART1_TX 
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1); // USART1_RX 
// Configure Port E : Pins 7-15 as outputs 
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; 
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; 
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; 
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
GPIO_Init(GPIOE, &GPIO_InitStructure); 
} 
/**************************************************************************************/ 
void USART1_Configuration(void) 
{ 
USART_InitTypeDef USART_InitStructure; 
/* USARTx configuration ------------------------------------------------------*/ 
/* USARTx configured as follow: 
- BaudRate = 9600 baud 
- Word Length = 8 Bits 
- One Stop Bit 
- No parity 
- Hardware flow control disabled (RTS and CTS signals) 
- Receive and transmit enabled 
*/ 
USART_InitStructure.USART_BaudRate = 9600; 
USART_InitStructure.USART_WordLength = USART_WordLength_8b; 
USART_InitStructure.USART_StopBits = USART_StopBits_1; 
USART_InitStructure.USART_Parity = USART_Parity_No; 
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; 
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; 
USART_Init(USART1, &USART_InitStructure); 
USART_Cmd(USART1, ENABLE); 
} 
/**************************************************************************************/ 
int main(void) 
{ 
int i; 
char c; 
RCC_Configuration(); 
GPIO_Configuration(); 
USART1_Configuration(); 
i = 30; 
while(i--) { 
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); // Wait for Empty 
USART_SendData(USART1, 0x49); // Send 'I' 
//Load the byte onto pins 8-15 of Port E 
//reset all 8 pins 
GPIO_ResetBits(GPIOE, GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15); 
c = i; 
if(c & 0x01) { 
GPIO_SetBits(GPIOE, GPIO_Pin_8); 
} 
if(c & 0x02) { 
GPIO_SetBits(GPIOE, GPIO_Pin_9); 
} 
if(c & 0x04) { 
GPIO_SetBits(GPIOE, GPIO_Pin_10); 
} 
if(c & 0x08) { 
GPIO_SetBits(GPIOE, GPIO_Pin_11); 
} 
if(c & 0x10) { 
GPIO_SetBits(GPIOE, GPIO_Pin_12); 
} 
if(c & 0x20) { 
GPIO_SetBits(GPIOE, GPIO_Pin_13); 
} 
if(c & 0x40) { 
GPIO_SetBits(GPIOE, GPIO_Pin_14); 
} 
if(c & 0x80) { 
GPIO_SetBits(GPIOE, GPIO_Pin_15); 
} 
GPIO_SetBits(GPIOE, GPIO_Pin_7); 
Delay(500); 
GPIO_ResetBits(GPIOE, GPIO_Pin_7); 
Delay(500); 
} 
while(1); // Don't want to exit 
} 
void Delay(int ms) { 
ms = ms * 168000 / 4; 
while (ms) { 
ms--; 
} 
} 

I see the I characters coming out of the RS232 but never see anything on PortE pin7 (or pins 8-15 for that matter). PortE_7 seems to be behaving like an input as well because if I connect it to a different board with a pin configured as an input but with pull-up, PortE_7 follows it to high.
chrispadbury
Associate III
March 27, 2012
Posted on March 27, 2012 at 13:02

Note: it is a while(1) as the last line of code not just while().

Tesla DeLorean
Guru
March 27, 2012
Posted on March 27, 2012 at 16:00

/* GPIOE clock enable */ 
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); 

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
chrispadbury
Associate III
March 27, 2012
Posted on March 27, 2012 at 16:50

Sorry, should have spotted that.

Thanks for your help.

chrispadbury
Associate III
March 28, 2012
Posted on March 28, 2012 at 17:54

Out of interest, Is there a more elegant way to write to the upper 8 pins of portE. I am more used to eight bit micros, where it is simpler dealing with single bytes all the time.