cancel
Showing results for 
Search instead for 
Did you mean: 

Sysclk and USB prescaler Confusion

durgesh777
Associate II
Posted on December 05, 2011 at 18:41

My application has a sequencial input data that consist of 128 bytes to be filled in 0,5 ms. So this is obtained by ADC and DMA function for STM32F103. All the data are copied to a buffer in DMA subroutine. The processing of the data(from the buffer) are done in the main function. The rate of data output (i.e. data processing) is slower than the rate of data input to the buffer for the clock summary as clipped in the attached file (it is suggested to see the first few rows of first files and last few rows in the second attachment).

Now the question is, SYSCLCK has to be 72Mhz but it seems it is not so, what could be the reason?

Also as USBPRE is stated as: 'PLL clock is divided by 1' which means 72 Mhz (as PLL is configured as 72 Mhz), but why USB clock is shown as 48 Mhz?

I have understood the codes in the main function should be executed in the frequency of SYSCLK.

So, it would be so nice if someone could solve my confusion.

Thanks in advance.

#sysclk-and-usb-prescaler
9 REPLIES 9
Posted on December 05, 2011 at 18:57

Also as USBPRE is stated as: 'PLL clock is divided by 1' which means 72 Mhz (as PLL is configured as 72 Mhz), but why USB clock is shown as 48 Mhz?

 

It also says RCC_CR = 0x001D040A, So USBPRE (bit 22) = 0, which is div 1.5. So 72 / 1.5 = 48 MHz. And PLLMUL translates to x 9. Confirm the external crystal is 8 MHz, not something like 12 or 25 MHz.

Your choices for CPU speed are either 72 MHz or 48 MHz, derived from an external crystal, for USB to be workable.

Conclusion : Your tools to decode the registers are broken. If in doubt do it manually.

If you can connect a serial port and the baud rate settings work correctly, then the device knows what the clocks should be and that they are correct/consistent.

    RCC_ClocksTypeDef RCC_ClockFreq;

    RCC_GetClocksFreq(&RCC_ClockFreq);

    printf(''SYS:%d H:%d, P1:%d, P2:%d, ADC:%d\r\n'',

                                            RCC_ClockFreq.SYSCLK_Frequency,

                                            RCC_ClockFreq.HCLK_Frequency,        // AHB

                                            RCC_ClockFreq.PCLK1_Frequency,    // APB1

                                            RCC_ClockFreq.PCLK2_Frequency,    // APB2

                                            RCC_ClockFreq.ADCCLK_Frequency);

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
durgesh777
Associate II
Posted on December 05, 2011 at 22:54

Thank you for the reply and for your help.

Yes, it seem that the USB prescaler are not being calculated as required.

The other values are o.k. 

Crystal oscillator = 8 Mhz (Olimex stmh103 board)

TIM1 to TIM4 all are running as per desired (or as per calculation).

Problem: Time taken in the main to process the memory is almost 1.45 times that it takes to fill memory.

So, is there any possibility that main programs(CPU) is running in 48 Mhz while others are running with 72 Mhz? (Depending upon the information i have provided in the picture).

Posted on December 05, 2011 at 23:19

I have no idea what your processing consists of, but the chip looks to be running at 72 MHz.

Code running from flash will clearly be degraded in it's performance compared to that running in ram.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
durgesh777
Associate II
Posted on December 15, 2011 at 15:40

My processing is with the line scan camera. 128 bytes are coming at 2kHz and so the conversion of analog to digital is done through ADC and DMA. The values stored at some array from DMA is processed in main function. So the input and the output rate of data is drastically different. This is the problem.

As you suggested about the serial communication to check the system clock. Do i have to use USART (USART1_Tx & USART1-Rx) or SPI1_MISO; SPI1_MOSI. Actually i would like to have the values displayed in hyperterminal (that would be easy for me).

Waiting for the reply.

durgesh777@yahoo.com

Posted on December 15, 2011 at 17:16

Any of the USART will suffice, under Keil easy enough to redirect/retarget printf() to which ever port you want, or to just write some serial output debug routines. Used USART1, and USART3, for debug console in the past.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
durgesh777
Associate II
Posted on December 15, 2011 at 18:40

For USART;

i wrote:

USART_InitStructure.USART_BaudRate = 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_Rx | USART_Mode_Tx;

 

Now how do i give the adress of USART.

In the examples provided they are,

STM_EVAL_COMInit(COM1, &USART_InitStructure);

since i am not using EVAL board this is not possible.

In this case is it possible via:

USART_SetAddress(USARTx, USART_Address);

If so where would be the address.

I would request to help me on this.

Posted on December 15, 2011 at 19:38

For USART;

i wrote:

USART_InitStructure.USART_BaudRate = 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_Rx | USART_Mode_Tx; Now how do i give the adress of USART. In the examples provided they are, STM_EVAL_COMInit(COM1, &USART_InitStructure); since i am not using EVAL board this is not possible. In this case is it possible via: USART_SetAddress(USARTx, USART_Address); If so where would be the address. I would request to help me on this. Yeah, I don't understand where you are going there. Here's how it works in Keil.

/******************************************************************************/
void USART_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
/* Configure USART Tx as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; // PA.09 USART1.TX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure USART Rx as input floating */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; // PA.10 USART1.RX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* USART resources configuration (Clock, GPIO pins and USART registers) ----*/
/* USART configured as follow:
- BaudRate = 115200 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 = 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_Rx | USART_Mode_Tx;
/* Enable UART clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
/* USART configuration */
USART_Init(USART1, &USART_InitStructure);
/* Enable the USART1 */
USART_Cmd(USART1, ENABLE);
}
/******************************************************************************/
#include <
stdio.h
>
#include <
rt_misc.h
>
#pragma import(__use_no_semihosting_swi)
struct __FILE { int handle; /* Add whatever you need here */ };
FILE __stdout;
FILE __stdin;
int sendchar(char c)
{
while((USART1->SR & 0x80)==0); // 80 = TXE, 40 = TC
USART1->DR = c;
return(1);
}
int getkey(void)
{
while((USART1->SR & 0x20)==0); // 20 = RXNE
return(USART1->DR);
}
int fputc(int ch, FILE *f)
{
if ((char)ch == '
')
sendchar('
');
return (sendchar((char)ch));
}
int fgetc(FILE *f) {
return (getkey());
}
int ferror(FILE *f) {
/* Your implementation of ferror */
return EOF;
}
void _ttywrch(int ch)
{
if ((char)ch == '
')
sendchar('
');
sendchar((char)ch);
}
void _sys_exit(int return_code) {
label: goto label; /* endless loop */
}
/**************************************************************************************/

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
durgesh777
Associate II
Posted on December 26, 2011 at 01:51

I am limited to use Ride7 based upon the board, emulator (programmer) i am using and hence i was referencing the examples.

No matter what IDE is used, the flow has to be the same.

With this regard, i could easily understand the first part. What about the second part? Is it the user created lines (programs) or written inbuilt somewhere (e.g. misc.c)?

I would be glad to know the reference to the second part.

durgesh777
Associate II
Posted on December 26, 2011 at 18:19

Thanks, now it is not a problem.

the first part you wrote is is enough alongwith the printf.