Ynt: STM32F100RB Clock Ayarları.

Başlatan muhittin_kaplan, 23 Ekim 2012, 22:18:48

camby

Alıntı yapılan: muhittin_kaplan - 23 Ekim 2012, 22:18:48
Birtürlü PLL i aktif edip Çıkış Portlarını Max hız olan 24Mhz de çalıştıramadım. Yardıma ihtiyacım var.

mesaj birleştirme:: 24 Ekim 2012, 02:40:31

Karman Çorman Oldu. bazen 6mhz bazen 3 mhz aldım bazense hiç alamadım
Ayar Kodlarım aşağıda. Yardım eden olursa sevinirim.

#include <stm32f10x.h>

void SystemInit(void)
{

unsigned int i;
			for (i=0;i<0x00100000;i++);     // OSC oturtma ve kurtarma rutini
			
			RCC->CFGR |= 0x00012480;       //AHB,APB1,APB2 hep 2 ye bölüyor

	
			
			RCC->CR |=0X00010000;   // HSE Xtal osc calismaya baslasin        
			while (!(RCC->CR & 0x00020000));// Xtal osc stabil hale gelsin
	
			RCC->CFGR2 =0x00000000; // PREDIV1 BÖLME YOK
			RCC->CFGR |=0x00010000; //PLLSRC PLLDIV OLARAK AYARLANDI.
			RCC->CFGR |=0x00180000; //PLLMUL x8 SEÇILDI 	
			RCC->CR |= 0x01000000;            // PLL calismaya baslasin 
			while(!(RCC->CR & 0x02000000)); // Pll hazir oluncaya kadar bekle
			RCC->CFGR |= 0x00000002;        // Sistem Clk u PLL uzerinden besleyelim
			while ((RCC->CFGR & 0x0000000F) != 0x0000000A); // Besleninceye kadar bekle
			
	
		
		
		RCC->APB2ENR |= 0x0000001C;    
		GPIOC->CRL &= 0x00000000;
		GPIOC->CRL |= 0x33333333;     //PC0-7 Çýkýþ olarak ayarlandý (Max 50MHz)

		GPIOC->CRH &= 0x00000000;
		GPIOC->CRH |= 0x33333333;    //PC8-15 Çýkýþ olarak ayarlandý (Max 50MHz)

}


int main()
{

	
	

	while (1)  // sonsuz döngü
	{
		//Deger[0]++;
		
		GPIOC->ODR=0xFFFFFFFF;
			//delay(0x00000FFF);
		
		GPIOC->ODR=0x00000000;
			//delay(0x00000FFF);


	}
}


c portunu dinleyerek en fazla 6mhz alabildim. onuda nasıl yaptım şu an hatırlamıyorum.

mesaj birleştirme:: 24 Ekim 2012, 22:03:51

bakan yok ama olsun çalışmaya devam.

ne yaptıysam 6mhz i geçemedim.

Olması gereken max çıkış frekansı nedir ? 12 MHz 'mi ? 24 MHz mi ?

Çalışma frekansı 24 MHz olduğu için , 12 MHz çıkış alabiliriz diye tahmin ediyordum. Ancak datasheet 60. sayfa max I/O frekansı 24 MHz olarak yazıyor. Referans manuel'de ise en hızlı modda 50MHz yazılıp geçilmiş. Ancak STM32F100xx serisindeki tüm işlemciler zaten 24 MHz.

Ayrıca sonsuz döngünün içindeki bu kod ile :
int main()
{

    
    

    while (1)  // sonsuz döngü
    {
 
        GPIOC->ODR=0xFFFFFFFF;
     
        GPIOC->ODR=0x00000000;

    }


İstenilen Max çıkışı görebileceğimizi sanmıyorum çünkü son komuttan sonra üste dönüş için GOTO gibi bir dallanma komutu kullanılacaktır bu da periyodu , duty'i ve frekansı etkileyecektir doğrudan. Öyle değil mi ?

muhittin_kaplan

Hocam Konuyu Hallettim. MCO çıkışından 12mhz gördüm. Buda PLL/2 den 24Mhz e denk geliyor. 32f4 için hazırladığım excel dosyası da işime yaradı bu arada.

camby

Alıntı yapılan: muhittin_kaplan - 27 Ekim 2012, 17:08:00
Hocam Konuyu Hallettim. MCO çıkışından 12mhz gördüm. Buda PLL/2 den 24Mhz e denk geliyor. 32f4 için hazırladığım excel dosyası da işime yaradı bu arada.

Tebrikler :) . Max output hızı 12 MHz olacaktır değil mi ?

muhittin_kaplan

MCO dan 12Mhz okuyurum hocam. Oda PLL in 24Mhz olduğu anlamına geliyor.

camby

Alıntı yapılan: muhittin_kaplan - 27 Ekim 2012, 17:20:18
MCO dan 12Mhz okuyurum hocam. Oda PLL in 24Mhz olduğu anlamına geliyor.
evet evet bunu anladım. Bu sayede PLL hızını görmüş oluyorsunuz.

Demek istediğim       

GPIOC->ODR=0xFFFFFFFF;
     
        GPIOC->ODR=0x00000000;

komutları ile MCO kullanmadan herhangi bir pinden ulaşabileceğimiz hız da 12 MHz olacaktır heralde..

muhittin_kaplan

Hocam Bunu AHB, APB1 veya APB2 bölücülerinin ayarlarıyla yapabiliyorsunuz.

camby

#21
MCO'dan system clock kullanarak 24 MHz okudum.

--------------------

MCO'dan farklı olarak , Yazılım ile oluşturduğum sinyal ile I/O frekansına bakıyorum , kod aşağıdaki gibi :
while(1) {				// Loop forever               

			
		GPIOC->ODR= 0x00000300;		
		GPIOC->ODR= 0x00000000;	
		GPIOC->ODR= 0x00000300;
		GPIOC->ODR= 0x00000000;
		GPIOC->ODR= 0x00000300;
		GPIOC->ODR= 0x00000000;
		GPIOC->ODR= 0x00000300;
		GPIOC->ODR= 0x00000000;
		GPIOC->ODR= 0x00000300;
		GPIOC->ODR= 0x00000000;
		GPIOC->ODR= 0x00000300;
		GPIOC->ODR= 0x00000000;

	}
}


Ölçtüğüm frekans 4.96 MHz . Aynı işlemi BSRR kullanarak yaptım , frekansın değişmeyeceğini düşünmeme rağmen ölçütüğüm frekans 5.6 MHz.

Kullanmakta olduğumuz 24 MHz 1.25 DMIPS  işlemci ile bu kodlarda arka planda neler oluyor hiçbir fikrim yok.


-------------------

Alıntı yapılan: XX_CİHAN_XX - 26 Ekim 2012, 16:43:24

Şuna da eminim ki derleyici bu işlemi yaparken portu 11 kez sağa kaydırmıyor direk 11. bitin konumunu sorguluyor.


Kaydırma işi , ilk başta garipsedim ama kullanımı güzel geldi bana. Buradaki kod ile çıkış 1.33 MHz :

while(1) {				// Loop forever               
	
		GPIOC->ODR |=  (3UL << 8);		
		GPIOC->ODR &= ~(3UL << 8);
		GPIOC->ODR |=  (3UL << 8);		
		GPIOC->ODR &= ~(3UL << 8);
		GPIOC->ODR |=  (3UL << 8);		
		GPIOC->ODR &= ~(3UL << 8);
		GPIOC->ODR |=  (3UL << 8);		
		GPIOC->ODR &= ~(3UL << 8);
		GPIOC->ODR |=  (3UL << 8);		
		GPIOC->ODR &= ~(3UL << 8);
		GPIOC->ODR |=  (3UL << 8);		
		GPIOC->ODR &= ~(3UL << 8);
	
	}


Kaydırma ile ODR yerine BSRR kullanınca da durum aynı.


Cihan hocam, kaydırma kullanınca performans değişiyor direk. Bana gerçekten arka planda kaydırma and , or yapıyor gibime geldi. 11. bitin konumunu sorgulama gibi bir durumu olacağını sanmıyorum çünkü mimari bize zaten GPIO'lara yanlızca word ve half word erişim olduğunu söylüyor.

mesaj birleştirme:: 29 Ekim 2012, 16:01:06

bit banding denen konuyu bilmiyorum şu an için.

muhittin_kaplan

Alıntı YapKullanmakta olduğumuz 24 MHz 1.25 DMIPS  işlemci ile bu kodlarda arka planda neler oluyor hiçbir fikrim yok.
Hocam Assembly komutlaraına bakarsanız
GPIOC->ODR= 0x00000300; komutu için 3 asm komutu çalışıyor.

XX_CİHAN_XX

#23
Az önce STM32F4 ile bir takım denemeler yaptım. Keil kullandım.
Aşağıdaki komutların hepsi aynı clock saykılında işletiliyor. Ve bunların hepsi aynı işi yapıyor (Portb 6 yı set ediyor)

      GPIOB->BSRRL = GPIO_Pin_6;

      GPIOB->ODR = 0x40;

      GPIOB->ODR = 1 << 6;

Örneğin B6 pini ile birlikte B7 pininide set etmek istediğimde

      GPIOB->BSRRL = GPIO_Pin_6 | GPIO_Pin_7;

      GPIOB->ODR = 0xC0;

      GPIOB->ODR = (1 << 6) | (1 << 7);

Bu kodların hepsi aynı işi tek asm komutu ile yapabilmektedir.
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.

muhittin_kaplan

Alıntı YapBu kodların hepsi aynı işi tek asm komutu ile yapabilmektedir.
Eminmisin ?

X-Fi

#25
Evet yapabilir. Aslında (1 << 6) | (1 << 7) bu ifade 0xC0 dan farklı değil. Birazda derleyici marifeti. Formül girersiniz değişken yoksa sonucu kaydeder.
http://www.coskunergan.dev/    (Yürümekle varılmaz, lakin varanlar yürüyenlerdir.)

XX_CİHAN_XX

Aynen öyle hocam tamamen derleyici marifeti.
Fakat = yerine &= yada |= gibi operatörler işin içine girince asm komut sayısı tek olmuyor.
Ancak yukarıdakilerin hepsini denedim hepsinde de en yüksek hızda tek asm komutuyla aynı işi yapabildiğini gördüm.
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.

X-Fi

anci c nin bir güzel yanıda budur aynı kodu bir çümledede yazabilirsin bir kelimeylede ikiside aynı işi yapar keilde optimasyon ayarları var bazı durumlarda çelişirse ne yapmak istediğini bilmez optimasyon ayarlarına bakar.
http://www.coskunergan.dev/    (Yürümekle varılmaz, lakin varanlar yürüyenlerdir.)

muhittin_kaplan

or yada and le maskelediğinizde 3asm yapıyor.

camby

Alıntı yapılan: XX_CİHAN_XX - 30 Ekim 2012, 14:22:04
Aynen öyle hocam tamamen derleyici marifeti.
Fakat = yerine &= yada |= gibi operatörler işin içine girince asm komut sayısı tek olmuyor.
Ancak yukarıdakilerin hepsini denedim hepsinde de en yüksek hızda tek asm komutuyla aynı işi yapabildiğini gördüm.

Keil'de arka plandaki komutlara karşılık ASM kodları nasıl görebiliyoruz ?