Haberler:

Foruma Resim Yükleme ve Boyut Sınırlaması ( ! )  https://bit.ly/2GMFb8H

Ana Menü

STM32F4 Discovery - Vizeler

Başlatan bunalmis, 24 Aralık 2011, 15:13:13

fryrmnd

muhittin hocam bunalmış hocam bunun için üretilen clock frekansını dışarı veren bir program yazmıştı.
https://www.picproje.org/index.php/topic,35896.0.html
sanırım bu denemeniz için uygun olabilir.

z

Alıntı yapılan: fryrmnd - 26 Aralık 2011, 15:44:27
hocam farkındayım ama çok soruyoz ama. daha önce debugla felan çok uğraşmayınca. peki dışardan buton ve interrupt kısmında bir nevi test noktası koyarak gözlemliyorsunuz. başka bir register mesela bir çevre birimin konfigürasyon registerı. değer atadık. bunun içeriğini kartı debug ederken peripherals menüsünden mi görebilirim.

Dedigim gibi ben peripheral menu falan kullanmiyorum.

Benim yontemimi kullanmak istersen asagida.

#include "STM32F4xx.h"
// FCPU =168Mhz
// FAHB =FCPU
// FAPB2=FCPU/2
// FAPB1=FCPU/4
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 = 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 = 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 |= 0x0000000F;     // GPIO A,B,C,D clock'u aktif edelim 
    GPIOD->MODER = 0x55000000;      // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (LEDler icin)
    GPIOD->OSPEEDR= 0xFFFFFFFF;     // GPIOD nin tum cikislari en yuksek hizda kullanacagiz 
} 
void EXTI0_IRQHandler ()
{
    EXTI->PR|=0x00000001;           // EXTIO INT flagimizi silelim
    GPIOD->ODR^=0x00001000;     
} 
int main()
{
//  Butona basinca pinimiz H oluyor
    GPIOA->MODER&=~0x00000003;      // GPIO pin ancak inp modunda interrupt uretebilir (Rehber 143)
    SYSCFG->EXTICR[0]&=~0x0000000F; // GPIO A0 interrupt uretecek
    EXTI->RTSR=1;                   // Yukselen kenar tetiklemesi yapacagiz. (EXTI0)
    EXTI->FTSR=0;                   // Dusen kenar tetiklemesi istemiyoruz.  (EXTI0)
    EXTI->IMR=1;                    // EXTI0 Int enable (Rehber 202-203)
    EXTI->EMR=0;                    // Event istemiyoruz
//    NVIC->ISER[0] = 0x00000040;   // NVIC EXTI0_IRQ interrupti acalim
    EXTI->PR|=1;                    // Flagi silelim ve pusuya yatalim
    while((EXTI->PR&1)==0);         // Int uretilirse flag set olur 
    while(1);                       // Bu satira break point koy   
}


Gecmisteki deneyimler nedeniyle neden peripheral menu vs kullanmadigimi soyleyeyim.

Keil bile olsa peripheral menuler vs BUG icerebilir. Hata yapiyorsam ben yapayim, bir baskasinin hatasi yuzunden sac bas yolmayayim mantigindan
boyle yapiyorum.

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

fryrmnd

anladım hocam teşekkür ederim.

muhittin_kaplan

Örnek Programlara Baktım Bulamadım. Bende Biraz Tırmaladım Ama Güzel Oldu sanırım
#include "STM32F4xx.h"
 
void SystemInit()
{
unsigned int i;
 for (i=0;i<0x00100000;i++);          // OSC oturtma ve kurtarma rutini
    RCC->CFGR |= 0x00609400;         // AHB ve APB hizlarini max degerlere set edelim
									//6 ile Cout1 i PLL clock selected yapıldı.
    RCC->CR |= 0x00010000;            // HSE Xtal osc calismaya baslasin        
    while (!(RCC->CR & 0x00020000));// Xtal osc stabil hale gelsin
    RCC->PLLCFGR = 0x07431008;      // PLL katsayilarini M=8, N=20, 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 |= 0x0000000F;    // GPIO A,B,C,D clock'u aktif edelim 

    GPIOA->MODER = 0xAAAAAAAA;     	// GPIOA nin tüm pinleri cikisları Alternatif yapıldı Clock 1 çıkış İçin 
									// GPIOA.8 Clock Out REFBER Sayfa 91
    GPIOA->OSPEEDR= 0xFFFFFFFF;   // GPIOA nin tum cikislari en yuksek hizda kullanacagiz  

    GPIOD->MODER = 0x55000000;     // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (LEDler icin)
    GPIOD->OSPEEDR= 0xAAAAAAAA;   // GPIOD nin tum cikislari en yuksek hizda kullanacagiz 
}
 
int main()											  
{
   
    while(1)
   {
		     
   
     	GPIOD->ODR=0x00001000;
	GPIOD->ODR=0x00000000;

   } 
}
				 

Şu an Pll çıkışını porta.8 den görüyorum sanırım (8Mhz.)

fryrmnd

örnek program alttta hocam. // satırına alınmamış bazı yorumlarıda almayı unutmayın.

CPU 8 Mhz Xtal OSC ile 168Mhz de koşuyor.  (Acaba)
AHB frekansı 168 Mhz (Acaba)
APB1 frekansı 42 Mhz (Acaba)
APB2 frekansı 84 Mhz (Acaba)
 
// Programın başı
 
#include "STM32F4xx.h"

void SystemInit()
{
//  Yukarıdaki örnek programdaki kodların aynısı
}

int main()
{
//  MOC2 pininden SYSCLK cikacagiz
    RCC->CFGR &= 0x07FFFFFF;         // 31,30,29,28,27 nolu bitleri silelim (Aslinda zaten 0)  (Prescaler degerinide silelim)
    RCC->CFGR |= 0x30000000;   // MCO2 prescaler /4 secildi
 
//  Hard sayfa 46 dan MCO2 nin GPIO C9 pini oldugu tespit edildi
//  http://img263.imageshack.us/img263/4633/pinlistesi.jpg dan PC9 un bos pin oldugu teyid edildi
//  PC9 a hangi alternatif fonksiyon atanacağını bulalım  (Hard Sayfa 50 den MCO2 nin AF0 oldugu goruldu)
 
    GPIOC->AFR[1] &= ~0x000000F0;  // 7,6,5,4 nolu bitler silindi 
//  Keil yada ST yukarıdaki registeri neden structure içinde array tanımlamış anlamadım,
//  Halbuki diğer regler gibi yapabilirdi (header dosyayı değiştirmek istemiyorum ama istersek yapabiliriz)

    GPIOC->OSPEEDR =  0xFFFFFFFF;  // GPIOC nin tum cikislarinı en yuksek hizda kullanacagiz
 
// GPIOC de 9 nolu pine ait cikisi alternatif fonksiyon secelim
 
    GPIOC->MODER =  0x00080000;    // Bit 19=1 ve Bit 18=0 yaparak pinin alternatif fonksiyon olmasini sagladik
 

    while(1)
      {
      }
}

// Programın sonu
 
MCO2 pini (PC9) scopla gözlendi ve 42Mhz ölçüldü. MCO2 prescaler 4'e set edildiğindenö SYSCLK frekansımızın 4x42=168Mhz oldugu anlaşıldı.
Burda hata olsaydı yanlışlıkla overclock yapmış ve bir ihtimal sistemi 336Mhz ile besleyebilirdik.

Neden prescalerı 1 yapmadıkda 4 yaptık?  Dokümanlarda, GPIO lardan 100Mhz den yüksek frekansda sinyal çıkamazsınız deniyor.

SYSCLK 168Mhz buna rağmen Timer7 örneğindeki ledler 1 sn yerine 0.5 sn de yanıp sönüyorsa, olası durumlar;
 
1. APB1 BUS'ı 42 yerine 84Mhz ile besledik.
2. Timer Clk kaynağı APB1 BUS clk dan beslenmiyor.
3. Timer programında mantık hatası yapıyorum.
 
Sonuç: Timer7 programındaki hatayı hala bulamadık. Fakat bu program sayesinde alternatif fonksiyon kullanımını görmüş olduk.

z

Bu baslik altinda bir arkadasin LIS302DL MEMS motion sensor ile ilgili sorusu vardi. Ornek kodlardaki MEMS uygulamasini tekrar denedigimde bazen tutarsiz davrandigini gordum.

Asagidaki programda, karti elinizle tutup egdikce ledler egilen yonde isildiyor.

#include "STM32F4xx.h"
 
unsigned short PWM[8];  // PWM registerler
unsigned short SRG[8];  // Shadow Registerler
unsigned short CNTR;    // PWM Counter
signed char who,x,y,z,xo,yo,zo;   


/*****************************************************************************************************
         CPU PLL ile 168Mhz de kosturulur
         AHB frekansy 168 Mhz
         APB1 frekansy 42 Mhz
         APB2 frekansy 84 Mhz
*****************************************************************************************************/
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 = 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 = 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  = 0x55550000;     // GPIOD nin 15, 14, 13, 12, 11, 10, 9, 8 pinleri cikis tanimlandi (LEDler icin)
     GPIOD->OSPEEDR= 0xFFFFFFFF;     // GPIOD nin tum cikislari en yuksek hizda kullanacagiz 

//  GPIOA da A7, A6, A5 pinleri, LIS302DL cipiyle haberlesmek icin SPI moduna alinacak   
 
     GPIOA->AFR[0]=0x55500000;       // SPI1 secelim (Rehber Sayfa 141), Hard Sayfa 49
     GPIOA->MODER|=0x0000A800;       // A7,A6,A5 Alternatif fonksiyon
     RCC->APB2ENR|=0x00001000;       // SPI1 clk enable   //   GPIOE3 pinini output tanimlayalim (LIS302DL SPI/I2C secimi)   
     GPIOE->MODER  = 0x00000040;     // GPIOE nin 3 nolu pini cikis tanimlandi
     GPIOE->OSPEEDR= 0xFFFFFFFF;     // GPIOE nin tum cikislari en yuksek hizda kullanacagiz
     GPIOE->BSRRL=0x0008;            // GPIOE3=1; LIS302DL CS=1   
     SPI1->CR1=0x00000B7F;           // SPI1 16 bit, master , fulldublex vs
     SPI1->CR2=0X0000;

     RCC->APB1ENR|=0x00000020;       // Timer7 CLK'u aktif edelim (84 Mhz)
     TIM7->CR1=0x0080;               // Otomatik Reload
     TIM7->PSC =839;                 // Prescaler degerimiz 839, Count frekansimiz = fCK_PSC / (Yuklenen Deger + 1) 84E6 / (840) = 100 KHz
     TIM7->ARR =1;                   // Counter, Decimal 1 olunca basa donsun. Her 20 mikrosaniye de bir timer int olusacak.
     TIM7->DIER=0x0001;              // Update Int enable
     NVIC->ISER[1] = 0X00800000;     // NVIC de Timer 7 interrupta izin verelim
     TIM7->CR1|=0x0001;              // Counter Enable
     
} 

void TIM7_IRQHandler()
{
unsigned short d,i,j;
 
    TIM7->SR=0;                       // Timer Int Flagini silelim 
    d=GPIOD->ODR | 0xFF00;
    CNTR++;
    if(CNTR>=255)
      {
        CNTR=0;
        for(i=0;i<8;i++) 
         { 
           if(PWM[i]>255) PWM[i]=255;
           SRG[i]=PWM[i]; 
         }  
      }
    j=0x8000;
    for(i=0;i<8;i++)
      {
       if (CNTR>=SRG[i]) d&=~j;
       j=j>>1;
      } 
    GPIOD->ODR=d;
} 

void Write(char Adr,unsigned char Data)
{
      GPIOE->BSRRH=0x0008;            // LIS302DL CS=0
      SPI1->DR=((Adr&0x3F)<<|Data;
      while(!(SPI1->SR&2));
      GPIOE->BSRRL=0x0008;            // LIS302DL CS=1
}   
 
char Read(char Adr)
{
char Dat; 
      GPIOE->BSRRH=0x0008;            // LIS302DL CS=0
      SPI1->DR=((Adr&0x3F)|0x80)<<8;
      while(!(SPI1->SR&1));
      Dat=SPI1->DR;
      GPIOE->BSRRL=0x0008;            // LIS302DL CS=1
      return(Dat);
}   

int main()
{
int i;
      if(Read(0x0F)==0x3B)   // Who are you ?
       {
          Write(0x20,0x47);  // Data Rate=100Hz, Full Scale=2g, Activate, x,y,z enable
          while(1)
            {
               who=Read(0x27); // Statusu ogrenelim. Kim hazir kim deðil?
               if (who&1) 
                {
                  x=(Read(0x29)+xo);
                  xo=x>>1;
                  if (x>=0) PWM[0]=x;
                  else PWM[2]=-x;
                }  
               if (who&2) 
                {
                  y=Read(0x2B)+yo;
                  yo=y>>1;
                  if (y>=0) PWM[1]=y;
                  else PWM[3]=-y;
                }  
               if (who&4) 
                {
                  z=Read(0x2D);
                }  
            }
       }
       
      TIM7->DIER=0x0000;              // Update Int disable
      while(1)
       {
         for(i=0;i<0x1000000;i++);
         GPIOD->ODR^=0x0000F000;
       }  
       
}
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

M_B

#96
Merhaba Hocam;
kodunuzu kopyala yapıstır yaptım derleme esnasında altakı hatayı verdi.
Hatanının oldugu yere baktıgımda ise bir parantezin eksik oldugunu gordum duzeltım ama olmadı.

Build target 'Target 1'
assembling startup_stm32f4xx.s...
compiling main.c...
main.c(81): error:  #29: expected an expression
Target not created


Parantezin eksik oldugu yer.

void Write(char Adr,unsigned char Data)
{
      GPIOE->BSRRH=0x0008;            // LIS302DL CS=0
      SPI1->DR=(Adr&0x3F)<<|Data);                         // Eksik olan yer.
      while(!(SPI1->SR&2));
      GPIOE->BSRRL=0x0008;            // LIS302DL CS=1
}   


Not: Yazım duzeltmesi yapıldı.
İmkanın sınırlarını görmek için imkansızı denemek lazım.                                                             Fatih Sultan Mehmet

z

#97
void Write(char Adr,unsigned char Data)
{
      GPIOE->BSRRH=0x0008;            // LIS302DL CS=0
      SPI1->DR=((Adr&0x3F)<<|Data;
      while(!(SPI1->SR&2));
      GPIOE->BSRRL=0x0008;            // LIS302DL CS=1
}   


Yukarida 8 ve parantez kapa yan yana gelince parantez yutuluyor.

Asagida ise 8 ve parantez kapa yan yana gelince siritan gozluklu adam cikiyor.

void Write(char Adr,unsigned char Data)
{
      GPIOE->BSRRH=0x0008;            // LIS302DL CS=0
      SPI1->DR=((Adr&0x3F)<< 8) |Data;
      while(!(SPI1->SR&2));
      GPIOE->BSRRL=0x0008;            // LIS302DL CS=1
}   


8)  8 )

Bu durumda kodlara guvenemeyecekmiyiz?
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

K46

Alıntı yapılan: bunalmis - 26 Aralık 2011, 23:26:09


8 ve parantez kapa yan yana gelince siritan gozluklu adam cikiyor.



Hocam mesaj yazma ekranının alt kısmında "Gülümseme kullanma" kutucuğu var orayı işaretleyince ne yazıldıysa o şekilde çıkması lazım.

Deneme 8)
Bak, ibret al, yere düşen yaprağa, O da eskiden, yukarıdan bakardı toprağa!

madpic

Bu baslik altinda bir arkadasin LIS302DL MEMS motion sensor ile ilgili sorusu vardi.


teşekkürler sayın hocam
kit işyerinde kaldığı için deneyemiyorum
ilk fırsatta kodları inceleyeceğim

muhittin_kaplan

Hocam NVIC nedir ? Biraz Anlatabilirmisiniz ?(Bu birinci Sorum)
Alakasız ikinci Sorum CMSIS Nedir ? (Bir çeşit kütüphane mi ?)

z

#101
NVIC Nested Vectored Interrupt Controller

Gelen interruptlari yoneten birimin adi. Bir interrupt geldiginde sapilacak adresi ogrenen, kesme icinde kesmelere de izin veren, interrupt onceliklerini ayarlamamiza saglayan donanim.

Interruptlarin kullanildigi ornek programlarimiza bakarsaniz yaptigimiz is, cevre biriminin interrupt ozelligini acmak, daha sonra da NVIC de bu interrupta izin vermek.

Iyi hatirlattin. Bir ara da birden fazla interrupt kullanan ornek yapalim ve interrupt oncelikleriyle oynayalim.

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

CMSIS ise Cortex Microcontroller Software Interface Standart

Registerlerle ugrasip cevre birimlerini hazirliyoruz ya. Bu islem her islemci degistirdigimizde yeni bastan ogrenilmesi gereken bir islem.  STM CM4 de calisiyoruz. Diyelimki registerlerle kedinin fareyle oynadigi gibi oynamaya basladiniz. Fakat ileri bir tarihte NXP CM4 islemci kullanmaya karar verdiniz. Bu kez bu cipin dokumanlarini da sil bastan okumaya baslayacagiz.

Gerci bir firmanin islemcisinde ustalasinca baska bir firmanin islemcisinde zorlanmazsiniz fakat dokumanlari sil bastan okumaniz gerekir.

CMSIS de rutinler standartlastirilmis. Hangi islemciyi kullanirsaniz kullanin degismeyecek. Fakat bunun icin CMSIS kullanimini ogrenmeniz gerekecek. Ben bu konuya hic girmeyecegim. Bir ara bir arkadas bu konuda notlar hazirlayacagini soylemisti.


Mesela NXP sitesinden aldigim bir ornek

/* Set PORT0_4 direction to output */

LPC_GPIO0->DIR |= 0x10;

/* Set PORT0_4 high */

LPC_GPIO0->DATA |= 0x10;

Ornegin yukarida bizim yaptigimiz gibi yani registerlere veri yukleyerek portun  4 nolu biti 1 yapilmis.Asagida ise CMSIS fonksiyonlari kullanilarak ayni islem yapilmis

/* Set PORT0_4 to output */
/* void GPIOSetDir( uint32_t portNum, uint32_t bitPosi, uint32_t dir) */
GPIOSetDir(0, 4, 1);

/* Set PORT0_4 to HIGH */
/*void GPIOSetValue( uint32_t portNum, uint32_t bitPosi, uint32_t bitVal ) */
GPIOSetValue(0, 4, 1);

CMSIS evet bir kutuphane ve bana cok itici geliyor.  Fakat bir kere ogrenirseniz rahat edebilirsiniz.
CMSIS rutinleri cipin icindeki ROMA gomulu hazir derlenmis fonksiyonlar da olabilir, derleme sonucunda elde edilecek fonksiyonlarda olabilir.

TI ciplerinde ROMDA duruyor. (Flash haricinde)

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

muhittin_kaplan

Yani Şunumu Anlamalıyım ?
CAMIS Öğrenirsem ST, NXP vs fark etmeden yazabilirim.

z

Emin olmamakla birlikte evet. Fakat bir elektronikci olarak guzelim registerler varken kafani bir suru ivir zivir fonksiyon isimleriyle dolduracaksin. Degermi?
Yazilimci olsan neyse.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

fryrmnd

ben pes ediyorum bunalmış hocam. açarsanız seneye tekrar alırım bu dersi. biraz daha picle uğraşmak gerek galiba. adc yi bile ayarlayamadım.