STM32F407 Cortex M4 şamataları

Başlatan bunalmis, 16 Ekim 2011, 17:14:50

ergen

#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 
    GPIOB->MODER = 0x00000015;      // GPIOB nin 0,1,2 pinleri cikis tanimlandi (LEDler icin)
    GPIOB->OSPEEDR= 0xFFFFFFFF;     // GPIOD nin tum cikislari en yuksek hizda kullanacagiz 
	  RCC->APB2ENR|=0x4000;           // SYSCFG Enable
	  GPIOA->PUPDR |= 0x00000008;
} 

volatile int countingSemaphore1 = 0;

void EXTI1_IRQHandler ()
{
	  countingSemaphore1++;
    
} 
void ledyak(void)
{
	  EXTI->PR|=0x00000002;           // EXTI1 INT flagimizi silelim
	  GPIOB->ODR^=0x00000007;         // Toggle islemi
}


int main()
{
		
//  Butona basinca pinimiz H oluyor
    GPIOA->MODER &=~0x0000000C;      // GPIO pin ancak inp modunda interrupt uretebilir (Rehber 143)
	  
    SYSCFG->EXTICR[0]&=~0x000000F0; // GPIO A1 interrupt uretecek
    EXTI->RTSR=0x00000002;          // Yukselen kenar tetiklemesi yapacagiz. (EXTI1)
    EXTI->FTSR=0;                   // Dusen kenar tetiklemesi istemiyoruz.  (EXTI1)
    EXTI->IMR=0x00000002;           // EXTI1 Int enable (Rehber 202-203)
    EXTI->EMR=0;                    // Event istemiyoruz
    NVIC->ISER[0] = 0x00000080;     // NVIC EXTI1_IRQ interrupti acalim
 	  while(1)
	  {
			if(countingSemaphore1 > 0)
			{
				 countingSemaphore1--;
				 ledyak();
                       }
         }
}




Arkadaşlar bana yardımcı olcak kimse yokmu.hızlı tepki vercek olan led toggle uygulamam debug yapınca çalışıyor ama normalde çalışmıyor anlamadım bi türlü kafayı yemek üzereyim :(


fatih6761

@ergen sen halâ semafor olayında mı kaldın? Şu şekile bir eklemeyle kullanabilirsin...
static volatile int durum = 0;

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 
    GPIOB->MODER = 0x00000015;      // GPIOB nin 0,1,2 pinleri cikis tanimlandi (LEDler icin)
    GPIOB->OSPEEDR= 0xFFFFFFFF;     // GPIOD nin tum cikislari en yuksek hizda kullanacagiz 
    RCC->APB2ENR|=0x4000;           // SYSCFG Enable
    GPIOA->PUPDR |= 0x00000008;
	GPIOA->MODER &= ~(0x0C);
	SYSCFG->EXTICR[0] &= ~(0xF0);
	EXTI->RTSR = 0x02;
	EXTI->FTSR = 0;
	EXTI->IMR = 0x02;
	EXTI->EMR = 0;
	NVIX->ISER[0] = 0x80;
	
	while(1)
	{
		while(durum == 0)
		{
			// Interrupt durum değerini set edinceye kadar bekle...
		}
			
		GPIOB->ODR ^= 0x00000007;  // Toggle islemi
		durum = 0;
		
		
	}
} 

void EXTI1_IRQHandler()
{
	EXTI->PR|=0x00000002;           // EXTI1 INT flagimizi silelim
	if(durum == 0)
		durum = 1;
}

void main()
{
	volatile int i;
	
	while(1)
	{
		while(durum == 0)
		{
			// Interrupt durum değerini değiştirene kadar bekle...
		}
		
		GPIOV->ODR ^= 0x00000007;
		
		for(i = 0; i < 0x07FFFF; i++)
			;
		
		durum = 0; // Durumu sıfırla...
	}
}

marecrisium

#1082
Alıntı yapılan: cooldoubtless - 13 Eylül 2012, 00:30:32
ciddi olamazsın hocam hemen bana bir vidyo resim bir şeyler gönder nasıl heyecanlandım :D kodlar bizim kodlar değil mi yoksa kendin mi yazdın? ben benim vidyoyu ekliyorum izlerseniz bir zahmet motor aynen bole oldgu yerde debeleniyor..

SNC00208

Kodları ben yazdım hocam PWM i timer 1 ile ürettim. Dediğim gibi 50 Hz %5 ile %10 arasında değiştiriyorum. Sende frekans sorunu var galiba öyle görünüyor.Timer1 ayar için şunları kullandım.ADC den okuduğum değer ile de duty cycle'i ayarladım. İnternetim yavaş olduğu için vidyo yükleyemiyorum şu an. Daha hızlı bir bağlantı olduğunda yüklüycem.

void timer1ayar()
{
    TIM1->PSC     = 3281-1;               // Prescaler degerimiz  Count frekansimiz = fCK_PSC / (Yuklenen Deger + 1) 
    TIM1->ARR     = 1024;                 // sayıcı=ARR olduğunda sayıcı başa döner (periyot) 15kHz
	TIM1->CCR1    = 972;				     // duty cycle oranı
	TIM1->CCR2    = 300;
	TIM1->CCR3    = 300;
	TIM1->CCR4    = 0;

  //  TIM1->DIER    = 0x0021;               // Update Int enable	+ COM int. etkin
    NVIC->ISER[0]|= 0X04000000;           // NVIC de Timer 1 interrupta izin verelim
	TIM1->CCMR1  |= 0x00006868;			  //CC1 ve CC2 PWM 1 mod seçildi
	TIM1->CCMR2  |= 0x00006868;			  //CC3 ve CC4 PWM 1 mod seçildi
 	TIM1->CCER   |=	0x0113;			      // CC1,CC2,CC3 ve CC4 etkin CCP1 türü çıkış(normal PWM)
 	TIM1->BDTR    = 0x00000C800;		  // MOE etkin AOE etkin   OSSR 
 //	TIM1->CR2     = 0x00000FF01;          //  yükleyiciler etkin OCx1
  	
    TIM1->CR1    |= 0x0081;               // Counter Enable	Otomatik yükleme
 
}								
 


http://t.co/ZU2SKv0Q  şöyle bir fotoğraf yükledim umarım yardımcı olur.

ergen

#1083
#include "STM32F4xx.h"

// FCPU =168Mhz
// FAHB =FCPU
// FAPB2=FCPU/2
// FAPB1=FCPU/4
volatile unsigned int i;
volatile int durum = 0;

void SystemInit()
{


    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 
    GPIOB->MODER = 0x00000015;      // GPIOB nin 0,1,2 pinleri cikis tanimlandi (LEDler icin)
    GPIOB->OSPEEDR= 0xFFFFFFFF;     // GPIOD nin tum cikislari en yuksek hizda kullanacagiz 
    RCC->APB2ENR|=0x4000;           // SYSCFG Enable
    GPIOA->PUPDR |= 0x00000008;
    //  Butona basinca pinimiz H oluyor
    GPIOA->MODER &=~0x0000000C;      // GPIO pin ancak inp modunda interrupt uretebilir (Rehber 143)
    SYSCFG->EXTICR[0]&=~0x000000F0; // GPIO A1 interrupt uretecek
    EXTI->RTSR=0x00000002;          // Yukselen kenar tetiklemesi yapacagiz. (EXTI1)
    EXTI->FTSR=0;                   // Dusen kenar tetiklemesi istemiyoruz.  (EXTI1)
    EXTI->IMR=0x00000002;           // EXTI1 Int enable (Rehber 202-203)
    EXTI->EMR=0;                    // Event istemiyoruz
    NVIC->ISER[0] = 0x00000080;     // NVIC EXTI1_IRQ interrupti acalim
} 



void EXTI1_IRQHandler ()
{
      if(durum==0);
      durum=1;
      EXTI->PR|=0x00000002;           // EXTI1 INT flagimizi silelim
} 


int main()
{
        

 	  
	  while(1)
    {
			 while(durum==0)
			 {
			 }
			 
			 
       GPIOB->ODR^=0x00000007;         // Toggle islemi
			 for(i = 0; i < 0x07FFFF; i++);
			 durum=0;
			 
		
		}
		
}


sonunda oldu :D fatih hocam system init içindeki while(1) döngüsü fazlaydı heralde onu kaldırdım birde birkaç syntax hatası vardı düzelttim ve sonuç süper ;D bir de hatamı zannedersem anladım.interrupt fonksiyonunun sonunda EXTI1 INT flag ını silmem gerekiyodu.bu olmadığı için devamlı interrupt a giriyodu diye düşünüyorum.şimdi sıra bunu 16 butonlu bir klavyeye uyarlıcam ve plc ile rs485 üzerinden haberleştircem.teşekkürler fatih hocam.

fatih6761

Rica ederim. Kodları acele yazınca oluyor öyle bir iki hata... :)

cooldoubtless

#1085
Alıntı yapılan: marecrisium - 13 Eylül 2012, 14:39:35
Kodları ben yazdım hocam PWM i timer 1 ile ürettim. Dediğim gibi 50 Hz %5 ile %10 arasında değiştiriyorum. Sende frekans sorunu var galiba öyle görünüyor.Timer1 ayar için şunları kullandım.ADC den okuduğum değer ile de duty cycle'i ayarladım. İnternetim yavaş olduğu için vidyo yükleyemiyorum şu an. Daha hızlı bir bağlantı olduğunda yüklüycem.

void timer1ayar()
{
    TIM1->PSC     = 3281-1;               // Prescaler degerimiz  Count frekansimiz = fCK_PSC / (Yuklenen Deger + 1) 
    TIM1->ARR     = 1024;                 // sayıcı=ARR olduğunda sayıcı başa döner (periyot) 15kHz
	TIM1->CCR1    = 972;				     // duty cycle oranı
	TIM1->CCR2    = 300;
	TIM1->CCR3    = 300;
	TIM1->CCR4    = 0;

  //  TIM1->DIER    = 0x0021;               // Update Int enable	+ COM int. etkin
    NVIC->ISER[0]|= 0X04000000;           // NVIC de Timer 1 interrupta izin verelim
	TIM1->CCMR1  |= 0x00006868;			  //CC1 ve CC2 PWM 1 mod seçildi
	TIM1->CCMR2  |= 0x00006868;			  //CC3 ve CC4 PWM 1 mod seçildi
 	TIM1->CCER   |=	0x0113;			      // CC1,CC2,CC3 ve CC4 etkin CCP1 türü çıkış(normal PWM)
 	TIM1->BDTR    = 0x00000C800;		  // MOE etkin AOE etkin   OSSR 
 //	TIM1->CR2     = 0x00000FF01;          //  yükleyiciler etkin OCx1
  	
    TIM1->CR1    |= 0x0081;               // Counter Enable	Otomatik yükleme
 
}								
 


http://t.co/ZU2SKv0Q  şöyle bir fotoğraf yükledim umarım yardımcı olur.

hocam naptın sen ADC yi niye karıştırdın şimdi :) SystemInit aynı heralde Main de de bu fonksiyonu çağırdın değil mi? ben de denedim şimdi çalışmadı yahu işe bak..timer 1 channel4 den sıfır almam gerekli ama yine gerilim okunuyor..

marecrisium

Alıntı yapılan: cooldoubtless - 13 Eylül 2012, 20:09:03
hocam naptın sen ADC yi niye karıştırdın şimdi :) SystemInit aynı heralde Main de de bu fonksiyonu çağırdın değil mi? ben de denedim şimdi çalışmadı yahu işe bak..timer 1 channel4 den sıfır almam gerekli ama yine gerilim okunuyor..
Bu fonksiyonları main içinde çağırıp timerı kuracaksın evet. Adc ile doluluk oranını ayarlamak daha rahat olur bu yüzden kullandım. Bir de PWM çıkışları için ilgili pinleri alternative function olarak seç ve timer1 in saat kaynağını mutlaka aç yoksa çalışmaz sayıcı.

ergen

#include "STM32F4xx.h"
#define GPIO_A(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOB->ODR) << 5) + ((b) << 2)))
#define GPIO_B(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOB->ODR) << 5) + ((b) << 2)))
#define GPIO_C(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOB->ODR) << 5) + ((b) << 2)))
#define GPIO_D(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOB->ODR) << 5) + ((b) << 2)))
#define GPIO_E(b) *((volatile unsigned long *)( 0x42000000 + (((unsigned long)&GPIOB->ODR) << 5) + ((b) << 2)))

// FCPU =168Mhz
// FAHB =FCPU
// FAPB2=FCPU/2
// FAPB1=FCPU/4
volatile unsigned int i;
volatile int durum = 0;


void SystemInit()
{


    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 
    GPIOB->MODER = 0x00000015;      // GPIOB nin 0,1,2 pinleri cikis tanimlandi (LEDler icin)
    GPIOB->OSPEEDR= 0xFFFFFFFF;     // GPIOD nin tum cikislari en yuksek hizda kullanacagiz 
    RCC->APB2ENR|=0x4000;           // SYSCFG Enable
    GPIOA->PUPDR |= 0x000000A8;     // 
	  //  Butona basinca pinimiz H oluyor
    GPIOA->MODER &=~0x000000FC;      // GPIO pin ancak inp modunda interrupt uretebilir (Rehber 143)
    SYSCFG->EXTICR[0]&=~0x0000FFF0; // GPIO A1 ve A2 interrupt uretecek
    EXTI->RTSR=0x0000000E;          // Yukselen kenar tetiklemesi yapacagiz. (EXTI1-EXTI2)
    EXTI->FTSR=0;                   // Dusen kenar tetiklemesi istemiyoruz.  (EXTI1-EXTI2)
    EXTI->IMR=0x0000000E;           // EXTI1 Int enable (Rehber 202-203)
    EXTI->EMR=0;                    // Event istemiyoruz
    NVIC->ISER[0] = 0x00000380;     // NVIC EXTI1_IRQ interrupti acalim
} 



void EXTI1_IRQHandler ()
{
	    if((durum==0)&& (GPIO_B(0)==0))
      {
				
        durum=1;
      }
			
			EXTI->PR|=0x00000002;           // EXTI1 INT flagimizi silelim
      
} 

void EXTI2_IRQHandler ()
{
	    if((durum==0)&& (GPIO_B(1)==0))
	    {
				
        durum=2;
      }
	    
			EXTI->PR|=0x00000004;           // EXTI2 INT flagimizi silelim
	    
}

void EXTI3_IRQHandler ()
{
	    if(durum==0)
			{
				
	      durum=3;
			}
	    
			EXTI->PR|=0x00000008;           // EXTI2 INT flagimizi silelim
	    
}


int main()
{
        

 	  while(1)
    {
			 switch(durum)
			 {
			    case 1:
				 {
					  GPIO_B(1)=0;
					  GPIO_B(0)^=1;         // Toggle islemi
			      for(i = 0; i < 0x07FFFF; i++);
			      durum=0;
					  break;
			   }
				  
				  case 2:
				{
					  GPIO_B(0)=0;
					  GPIO_B(1)^=1;         // Toggle islemi
			      for(i = 0; i < 0x07FFFF; i++);
			      durum=0;
					  break;
					  
				}
				
				  case 3:
				{
					  
					  GPIO_B(2)^=1;        // Toggle islemi
			      for(i = 0; i < 0x07FFFF; i++);
			      durum=0;
					  break;
					  
				}
			}
				
			 
		}
		
}


arkadaşlar bu kodlarla üç ledi istedigim gibi kontrol ediyorum fakat modbus ile nasıl haberleştircem bitürlü yapamadım.bülent hocanın dma daki dataları gönderen interrupt ile de dma ya data alan bi örnegi var ama bunun içine modbus ı nasıl dahil etcem.modbus nasıl çalışır bilmiyorum.dökümanlarına baktım çok bişey anlamadım yardımcı olurmusunuz lütfen.

Enginar

#1088
Arkadaşlar yazılan kodları inceleyerek interruptları anlamaya çalışıyorum

NVIC->ISER[1] = 0X00800000; // dökümanlarını karıştırdım ama bu kodu bi türlü anlayamadım :'(

[1] indisi ve 0x00800000 adresi ne anlama geliyo ?

Yardımlarınızı bekliyorum arkadaşlar ve şimdiden teşekkür ederim... :)

GreeN

#1089
NVIC ile ilgili cortex-m3 çekirdeği için bir bilgi vardı.

Rehber 195. sayfada interruplar için bir tablo var. bu tablonun ilk sutunu NVIC->ISERx 'in alacağı değerle alakalıdır.


Öncelikle şunu bilelim NVIC->ISER[0]  0 ile 31 arası interruptlar için ,
                                  NVIC->ISER[1]  32 ile 63 arası interruptlar için kullanılıyor....

Senin sorduğun NVIC->ISER[1] = 0X00800000; koduna bakalım.
ISER[1]  kullanıldığı için demekki ikinci 32 interrupt listesinde , 0X00800000 değeri ise registerin 23. biti set edildiği anlamına geliyor.
32+23 =55 , tablodan 55. kesme TIM7 ile alakalı bir kesme olduğunu göreceksin.

Şimdi misal tablodan DMA2_Stream0 ile ilgili bir intterrup oluşturman gerek tabloda 56. sırada ,
56-32 = 24 (24. bit set edilecek anlamına geliyor) 0X01000000 ,  NVIC->ISER[1] = 0X01000000;

Terörü Lanetliyoruz.

muhittin_kaplan


Enginar

Çok Teşekkür Ederim yardımlarınız için çok iyi anladım :)

Enginar

Peki programda kodlarımızı yazarken bildiğim kadarıyla belli bi mantık sırasına veya düzene göre yazıyoruz . Bazı kodların yerini değiştirdiğimiz taktirde programımız çalışmıyo veya eksik çalışıyo :'( Kodlarımızı hangi mantığa veya düzene göre Nasıl yazmalıyız ?  Bu konuda bilgisi olan arkadaşların yardımlarını bekliyorum :)

XX_CİHAN_XX

Ben böyle soruları sormaya başladığım zamanlarda 8 bitlik basic piclerle oynamaya çalışıyordum. Şimdi devir değişti sanırım ilk defa programlamaya 32bitlik hi performance mcu larla mı başladınız merak ediyorum doğrusu  :o
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.

Enginar

Sanırım sorumu yanlış aktardım.

Şöyle sorayım Mesela SystemInt içindeki kodların yerlerini , sırasını değiştirdiğimizde kodlarımız neden çalışmıyo ? Bunu neye göre tayin edeceğiz ?