Yardım: STM32F4 Discovery Led uygulaması

Başlatan muhendisbey, 04 Ağustos 2012, 17:53:13

muhendisbey

Merhaba arkadaşlar
Uzun süredir yatan kitim ile iş buluncaya kadar C yi öğrenmeye karar verdim. Bülent hocamın notlarından şimdilik harfiyen gidiyorum. Onun örnek uygulamasını biraz değiştirerek bir program yazdım
#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 |= 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 
}


int main()
{
	int a;
	int n=0;
	int yon=0;
    while(1)
      {
        if (GPIOA->IDR & 0x000000001) {yon=yon++; for(a=0; a<10000000; a++);}
		
		if (yon>1) yon=0;  
		
		if (yon==0) n=n+1 ;
		else n=n-1;

		if (yon>1) yon=0; 
		if (n>4) n=1;	
		if (n<1) n=4; 		
			

		if(n==1)	{GPIOD->ODR= 0x00001000;	for(a=0; a<10000000; a++);	   }
				
		if(n==2)	{GPIOD->ODR= 0x00002000;	for(a=0; a<10000000; a++); 	   }
			
		if(n==3)	{GPIOD->ODR= 0x00004000;	for(a=0; a<10000000; a++); 	   }
			
		if(n==4)	{GPIOD->ODR= 0x00008000;	for(a=0; a<10000000; a++);	   }
		
						

			
			
			     
      } 
}
// Programın sonu.


Şimdi isteğim şu. Mesela Sira adında bir alt program oluşturup n in değerine göre led yakacağım, yani main altından if li led komutlarını nasıl ayırt ederim?
Şöyle birşey
Sira(n) gibi bir fonksiyon n=1 dediğimde yeşil yanacak.

Bir diğer sorum zamanlama. Örneğin tam 1ms lik gecikme için ne yapmam gerekir hesaplaması nasıl yapılıyor?

Şimdiden herkese teşekkürler, kolay gelsin.
Zulmü alkışlayamam, zalimi asla sevemem; Gelenin keyfi için geçmişe kalkıp sövemem.

Klein

bunun birkaç yolu var.

1. yol.
const uint32_t mask[]={0x00000000,0x00001000,0x00002000,0x00004000,0x00008000};
GPIOD->ODR = mask[n];

2. yol
switch(n){
       case 1: GPIOD->ODR= 0x00001000; break;
       case 2: GPIOD->ODR= 0x00002000; break;
       case 3: GPIOD->ODR= 0x00004000; break;
       case 4: GPIOD->ODR= 0x00008000; break;
}

3. yol.

      GPIOD->ODR= 0x00001000 << (n-1);

sseedat

gecikmeyi ben böyle kullanıyorum.
delay.h
extern void Delay_ms(unsigned long Bekle);
extern void Delay_us(unsigned long Bekle);

delay.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//       Kullanılışı;
//       Delay_ms(100);   // 100 msn Bekle.
//       Delay_us(100);   // 100 usn Bekle.
//       Not CPU OSC = 168 mhz - 210 MIPS

#include "Delay.h"

void Delay_ms(unsigned long Bekle)
{
    Bekle = Bekle * 21008;   // mSn ye ye çevirdik. OSC 168Mhz de uçuyor.
    while(Bekle>0){Bekle--;}
}

void Delay_us(unsigned long Bekle)
{
    Bekle = Bekle * 21;   // uSn ye ye çevirdik. OSC 168Mhz de uçuyor.
    while(Bekle>0){Bekle--;}
}
Görünmez bir mezarlıktır Zaman...

Klein

Alıntı yapılan: muhendisbey - 04 Ağustos 2012, 17:53:13

Bir diğer sorum zamanlama. Örneğin tam 1ms lik gecikme için ne yapmam gerekir hesaplaması nasıl yapılıyor?
Şimdiden herkese teşekkürler, kolay gelsin.

https://www.picproje.org/index.php/topic,35896.0.html

System Tick Counter kullanarak 1ms lik int uretmek başlığı.

muhendisbey

Cevaplarınız için çok teşekkürler, hemen bir soru daha sorayım

değişkeni tanımlamamız lazım ör:

int a;

bunu programı yazarken nereye tanımlamamız gerekli? Main'in içinde bazen sorun yaşıyorum. Yoksa ayarlamalar yaptıktan sonra tanımlayabilir miyiz? En iyi nerede yapmalıyım.

Kendimi aptal gibi hissediyorum ama öğreten olmadı :S
Zulmü alkışlayamam, zalimi asla sevemem; Gelenin keyfi için geçmişe kalkıp sövemem.

Yuunus

dahil ettiğin kütüphanelerin hemen altına da tanımlayabilirsin sanırımo zaman global oluyor.

pisayisi

Alıntı yapılan: Klein - 04 Ağustos 2012, 18:07:33
bunun birkaç yolu var.



3. yol.

      GPIOD->ODR= 0x00001000 << (n-1);

Dünya çapında kabul gören 3. yoldur buna alışın derim ;D
Murat

tyildizak

#7
Alıntı yapılan: muhendisbey - 04 Ağustos 2012, 21:00:58
int a;

bunu programı yazarken nereye tanımlamamız gerekli? Main'in içinde bazen sorun yaşıyorum. Yoksa ayarlamalar yaptıktan sonra tanımlayabilir miyiz? En iyi nerede yapmalıyım.


şu mesajı hatta konunun  tamamını okursanız faydalı olacaktır:  https://www.picproje.org/index.php/topic,35908.msg257145.html#msg257145


muhendisbey

#8
Alıntı yapılan: tyildizak - 04 Ağustos 2012, 21:50:12
şu mesajı hatta konunun  tamamını okursanız faydalı olacaktır:  https://www.picproje.org/index.php/topic,35908.msg257145.html#msg257145

Hocam çok sağol bunu öğrendiğim iyi oldu. O konu altından ilerliyorum hatta bir doc dosyası oluşturdum yakında çıktısını da alacağım :)
ASM ile ARM'yi ilerletemedim C'ye döndüm biraz zorlanıyorum.

mesaj birleştirme:: 05 Ağustos 2012, 00:44:36

const uint32_t mask[]={0x00000000,0x00001000,0x00002000,0x00004000,0x00008000};
GPIOD->ODR = mask[n];

Bu komutun mantığı nasıl işliyor? Yani Const uint32_t mask[]= yapısındaki komutları açıklayabilir misiniz?
Zulmü alkışlayamam, zalimi asla sevemem; Gelenin keyfi için geçmişe kalkıp sövemem.

muhendisbey

Alıntı yapılan: gerbay - 05 Ağustos 2012, 00:46:43
hocam RTOS falan yazmaya kalkmayacaksanız ARM için ASM ye gerek yok, aramazsınız, çok fazla ihtiyaç hissetmezsiniz..

Yok işte denedim öyle PIC'e yazmaya benzemiyor. Farklı bir iş orası kesin.
Zulmü alkışlayamam, zalimi asla sevemem; Gelenin keyfi için geçmişe kalkıp sövemem.

tyildizak

Alıntı yapılan: muhendisbey - 05 Ağustos 2012, 00:33:55
C'ye döndüm biraz zorlanıyorum.

C ile ilgili şu kitabı  elinizin altında bulundurmanızı öneririm, bulabilirseniz orjinalini de mutlaka alın, : c kılavuzu-kaan aslan

muhendisbey

Anladım. Gerbay çok teşekkür ederim. Herhalde C'yi sökene kadar biraz başınızı ağrıtacağım...
tyildizak kitabı hemen indiriyorum, bakayım belki orijinalini de bulurum.
Zulmü alkışlayamam, zalimi asla sevemem; Gelenin keyfi için geçmişe kalkıp sövemem.

LukeSkywalker

Uint32_t  deki t nedir? Uint32'dn farkı nedir?

muhendisbey

Valla bu son açıklama da ekmek kadayıfı oldu üstüne :) Sorandan da cevaplayandan da Allah razı olsun. Ben soracaktım, kendi kendime çok sordun yeter kafa şişirme dediğim için sormadım :)
Zulmü alkışlayamam, zalimi asla sevemem; Gelenin keyfi için geçmişe kalkıp sövemem.

muhendisbey

Hocam yöntemleri denedim shift işlemi hariç. O işi de biliyorum sadece ardışıklık olmasa böyle bir işlemi kullanmak daha zor oluyor. Amaç farklı yapılar öğrenmek.

1 yolda aldığım hata

main.c(45): error:  #268: declaration may not appear after executable statement in block

#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 |= 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 
}


int main()
{
	int a;
	int n=0;
	int yon=0;
    while(1)
      {
        if (GPIOA->IDR & 0x000000001) {yon=yon++; for(a=0; a<10000000; a++);}
		
		if (yon>1) yon=0;  
		
		if (yon==0) n=n+1 ;
		else n=n-1;

		if (yon>1) yon=0; 
		if (n>4) n=1;	
		if (n<1) n=4; 		
			

		const uint32_t mask[]={0x00000000,0x00001000,0x00002000,0x00004000,0x00008000};
		GPIOD->ODR = mask[n];
		
						

			
			
			     
      } 
}
// Programın sonu.


Buradaki hata neden kaynaklanıyor? Hata açıklamasını anladım ama çözümünü bulamadım. Bu yöntem bayağı hoşuma gitti bir de kullanabilsem iyi olacak :)

Zulmü alkışlayamam, zalimi asla sevemem; Gelenin keyfi için geçmişe kalkıp sövemem.