cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 why I cant comunicate with USART1 ?

mehmet.karakaya
Associate III
Posted on February 23, 2013 at 15:36

hello forum ,

please have a look at my STM32F4 code - the USART1 interrupt never gets called when a character arrives at the serial port I am sure about my PC side program becouse it is tested with F103 before

void
init_serp_1( 
void
) { 
RCC_APB1PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); 
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); 
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); 
Tx_len = 0; 
Tx_ptr = 0; 
Rx_ptr = 0; 
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); 
//******************************************************* 
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_Speed = GPIO_Speed_50MHz; 
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 
GPIO_Init(GPIOB, &GPIO_InitStructure); 
GPIO_PinAFConfig(GPIOB,GPIO_PinSource6,GPIO_AF_USART1); 
GPIO_PinAFConfig(GPIOB,GPIO_PinSource7,GPIO_AF_USART1); 
//******************************************************* 
USART_Cmd(USART1,ENABLE); 
USART1->SR &= ~USART_FLAG_TC; 
// clear interrupt 
} 
//************************** 
void
USART1_IRQHandler(
void
) 
{ 
volatile unsigned 
int
IIR; 
IIR = USART1->SR; 
if
(IIR & USART_FLAG_RXNE) { 
// read interrupt 
USART1->SR &= ~USART_FLAG_RXNE; 
Rx_buffer[Rx_ptr] = USART_ReceiveData(USART1); 
Rx_ptr++ ; 
if
(Rx_ptr > 511) {Rx_ptr=0;com0err=1;} 
if
(ending_char()) do_instruction(); 
} 
if
(IIR & USART_FLAG_TC) { 
USART1->SR &= ~USART_FLAG_TC; 
// clear interrupt 
if
(Tx_ptr < Tx_len) { 
Tx_ptr++; send_char (Tx_buffer[Tx_ptr]);} 
else
USART_ITConfig(USART1, USART_IT_TC, DISABLE); 
} 
} 
//********************************** 
void
NVIC_Configuration(
void
) 
{ 
NVIC_InitTypeDef NVIC_InitStructure; 
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); 
/* Enable the USARTx Interrupt */ 
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; 
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; 
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; 
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
NVIC_Init(&NVIC_InitStructure); 
} 

#stm32f4-usart
7 REPLIES 7
Posted on February 23, 2013 at 15:52

RCC_APB1PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

// APB2 surely? You don't need to clear the SR register bits, reading/writing DR does this Use TXE, not TC as that has the worst inter symbol timing.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on February 23, 2013 at 16:00

// STM32 USART IRQ TX/RX Loop (USART1 Tx PB.6, Rx PB.7) STM32F4 Discovery - sourcer32@gmail.com
#include ''stm32f4_discovery.h''
volatile char StringLoop[] = ''The quick brown fox jumps over the lazy dog

'';
/**************************************************************************************/
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);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1);
}
/**************************************************************************************/
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);
}
/**************************************************************************************/
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Configure the NVIC Preemption Priority Bits */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
/* Enable the USART1 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/**************************************************************************************/
void USART1_IRQHandler(void)
{
static int tx_index = 0;
static int rx_index = 0;
if (USART_GetITStatus(USART1, USART_IT_TXE) != RESET) // Transmit the string in a loop
{
USART_SendData(USART1, StringLoop[tx_index++]);
if (tx_index >= (sizeof(StringLoop) - 1))
tx_index = 0;
}
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) // Received characters modify string
{
StringLoop[rx_index++] = USART_ReceiveData(USART1);
if (rx_index >= (sizeof(StringLoop) - 1))
rx_index = 0;
}
}
/**************************************************************************************/
int main(void)
{
RCC_Configuration();
GPIO_Configuration();
NVIC_Configuration();
USART1_Configuration();
while(1); // Don't want to exit
}
/**************************************************************************************/

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
mehmet.karakaya
Associate III
Posted on February 23, 2013 at 18:02

RCC_APB1PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); 

this line was wrong indeed I corrected it and USART1 interrupt started to work however this time the received characters are garbage ( I observe with JTAG) ( not equal to the ones I send from PC ) have I fried the usart1 pins ? becouse this code was absolutely working at STM32F103
Posted on February 23, 2013 at 19:06

As you've done this before, I'm going to assume the CMOS levels are not the issue.

You might want to consider the crystal you're using for HSE, and how HSE_VALUE is defined within the project, and the clock/pll settings in system_stm32f4xx.c

The STM32F4 library generally assumes a 25 MHz crystal, while the STM32F4-Discovery uses an 8 MHz one. A disparity here will cause all kinds of issues with baud clocks.

If in doubt attach a scope and measure some bit timings.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
mehmet.karakaya
Associate III
Posted on February 24, 2013 at 13:38

0690X00000602kWQAQ.jpg

hello Clive , as you have said I looked closely at the crystal it is neither 25 nor 8 MHz - it is 12 MHz but the HSE_VALUE is declared as 25 MHz

#if !defined (HSE_VALUE) 
#define HSE_VALUE ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */ 
#endif /* HSE_VALUE */

however the RCC_ClockFreq gives the correct values as you can see at the attached picture above --> 168 MHZ , 42 MHz and 84 MHz if I declare the HSE_VALUE as 12 MHz the clock values changes ( not 168 Mhz anymore ) more strange ; I measured the baud rate as ~ 4500 Kbaud with osciloscope with my original baudrate setting of 9600 I changed it to 19200 and I could comunicate with my board succesfully at 9600 baud (PC) my board is produced by OLIMEX and I think they adjusted the below function according to 12 MHz crystal I want ask which line I have to change and how , to get correct values of baudrate and system clocks thank you

static
void
SetSysClock(
void
) 
{ 
/******************************************************************************/
/* PLL (clocked by HSE) used as System clock source */
/******************************************************************************/
__IO uint32_t StartUpCounter = 0, HSEStatus = 0; 
/* Enable HSE */
RCC->CR |= ((uint32_t)RCC_CR_HSEON); 
/* Wait till HSE is ready and if Time out is reached exit */
do
{ 
HSEStatus = RCC->CR & RCC_CR_HSERDY; 
StartUpCounter++; 
} 
while
((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); 
if
((RCC->CR & RCC_CR_HSERDY) != RESET) 
{ 
HSEStatus = (uint32_t)0x01; 
} 
else
{ 
HSEStatus = (uint32_t)0x00; 
} 
if
(HSEStatus == (uint32_t)0x01) 
{ 
/* Select regulator voltage output Scale 1 mode, System frequency up to 168 MHz */
RCC->APB1ENR |= RCC_APB1ENR_PWREN; 
PWR->CR |= PWR_CR_VOS; 
/* HCLK = SYSCLK / 1*/
RCC->CFGR |= RCC_CFGR_HPRE_DIV1; 
/* PCLK2 = HCLK / 2*/
RCC->CFGR |= RCC_CFGR_PPRE2_DIV2; 
/* PCLK1 = HCLK / 4*/
RCC->CFGR |= RCC_CFGR_PPRE1_DIV4; 
/* Configure the main PLL */
RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | 
(RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24); 
/* Enable the main PLL */
RCC->CR |= RCC_CR_PLLON; 
/* Wait till the main PLL is ready */
while
((RCC->CR & RCC_CR_PLLRDY) == 0) 
{ 
} 
/* Configure Flash prefetch, Instruction cache, Data cache and wait state */
FLASH->ACR = FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS; 
/* Select the main PLL as system clock source */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); 
RCC->CFGR |= RCC_CFGR_SW_PLL; 
/* Wait till the main PLL is used as system clock source */
while
((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL); 
{ 
} 
} 
else
{ 
/* If HSE fails to start-up, the application will have wrong clock 
configuration. User can add here some code to deal with this error */
} 
} 

Posted on February 24, 2013 at 15:02

The RCC_ClockFreq structure is a pure computation exercise, not a physical measurement.

You need to set the compilers command line to have the define -DHSE_VALUE=12000000 this may be a compiler related project setting, or done more explicitly.

The you will need to go into system_stm32f4xx.c and modify one or more of the PLL_x values. For integer HSE values, probably just PLL_M

#define PLL_M 12 // Divide HSE to get 1 MHz comparison frequency

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on June 24, 2013 at 01:03

Here, enabling the interrupt

// STM32 USART IRQ TX/RX Loop (USART1 Tx PB.6, Rx PB.7) STM32F4 Discovery - sourcer32@gmail.com
#include ''stm32f4_discovery.h''
volatile char StringLoop[] = ''The quick brown fox jumps over the lazy dog

'';
/**************************************************************************************/
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);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1);
}
/**************************************************************************************/
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);
USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
}
/**************************************************************************************/
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Configure the NVIC Preemption Priority Bits */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
/* Enable the USART1 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/**************************************************************************************/
void USART1_IRQHandler(void)
{
static int tx_index = 0;
static int rx_index = 0;
if (USART_GetITStatus(USART1, USART_IT_TXE) != RESET) // Transmit the string in a loop
{
USART_SendData(USART1, StringLoop[tx_index++]);
if (tx_index >= (sizeof(StringLoop) - 1))
tx_index = 0;
}
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) // Received characters modify string
{
StringLoop[rx_index++] = USART_ReceiveData(USART1);
if (rx_index >= (sizeof(StringLoop) - 1))
rx_index = 0;
}
}
/**************************************************************************************/
int main(void)
{
RCC_Configuration();
GPIO_Configuration();
NVIC_Configuration();
USART1_Configuration();
while(1); // Don't want to exit
}
/**************************************************************************************/

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