22 Kasım 2015 Pazar

Dairesel Tampon (Circular Buffer) Kullanımı


Dairesel bir tampon veri için geçici tampon görevi yapan ayrılmış bir hafıza parçasıdır.  Özel bir şekilde düzenlenmiştir; gelen veri tamponu tampon tam dolana kadar doldurur ve daha sonra gelen veriler tekrar tamponu eski verilerin üzerine yazarak doldurmaya devam eder. Yeni veriler eski verilerin üzerine yazılmadan eski verileri kullanmak yazılımın görevidir.

Genelde bir dizi (array) ve bu dizi içerisinde bir işaretleyici (pointer) kullanarak dairesel tampon oluşturulur. Ancak işaretleyici dizine bağlı olmalı ve dizi dışında bir yeri göstermemelidir. Bu durum programın çökmesine neden olabilir. İşaretçi dizin dışında bir alana gelen veriyi yazar ise bu başka fonksiyonların kullandığı bir hafıza alanındaki değeri veya sistem hafıza alanında bir yerdeki veriyi bozacaktır. Bunun önlenmesi gerekmektedir.

Diyelim ki 2 üzeri N uzunluğunda bir dizi kullanmaya karar verdik. Burada ki N doğal bir sayıdır. “N” 3 (üç)’e eşit olsun. Biz 8 elemanlı bir dizi ile ilgilenmiş oluruz. Bu dizinin indeks değer aralığı 0 ile 7 arasında desimal veya “000” ile “111” arasında binary’dır.  Biz binary olarak yazılmış Ptr olarak isimlendirilmiş bir integer sayı alır isek ve sadece en alt üç bit’ini işaretleyicide kullanır isek bu üç bit noktası dizi içeresinde birer elemana karşılık gelecektir. Bu nedenle 8-bit bir işaretçinin sadece en alt 3(üç) bit’ini kullanıp diğer bit’leri AND işlemine tabi tutarak işaretçiyi hep dizi adresi içerisinde tutabiliriz. Böylece “111” son kullanılabilir indeks değeri olur.

Şimdi Ptr sayısını 0 (sıfır)’dan başlayarak 1(bir) artırıldığını ve Ptr’nin dizi içerisinde işaretçi olarak kullanıldığını düşünelim. Ptr’nin değeri maksimum 7(yedi) olacak şekilde AND işlemine tabi tutulur ise Ptr her artırıldığında dizinin eleman 0, eleman 1, eleman 2 ve eleman 7 ve tekrardan eleman 0’a döndüğü görülecektir.

Düşünün Ptr değeri 2(iki)’den başlayarak 1(bir) azaltılsın ve daha kolay anlayabilmemiz için 8-bit binary kullanalım. Azaltılan sayılar 00000010b den 00000001b ve daha sonra 00000000b olur. Devam edilir ise 11111111b, 11111110b ve 11111101b vb. devam eder. İşaretli integer sayıların 2(iki)’nin tamlayanı olarak yazıldığını hatırlayın. 11111111b işaretli tam sayı olarak -1’e denk gelir ve 11111110b ise -2’ye denk gelir. Ptr’nin en düşük 3(üç) bit’ini dizi sınırlarının içinde tekrar koruyalım ve 2, 1, 0 ,7, 6 gibi Ptr değeri almaya çalışalım. Yani 0(sıfır)’dan azaltma yaptığımızda 11111111b yerine 7 elemanına ulaşalım. Bu şekilde kullanılan bir dizi dairesel tampon olarak adlandırılır.

Hüner basit AND lojik fonksiyonuna dayanır ve 2 üzeri N elemanlı bir dairesel tampon için etkilidir. Diğer uzunluklarda işaretleyici için karmaşık bir sınırlayıcı gerekir ve en iyisi bu durumdan kaçınmaktır.

Biz bu uygulamada DAC sinyalinin üretilmesini geciktirmek için bir dairesel tampon kullandık. Bu programda donanım kurulumlarını önceki yazılarımızda anlattığımız için burada tekrar anlatılmayacaktır. Giriş sinyalini periyodik olarak örnekleyen bir ADC kullanılmıştır(gerçekte her iki ADC’de kurulur ve çalıştırılır, fakat sadece birinin sonucu kullanılmıştır). Örneklenen veriler “Result” ismi verilen bir dairesel tamponda kayıt edilmektedir. 2(iki) DAC’tan bir ADC sonucuna direkt bağlıdır. Diğer DAC, ADC sonucunun 100 örnek öncesini verecektir. Tam kod listesi Figür 1’de verilmiştir.

#include "stm32f4xx.h"

int Result[1024], Ptr = 0;

void main () {
// GPIO clock aktif etme, dijital pin tanımlamaları
RCC->AHB1ENR |= 0x00000001; // GPIOA clock aktif edilir.
RCC->AHB1ENR |= 0x00000010; // GPIOE clock aktif edilir.
GPIOE->MODER |= 0x00010000; // PE08 çıkış pin’i: zaman işareti
GPIOA->MODER |= 0x00001000; // PA06 çıkış pin’i: LED
// DAC kurulumu
RCC->APB1ENR |= 0x20000000; // DAC clock aktif et.
DAC->CR |= 0x00010001; // DAC kontrol register, her iki kanal açık
GPIOA->MODER |= 0x00000f00; // PA04, PA05 analog çıkışlar
// ADC kurulumu
RCC->APB2ENR |= 0x00000100; // ADC1 için clock
RCC->APB2ENR |= 0x00000200; // ADC2 için clock
ADC->CCR = 0x00000006; // sadece eş zamanlı mod
ADC1->CR2 = 0x00000001; // ADC1 açık
ADC1->SQR3 = 0x00000002; // PA02’yi giriş olarak kullan
ADC2->CR2 = 0x00000001; // ADC1 açık
ADC2->SQR3 = 0x00000003; // PA03’ü giriş olarak kullan
GPIOA->MODER |= 0x000000f0; // PA02, PA03 analog girişler
ADC1->CR2 |= 0x06000000; // TIM2, TRG0 SC kaynağını kullan
ADC1->CR2 |= 0x10000000; // harici SC aktif, yükselen kenar
ADC1->CR1 |= 0x00000020; // EOC için ADC kesmesi aktif
// NVIC kesmesi aktif
NVIC_EnableIRQ(ADC_IRQn); // ADC için NVIC kesmesi aktif
// Timer 2 kurulumu
RCC->APB1ENR |= 0x0001; // Timer 2 için clock aktif
TIM2->ARR = 8400; // otomatik geri yükleme değeri: 8400 == 100us
TIM2->CR2 |= 0x0020; // TRGO güncelleme olayı için TRG0 seçili(UE)
TIM2->CR1 |= 0x0001; // sayıcı aktif
// zaman gecikmesi
while (1) {
if (GPIOE->IDR & 0x0001) GPIOA->ODR |= 0x0040; // LED açık
else GPIOA->ODR &= ~0x0040; // else LED kapalı
};
}
// kesme fonksiyonu
void ADC_IRQHandler(void) //geçiş süresi yaklaşık 400ns!
{
GPIOE->ODR |= 0x0100; // PE08 high yap
Ptr = (Ptr + 1) & 1023; // işaretçiyi artır ve değeri limitle
Result[Ptr] = ADC1->DR; // ADC değerini dairesel tamponda sakla ve EOC bayrağını temizle
DAC->DHR12R1 = Result[Ptr]; // anlık sonucu DAC’a at.
DAC->DHR12R2 = Result[(Ptr - 100) & 1023]; // önceki sonucu DAC’a at.
GPIOE->ODR &= ~0x0100; // PE08 low yap
}

Şimdilik bu kadar arkadaşlar Gülen
Sorularınız ve önerileriniz için m.hakki.kaplan@gmail.com adresinden her zaman bana ulaşabilirsiniz.
Hakkı KAPLAN

20 Kasım 2015 Cuma


Kesmeler ve Timer TIM5

Daha önceki yazılarımızda kesme işlemini anlatmıştık (Kesmeler ve Portlar yazısı). Bu uygulamada Timer ve kesme işlemini kullanarak işlemcinin kesin olarak tanımlanmış zaman aralıklarında bazı yararlı işler yapması sağlanmıştır. Bu durumda işlemci port E’nin bit-3’ünde her kesme isteğinde 2 (iki) ardışık darbe sinyali oluşturur.


Mikrodenetleyicinin bu uygulamadaki davranışları basit bir şekilde Figür 1’de gösterilmiştir.

Figür 1. Periyodik kesme istekleri uygulamasında kullanılan basitleştirilmiş yapı

Bu uygulamada TIM5 Timer’ı kullanılmıştır. TIM2 Timer önceki yazılarımızda anlatılmıştı. TIM5 Timer kullanımına TIM2 Timer kullanımına benzer. TIM5 Timer 32-bit sayıcı ve sayma için kontrol ve giriş sinyali seçimi için ek donanıma sahiptir. TIM5 Timer mikrodenetleyici içerisindeki 84MHz frekansı ile sürülür. Bu sayıcı için çok hızlı bir clock’tur. Varsayılan olarak Multiplexer daha önce tanımlanan multiplexer’lar ile bu clock sayıcı girişine bağlanmıştır.

                TIM5 Timer önceden tanımlanmış değerden yukarı doğru sayar ve sıfır olduğunda reset’lenir. Sayaç değeri sıfıra döndüğünde güncelleme olayı çağırılır. Ön değer TIM5_ARR(Auto Reload Register) register’ı içerisinde tutulur. TIM5_ARR register değeri sıfır ise o zaman sayıcı 4.294.967.295’e kadar sayar.  TIM5_ARR register’ı 84000 olarak ayarlanır ve clock 84MHz kullanılarak figür 1’de görüldüğü gibi T zaman aralıklı sinyaller 1ms olacak şekilde üretilir. Bu güncelleme kesme isteği kullanılarak yapılabilir.

                Güncelleme olayları NVIC denetleyicisinin girişi için kesme istekleri konumlandırılır. TIM5 Timer’ından gelen kesme isteği için kanal aktif edilmelidir. Bu “NVIC_EnableIRQ” fonksiyonu çağırılarak NVIC denetleyici aktif edilerek yapılır.

                Kesme fonksiyonu kesme isteği ile çalıştırılır. Sinyal oluşturmak için işletilecek olan komutlar Kesme fonksiyonu içinde yapılmalıdır. Bu durumda 4 duruma ihtiyaç vardır; port E pin 8 high-low-high-low yapılır. Ek olarak güncelleme olayı TIM5_SR (Status Register) bit-0’ da tutulur. Bu bit aynı kesme isteğinin tekrarlayabilmesi için kesme fonksiyonu içerisinde temizlenmelidir.

Ve olaylar şu şekilde devam eder. TIM5 sayacı önceden belirlenmiş değere geldiğinde TIM5_ARR register’ında tekrar yüklenir, TIM5_CNT sayaç register’ının içeriği sıfıra döndüğünde olaylar tetiklenir ve ardından sayaç sıfırdan saymaya başlar. Tekrar yüklenen olaylar TIM5_SR register’ı bit-0’ına kayıt edilir ve eş zamanlı olarak TIM5 Timer üzerinden NVIC denetleyicisinde kesme isteğine izin verilir. Daha sonra NVIC denetleyici bu parça kesme isteğine cevap vermek için aktif edilir.  Normal program akışında işlemci bununla kesme işlemini yapmaya zorlanır. Ve kesme fonksiyonu çalıştırılır. Kesme fonksiyonu içerisinde işlemci port E pin bit-3’ünü 2 kez ardışık darbe sinyali oluşacak şekilde değiştirir ve kesme fonksiyonunun çalışmasını kabul etmek için güncelleme olayı kaydının tutulduğu TIM5_SR register’ının bit-0’ını temizler. Daha sonra işlemci normal programa devam eder.
Uygulama kodları figür 2’de verilmiştir. Program port A, port E ve TIM5 Timer clock’larının aktif edilmesi ile başlar. Port E’deki pin çıkış olarak ayarlanır darbe sinyalleri burada oluşacaktır ve port A’nı pin’i çıkış olarak ayarlanır. Burada bir adet LED bağlıdır. Butona basılı tutulduğunda LED yanmakta, buton bırakıldığın LED sönmektedir. Bu işlem normal program içerisinde yapılmaktadır.

#include "stm32f4xx.h"
int main () {
RCC->AHB1ENR |= 0x0010; // GPIOE ve GPIOA clock aktif edilir.
RCC->APB1ENR |= 0x00000008; // Timer 5 clock aktif edilir.
GPIOE->MODER |= 0x00010000; // port E pin’i çıkış olarak ayarlanır.
GPIOA->MODER |= 0x00001000; // LED’in bağlı olduğu pin çıkış olarak ayarlanır.
NVIC_EnableIRQ(TIM5_IRQn); // TIM5 kesmesi aktif edilir.
TIM5->ARR = 84000; // Auto Reload Register değeri => 1ms
TIM5->DIER |= 0x0001; // DMA/IRQ Enable Register – kesme güncellemesi aktif edilir.
TIM5->CR1 |= 0x0001; // sayma işlemi başlatılır
while (1) {
if (GPIOE->IDR & 0x01) GPIOA->ODR |= 0x0040; // butona basıldı ise LED’i yak.
else GPIOA->ODR &= ~0x0040; // LED’i söndür.
};
}

void TIM5_IRQHandler(void)
{
TIM5->SR &= ~TIM_SR_UIF; // TIM5 kesme bayrağını temizle
GPIOE->ODR |= 0x0100; // PE08 yukarı (high)
GPIOE->ODR &= ~0x0100; // PE08 aşağı (low)
GPIOE->ODR |= 0x0100; // PE08 yukarı (high)
GPIOE->ODR &= ~0x0100; // PE08 aşağı (low)
}
Figür 2. Port E bit-3 kesme isteği kurulumu

                Kesme denetleyicisi “NVIC_EnableIRQ” fonksiyonunun TIM5 timer tarafından çağrılmasıyla aktif edilir. Kurulum TIM5 timer ayarlarının yapılması ile sona erer. Geri yükleme değeri TIM5_ARR register’ı içerisine yazılır ve güncelleme olayı TIM5_DIER register’ının LS bit’inin ayarlanması ile kesme isteği tarafından konumlandırılır. Sonuç olarak timer TIM5_CR kontrol register’ının LS bit’ini set ederek çalıştırmak için aktif eder.
Ana döngü içerisinde buton kontrol edilir. Butona basılı tutulduğu sürece LED yanar durumda kalır.
Kesme fonksiyonu kesme vektör tablosunda ki isme göre isimlendirilir(TIM5_IRQHandler). Fonksiyon herhangi bir değişken içermez, tanımlamada “void” kelimesi kullanılır. Fonksiyon içerisinde ilk olarak güncelleme olayı bayrağı temizlenir ve daha sonra 2(iki) darbe sinyali üretilir.

Şimdilik bu kadar arkadaşlar Gülen
Sorularınız ve önerileriniz için m.hakki.kaplan@gmail.com adresinden her zaman bana ulaşabilirsiniz.
Hakkı KAPLAN

11 Kasım 2015 Çarşamba

STM32F407 Timer 2 ile Darbe Sayımı

Mikrodenetleyici 14 (on dört) tane Timer’a sahiptir. Diğer özellikleri figür 1’de aşağıda gösterilmiştir (DM00037051.pdf sayfa 29).  Her Timer grubunun detaylı özellikleri için RM0090 teknik dokümanına bakabilirsiniz. Biz bu uygulamamızda Timer2’yi mikrodenetleyicinin pin’ine uygulanan darbeleri saymak için kullanacağız. Sayılan darbeleri anlık LCD üzerinde göstereceğiz. 3 (üç) adet buton, saymayı başlatmak için, durdurmak için ve başa almak için kullanılacaktır. Timer2 (RM0090, bölüm 14)  giriş pin’i olarak geliştirme kartımızın (stm32f4discovery) kenarlarında bulunan bir pin’i kullanacaktır.


Figür 1. STM32F407 içerisinde bulunan Timer’ların diğer özellikleri

                Kullanılan 16-bit sayıcı TIM1 ve TIM8 Timer’ları, mikrodenetleyici içerisinde bulunan tüm Timer’lardan daha karmaşık Timer’lardır. TIM2 ve TIM5 Timer’ları TIM1/TIM8 ‘in 32-bit sürümleridir. Fakat daha az donanım içerirler ve bundan dolayı daha az seçenekleri vardır. TIM3 ve TIM4 Timer’ları TIM2/TIM5’in 16-bit sürümleridir. TIM9, TIM10 ve diğerleri TIM4 Timer’ın düşük sürümleridir.


                Tüm Timer’lar RM0090 teknik dokümanında Figür 65, sayfa 294’de blok diyagram olarak verilmiştir. Biz uygulamada TIM2 Timer’ını kullanacağız ve bu nedenle basitleştirilmiş TIM2 Timer blok diyagramı Figür 2’de gösterilmiştir (referans doküman RM0090, Figür 119, sayfa 419).

Figür 2. TIM2 ve TIM5 Timer’larının blok diyagramıdır. Sayıcılar yeşil kutular ile clock seçimi mavi kutular ile giriş sinyalleri şartlandırıcıları pembe kutular ile ve çıkış kontrolü gri kutular ile gösterilmiştir.

                CNT sayıcısının (Yeşil) içeriği TIM2_CNT register’ı içerisindedir ve bu register içerisinden okunarak anlık değer LCD üzerinde gösterilebilir. Bu register 32-bit genişliğindedir. Pre-scaler ve auto-reload register’larını biz bu uygulamada kullanmayacağız.

                Sayıcı sayma işlemi için clock sinyaline ihtiyaç duyar(CK_PSC). Clock sinyali figür 2’de üst kısımda mavi kutucuklar ile gösterilen parçalardan elde edilir. Sayma işlemi için birkaç sinyal ve clock sinyali seçimi için multiplexer’lar bulunur (bu uygulama için 2 tanesini kullanıyoruz). TIM2_CH2 Timer girişini, port A’nın PA01 pin’ini kullanacağız. Test kartımızda bulunan PA01 hattı tamponlanmıştır. Sinyal port A’nın PA01 pin’i üzerinden CK_PSC’ye gelmelidir.

1)      Bir Multiplexer mavi kutucuğun en sağında gizlenmiştir; bu Multiplexer MUX_CLK2 olarak isimlendirilir. Bu Multiplexer SMS (Slave Mode Selection) register’ı içerisinde bulunan 3 (üç) bit vasıtasıyla kontrol edilir. SMS’in 3 (üç) biti “External clock Mode 1” olarak ayarlanır ki sayaç clock’u için de TRGI (Trigger Input) hattı seçilir. Detaylı bilgi için RM0090 teknik dokümanının sayfa 458’indeki açıklamalara bakabilirsiniz.
2)      Bir Multiplexer tetikleme (Trigger) sinyalini kaynaklardan seçmek için kullanılır. Bu seçimin kontrolü için TS olarak isimlendirilen TIM2_SMCR register’ı içerisinde yer alan 3 (üç) bit kullanılır. Bu bit’ler “110” olarak ayarlandığında TI2FP2 (Timer girişi 2, Filtrelenmiş, öncelik olarak hat 2 seçilmiş) hattı seçilir. Bu sinyal pembe kutulardan çıkarak TIM2_CH2 girişindeki sinyal şartlandırıcısında sonuçlanır.
Clock sinyali kullanılmadan önce pembe kutulardaki bir modül içerisinde kullanıma uygun hale getirilir. Buraya TIM2_CH2 girişinden gelen sinyal filtrelenmiş ve doğru kenarda (yükselen veya düşen) sayma işlemi seçilebilir. Her iki ayarlamada TIM2_CCMR1 (Capture Compare Mode 1, bu register TIM2_CH1 ve TIM2_CH2 giriş/çıkışlarına hitap eder diğer 2 (iki) giriş/çıkış’lara da TIM2_CCMR2 hitap eder) register’ının üst yarısında yapılır. Bu ayarlara karşı gelen bit’ler CCS2 (Capture/Compare Selection 2) ve IC2F (Input Channel 2 Filtering) olarak isimlendirilirler. Detaylı bilgi için RM0090 teknik dokümanında sayfa 466’ya bakabilirsiniz.

                Yapılacak bir sonraki şey TIM2_CH2 girişini port A’nın PA01 pin’ine atamak olacaktır. Bunu yapmak için “alternatif fonksiyonlar” olarak adlandırılan seçenekleri port A register’larından ayarlamak zorundayız. Her port için 16(on altı) adet alternatif fonksiyon mevcuttur(RM0090, sayfa 190, Figür 14’e bakabilirsiniz). 16 olasılığın birini seçmek için 4-bit kullanılır. Komple bir port’un alternatif fonksiyonunu seçmek için; 16-bit port pin’leri ise 16x4 = 64 bit’e ihtiyaç duyulur. Bu 64 bit 32-bit’lik AFR[x] olarak adlandırılan register’lar içerisindedir. Burada gösterilen “x” 0 (sıfır) veya “1” değerini alabilir. PA00 pin’i için kullanılacak olan 4 bit AFR[0] register’ının düşük 4 bit’idir. AFR[0] register’ının bir sonraki 4 bit’i ise PA01 pin’ine karşılık gelir (detaylı bilgi için RM0090 teknik dokümanının 287 ve 288nci sayfalarına bakabilirsiniz). TIM1 ve TIM2 Timer’larının alternatif fonksiyonları “0001” yazılarak seçilidir ve biz PA01 için alternatif fonksiyonu değiştiriyoruz. AFR[0] 0x00000010 olmalıdır.

                İlk olarak doğru alternatif fonksiyon seçilidir, port A’nın bit’i için mod ayarının değiştirilmesiyle aktif edilir. Bir bit giriş(00), çıkış (01), alternatif fonksiyon(10) veya analog (11) olarak tanımlanabilir. Bit tanımlamaları GPIOA_MODER olarak adlandırılan register içerisinden yapılır, her port pin’i için 2 (iki) bit kullanılır. PA1 için mod ayarını GPIOA_MODER register’ının içerisine 0x00000008 ( 0000 0000 0000 0000 0000 0000 0000 1000 binary) yazarak yapılır.

                Daha sonra TIM2_CR1 register’ında bulunan CEN bit’inin “1” yapılması ile sayma işlemi başlatılır.

                Örnek program kodu figür 3’de gösterilmiştir. Program standart include dosyaların tanımlanması ile başlar. Port A, port E ve TIM2 Timer için clock aktif edilir. LCD kurulumu yapılır. Sonraki iki satırda port A bit 1 ve TIM1/TIM2 alternatif fonksiyonları aktif edilir. LCD’ye mesaj yazdırılır.

                Timer TIM2 ‘yi kurmak için 3 adım vardır;

1)      TIM2_CCMR1 register’ının 9..8 bit’lerine “01” yazarak TI2 için CH2 giriş kanalı olarak tanımlanır.
2)      TIM2_SMCR register’ının düşük 3 (üç) bit’ine “111” yazılarak External Clock Mode seçilir.
3)      TIM2_SMCR register’ının 6..4 bit’lerine “110” yazılarak Filtrelenmiş Timer girişi seçilir.

TM2_CR1 register’ının bit 0’ına “1” yazılarak sayma işlemi aktif edilir.

        Sonsuz döngü içerisinde sayıcının içeriği LCD ekrana biraz gecikme verilerek gönderilir. Butona basılıp basılmadığı kontrol edilir. Hangi butona basıldı ise o butona ait işlem gerçekleştirilir. Butonlara ait işlemler;
1)      Sayıcıyı reset’leme
2)      Sayıcıyı başlatma
3)      Sayıcıyı durdurmadır.

#include "stm32f4xx.h"
#include "LCD2x16.c"

void main (void){
RCC->AHB1ENR |= 0x01 + 0x10; // Port A  ve  E için clock
RCC->APB1ENR |= 0x01; // Timer2 için clock
LCD_init(); // LCD kurulumu
GPIOA->MODER |= 0x00000008; // tüm port pinleri giriş fakat: PA1 => AF mod
GPIOA->AFR[0] |= 0x00000010; // PA01 için AF1 seçilir-> TIM2_CH2
LCD_string("Timer2:", 0x00); // LCD ekrana mesaj gönder
TIM2->CCMR1 |= 0x0100; // kanal 2 olarak TI2 seçilir
TIM2->SMCR |= 0x0007; // Ext. clk mod 1
TIM2->SMCR |= 0x0060; // TI2FP2 olarak External clock
TIM2->CR1 |= 0x0001; // saymayı aktif hale getir
while (1)
 {
LCD_uInt32(TIM2->CNT,0x40,1); // sayma değerini LCD’ye gönder
for (int i = 0; i<100000; i++) {}; // zaman gecikmesi
if (GPIOE->IDR & 0x01) TIM2->CNT = 0; // sayıcıyı reset’le
if (GPIOE->IDR & 0x02) TIM2->CR1 |= 0x01; // sayıcıyı başlat
if (GPIOE->IDR & 0x04) TIM2->CR1 &= ~0x01; // sayıcıyı durdur
};
}

Şimdilik bu kadar arkadaşlar Gülen
Sorularınız ve önerileriniz için m.hakki.kaplan@gmail.com adresinden her zaman bana ulaşabilirsiniz.
Hakkı KAPLAN

9 Kasım 2015 Pazartesi


STM32F407 Analog Dijital Çeviriciler
Donanım – ADC Bloğu
STM32F407 mikrodenetleyicisinin içerisinde 3 (üç) adet 12-bit analog dijital çevirici (ADC) blok bulunur. Her ADC bloğun çevrim süresi yaklaşık 1us’dir. ADC yapılandırması çok çeşitlidir ve biz bu yazımızda basit olarak iki voltajın ölçümünü eş zamanlı olarak 2 (iki) ADC kullanarak gerçekleştireceğiz.

Basitleştirilmiş bir ADC blok şeması Figür 1’de verilmiştir. (Blok şema RM0090 teknik dokümanından Figür 44 sayfa 387’den alınmıştır.) ADC bloğunun komplesi 2 (iki)den fazla ADC, bazı özellikler ve ek olarak bazı ayarlar içermektedir.

                                                 Figür 1. ADC blok diyagramı

Figür 1’de resmin merkezinde ADC yer almaktadır. Besleme hattı VDDA ve VSSA, referans hatları olan VREF+ ve VREF- ve mikrodenetleyicinin tüm pin’lerini bu çalışma şekli desteklemektedir. Ek olarak, ADCCLK olarak adlandırılan gerekli olan clock sinyali mikrodenetleyici tarafında üretilmektedir. Analog giriş sinyalleri mikrodenetleyicinin ADCx_INxx olarak isimlendirilen pin’lerinden dış dünya ile bağlantı yapılır ve “Analog mux” olarak isimlendirilen bir multiplexer’a girerler. Dış dünyadan bağlanabilen 16 pin mevcuttur ve multiplexer’a ek olarak 3 (üç) girişe daha izin verilir. Bu bahsi geçen 3 (üç) giriş mikrodenetleyicinin sıcaklığını, besleme voltajını ve referans hattını ölçmek için kullanılmaktadır. ADC register’ları ile bu pin’ler seçilebilir. Bu seçim manuel olarak yapılmak isteniyor ise ADCx_SQR3 register’ı kullanılır.

                ADC çevrim sonucunu “Regular Data Register(ADCx_DR)” register’ının içerisine yazar. Burada kullanılan “x” Hangi ADC’nin kullanılacağını belirtir(1,2 veya 3 gibi).

                ADC bloğu donanımda önceden belirlenen 16 pin için ardışık çevrimlerin sayısı kadar ardışık çevrim modu uygulanmasına niyetlenildiğinde, istenen Multiplexer ayarları ADCx_SQR1 ve ADCx_SQR2 register’ları ayarlanmalıdır. Buna rağmen çevrim sonuçlarının tutulduğu bir register bulunur bu nedenle bir kullanıcı programı veya DMA donanımı sonraki çevrim bitmeden önce veri register’ındaki çevrim sonucunu taşımak zorundadır.

                Çevrim parametreleri ADCx_CR1 ve ADCx_CR2 register’ları içerisindeki bit’lerin set edilmesi ile kullanılır. ADCx_SMPR1 ve ADCx_SMPR2 register bit’leri vasıtası ile her çevrim sırasının örnek alma zamanı ayarlanır. Ayrıca, çevrim mikrodenetleyicinin diğer donanımlarından gelen çeşitli sinyaller ile veya yazılım ile başlatılabilir ve bu figür 1’de alt tarafında gösterilmiş olan Multiplexer ile seçilebilir. Detay için RM0090 teknik dokümanında Figür 1 bölüm 11’e bakabilirsiniz.

                Örnek bir program hazırladık ve Figür 2’de listeledik. Bu program ADC1 ve ADC2’yi PA2 ve PA3 pinleri üzerindeki voltajı ölçmek için kullanmıştır. ADC’lerin, Port A ve LCD ekranın kurulumları ile program başlar ve ardından sonsuz döngü içerisine girer. Sonsuz döngü içinde yazılım komut ile ölçümü başlatır ve biraz zaman gecikmesi ile çevrimin bitmesini bekler. Sonunda her iki ADC sonuçları LCD ekrana gönderilir.

                Bazı kurulumlar her ADC için ortaktır. Bu ortak bit’ler ADC ortak register’ı olan kontrol register (ADC_CRR) içerisinde yer alır. Diğer kurulumlar her ADC için ayrıdır ve eşleşen bit’ler her ADC için bölünmüş register’larda tutulurlar.

Demo program eş zamanlı modda çalışan 2 (iki) ADC kullanır. Her iki ADC bir yazılım komutuyla çevrime başlar. Bu seçenek “Regular simultaneous mode only” olarak isimlendirilir ve ADC ortak kontrol register (ADC_CCR, ortak register tüm 3 (üç) ADC içindir) düşük 5 (beş) bit’ine “00110” yazarak seçilir. Tüm ADC’ler için clock varsayılan değerde bırakılmıştır ve pre-scaling aktif edilmemiştir.

Giriş sinyali için örnek alma zamanı varsayılan değerinde ve ADC clock cycle en kısa olacak şekilde bırakılmıştır; örnekleme zamanı değiştirilmek istenir ise her ADC için ayrılmış olan ADCx_SMPR1 ve ADCx_SMPR2 register’ları içerisinde 3 (üç) bit olarak sıralanmış olan kısımlara yazmak gerekir.

 #include "stm32f4xx.h"
#include "LCD2x16.c"
/* giriş pinleri PA2 & PA3 -> analog olarak ayarlanmak zorundadır
  Port A  clock aktif olmalıdır */
int main () {
unsigned int j;
/*-----------------------------------------------------------------------------*/
/* Yazılım tetiklemeli, çift, eş zamanlı örnek alma                     */
/*-----------------------------------------------------------------------------*/
RCC->APB2ENR |= 0x00000100 + 0x00000200;    // ADC1 ve ADC2 clock aktif edilir.
RCC->AHB1ENR |= 0x00000001 + 0x00000002;    // GPIOA ve GPIOB clock aktif edilir.
ADC->CCR = 0x00000006;   // DMA kullanılmaz, Regular simultaneous mode only seçilir.
ADC1->CR2 = 0x00000001;    // Kontrol Register 2: ADC1 açık
ADC1->SQR3 = 0x00000002;  // regular SeQuence Register 3
ADC2->CR2 = 0x00000001;    // Kontrol Register 2: ADC2 açık
ADC2->SQR3 = 0x00000003;  // regular SeQuence Register 3
GPIOA->MODER |= 0x000000f0; // MODE Register -> PA2, PA3 pinleri analog
LCD_init();
LCD_string("ADC1=", 0);
LCD_string("ADC2=", 0x40);
while (1) {
ADC1->CR2 |= ADC_CR2_SWSTART;  // çevrim eş zamanlı başlatılır.
for (j = 0; j<100; j++){};                           // çevrimin bitmesi beklenir.
LCD_Int16((int)ADC1->DR, 0x06, 1);    // sonuç LCD ekranın 1nci satırına yazılır
LCD_Int16((int)ADC2->DR, 0x46, 1);    // sonuç LCD ekranın 2nci satırına yazılır
            };
}



5 Kasım 2015 Perşembe

STMF4 Dijital Analog Çeviriciler


STM32F4 Dijital Analog Çeviriciler

2(iki) adet 12-bit Dijital Analog çevirici (DAC) mevcuttur. Prensip blok diyagram Figür 1’de gösterilmiştir.(Kaynak Fig.48, RM0090, sayfa 251).

Figür 1. Tek bir DAC için blok diyagram

        Aktif DAC aşağıdaki kısımda gösterilmiştir. Mikrodenetleyicinin sol tarafına gelen tüm pinler referans sinyali ve güç kaynağı hatları ile bu çalışma desteklenir. DAC’ın çıkışı sağ taraftaki pindir. Kullanıcı programda analog sinyale çevrilecek olan veriyi DAC içinde bulunan DHR register’a yazar. Buradan veri DOR isimli register içerisine gönderilir ve aynı anda DAC ile analog sinyale çevrilir.

DAC_DHR12R1 DAC kanal 1 için sağ tarafta hizalandırılmış 12-bit register
DAC_DHR12L1 DAC kanal 1 için sol tarafa hizalandırılmış 12-bit register
DAC_DHR8R1 DAC kanal 1 sağ hizalandırılmış 8-bit register
DAC_DHR12R2 DAC kanal 2 sağ hizalandırılmış 12-bit register’dır. Bu register yapları DHR register’da yer alırlar.

        DHR register içerisine gönderilen veri otomatik olarak DOR register içerisine taşınır. Fakat bu yazılım aracılığıyla (SWTRIGx), donanım aracılığı ile (TIMx_TRGO) veya harici sinyaller ile (EXTI_9) Figür 1’de DHR register’ın üst tarafında yer alan Multiplexer’ın kontrol register’ı olan TSELx[2:0] ile tanımlanmaktadır. DHR register’ın her yarımı bir DAC için kullanılır. Böyle bir organizasyon seçilen iki DAC üzerinden sinyalleri eş zamanlı bir şekilde dışarı verir. Direkt hafıza erişimi (DMA Direct Memory Access) kullanılarak veri DAC’a gönderilebilir.

        Ek olarak donanımda “Control logicx box” adı verilen gürültü üretebilen veya üçgen dalga sinyali üretebilen bir yapı vardır.

        İki DAC içinde DAC-CR(DAC kontrol register), DAC_SWTRIGR (DAC software Trigger register) ve DAC_SR(DAC durum register’ı) bit’ler tanımlanmıştır. Detaylı bilgi için RM0090 dokümanının bölüm 12’sine bakabilirsiniz.

        Örnek programımızda 2(iki) DAC kullanılarak farklı testere dişi (saw-tooth) sinyaller oluşturulmuştur. Başlangıçta her iki DAC’ın kurulumu yapılır ve sonsuz döngüye girilir. Döngü içerisinde testere-dişi sinyali için veriler hesaplanır ve DAC_DHR12R1 ve DAC_DHR12R2 register’larına yazılır.

#include "stm32f4xx.h"
/*
PA4 & PA5 çıkışları -> bu pinler analog olmak zorundadır!
GPIOA->MODER |= 0x00000f00;
*/
int main () {
     unsigned int j;
     RCC->APB1ENR |= 0x20000000;                // DAC clock aktif edilir.
     DAC->CR |= 0x00010001;                            // DAC kontrol register her iki kanal da açık
     GPIOA->MODER |= 0x00000f00;                // MODE PortA, PA4 & PA5 analog çıkış yapılır
     while (1) {                                                      // sonsuz döngü
     DAC->DHR12R1 = j & 0xfff;                       // yükselen rampa
     DAC->DHR12R2 = 0xfff - (j & 0xfff);         // düşen rampa
     j = (j + 1) & 0x0fff;                                        // yeni değer hesapla
     };

};

Şimdilik bu kadar arkadaşlar Gülen
Sorularınız ve önerileriniz için m.hakki.kaplan@gmail.com adresinden her zaman bana ulaşabilirsiniz.
Hakkı KAPLAN

3 Kasım 2015 Salı

UBUNTU 15.04 İŞLETİM SİSTEMİNE STM32 İÇİN ECLIPSE KEPLER KURULUMU
İndirilmesi Gereken Dosyalar

eclipse-cpp-kepler-SR1-linux-gtk.tar.gz

gcc-arm-none-eabi-4_8-2013q4-20131204-linux.tar.bz2

stlink-master.zip

openocd-0.9.0.tar.bz2

Yukarıda linkleri verilen dosyaları bilgisayarınıza indirdikten sonra gcc-arm kurulumu ile başlayalım.
  •  Home klasörü içerisine “ARMToolchains” isimli yeni bir klasör oluşturun.
  • “gcc-arm-none-eabi-4_8-2013q4-20131204-linux.tar.bz2” dosyasını bulunduğu klasör içine çıkarın.
  • Çıkarmış olduğunuz klasörü kes-yapıştır ile “ARMToolchains” isimli klasöre taşıyın.
  • Taşıdığınız “gcc-arm-none-eabi-4_8-2013q4” klasörünün içine girin.
  • Girmiş olduğunuz klasör içerisinde “bin” isimli klasörün de içine girin.
  • Klasör içerisinde boş bir alana gelerek farenizin sağ tuşuna basın. Açılan menüden Terminali açın.
  • Terminale “ls” komutunu yazın ve enter tuşuna basın. “bin” klasörü içerisindeki dosyalar ekranda listelenecektir. Listelenen dosya isimleri içerisinde “arm-none-eabi-gcc” var mı kontrol edin.
  • Terminal komut satırına “arm-none-eabi-gcc” yazıp enter tuşuna basın.
  • Benim işletim sistemim Türkçe olduğu için “ arm-none-eabi-gcc” programı şu anda kurulu değil. Kurulumunu şunu yazarak yapabilirsiniz:  sudo apt-get install gcc-arm-none-eabi mesajı gelecektir.
  • Terminal komut satırına “pwd” yazıp enter tuşuna basın. Bu komut ile bulunduğunuz klasörün sistemdeki yolu verilecektir. “/home/hmklp/ARMToolchains/gcc-arm-none-eabi-4_8-2013q4/bin”
  • Gelen bu yolu fare yardımı ile seçip kopyalayın.
  • Terminal komut satırına “echo  PATH=$PATH:” yazın ve kopyalamış olduğunuz yolu buraya fare yardımı ile yapıştırın ( CTRL+V kullanmayın!).
  • “echo PATH=$PATH:/home/hmklp/ARMToolchains/gcc-arm-none-eabi-4_8-2013q4/bin” ve enter’a basın. Ekranda aşağıdakine benzer bir mesaj gelecektir.
  • “PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/home/hmklp/ARMToolchains/gcc-arm-none-eabi-4_8-2013q4/bin” mesajın sonunda görüldüğü gibi PATH kısmına eklentimizi yapmış olduk.
  • Terminal komut satırına “ echo PATH=$PATH:/home/hmklp/ARMToolchains/gcc-arm-none-eabi-4_8-2013q4/bin  >> /home/hmklp/.bashrc” yazın ve enter tuşuna basın.
  • Terminal komut satırına “source $HOME/.bashrc” yazıp enter tuşuna basın.
  • Terminal komut satırına “arm-none-eabi-gcc” yazıp enter tuşuna basın. Aşağıdakine benzer bir mesaj alacaksınız. “arm-none-eabi-gcc:  fatal error; no input files compilation terminated.”
  • Terminal komut satırına “arm-none-eabi-gcc –version” yazıp enter’a basın. Kurmuş olduğumuz gcc derleyicisinin sürümü görüntülenecektir.Arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 4.8.3 20131129 (release) [ARM/embedded-4_8-branch revision 201541]Copyright © 20133 Free Software Foundation, Inc.This is free software; see the source for copying  conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  • Şimdi açmış olduğumuz terminali “exit” komutu ile kapatalım.

Eclipse Kepler kurulumunu yapalım.

  •  Daha önce indirmiş olduğumuz “eclipse-cpp-kepler-SR1-linux-gtk.tar.gz”  sıkıştırılmış dosyayı bulunduğu klasör içerisine açın.
  • “eclipse” isimli bir klasör oluşacaktır. Bu klasörün adını “eclipseARM” olarak değiştirin.
  • Bu klasörü kes-yapıştır ile “ARMToolchains” klasörü içerisine taşıyın.
  • “eclipseARM” klasörü içerisine girin ve “eclipse” dosyasını çift tıklayarak Eclipse programını çalıştırın.
  • Program açılışında projelerinizin nereye kayıt edileceğini belirten “Workspace” kısmına “/home/hmklp/workspaceSTM32” yazın veya kendi istediğiniz bir konumu yazabilirsiniz. “Ok” butonuna basın ve program açılışını tamamlayın.
  • Program açıldıktan sonra “Welcome” sekmesini kapatın.
  • “Help” menüsüne girin. Menüden “Install New Software..” seçeneğini tıklayın.
  • Açılan menüde bulunan “Add..” butonuna basarak “Add Repository” menüsünü açın.
  • Açılan menüde “Name “ kısmına “GNU ARM eclipse” yazın.
  • “Location” kısmına http://gnuarmeclipse.sourceforge.net/updates internet linkini yazın. “Ok” butonuna basarak işlemi başlatın.
  • Açılan menüde bir müddet “Pending..” mesajı görünür. Daha sonra “GNU ARM C/C++ Cross Development Tools” yazısı gelir. Bu yazının yanındaki kutucuğu fare yardımıyla işaretleyin ve “Next “ butonuna basın.
  • Açılan menüde tekrar “Next “ butonuna basın. “Review License” menüsü açılacaktır.
  • “Review License” menüsünde “I accept the terms of the license agreement” seçeneğini fare yardımı ile seçin ve “Finish” butonuna basarak program yükleme işlemini başlatın.
  • Belirli bir yükleme sonunda “Security Warning” mesaj kutusu belirecektir. Bu mesaj kutusuna “Ok” butonuna basarak kurulum işlemine devam edin.
  • Kurulum sonunda “You will need to restart Eclipse for the changes to take effect. Would you like to restart now?” mesaj kutusu açılır. Mesajda kısaca ”Eclipse’de yapılan değişikliklerin etkili olabilmesi için şimdi Eclipse’i yeniden başlatmak ister misiniz?”  Diye sorulmaktadır. “Yes” butonuna basarak Eclipse’i yeniden başlatın.


Şimdi Eclipse’de yeni bir proje oluşturalım.

  •  Açık olan Eclipse programında “File” menüsünden “New” kısmından “C Project” kısmını seçin.
  • Açılan menüden “Executable” altında yer alan listeden “STM32F4xx C/C++ Project”i seçin.
  • “Project Name” kısmına blinkyLED yazın ve “Next” butonuna basın.
  • Açılan menüde işlemci ayarları ilgili seçenekler gelecektir. Tekrar “Next” butonuna basın.
  • Açılan menüde “Folder setting” kısmı gelecektir. Tekrar “Next” butonuna basın.
  • Açılan menüde “Select Configuration” menüsü gelecektir.
  • Açılan menüde “Cross GNU ARM Toolchain” kısmı vardır. Burada daha önce kurulumunu yaptığımız GNU arm-none-eabi-gcc derleyicisinin yolunu tanımlamamız gerekiyor.
  • Bu menüde “Toolchain path:” kısmı boş olarak gelecektir. Bu kutucuğun yanında bulunan “Browse..” butonuna basın.
  • Açılan menüde daha önce oluşturduğumuz “ARMToolchains” klasörünü açın. Daha sonra “gcc-arm-none-eabi-4_8-2013q4” klasörünü açın. Bu klasör içinde yer alan “bin” isimli klasörü açın. “Ok” butonuna basarak menüyü kapatın. “Toolchain path:” kısmında bu son girdiğiniz klasöre kadar olan yol adresi görülecektir. “/home/hmklp/ARMToolchains/bin”
  • “Finish” butonuna basarak projemizi oluşturalım.
  • Projemiz oluştuktan sonra ekranın sol alt tarafında “C/C++ Indexer (4%) “ gibi bir ifade çıkar. Bu ifadenin 100% olup tamamlanmasını bekleyin.
  • Ekranın üst sol kısmında bulunan çekiç simgesine basarak projeyi derleyiniz.
  • Derleme bittiğinde Alt kısımda yer alan “Console” isimli kısımda aşağıdakine benzer bir mesaj çıkacaktır.

       Invoking: Cross AM GNU Print Size

             arm-none-eabi-size  --format = berkley “blinkyLED.elf”
             text            data            bss               dec       hex          filename
            8681          176             420             9277      243d        blinkyLED.elf
            Finished building:  blinkyLED.siz
            19:33:03 Build Finished (took 6s.961ms)

  • Bu mesaj programın başarı ile derlendiğini ifade eder.
  • Şimdi ekranın üst kısmındaki “Window” menüsü altından “Preferences” kısmını tıklayın.
  • Açılan menüden “General” yazısının yanında bulunan ok işaretine basarak alt menülerini görünür hale getirin.
  • Açılan alt menüden “Workspace” seçeneğini tıklayın. Yan menüde çıkan seçeneklerden aşağıdaki kısımları işaretli değiller ise işaretleyin.
“Build automatically”
“Refresh on Access”
“Save automatically before build”
“Prompt”
“Default (UTF-8)”
“Default (Unix)”
Bu listenin dışındakiler seçili olmamalıdır.
  • “Apply” butonuna basın ve ardından “Ok” butonuna basarak menüyü kapatın.
Stlink-master kurulumunu yapalım.
  •  Daha önce indirdiğimiz “stlink-master.zip” dosyasını bulunduğu dizine çıkartın.
  • Dizine çıkan “stlink-master” isimli klasörü daha önce oluşturmuş olduğumuz “ARMToolchains” klasörü içerisine kes-yapıştır ile taşıyın.
  • Kuruluma başlamadan önce terminali açın.
  • Terminal komut satırına “sudo apt-get updates” yazarak enter tuşuna basın.
  • Terminal komut satırına “sudo apt-get install build-essential” yazarak enter tuşuna basın.
  • Terminal komut satırına “sudo apt-get install automake” yazarak enter tuşuna basın.
  • Terminal komut satırına “sudo apt-get install checkinstall” yazarak enter tuşuna basın.
  •  Terminal komut satırına “sudo apt-get install autoconf” yazarak enter tuşuna basın.
  •  Terminal komut satırına “sudo apt-get install qt4-qmake libqt4-dev libqt4-gui libqt4-xml qt4-designer qtcreator libusb-0.1-4 libusb-1.0-0-dev” yazarak enter tuşuna basın ve kurulumları tamamlayın.
  • Terminali kapatın.
  • “stlink-master”  klasörünün içinde yer alan “README” dosyasını açın.
  • Dosya içerisinde “COMPILING” başlığı altında bulunan kısmı bulun. Bu kısımdaki komutları teker teker işletmemiz gerekecek.
$ ./autogen.sh
$ ./configure
$ make
  • Şimdi “stlink-master” klasörü içerisinde terminali açın.
  • Terminal komut satırına “./autogen.sh” yazarak enter tuşuna basın.
  • Terminal komut satırına “./configure” yazarak enter tuşuna basın.
  • Terminal komut satırına “make “yazarak enter tuşuna basın.
  • Make işlemi bitiğinde terminal komut satırına “sudo make install” yazıp enter tuşuna basın.
  • Kurulum bittiğinde terminal komut satırına “whereis st-flash” yazarak enter tuşuna basın. Kurulum sonrasında “st-flash” isminde yürütülebilir bir dosya oluşmuştur. Bu dosyanın yolunu almak için bu komutu kullandık. Bu komut cevabı olarak aşağıdakine benzer bir mesaj gelecektir.
“st-flash: /usr/local/bin/st-flash”
  • Mesajdaki adres kısmını kopyalayın.
  • Eclipse programına geri dönün.
  • Eclipse programının “Run” menüsünden “External Tools” kısmını açın.
  • Bu kısımdan “External Tools Configurations” menüsünü açın.
  • Açılan menünün sol üst tarafında bulunan “Program” yazısını fare yardımı ile tek tıklayın ve seçin.
  •  Üst taraftaki dosya işaretine tıklayarak “Program” yazısının altına “New configuration” isimli bir seçenek oluşturun.
  •  “New configuration” yazısının üzerini fare yardımı ile tek tıklayın ve seçin.
  •  Sol tarafta açılan kısımda bulunan “Name” isimli kısmın yanındaki “New configuration” yazısını silin ve yerine “st-linkv2” yazın.
  • “Main” sekmesinde bulunan “Location” kısmına daha önce terminal ekranından kopyaladığımız st-flash dosyasının yolunu yapıştırın.
  • “Working Directory” kısmının sağ tarafında bulunan “Variables..” butonun tıklayın.
  •  Açılan menüden “project_loc” seçeneğini seçip “Ok” butonuna basıp açık olan menüden çıkın. “Working Directory” kısmında “${Project_loc} yazısı çıkacaktır. Bu yazının yanına “/Release” yazın.
  • “Arguments:” kısmına “write” yazın ve bir boşluk bırakın.
  • Sağ tarafta bulunan “Variables..” butonuna basarak açılan menüden “project_name” i seçin.
  • “Ok” butonuna basarak açılmış olan menüyü kapatın.
  • “Arguments:” kısmında “write ${project_name}” yazısı oluşacaktır.
  • Bu yazının yanına “.bin 0x08000000” ekleyerek şu duruma getirin;
“write ${project_name}.bin 0x08000000”
  • “Apply” butonuna basın.
  •  “Run” butonuna basın.
  •  Eclipse ekranında bulunan “Project “ menüsünden “Properties”  kısmını açın. Açılan menüden “C/C++ Build” kısmının altından “Setting”i seçin. Sağ tarafta açılan menüden “Cross ARM GNU Create Flash Image” isminin altındaki “General” kısmını seçin.
  • Sağ tarafta açılan menüden “Output file format (-O)” kısmının yanındaki kutucuktan “Raw binary” kısmını seçin.
  • “Apply” butonuna ve ardından “Ok” butonuna basarak menüden çıkın.
  • Programı derleyin.
  • “Run” menüsü altından “External Tools” kısmından “External Tools Configurations” kısmını açın.
  • “Run” butonuna basarak derlenmiş olan programı STM32F4Discovery kartına gönderin. Kart üzerindeki LED’in yanıp söndüğünü göreceksiniz.


OpenOCD Kurulumunu yapalım.

  • Eclipse’i açın.
  • “File” menüsünden “new” kısmından “C Project”i seçin.
  •  Proje ismi olarak “debugTEST” yazın.
  • “Project type” kısmından “STM32F4XX C/C++ Project” seçeneği seçin ve projeyi oluşturun.
  • “Project Explorer” kısmında oluşturduğumuz projenin altında “src” kısmını tıklayın ve “main.c” dosyasını çift tıklayarak açın.
  • “main.c” içeriğini silin ve aşağıda verilen program kodunu yazın.


#include “stm32fxx.h”
int main {
               while(1) {
                               *((uint32_t volatile*)(0x40023810))=0x08;
                               *((uint32_t volatile*)(0x40023810))=0x00;
                               *((uint32_t volatile*)(0x40023830))=0x08;
                               *((uint32_t volatile*)(0x40020C00))=0x55000000;
                               *((uint32_t volatile*)(0x40020C18))=0xF000;
                               }
}
  • Daha sonra “Release” olarak  derleyin.
  • “Project” menüsünden “Properties” menüsünü açın.
  • Buradan “C/C++ Build” kısmını açın.
  • Açılan kısmın altında bulunan “setting” kısmını seçin.
  •  Sol tarafta açılan menüden “Cross ARM GNU Create Flash Image” kısmının altında bulunan “General” kısmına tıklayın.
  • Sol üst tarafta açılan kısmında yer alan “Output file format (-O)” kısmının yan tarafındaki listeden “Raw binary” seçeneğini seçin ve “Run” ile menüden çıkın.
  • Programı “Debug” olarak derleyin.
  •  Daha önce indirdiğimiz “openocd-0.9.0” dosyasını bulunduğu dizine açın.
  •   Açılan “openocd-0.9.0” klasörünü kes-yapıştır yöntemiyle daha önce oluşturduğumuz “ARMToolchains” klasörüne taşıyın.
  •  “openocd-0.9.0” klasörünün içerisinde terminal programını çalıştırın.
  •  Terminal komut satırına “sudo apt-get install libusb-dev libusb-1.0.0-dev libftdi-dev libftdi1” yazarak enter tuşuna basın.
  • Gerekli kurulumların bitmesini bekleyin.
  •   Terminal komut satırına “./configure --enable-verbose  --enable-verbose-jtag-io --enable-parport --enable-jlink --enable-ulink --enable-stink --enable-ti-icdi --enable-ftdi” yazın ve enter tuşuna basın.
  • Kurulumun bitmesinin ardından terminal komut satırına “make” yazarak enter tuşuna basın.
  • Make işleminin bitmesini bekleyin. Biraz uzun sürebilir Gülen
  • Terminal komut satırına “sudo make install” yazın ve enter tuşuna basın.
  • Kurulumun bitmesinin ardından terminal komut satırına “whereis openocd” yazarak enter tuşuna basın. Mesaj olarak openocd’nin sistemdeki yolu verilecektir. Bu yolu kopyalayın.
  •  Terminal komut satırına “openocd -f tcl/board/stm32f4discovery.cfg” yazın ve enter tuşuna basın.  Terminalde gelen mesajların sonunda mesaj olarak;
“Info: stm32f4x.cpu; hardware has 6 breakpoints, 4 watchpoints” geldi ise openocd başarı ile kurulmuş ve stm32f4discovery kartına st-link üzerinden bağlantı kurulmuş demektir. Bağlantıdan çıkmak için “Ctrl+c” tuşlarına basın.
  • Eclipse programını açın.
  •  “Run” menüsünden “External Tools” kısmından “External Tools Configurations..” menüsüne girin.
  • “Program” kısmının altında yeni bir configuration dosyası oluşturun.
  • Oluşturmuş olduğunuz “New configuration” isimli kısmın ismini “openocd” olarak değiştirin.
  • “Arguments” kısmına “-f tcl/board/stm32f4discovery.cfg” yazın.
  • “Location” kısmına “daha önceki adımlarda “whereis openocd” ile alıp kopyaladığımız yolu yapıştırın.
  •  Terminal komut satırına “pwd” yazın ve enter’a basın. Gelen mesajı kopyalayın.
  •  “Arguments” kısmında yazdığımız yazıda “-f” kısmının önüne bu kopyaladığımız yolu yapıştırın ve yolun sonuna “/” koyun. Şu şekilde olacaktır;
“-f /home/hmklp/ARMToolchains/openocd-0.9.0/tcl/board/stm32f4discovery.cfg”
  • “Apply” butonuna ve ardından “Run” butonuna basarak openocd’yi çalıştırın.
  • Eclipse ekranında yer alan “Console” kısmında bazı mesajlar gelecektir. Mesaj sonunda;
“Info: stm32f4x.cpu: hardware has 6 breakpoints, 4 watchpoints” mesajı görüntülenecektir. Bu mesaj openocd’nin çalıştığını gösterir. Eclipse artık st-link üzerinden openocd kontrolünde stm32f4discovery kartına bağlanmıştır.
  •  Eclipse ekranından “Run” menüsü altından “Debug  Configuraitons..” menüsünü açalım.
  • Açılan menünün sol tarafındaki listeden “GDB Hardware Debugging” kısmını seçin ve sol üst tarafta dosya işaretine basın.
  • Sol tarafta “debugTESTDebug” isimli bir kısım oluşacaktır.
  • Bu oluşan kısımdan “Search Project” butonuna basın.
  • Açılan menüden “debugTEST.elf” seçeneğini seçin ve “Ok” butonuna basarak menüyü  kapatın.
  • “Apply” butonunun yan tarafında bulunan “Using GDB (DSF) Hardware Debugging Launcher – Select other…” yazısının link olarak gösterilen “Select other” kısmına tıklayın.
  • “Select Preferred Launcer” menüsü açılacaktır.
  • Açılan menüden “Use configuration specific setting” kısmını işaretleyin.
  • “Launcher” kısmında bulunan listeden “GDB Hardware Debugging Launcher” işaretleyin ve “Ok” tuşuna basarak menüden çıkın.
  • “Debugger” sekmesini açın.
  • Terminali açın. Komut satırına “which arm-none-eabi-gdb” yazın ve enter’a basın.
  • Çıkan yolu kopyalayın. “/home/hmklp/ARMToolchains/gcc-arm-none-eabi-4_8-2013q4/bin/arm-none-eabi-gdb”
  • “Debugger” sekmesinde yer alan “GDB Command” kısmına kopyaladığınız yolu yapıştırın.
  • Aynı kısımda bulunan “Remote Target” kısmından “Use remote target” seçeneğini işaretleyin.
  • “JTAG Device” kısmından “Generic TCP/IP” yi seçin.
  •  “Port number:” kısmına “3333” yazın.
  •  “Setup” sekmesini açın.
  •  “Halt” yazısının altında bulunan kutuya “monitor reset halt” yazın.
  • “Common” sekmesini açın.
  • “Display favorites” kısmında bulunan “Debug” seçeneğini işaretleyin.
  • “Apply” butonuna basın ve ardından “Debug” butonuna basın.
  • Gelen mesaj kutusunun “Ok” tuşuna basarak devam edin.

Böylece openocd kurulumunu tamamlamış olduk. Şimdi debug esnasında işlemcimizin tüm register’larını görebilmemiz ve değiştirebilmemize yarayacak bir eklenti ekleyelim.

  • Eclipse programımızı açalım.
  • “Help” menüsünden “Install New Software” i açın.
  •  “Add” butonuna basın.
  • Açılan menüde “Name:” kısmına “embsysregview” yazın.
  • “Location:” kısmına http://embsysview.sourceforge.net/update-beta yazın ve “Ok” butonuna basın.
  • “Next” butonuna basın.
  • Tekrar “Next” butonuna basın.
  • Gelen menüde “I accept the terms of the license agreement” kısmını işaretleyin ve “Finish” butonuna basın.
  • Kurulum başlayacaktır. Bir süre sonra gelen mesaj kutusunda “Ok” butonuna basarak kuruluma devam edin.
  • Kurulumun bitiminde Eclipse’in yeniden başlatılması için onay isteyen bir mesaj kutusu gelecektir. “Ok” butonuna basın ve Eclipse’i yeniden başlatın.
  • Eclipse programı açıldıktan sonra yazdığınız programı “Debug” olarak derleyin.
  • Openocd’yi “Run” menüsünden “External Tools” kısmından “openocd” kısmına tıklayarak çalıştırın.
  • “Run” menüsü altındaki “Debug Configurations” kısmını açın.
  • “Debug” butonuna basarak programınızı debug modunda başlatın.
  •  Window” menüsü altından “Show view” kısmına tıklayın.
  • Açılan listeden “Other” kısmını tıklayın.
  • Açılan menüden “Debug” kalsörüne tıklayın.
  • Burada “Embsys Registers” seçeneğini seçin.
  • Eclipse ekranında “Embsys Registers” adında bir bölüm oluşacaktır.
  • Bu oluşan kısımda “ERROR: Please select a chip using the preference page” yazısının yanındaki işarete tıklayın.
  • Açılan menüden
“Architecture” kısmından “cortex-m4”ü

“Vendor” kısmından “STMicro”yu

“Chip” kısmından “stm32f40x”i

“Board”  kısmından “STM32F+DISCOVERY”i seçin.

Artık debug yaparken işlemcinin tüm register’larını görebilir ve hatta değiştirebilirsiniz.


Şimdilik bu kadar arkadaşlar Gülen
Sorularınız ve önerileriniz için m.hakki.kaplan@gmail.com adresinden her zaman bana ulaşabilirsiniz.
Hakkı KAPLAN