STM32F4 işlemcinin çalışma Hızı sorunu

Başlatan promate, 29 Nisan 2012, 18:13:45

promate

Merhaba Arkadaşlar,

Aşağıdaki kodu çalıştırdığımda LED pin çıkışlarına veya D portunun herhangi pinine osilaskop bağladığımda 10.50 Hz (95.2 ms) periotdlu karedalga sinyal aliyorum. ARM 168Mhz çalışma hızına ayarlanmış olmasına rağmen çok yavaş çalışıyor.

Aynı kodu 150Mhz hızında çalışan başka bir kontrolcüde çalıştırdığımda 9.34 Mhz (107.0 ns) periotlu karedalga sinyal alabiliyorum.
ARM işlemcide hız sorunu neden kaynaklanmaktadır?. Bu konuda yardımcı olursanız sevinirim.



#include "STM32F4xx.h"

void SystemInit()
{
unsigned int i;

    for (i=0;i<0x00100000;i++);        // OSC oturtma ve kurtarma rutini
    RCC->CFGR |= 0x00009400;           // AHB ve APB hizlarini max degerlere set edelim
    RCC->CR |= 0x00010000;             // HSE Xtal osc calismaya baslasin       
    while (!(RCC->CR & 0x00020000));   // Xtal osc stabil hale gelsin
    RCC->PLLCFGR = 0x07405408;         // PLL katsayilarini M=8, N=336, P=2 ve Q=7 yapalim//  RCC->PLLCFGR = 0x07402A04;     // PLL katsayilarini M=4, N=168, P=2 ve Q=7 yapalim
    RCC->CR |= 0x01000000;             // PLL calismaya baslasin  (Rehber Sayfa 95)
    while(!(RCC->CR & 0x02000000));    // Pll hazir oluncaya kadar bekle//  FLASH->ACR = 0x00000705;        // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
    FLASH->ACR = 0x00000605;           // Flash ROM icin 5 Wait state secelim ve ART yi aktif edelim (Rehber Sayfa 55)
    RCC->CFGR |= 0x00000002;           // Sistem Clk u PLL uzerinden besleyelim
    while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
    RCC->AHB1ENR |= 0x0000001F;        // GPIO A,B,C,D,E clock'u aktif edelim
    GPIOD->MODER = 0x55555555;         // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (LEDler icin)
    GPIOD->OSPEEDR= 0xFFFFFFFF;        // GPIOD nin tum cikislari en yuksek hizda kullanacagiz

}

int main()
{
   long long i;
    while(1)
      {
         for(i=0;i<1000000;i++);
         GPIOD->ODR=~GPIOD->ODR; //D15---D11 LED çikislari
      }
}

promate

arkadaşlar biz ARM işlemciyi 5wait state ile flash dan çalıştırdığımız için yavaş kalıyor olabilir mi?

memo333

öncelikle cpu hızı ile portların hızı aynı değil. yanılmıyorsam 50MHz üstü zaten alamayacaksın.

birde kodda;

Alıntı yapılan: promate - 29 Nisan 2012, 18:13:45
    while(1)
      {
         for(i=0;i<1000000;i++);
         GPIOD->ODR=~GPIOD->ODR; //D15---D11 LED çikislari
      }

[jstex]for(i=0;i<1000000;i++);[/jstex]
yazmışsın. bu belli bir gecikmeye neden olmaz mı?
Gömülü Linux Notları --> http://linuxedu.xyz/

promate

Alıntı yapılan: memo333 - 29 Nisan 2012, 21:45:29
öncelikle cpu hızı ile portların hızı aynı değil. yanılmıyorsam 50MHz üstü zaten alamayacaksın.

birde kodda;

[jstex]for(i=0;i<1000000;i++);[/jstex]
yazmışsın. bu belli bir gecikmeye neden olmaz mı?

evet bilerek yazdım portları yüksek hızda sürmesin diye bilirli bir değerde geciktirme verdim.işlemcinin çalışma hızı 168Mhz. Bir komutu yürütme hızı 1/168x10e6 =yaklasık 5.95 ns eder.  döngü sayıcı değeri 10e6 olduğuna göre 5.95nsx10e6=0.00595 sn eder. karedalganın periodu 0.00595 sn olamsı beklenir.

mozkan87

İşlemci bir for döngüsünü tek cycle da işleyemez.

promate

evet haklısın 2 bilemedin 4 cycle dahi olsa yinede yavaş çalışmasını hala anlayamadım

z

 Derleyici, for(i=0;i<1000000;i++); satirini optimizasyon seceneklerine bagli olarak kaldirilip atabilir.

Hizli calistigini iddia ettigin islemcide 1E6 gibi bir loop oldugu halde 9.34Mhz kare dalga aliyorsan bunun tek anlami vardir bu da derleyicinin bu satiri kaldirip attigi.



Bana e^st de diyebilirsiniz.   www.cncdesigner.com

bocek

Alıntı yapılan: gerbay - 30 Nisan 2012, 12:07:44
hocam "long long i"   değişkenini volatile tanımlamak zorundasınız
tamamen öğrenmek için soruyorum.
burda volatile tanımlamanın gerekliliği nedir?
benim bildiğim, volatile tanımlamak şu anlama geliyor. "bu değişkenin değeri her an değişebilir. onun için bu değişkenin değerini getirirken optimizasyon kullanma. yani "dur, o değişkeni en son okuduğumdan beri değişiklik olmadı, tekrar okumaya gerek yok, şuraya bi yere not almıştım ordan alırım işimi görürüm" gibi bir optimizasyon kullanma. her seferinde yeniden oku."
bu yüzden de interrupt içinde içeriği değiştirilen her 'global' değişken volatile olarak tanımlanır.
burda neden gerektiğini anlamadım? başka bir sebebi mi var?
1 ya da 0. işte 'bit'ün mesele..

z

Derleyici yüksek optimizasyon seviyesinde derleme yaparken for(i=0;i<1000000;i++); satırına bakıyor i diye bir değişken 0 dan 1E6 ya kadar bir bir artıyor fakat hiç bir yerde i değeri kullanılmıyor bu satırı derlemeye gerek yok diyor.

Değişkeni volatile tanımladığında derleyiciye şunu diyorsun. Sen ben ne yazdıysam onu derle, kafana göre kısaltmalara gitme.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com