Author Topic: STM32F4Discovery USART problems  (Read 19843 times)

0 Members and 1 Guest are viewing this topic.

Offline skerdziusTopic starter

  • Contributor
  • Posts: 26
STM32F4Discovery USART problems
« on: February 08, 2013, 07:24:00 pm »
i am using STM32F4Discovery board with CP2102 based USB-TTL converter to send data between PC and this board. so i connect RX, TX wires i use STM32F4xx_DSP_StdPeriph_Lib_V1.0.1 libraries and uVision Keil IDE. i send symbols, but in terminal i recieve a bunch of irrelevant symbols i am using example of USART code found on internet.
 

Offline ve7xen

  • Super Contributor
  • ***
  • Posts: 1192
  • Country: ca
    • VE7XEN Blog
Re: STM32F4Discovery USART problems
« Reply #1 on: February 08, 2013, 07:31:39 pm »
Looks like a baudrate mismatch. We can't do much to help without your code...
73 de VE7XEN
He/Him
 

Offline enz

  • Regular Contributor
  • *
  • Posts: 134
  • Country: de
Re: STM32F4Discovery USART problems
« Reply #2 on: February 08, 2013, 07:33:31 pm »
Wrong Baudrate?
 

Offline Bored@Work

  • Super Contributor
  • ***
  • Posts: 3932
  • Country: 00
Re: STM32F4Discovery USART problems
« Reply #3 on: February 08, 2013, 08:07:45 pm »
Wrong baudrate. Send 'U's in an endless loop from the board. Use an oscilloscope to check the baud rate you are really sending.

Also check number of bits, stop bit length and parity bit (if any).
I delete PMs unread. If you have something to say, say it in public.
For all else: Profile->[Modify Profile]Buddies/Ignore List->Edit Ignore List
 

Offline skerdziusTopic starter

  • Contributor
  • Posts: 26
Re: STM32F4Discovery USART problems
« Reply #4 on: February 08, 2013, 08:10:11 pm »
i am aware of baudrate and i set it right.
Code: [Select]
#include <stm32f4xx.h>
#include <misc.h> // I recommend you have a look at these in the ST firmware folder
#include <stm32f4xx_usart.h> // under Libraries/STM32F4xx_StdPeriph_Driver/inc and src

#define MAX_STRLEN 12 // this is the maximum string length of our string in characters
volatile char received_string[MAX_STRLEN+1]; // this will hold the recieved string

void Delay(__IO uint32_t nCount) {
  while(nCount--) {
  }
}

/* This funcion initializes the USART1 peripheral
 *
 * Arguments: baudrate --> the baudrate at which the USART is
 *    supposed to operate
 */
void init_USART1(uint32_t baudrate){

/* This is a concept that has to do with the libraries provided by ST
* to make development easier the have made up something similar to
* classes, called TypeDefs, which actually just define the common
* parameters that every peripheral needs to work correctly
*
* They make our life easier because we don't have to mess around with
* the low level stuff of setting bits in the correct registers
*/
GPIO_InitTypeDef GPIO_InitStruct; // this is for the GPIO pins used as TX and RX
USART_InitTypeDef USART_InitStruct; // this is for the USART1 initilization


/* enable APB2 peripheral clock for USART1
* note that only USART1 and USART6 are connected to APB2
* the other USARTs are connected to APB1
*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

/* enable the peripheral clock for the pins used by
* USART1, PB6 for TX and PB7 for RX
*/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

/* This sequence sets up the TX and RX pins
* so they work correctly with the USART1 peripheral
*/
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; // Pins 6 (TX) and 7 (RX) are used
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; // the pins are configured as alternate function so the USART peripheral has access to them
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; // this defines the IO speed and has nothing to do with the baudrate!
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; // this defines the output type as push pull mode (as opposed to open drain)
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; // this activates the pullup resistors on the IO pins
GPIO_Init(GPIOB, &GPIO_InitStruct); // now all the values are passed to the GPIO_Init() function which sets the GPIO registers

/* The RX and TX pins are now connected to their AF
* so that the USART1 can take over control of the
* pins
*/
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1);

/* Now the USART_InitStruct is used to define the
* properties of USART1
*/
USART_InitStruct.USART_BaudRate = baudrate; // the baudrate is set to the value we passed into this init function
USART_InitStruct.USART_WordLength = USART_WordLength_8b;// we want the data frame size to be 8 bits (standard)
USART_InitStruct.USART_StopBits = USART_StopBits_1; // we want 1 stop bit (standard)
USART_InitStruct.USART_Parity = USART_Parity_No; // we don't want a parity bit (standard)
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // we don't want flow control (standard)
USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; // we want to enable the transmitter and the receiver
USART_Init(USART1, &USART_InitStruct); // again all the properties are passed to the USART_Init function which takes care of all the bit setting


/* Here the USART1 receive interrupt is enabled
* and the interrupt controller is configured
* to jump to the USART1_IRQHandler() function
* if the USART1 receive interrupt occurs
*/
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // enable the USART1 receive interrupt


// finally this enables the complete USART1 peripheral
USART_Cmd(USART1, ENABLE);
}

/* This function is used to transmit a string of characters via
 * the USART specified in USARTx.
 *
 * It takes two arguments: USARTx --> can be any of the USARTs e.g. USART1, USART2 etc.
 *    (volatile) char *s is the string you want to send
 *
 * Note: The string has to be passed to the function as a pointer because
 * the compiler doesn't know the 'string' data type. In standard
 * C a string is just an array of characters
 *
 * Note 2: At the moment it takes a volatile char because the received_string variable
 *    declared as volatile char --> otherwise the compiler will spit out warnings
 * */
void USART_puts(USART_TypeDef* USARTx, volatile char *s){

while(*s){
// wait until data register is empty
while( !(USARTx->SR & 0x00000040) );
USART_SendData(USARTx, *s);
*s++;
}
}

int main(void) {
 
  init_USART1(9600); // initialize USART1 @ 9600 baud

  USART_puts(USART1, "hello world"); // just send a message to indicate that it works

  while (1)

    }
}
comments are not mine, they are author's who posted this on internet
 

Offline Bored@Work

  • Super Contributor
  • ***
  • Posts: 3932
  • Country: 00
Re: STM32F4Discovery USART problems
« Reply #5 on: February 08, 2013, 08:15:46 pm »
i am aware of baudrate and i set it right.

Then it would work. But it is your choice. You can start to measure or you can continue sitting there claiming everything is right
I delete PMs unread. If you have something to say, say it in public.
For all else: Profile->[Modify Profile]Buddies/Ignore List->Edit Ignore List
 

Offline skerdziusTopic starter

  • Contributor
  • Posts: 26
Re: STM32F4Discovery USART problems
« Reply #6 on: February 08, 2013, 08:28:10 pm »
baudrate in code is set at 9600. i set the same value in terminal. so what could possibly go wrong?  :o and sorry, but i don't have osciloscope :-//
 

Offline AndreasF

  • Frequent Contributor
  • **
  • Posts: 251
  • Country: gb
    • mind-dump.net
Re: STM32F4Discovery USART problems
« Reply #7 on: February 08, 2013, 08:31:43 pm »
Code looks fine, but pin PB6 (your USART1_TX) is used as the I2C clock signal to the audio codec chip on the STM32F4Discovery, and maybe this causes some sort of interference.  :-//

I would try some of the other pins that aren't connected to anything else, eg. PA2 and PA3 (of USART2).
my random ramblings mind-dump.net
 

Offline enz

  • Regular Contributor
  • *
  • Posts: 134
  • Country: de
Re: STM32F4Discovery USART problems
« Reply #8 on: February 08, 2013, 08:42:59 pm »
Maybe you should change this:

Code: [Select]
void USART_puts(USART_TypeDef* USARTx, volatile char *s){

while(*s){
// wait until data register is empty
while( !(USARTx->SR & 0x00000040) );
USART_SendData(USARTx, *s);
*s++;
}
}

to this

Code: [Select]
void USART_puts(USART_TypeDef* USARTx, volatile char *s){

while(*s){
// wait until data register is empty
while( !(USARTx->SR & 0x00000040) );
USART_SendData(USARTx, *s);
s++;
}
}

Hint: Note the removed asterisk before s++
 

Offline Skimask

  • Super Contributor
  • ***
  • Posts: 1433
  • Country: us
Re: STM32F4Discovery USART problems
« Reply #9 on: February 08, 2013, 08:51:49 pm »
so what could possibly go wrong?

Said nobody...ever...
I didn't take it apart.
I turned it on.

The only stupid question is, well, most of them...

Save a fuse...Blow an electrician.
 

Offline skerdziusTopic starter

  • Contributor
  • Posts: 26
Re: STM32F4Discovery USART problems
« Reply #10 on: February 08, 2013, 09:15:19 pm »
i tried deleting asterix as told. everything compiled good but nothing changed. when i changed to USART2 nothing changed as well :S
 

Offline enz

  • Regular Contributor
  • *
  • Posts: 134
  • Country: de
Re: STM32F4Discovery USART problems
« Reply #11 on: February 08, 2013, 09:22:35 pm »
Weird, it seems that there are a couple of errors coming together.
With the asterisk in you were incrementing the data you want to send, not the pointer. So this was an endless loop.

Without the asterisk you are now incrementing the pointer, there's no longer an endlees loop and the intended data will be send. Two errors less.

Next point:
Is the system clock set to the value the baudrate will be calculated from?

 

Offline CarlG

  • Regular Contributor
  • *
  • Posts: 155
  • Country: se
Re: STM32F4Discovery USART problems
« Reply #12 on: February 08, 2013, 09:25:49 pm »
Have you verified that you're using the same PCLK and prescaler setting(s) as the USART code you're using requires?
 

Offline skerdziusTopic starter

  • Contributor
  • Posts: 26
Re: STM32F4Discovery USART problems
« Reply #13 on: February 09, 2013, 12:45:03 pm »
sorry, but i am not aware of these PCL prescaler or System clock settings. i don't know where to change them using standart peripheral libraries  :-// examples of usart code found on internet don't have any of these settings involved in them as i discovered  :-\
 

Offline gxti

  • Frequent Contributor
  • **
  • Posts: 507
  • Country: us
Re: STM32F4Discovery USART problems
« Reply #14 on: February 09, 2013, 02:43:16 pm »
With the asterisk in you were incrementing the data you want to send, not the pointer. So this was an endless loop.
Actually, no. In C, "++" binds more tightly than "*". So "*x++" is really "*(x++)" which is why you can do e.g ."*x++ = 0;". The before and after statements are equivalent.
 

Offline skerdziusTopic starter

  • Contributor
  • Posts: 26
Re: STM32F4Discovery USART problems
« Reply #15 on: February 09, 2013, 03:44:34 pm »
i found the formula in stm32f4xx_usart.h file, however i don't understand what are these parameters and how to change them in code  :-\
Code: [Select]
The baud rate is computed using the following formula:
                                            - IntegerDivider = ((PCLKx) / (8 * (OVR8+1) * (USART_InitStruct->USART_BaudRate)))
                                            - FractionalDivider = ((IntegerDivider - ((u32) IntegerDivider)) * 8 * (OVR8+1)) + 0.5
                                           Where OVR8 is the "oversampling by 8 mode" configuration bit in the CR1 register.
 

Offline mrflibble

  • Super Contributor
  • ***
  • Posts: 2051
  • Country: nl
Re: STM32F4Discovery USART problems
« Reply #16 on: February 09, 2013, 04:42:30 pm »
Here's a quick snippet from working code I normally use on that board. I think you can figure out how to change it from the current setting of 115200 baud to 9600 baud. ;-)


Code: [Select]
#include <stm32f4xx_usart.h>

/**
 * @brief Configure USART2 at 115200 baud, 8N1. Configure the GPIO pins (PA.2, PA.3) as push-pull.
 * @param None
 */
void USART2_Config(void)
{
        GPIO_InitTypeDef  GPIO_InitStructure;
        USART_InitTypeDef USART_InitStructure;
        NVIC_InitTypeDef  NVIC_InitStructure;

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

        // PA.2 = TX
        // PA.3 = RX
        GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_2 | GPIO_Pin_3;
        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
//      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
//      GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
        GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
        GPIO_Init(GPIOA, &GPIO_InitStructure);

        GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2); // PA.2 = TX
        GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2); // PA.3 = RX

//      USART_InitStructure.USART_BaudRate            = 9600;   // confirmed working. Remember to do: stty -F /dev/ttyUSB0 9600
        USART_InitStructure.USART_BaudRate            = 115200; // confirmed working. Remember to do: stty -F /dev/ttyUSB0 115200
        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_Tx | USART_Mode_Rx;
        USART_Init(USART2, &USART_InitStructure);
        USART_Cmd(USART2, ENABLE);
}
 

Offline mrflibble

  • Super Contributor
  • ***
  • Posts: 2051
  • Country: nl
Re: STM32F4Discovery USART problems
« Reply #17 on: February 09, 2013, 04:50:47 pm »
i am using STM32F4Discovery board with CP2102 based USB-TTL converter ...

I just noticed this... I also have a few of those. And some of those have the RX/TX labeled precisely the wrong way around. So better check and double check that CP2102 first.
 

Offline skerdziusTopic starter

  • Contributor
  • Posts: 26
Re: STM32F4Discovery USART problems
« Reply #18 on: February 09, 2013, 06:09:02 pm »
i can't explain this but i fix my connection like this:  i am using 115200 baudrate on my discovery board
Code: [Select]
init_USART1(115200); // initialize USART1 @ 115200 baud and on terminal i am listening at 38400 baudrate. then it works great  ;D thanks for help. maybe later i will find out a better solution, but it's enough  for now  :)
 

Offline AndreasF

  • Frequent Contributor
  • **
  • Posts: 251
  • Country: gb
    • mind-dump.net
Re: STM32F4Discovery USART problems
« Reply #19 on: February 09, 2013, 08:49:01 pm »
Ahhha, I'm going to take a wild guess here then, that your HSE_VALUE define is wrong. As you may have noticed, 115200 is exactly 1/3 of 38400, so it seems that your STM32F4 thinks it's running three times faster than it actually is. This HSE_VALUE must be the frequency of the crystal on your board (on mine it's 8 Mhz). If it's not defined elsewhere the startup code will use the value stored in "stm32f4xx.h", which is 25000000 (or 25Mhz). As you notice, 25Mhz is approx. 3 times 8 Mhz.

I'm not familiar with the Keil IDE, but I'm guessing there is a way to set "predefined symbols" and that's where you should include a line like this "HSE_VALUE = 8000000" (or whatever crystal frequency you have on your board).

from "system_stm32f4xx.c":
Code: [Select]
  *         (**) HSE_VALUE is a constant defined in stm32f4xx.h file (default value
  *              25 MHz), user has to ensure that HSE_VALUE is same as the real
  *              frequency of the crystal used. Otherwise, this function may
  *              have wrong result.
my random ramblings mind-dump.net
 

Offline mrflibble

  • Super Contributor
  • ***
  • Posts: 2051
  • Country: nl
Re: STM32F4Discovery USART problems
« Reply #20 on: February 09, 2013, 11:25:58 pm »
Yeah, that 25 MHz vs 8 MHz got me too when I just started. I grabbed some example code ... which of course just had to have the wrong PLL settings. You probably have it set to 25 MHz while you should have it set to 8 MHz.
 

Offline enz

  • Regular Contributor
  • *
  • Posts: 134
  • Country: de
Re: STM32F4Discovery USART problems
« Reply #21 on: February 10, 2013, 10:08:19 am »
With the asterisk in you were incrementing the data you want to send, not the pointer. So this was an endless loop.
Actually, no. In C, "++" binds more tightly than "*". So "*x++" is really "*(x++)" which is why you can do e.g ."*x++ = 0;". The before and after statements are equivalent.

You are right, i missed the binding precedence.
But then the asterisk does not do anything and is needless.
 

Offline mrflibble

  • Super Contributor
  • ***
  • Posts: 2051
  • Country: nl
Re: STM32F4Discovery USART problems
« Reply #22 on: February 10, 2013, 11:58:56 am »
But then the asterisk does not do anything and is needless.

O_o

You don't use pointers very often, do you?
« Last Edit: February 10, 2013, 12:01:47 pm by mrflibble »
 

Offline Bored@Work

  • Super Contributor
  • ***
  • Posts: 3932
  • Country: 00
Re: STM32F4Discovery USART problems
« Reply #23 on: February 10, 2013, 12:05:24 pm »
i can't explain this but i fix my connection like this:  i am using 115200 baudrate on my discovery board
Code: [Select]
init_USART1(115200); // initialize USART1 @ 115200 baud and on terminal i am listening at 38400 baudrate. then it works great  ;D thanks for help. maybe later i will find out a better solution, but it's enough  for now  :)

In other words, the baud rate is still wrong and was always wrong. And you are still in denial and call that a fix.
I delete PMs unread. If you have something to say, say it in public.
For all else: Profile->[Modify Profile]Buddies/Ignore List->Edit Ignore List
 

Offline mrflibble

  • Super Contributor
  • ***
  • Posts: 2051
  • Country: nl
Re: STM32F4Discovery USART problems
« Reply #24 on: February 10, 2013, 12:31:49 pm »
Yeah, but look on the bright side! Now the baud rate error is only about 4%. XD
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf