cancel
Showing results for 
Search instead for 
Did you mean: 

USART Loopback with STM32F107

loic
Associate II
Posted on May 20, 2015 at 11:35

Hi,

I would make a loopback with my board STM3210C using USART2. I use the code

/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Recieve%20more%20then%201%20Byte%20over%20USART&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&currentviews=3862

. Here is my main code :

while(1)
{
//Wait until a byte is received
while(USART_GetFlagStatus(USART2, USART_FLAG_RXNE) == RESET);
RXBUFF[j] = USART_ReceiveData(USART2);
if (USART_GetFlagStatus(USART2, USART_FLAG_TXE) != RESET)
USART_SendData(USART2, RXBUFF[j]);
j++;
if (j >= 1)
j = 0;
 } 

When I use the Hyperterminal to show the data exchange, I have a value returned only all the 4 or 5 values send. I just would send a number between 0 and 9, and receveid the same to verify the connexion. Thanks for your help Best regards Loïc
13 REPLIES 13
Posted on May 20, 2015 at 14:10

Think about what happens with your code if TXE isn't set? I probably assumed the output rate was at least as quick as the input rate, but they might be too close.

Make the buffer bigger, and double check with a debugger that you actually receive all the data correctly.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
loic
Associate II
Posted on May 20, 2015 at 15:03

Thanks for the reply.

TXE is set. I don't receive the good data in the buffer, but if I send a value defined in the main, there is no problem. The USART is defined with a baudrate of 9600 and I use the configuration of VCP (I use the STM3210C-Eval Board).

void USART_Config_Default(void)
{
/* EVAL_COM1 default configuration */
/* EVAL_COM1 configured as follow:
- BaudRate = 9600 baud 
- Word Length = 8 Bits
- One Stop Bit
- Parity Odd
- Hardware flow control disabled
- 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_Odd;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
/* Configure and enable the USART */
STM_EVAL_COMInit(COM1, &USART_InitStructure);
/* Enable the USART Receive interrupt */
USART_ITConfig(EVAL_COM1, USART_IT_RXNE, ENABLE);
}

Posted on May 21, 2015 at 03:27

8-bits with odd parity should be configure as 9-bit mode. ie 8 for the data, +1 for the parity.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
loic
Associate II
Posted on May 21, 2015 at 08:43

I have tried to change this parameter, but no results.

I have also tried 8bits/Even, 8bits/None, 9Bits/Odd and I have again the same problem.

This what I see in my hyperterminal when I write ''12345678901234567890123456789''

123455677899001234567889012345667889

Posted on May 21, 2015 at 11:42

Ok, perhaps you need to start over here and present your entire example. The fragments you've shown enable the receive interrupt, what exactly is the IRQ code doing? It's really hard to debug this stuff without adequate context.

What tool chain and debugger are you using?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
loic
Associate II
Posted on May 21, 2015 at 13:33

Here is my main.c (I have used the VCP Demo from USB FS Device Lib 3.3.0; the exemple of the V4 doesn't support SMT3210C).

There is some definitions/init of an ADC, this is normal if you find function for it. I use Putty as hyperterminal and µVision as IDE.

/******************** (C) COPYRIGHT 2011 STMicroelectronics ********************
* File Name : main.c
* Author : MCD Application Team
* Version : V3.3.0
* Date : 21-March-2011
* Description : Virtual Com Port Demo main file
********************************************************************************
/* Includes ------------------------------------------------------------------*/
#include ''stm32f10x.h''
#include ''usb_lib.h''
#include ''usb_desc.h''
#include ''hw_config.h''
#include ''usb_pwr.h''
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include ''stm32_eval.h''
#include ''stm3210c_eval_lcd.h''
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define ADC1_DR_Address ((uint32_t)0x4001244C)
#define wait 0
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Extern variables ----------------------------------------------------------*/
ADC_InitTypeDef ADC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
uint16_t x;
int
i;
int
j;
int
q;
int
waiting_time;
/* Private function prototypes -----------------------------------------------*/
void
RCC_Configuration(
void
);
void
GPIO_Configuration(
void
);
void
Interface_Init(
void
);
/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
* Function Name : main.
* Description : Main routine.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
int
main(
void
)
{
//hw_config.c modifié !
Set_System();
Set_USBClock();
USB_Interrupts_Config();
USB_Init();
Interface_Init();
LCD_DisplayStringLine(LCD_LINE_4, (uint8_t *)
''TEST VCP''
);
while
(1)
{
/* Wait until a byte is received */
if
(USART_GetFlagStatus(USART2, USART_FLAG_RXNE) != RESET)
{
x = USART_ReceiveData(USART2);
while
(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
USART_SendData(USART2, x);
}
}
}
void
Interface_Init(
void
)
{
STM_EVAL_LEDInit(LED1);
STM_EVAL_LEDInit(LED2);
STM_EVAL_LEDInit(LED3);
STM_EVAL_LEDInit(LED4);
STM3210C_LCD_Init();
LCD_Clear(LCD_COLOR_WHITE);
LCD_SetFont(&Font16x24);
LCD_SetBackColor(LCD_COLOR_WHITE);
LCD_SetTextColor(LCD_COLOR_BLUE);
RCC_Configuration();
GPIO_Configuration();
STM_EVAL_PBInit(BUTTON_KEY, BUTTON_MODE_GPIO);
STM_EVAL_PBInit(BUTTON_WAKEUP, BUTTON_MODE_GPIO);
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADCConvertedValue;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 1;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
DMA_Cmd(DMA1_Channel1, ENABLE);
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_55Cycles5);
ADC_DMACmd(ADC1, ENABLE);
ADC_Cmd(ADC1, ENABLE);
ADC_ResetCalibration(ADC1);
while
(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while
(ADC_GetCalibrationStatus(ADC1));
ADC_SoftwareStartConvCmd(ADC1, ENABLE); 
}
void
RCC_Configuration(
void
)
{
#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
/* ADCCLK = PCLK2/2 */
RCC_ADCCLKConfig(RCC_PCLK2_Div2);
#else
/* ADCCLK = PCLK2/4 */
RCC_ADCCLKConfig(RCC_PCLK2_Div4);
#endif
/* Enable peripheral clocks ------------------------------------------------*/
/* Enable DMA1 clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
/* Enable ADC1 and GPIOC clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC, ENABLE);
}
void
GPIO_Configuration(
void
)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Configure PC.04 (ADC Channel14) as analog input -------------------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
#ifdef USE_FULL_ASSERT
/*******************************************************************************
* Function Name : assert_failed
* Description : Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* Input : - file: pointer to the source file name
* - line: assert_param error line source number
* Output : None
* Return : None
*******************************************************************************/
void
assert_failed(uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf(''Wrong parameters value: file %s on line %d

'', file, line) */
/* Infinite loop */
while
(1)
{}
}
#endif

And here is the IRQ function :

/*******************************************************************************
* Function Name : EVAL_COM1_IRQHandler
* Description : This function handles EVAL_COM1 global interrupt request.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void
EVAL_COM1_IRQHandler(
void
)
{
if
(USART_GetITStatus(EVAL_COM1, USART_IT_RXNE) != RESET)
{
/* Send the received data to the PC Host*/
USART_To_USB_Send_Data();
}
/* If overrun condition occurs, clear the ORE flag and recover communication */
if
(USART_GetFlagStatus(EVAL_COM1, USART_FLAG_ORE) != RESET)
{
(
void
)USART_ReceiveData(EVAL_COM1);
}
}

Posted on May 21, 2015 at 15:10

This doesn't look to be consistent with your other code.

What exactly is EVAL_COM1? USART2

Is the IRQ reading the same USART as your loop back? Won't that conflict?

Can you just implement a simple loopback without all this other baggage?
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
loic
Associate II
Posted on May 21, 2015 at 15:52

Yes EVAL_COM1 is USART2.

Yes the IRQ read the same USART. I have just removed the comment on the IRQ when I paste it here.

The IRQ also comes from the example of ST.

Posted on May 21, 2015 at 18:02

Here is what I think a clear, and concise, example should look like

// STM32 USART2 (USART2 TX PD.05, RX PD.06) STM32F10x - sourcer32@gmail.com
#include ''stm32F10x.h''
/**************************************************************************************/
void RCC_Configuration(void)
{
/* Enable GPIO, AFIO clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_AFIO, ENABLE);
/* Enable UART clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
}
/**************************************************************************************/
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Configure USART Tx as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; // PD.05 USART2.TX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/* Configure USART Rx as input floating */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; // PD.06 USART2.RX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE); // Re-map USART, as USART2 is used as alternate pins on PD5/6, requires AFIO
}
/**************************************************************************************/
void USART_Configuration(void)
{
USART_InitTypeDef USART_InitStructure;
/* USART resources configuration (Clock, GPIO pins and USART registers) ----*/
/* USART 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 configuration */
USART_Init(USART2, &USART_InitStructure);
/* Enable the USART2 */
USART_Cmd(USART2, ENABLE);
}
/**************************************************************************************/
void USART_OutString(char *s)
{
while(*s)
{
while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); // Wait for Empty
USART_SendData(USART2, (u16)*s++);
}
}
/**************************************************************************************/
int main(void)
{
RCC_Configuration();
GPIO_Configuration();
USART_Configuration();
USART_OutString(''Welcome to wherever you are

'');
while(1)
{
uint16_t data;
while(USART_GetFlagStatus(USART2, USART_FLAG_RXNE) == RESET); // Wait for Character
data = USART_ReceiveData(USART2);
while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); // Wait for Empty
USART_SendData(USART2, data); // Echo
}
while(1); // Don't want to exit
}
/**************************************************************************************/
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf(''Wrong parameters value: file %s on line %d

'', file, line) */
/* Infinite loop */
while (1)
{
}
}
#endif
/**************************************************************************************/

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..