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.
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);
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--;}
}
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 (https://www.picproje.org/index.php/topic,35896.0.html)
System Tick Counter kullanarak 1ms lik int uretmek başlığı.
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
dahil ettiğin kütüphanelerin hemen altına da tanımlayabilirsin sanırımo zaman global oluyor.
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
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 (https://www.picproje.org/index.php/topic,35908.msg257145.html#msg257145)
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 (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?
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.
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 (http://ul.to/ifwbr0cg)
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.
Uint32_t deki t nedir? Uint32'dn farkı nedir?
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 :)
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 :)
mask tanımını global yap. Programın başında tanımla. C derleyicilerin çoğu rastgele yerde değişken veya sabit tanımlamaya izin vermez. Değişkeler veya sabitler blığun başında tanımlanmalıdır.
Sabitler genellikle blok içerisinde tanımlanmaz. Bu bir zorunluluk değildir. Blok içerisinde de tanımlanabilir ama genellikle kimse o şekilde kullanmaz.
örnek:
#include "STM32F4xx.h"
const uint32_t mask[]={0x00000000,0x00001000,0x00002000,0x00004000,0x00008000};
...
Alıntı yapılan: Klein - 07 Ağustos 2012, 07:57:18
mask tanımını global yap. Programın başında tanımla. C derleyicilerin çoğu rastgele yerde değişken veya sabit tanımlamaya izin vermez. Değişkeler veya sabitler blığun başında tanımlanmalıdır.
Sabitler genellikle blok içerisinde tanımlanmaz. Bu bir zorunluluk değildir. Blok içerisinde de tanımlanabilir ama genellikle kimse o şekilde kullanmaz.
örnek:
#include "STM32F4xx.h"
const uint32_t mask[]={0x00000000,0x00001000,0x00002000,0x00004000,0x00008000};
...
Hocam süpersiniz. Dediğiniz gibi yaptım ve sorunsuz çalışıyor. Yalnız birşey dikkatimi çekti
değişkenleri başta tanımlayınca programın işleme hızında bir değişiklik meydana geliyor, daha da yavaş çalışıyor.
Aksine çoğu zaman daha hızlı çalışır.
Yerel değişkenler stack katmanında tutulur. işleri bitince stack boşaltılır. tekrar ihtiyaç olunca tekrar buraya atılır. bu yüzden biraz yavaşlama olabilir.
Bu veriler işleme sokulurken işlemcinin dahili registerlerine atılır. işlemler burada yapılır. Registerler bellek alanlarına göre daha hızlıdır.
Eğer değerler registere atılıyor ve o register alanına tekrar ihtiyaç duyulmadığı için bu alan boşaltılmıyorsa , tespitiniz doğru olabilir. Ancak bu her zaman olabilecek bir durum değil. Döngüdeki işlemlerde işleme giren veri saysı çok az ise bazen olabilir.