2014-10-01 10:06 AM
Hi everybody, currently I'm working on STM32F4 discovery using Keil software, I'm implementing USART transmission at 9600 of baudrate.
I've definedUSE_STDPERIPH_DRIVER andHSE_VALUE=8000000 using the toolchain and it's works well , the baudrate is 9600, but when I exit the debug mode and press the reset button the STM32F4 transmit with a higher baudrate (100kbps). the pictures below are some screenshot of the options window also i've added a code in stm32f4xx_conf.h#if defined (HSE_VALUE)
/* Redefine the HSE value; it's equal to 8 MHz on the STM32F4-DISCOVERY Kit */
#undef HSE_VALUE
#define HSE_VALUE ((uint32_t)8000000)
#endif /* HSE_VALUE */
and i've removed the HSE_VALUE=8000000, and it works fine in debug mode but
this
still does not work without debug mode.
I hope someone can help me #stm32f4-discovery-usart-hse2014-10-01 10:23 AM
You'll need to look at the code some more, both what your using to setup the USART, and the code via SystemInit() which is setting up the clocks/PLL.
The debug probably does a number of things to the system to achieve it's own functionality, so check that GPIO clocks are enabled, and peripheral clocks are suitably enabled. Make sure any local/auto variable using the stack are suitably cleared, and all fields correctly set. Show your code.2014-10-01 12:11 PM
Hi, thanks for your answer, below is the code, please ignore commented code and code which doesn't have relashion with the
#include ''stm32f4xx.h''
#include ''stdint.h''
#define ADC1_DR_ADDRESS ((uint32_t)0x4001204C)
#define ADC2_DR_ADDRESS ((uint32_t)0x4001214C)
#define ADC3_DR_ADDRESS ((uint32_t)0x4001224C)
#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
// ADC common regular data register for dual and triple
#define ADC_CDR_ADDRESS ((uint32_t)0x40012308)
/* UART handler declaration */
USART_InitTypeDef UartHandle;
/* Private variables ---------------------------------------------------------*/
__IO uint32_t ADCConvertedVoltage = 0;
__IO uint32_t ADCTripleConvertedValue[3];
RCC_ClocksTypeDef Clocks;
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
DMA_InitTypeDef DMA_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
USART_ClockInitTypeDef USART_Clk_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
uint16_t ADCConvertedValue = 0;
uint16_t ADCLect=0;
uint16_t Counter=0;
uint16_t Done=0;
uint32_t PLL_M=8;
uint32_t PLL_N=336;
uint32_t PLL_P=2;
uint32_t PLL_Q=7;
volatile uint32_t msTicks; /* counts 1ms timeTicks */
FlagStatus Estado;
/*----------------------------------------------------------------------------
SysTick_Handler
*----------------------------------------------------------------------------*/
void SysTick_Handler(void) {
msTicks++;
}
/*----------------------------------------------------------------------------
delays number of tick Systicks (happens every 1 ms)
*----------------------------------------------------------------------------*/
void Delay (uint32_t dlyTicks) {
uint32_t curTicks;
curTicks = msTicks;
while ((msTicks - curTicks) <
dlyTicks
);
}
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++;
}
}
static void SystemClock_Config(void)
{
RCC_DeInit();
RCC_HSEConfig(RCC_HSE_ON);
if(RCC_WaitForHSEStartUp()){
RCC_PLLConfig(RCC_PLLSource_HSE,PLL_M,PLL_N,PLL_P,PLL_Q);
RCC_PLLCmd(ENABLE);
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
RCC_HCLKConfig(RCC_SYSCLK_Div1); //AHB clock = SYSCLK
RCC_PCLK1Config(RCC_HCLK_Div2); //APB1 clock = HCLK/2
RCC_PCLK2Config(RCC_HCLK_Div4); //APB2 clock = HCLK/4
RCC_GetClocksFreq(&Clocks);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);// for USART1
}
}
void Init_ADC(){
/* ADC Common configuration *************************************************/
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_2,//ADC_DMAAccessMode_Disabled;//ADC_DMAAccessMode_2;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
ADC_CommonInit(&ADC_CommonInitStructure);
/* ADC1 regular channel 12 configuration ************************************/
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//ENABLE;//DISABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC1, &ADC_InitStructure);
//ADC_EOCOnEachRegularChannelCmd(ADC1,ENABLE);
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_3Cycles);
}
void Init_DMA(){
/* DMA2 Stream0 channel0 configuration */
DMA_InitStructure.DMA_Channel = DMA_Channel_0;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_ADDRESS;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADCConvertedValue;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = 1;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream0, &DMA_InitStructure);
/* DMA2_Stream0 enable */
DMA_Cmd(DMA2_Stream0, ENABLE);
}
void Init_GPIO(){
/* USART1 */
/* Configure PB6(Tx) and PB7(Rx) in analog mode */
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOB, &GPIO_InitStructure);
// GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
// GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
//
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
// GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
// GPIO_Init(GPIOA, &GPIO_InitStructure);
/* ADC1 */
/* Configure PA1 in analog mode */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void Init_USART1(){
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_Init(USART1,&USART_InitStructure);
USART_ClockStructInit(&USART_Clk_InitStructure);
USART_ClockInit(USART1,&USART_Clk_InitStructure);
}
void USART1_IRQHandler(void)
{
// check if the USART1 receive interrupt flag was set
if( USART_GetITStatus(USART1, USART_IT_RXNE) ){
static uint8_t cnt = 0; // this counter is used to determine the string length
char t = USART1->DR; // the character from the USART1 data register is saved in t
/* check if the received character is not the LF character (used to determine end of string)
* or the if the maximum string length has been been reached
*/
if( (t != '
') && (cnt < MAX_STRLEN) ){
received_string[cnt] = t;
cnt++;
}
else{ // otherwise reset the character counter and print the received string
cnt = 0;
USART_puts(USART1, received_string);
}
}
}
int main()
{
SystemCoreClockUpdate();
SystemClock_Config();
if (SysTick_Config(SystemCoreClock / 168000)) { /* SysTick 1 msec interrupts */
while (1); /* Capture error */
}
Init_GPIO();
Init_USART1();
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // enable the USART1 receive 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);
USART_Cmd(USART1, ENABLE); // enable USART1
Init_DMA();
Init_ADC();
ADC_DMACmd(ADC1, ENABLE);
ADC_DMARequestAfterLastTransferCmd(ADC1,ENABLE);
//ADC_ContinuousModeCmd(ADC1,ENABLE); // to make sure the CONT is set
/* Enable ADC1 **************************************************************/
ADC_Cmd(ADC1, ENABLE);
ADC_SoftwareStartConv(ADC1);
while (1)
{
//USART_SendData(USART1,(uint16_t)0x0031);
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
USART_puts(USART1,''Popoviiiii :D
'');
ADCLect = ADCConvertedValue *3300/0xFFF;
//ADC_SoftwareStartConv(ADC1);
//Estado = ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC);
//if(Estado){
Done=1;
//ADCLect = ADC_GetConversionValue(ADC1);
//ADC_ClearFlag(ADC1,ADC_FLAG_EOC); // to clear the flags events.
//}
Delay(900);
}
return 0;
}
2014-10-01 12:32 PM
If you are using the Standard Peripheral Library, the HSE/PLL stuff should be set up in SystemInit() in system_stm32f4xx.c, specifically SetSysClock(). With CMSIS SystemInit() is call in the ResetHandler in startup_stm32f4xx.s, prior to starting C and calling your main() function. I would expect this is already done, in which can reprogramming the PLL while running from it, is also ill advised.
You should review that code, as your code to set up the PLL doesn't appear to wait for it to lock properly, or wait for it to transition to the PLL clock. You could also export internal system clocks via the MCO1 (PA8) pin, and measure those with a scope.2014-10-01 12:37 PM
ADCConvertedValue *3300/0xFFF;
// millivolts where VREF is 3.3V
Note that the STM32F4-DISCO runs the chip at 3V, not 3.3V, so *3000/0xFFF
2014-10-01 01:56 PM
yes, thanks , I've noticed it, well now I'm checking if the PLL is working with the code
static void SystemClock_Config(void)
{
RCC_DeInit();
RCC_HSEConfig(RCC_HSE_ON);
while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);
if(RCC_WaitForHSEStartUp()){
RCC_PLLConfig(RCC_PLLSource_HSE,PLL_M,PLL_N,PLL_P,PLL_Q);
RCC_PLLCmd(ENABLE);
while(SET != RCC_GetFlagStatus(RCC_FLAG_PLLRDY));
//Delay(900);
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
RCC_HCLKConfig(RCC_SYSCLK_Div1); //AHB clock = SYSCLK
RCC_PCLK1Config(RCC_HCLK_Div2); //APB1 clock = HCLK/2
RCC_PCLK2Config(RCC_HCLK_Div4); //APB2 clock = HCLK/4
RCC_GetClocksFreq(&Clocks);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_DMA2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);// for USART1
RCC_MCO1Config(RCC_MCO1Source_HSE,RCC_MCO1Div_1);
RCC_MCO2Config(RCC_MCO2Source_PLLCLK,RCC_MCO2Div_2);
}
The MCO1 with suorce clock HSE and works correctly ( 8MHz), and then I've tested the MCO2 and it work correctly , but when set MCO2 with source clock ''RCC_MCO2Source_PLLCLK'' doesn`t show anything.
2014-10-01 02:33 PM
Hi again, now everything is working well, so the problem was that I didn't write the code to wait until the PLL is ready to work, the code that sent you (the last one) was ok :D, and also define the symbols USE_STDPERIPH_DRIVER, HSE_VALUE=8000000 in the toolchain is enough, thanks for your help