2013-02-23 06:36 AM
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 beforevoid
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
2013-02-23 06:52 AM
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.
2013-02-23 07:00 AM
// 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
}
/**************************************************************************************/
2013-02-23 09:02 AM
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
2013-02-23 10:06 AM
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.2013-02-24 04:38 AM
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 */
}
}
2013-02-24 06:02 AM
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
2013-06-23 04:03 PM
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
}
/**************************************************************************************/