STM32VL-DISCOVERY дрыгание ногой используя стандартные библиотеки

Захотелось на досуге оценить, с какой частотой можно дергать ногами при использовании стандартных библиотек. Частоту мерил осциллографом АКИП 4113/1.
За основу возьмем следующую программу:

#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_usart.h"
#include "stm32f10x_flash.h"
#include "stm32f10x_exti.h"
#include "misc.h"

#define LED_PORT GPIOC
#define LED_GREEN GPIO_Pin_8
#define LED_BLUE GPIO_Pin_9

void SetupClock(void);

void LEDsInit()
{
		  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
		  GPIO_InitTypeDef GPIO_InitStructure;
		/* Светодиоды на PC8, PC9          */
		  GPIO_InitStructure.GPIO_Pin   = LED_GREEN | LED_BLUE;
		  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
		  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
		  GPIO_Init(LED_PORT, &GPIO_InitStructure);
}

int main(void)
{
	SetupClock();
	LEDsInit();

	while(1)
	{
		GPIO_WriteBit(LED_PORT, LED_GREEN, Bit_SET);
                GPIO_WriteBit(LED_PORT, LED_GREEN, Bit_RESET);
    }
}

void SetupClock()
{
      RCC_DeInit ();
      RCC_HSEConfig (RCC_HSE_ON);

      /* Wait till HSE is ready                                               */
      while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);

      RCC_HCLKConfig   (RCC_SYSCLK_Div1);   /* HCLK   = SYSCLK                */
      RCC_PCLK2Config  (RCC_HCLK_Div1);     /* PCLK2  = HCLK                  */
      RCC_PCLK1Config  (RCC_HCLK_Div1);     /* PCLK1  = HCLK/2                */
      RCC_ADCCLKConfig (RCC_PCLK2_Div4);    /* ADCCLK = PCLK2/4               */

      /* PLLCLK = 8MHz * 2 = 16 MHz                                           */
      RCC_PLLConfig (RCC_PLLSource_PREDIV1, RCC_PLLMul_7);

      RCC_PLLCmd (ENABLE);                  /* Enable PLL                     */

      /* Wait till PLL is ready                                               */
      while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);

      /* Select PLL as system clock source                                    */
      RCC_SYSCLKConfig (RCC_SYSCLKSource_PLLCLK);

      /* Wait till PLL is used as system clock source                         */
      while (RCC_GetSYSCLKSource() != 0x08);

}


Будем изменять множитель PLL. Щупом осциллографа смотрим на вывод PC8.
Программа писана под кокосом в кокосе.
Итак:
1. Без оптимизации
RCC_PLLMul_2 — 222,2 КГц
RCC_PLLMul_3 — 333,3 КГц
RCC_PLLMul_4 — 444,4 КГц
RCC_PLLMul_5 — 555,6 КГц
RCC_PLLMul_6 — 666,7 КГц
RCC_PLLMul_7 — 777,8 КГц
2. Оптимизация -O1
RCC_PLLMul_2 — 727,3 КГц
RCC_PLLMul_3 — 1,091 МГц
RCC_PLLMul_4 — 1,454 МГц
RCC_PLLMul_5 — 1,818 МГц
RCC_PLLMul_6 — 2,182 МГц
RCC_PLLMul_7 — 2,545 МГц
3. Оптимизация -O2
RCC_PLLMul_2 — 640 КГц
RCC_PLLMul_3 — 960 КГц
RCC_PLLMul_4 — 1,280 МГц
RCC_PLLMul_5 — 1,599 МГц
RCC_PLLMul_6 — 1,920 МГц
RCC_PLLMul_7 — 2,239 МГц
4. Оптимизация -О3
RCC_PLLMul_2 — 666,7 КГц
RCC_PLLMul_3 — 1,0 МГц
RCC_PLLMul_4 — 1,333 МГц
RCC_PLLMul_5 — 1,666 МГц
RCC_PLLMul_6 — 2,0 МГц
RCC_PLLMul_7 — 2,333 МГц

Вот. Можно ли увеличить при условии использования стандартных библиотек?

P.S.: какие-то траблы с вставкой картинок
  • 0
  • 07 сентября 2011, 13:34
  • Frolls

Комментарии (20)

RSS свернуть / развернуть
Как я понимаю, это просто проверка компилятора.
Интересно, что он насовал в главный цикл?
0
  • avatar
  • mzw
  • 07 сентября 2011, 13:59
а O2 как же? дефолтная для релиза и не отмечена.
0
Интересный анализ вы сделали. А что оптимизацию -O2 не делали?
Вообще-то результаты страннованые получились если честно, сперень оптимизации не дожна в такой степени влиять на результат. И особенно интересно — какой компилятор?
0
Для -О2 завтра сделаю. Плюс добавлю размер
А компилятор должен быть gcc, который с кокосом поставляется
0
кстати, код Ваш получился как заготовка, годная для начала любой новой проги.
копипаст и готово )) Благодарность )
0
Как паз боюсь, что влияет. И очень сильно. Этот цикл на ассемблере должен был бы дать частоту больше 10 МГц.
0
  • avatar
  • mzw
  • 08 сентября 2011, 00:32
Все правильно, т.к. используете вызов функции, я пробовал вот так:
#include<stm32f10x_rcc.h>
#include<stm32f10x_gpio.h>

#include «stm32f10x.h»
#include «stm32f10x_conf.h»

GPIO_InitTypeDef GPIO_InitStructure;

volatile int main(void)

{ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
GPIO_Init(GPIOC, &GPIO_InitStructure);
while(1)
{
GPIOC->BSRR = GPIO_BSRR_BS9;
GPIOC->BSRR = GPIO_BSRR_BR9;
}
}
частота получилась в районе 6мгц. при 24 опорной.
кстати листинг асма можно в кококсе посмотреть, это main.txt
Вот только st-link debug у меня глючит под хр, а под win7 x64 работает хорошо.
Кстати вышла версия 1.3, там стлинк уже встроен.
0
:-)
Задача стояла использовать стандартные библиотеки. Кстати, если уж на то пошло, то можно сделать то же самое без библиотек, чтобы потом сравнить выигрыш в быстродействии и используемой памяти
0
Как обычно: если все делать ручками, то конечно думаю выигрыш как минимум по месту в памяти будет, а цикл дерганья быстрее не получить.
Есть интересный момент, смотрел аналоговым осцилл., два импульса одинаковы, потом промежуток немного длиннее, потом опять пачка из 2 имп.
0
мм… может, у Вас вачдог включен?
0
Хм, не знаю, спасибо за наводку, хотя тогда цикл вачдога явно мал, да и в Вашем примере нет такого, я думаю что возможна синхронизация стробирования, вот фронт и не поспевает, ожидает следующий строб.
0
И все-таки, если прошиваете камень при помощи STM32 ST-LINK Utility, то посмотрите в опциях, стоит ли галочка в вачдоге (WDG_SW)
0
А в асм заглядывал? Мож gcc развернул цикл в нечто вида
loop:
  MOV GPIOC->BSRR, GPIO_BSRR_BS9
  MOV GPIOC->BSRR, GPIO_BSRR_BR9
  MOV GPIOC->BSRR, GPIO_BSRR_BS9
  MOV GPIOC->BSRR, GPIO_BSRR_BR9
  B loop
0
  • avatar
  • Vga
  • 12 сентября 2011, 06:48
В асм я после 580-й серии редко заглядываю, если уж совсем прижмет
0
0800031c <GPIO_WriteBit>:
 800031c:	b10a      	cbz	r2, 8000322 <GPIO_WriteBit+0x6>
 800031e:	6101      	str	r1, [r0, #16]
 8000320:	4770      	bx	lr
 8000322:	6141      	str	r1, [r0, #20]
 8000324:	4770      	bx	lr
 8000326:	bf00      	nop


080003d0 <main>:
 80003d0:	b570      	push	{r4, r5, r6, lr}
 80003d2:	f7ff ffc5 	bl	8000360 <SetupClock>
 80003d6:	f7ff ffa7 	bl	8000328 <LEDsInit>
 80003da:	4d08      	ldr	r5, [pc, #32]	; (80003fc <main+0x2c>)
 80003dc:	f44f 7480 	mov.w	r4, #256	; 0x100
 80003e0:	f04f 0601 	mov.w	r6, #1
 80003e4:	4628      	mov	r0, r5
 80003e6:	4621      	mov	r1, r4
 80003e8:	4632      	mov	r2, r6
 80003ea:	f7ff ff97 	bl	800031c <GPIO_WriteBit>
 80003ee:	4628      	mov	r0, r5
 80003f0:	4621      	mov	r1, r4
 80003f2:	f04f 0200 	mov.w	r2, #0
 80003f6:	f7ff ff91 	bl	800031c <GPIO_WriteBit>
 80003fa:	e7f3      	b.n	80003e4 <main+0x14>
 80003fc:	40011000 	.word	0x40011000
0
На самом деле я отвечал makser'у с его вариантом через регистры и импульсами по два через паузу.
0
  • avatar
  • Vga
  • 12 сентября 2011, 07:05
Пардоньте…
0
Нет, вот он цикл в асме, короче не придумаеш:
8000346: f44f 7100 mov.w r1, #512; 0x200
800034a: f04f 7200 mov.w r2, #33554432; 0x2000000
800034e: 6119 str r1, [r3, #16]
8000350: 611a str r2, [r3, #16]
8000352: e7fc b.n 800034e <main+0x32>
0
я ж выдрал кусок сгенереного gcc кода
0
И я привел код с моего примера тоже с гсс, вот и видно на сколько он короче и быстрее(3 команды в цикле), все таки видимо проблема «пачек» в синхронизации, гдето набегает 1 «лишний» такт опоры. Это не АВР, тут явно все сложнее.
(кстати, по аське не могу достучатся)
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.