STM32F4 Port Config header dosyası

Başlatan Klein, 15 Ocak 2012, 18:52:59

Klein

STM32F4 kiti ile uğraşırken, konfigürasyonlar için her seferinde rehberi aşıp sayfayı aramaktan ve bit saymaktan helak oldum.
Port konfigürasyonu ve kullanımını kolaylaştırmak için bir header dosyası yazdım. Şimdilik sadece portlar var. Zaman içinde diğer registerleri de ekleyeceğim.
Konfigürasyonda hız çok önemli değil. Ama portları program içinde kullanırken hız önemli olabilir. Bu yüzden şunlara dikkat edin.

PD->ODR |= 0x0000001  ile PD->ODR.pin.p0 = 1 arasında üretilen kod açısından fark yok. Keil aynı kodları üretiyor.
PD->ODR &= ~0x000001 ile PD->ODR.pin.po = 0 arasında fark yok.

Ama portun bir bitini toggle decekseniz
PD->ODR ^= 0x0000001 e göre PD->ODR.pin.p0 = ! PD->ODR.pin.p0 şeklinde kullanmak biraz daha fazla kod üretilmesine neden oluyor.

stm32f4xx_regs.h dosyası
#include "STM32F4xx.h" 

enum PORTMODES {PORT_INPUT, PORT_OUTPUT, PORT_ALTERNATE_FUNC, PORT_ANALOG};
enum PORTOUTTYPES {PORT_PUSH_PULL,	PORT_OPEN_DRAIN};
enum PORTSPEEDS {PORT_LOW_SPEED, PORT_MED_SPEED, PORT_FAST_SPEED, PORT_HI_SPEED};
enum PORTPUPDSETS {PORT_NOPU_NOPD, PORT_PULL_UP, PORT_PULL_DN, PORT_UNDEFINED};
enum PORTCFGLOCKS {PORT_CFGLOCK_PASSIVE,PORT_CFGLOCK_ACTIVE};

#define PA               ((PORTIO_TypeDef *) GPIOA_BASE)
#define PB               ((PORTIO_TypeDef *) GPIOB_BASE)
#define PC               ((PORTIO_TypeDef *) GPIOC_BASE)
#define PD               ((PORTIO_TypeDef *) GPIOD_BASE)
#define PE               ((PORTIO_TypeDef *) GPIOE_BASE)
#define PF               ((PORTIO_TypeDef *) GPIOF_BASE)
#define PG               ((PORTIO_TypeDef *) GPIOG_BASE)
#define PH               ((PORTIO_TypeDef *) GPIOH_BASE)
#define PI               ((PORTIO_TypeDef *) GPIOI_BASE)

typedef union
{
  __IO uint16_t all;
  	struct {
  		__IO uint16_t p0:1;	
  		__IO uint16_t p1:1;	
  		__IO uint16_t p2:1;	
  		__IO uint16_t p3:1;	
  		__IO uint16_t p4:1;	
  		__IO uint16_t p5:1;	
  		__IO uint16_t p6:1;	
  		__IO uint16_t p7:1;	
  		__IO uint16_t p8:1;	
  		__IO uint16_t p9:1;	
  		__IO uint16_t p10:1;	
  		__IO uint16_t p11:1;	
  		__IO uint16_t p12:1;	
  		__IO uint16_t p13:1;	
  		__IO uint16_t p14:1;	
  		__IO uint16_t p15:1;	
	}pin;
}T_uint16_BitType;

typedef union
{
  __IO uint32_t all;
  	struct {
  		__IO uint32_t p0:1;	
  		__IO uint32_t p1:1;	
  		__IO uint32_t p2:1;	
  		__IO uint32_t p3:1;	
  		__IO uint32_t p4:1;	
  		__IO uint32_t p5:1;	
  		__IO uint32_t p6:1;	
  		__IO uint32_t p7:1;	
  		__IO uint32_t p8:1;	
  		__IO uint32_t p9:1;	
  		__IO uint32_t p10:1;	
  		__IO uint32_t p11:1;	
  		__IO uint32_t p12:1;	
  		__IO uint32_t p13:1;	
  		__IO uint32_t p14:1;	
  		__IO uint32_t p15:1;	
  		__IO uint32_t :16;	
	}pin;
}T_uint32_BitType;

typedef union
{
  __IO uint32_t all;
  	struct {
  		__IO uint32_t p0:2;	// 00 input(reset state) , 01 gp out, 10 Alternate , 11 Analog
  		__IO uint32_t p1:2;	
  		__IO uint32_t p2:2;	
  		__IO uint32_t p3:2;	
  		__IO uint32_t p4:2;	
  		__IO uint32_t p5:2;	
  		__IO uint32_t p6:2;	
  		__IO uint32_t p7:2;	
  		__IO uint32_t p8:2;	
  		__IO uint32_t p9:2;	
  		__IO uint32_t p10:2;	
  		__IO uint32_t p11:2;	
  		__IO uint32_t p12:2;	
  		__IO uint32_t p13:2;	
  		__IO uint32_t p14:2;	
  		__IO uint32_t p15:2;	
	}pin;
}T_uint32_2BitType;

typedef union
{
  __IO uint64_t all;
 __IO uint32_t all32_lo;
 __IO uint32_t all32_hi;
  	struct {
  		__IO uint64_t p0:4;	// 00 input(reset state) , 01 gp out, 10 Alternate , 11 Analog
  		__IO uint64_t p1:4;	
  		__IO uint64_t p2:4;	
  		__IO uint64_t p3:4;	
  		__IO uint64_t p4:4;	
  		__IO uint64_t p5:4;	
  		__IO uint64_t p6:4;	
  		__IO uint64_t p7:4;	
  		__IO uint64_t p8:4;	
  		__IO uint64_t p9:4;	
  		__IO uint64_t p10:4;	
  		__IO uint64_t p11:4;	
  		__IO uint64_t p12:4;	
  		__IO uint64_t p13:4;	
  		__IO uint64_t p14:4;	
  		__IO uint64_t p15:4;	
	}pin;
}T_uint64_4BitType;

typedef struct
{
    T_uint32_2BitType MODER;    /*!< GPIO port mode register,               Address offset: 0x00      */
  	T_uint32_BitType OTYPER;   /*!< GPIO port output type register,        Address offset: 0x04      */
  	T_uint32_2BitType OSPEEDR;  /*!< GPIO port output speed register,       Address offset: 0x08      */
  	T_uint32_2BitType PUPDR;    /*!< GPIO port pull-up/pull-down register,  Address offset: 0x0C      */
  	T_uint32_BitType IDR; 		 /*!< GPIO port input data register,         Address offset: 0x10      */
  	T_uint32_BitType ODR;     	 /*!< GPIO port output data register,         Address offset: 0x14      */
  	T_uint16_BitType BSRRL;    /*!< GPIO port bit set/reset low register,  Address offset: 0x18      */
  	T_uint16_BitType BSRRH;    /*!< GPIO port bit set/reset high register, Address offset: 0x1A      */
  	T_uint32_BitType LCKR;     /*!< GPIO port configuration lock register, Address offset: 0x1C      */
  	T_uint64_4BitType AFR;   /*!< GPIO alternate function registers,     Address offset: 0x24-0x28 */
} PORTIO_TypeDef;


header kullanımı:
main.c

#include "stm32f4xx_regs.h"

void SystemInit()
{
                  //Bundan önce yapılması gereken diğer konfigürasyonları yaptıktan sonra:
                 // Eski kullanım şeklimiz:
                 //GPIOD->MODER  = 0x55550000;     // GPIOD nin 15, 14, 13, 12, 11, 10, 9, 8 pinleri cikis tanimlandi (LEDler icin)
                 // Headerdeki tanımlamaları kullanarak
                  PD->MODER.all = 0x55550000;
                  //Veya
	  PD->MODER.pin.p15 = PORT_OUTPUT;
	  PD->MODER.pin.p15 = PORT_INPUT;
                  PA->MODER.pin.p0 = PORT_INPUT;
                  PC->MODER.pin.p7 = PORT_ALTERNATE_FUNC;
                  PG->MODER.pin.p8 = PORT_ANALOG
                  
                 // Çıkış olarak ayarlanmış portun çıkış tipi 
                  PD->OTYPER.all = 0xFFFFFFFFF;
	  PD->OTYPER.pin.p15 = PORT_PUSH_PULL;
	  PD->OTYPER.pin.p15 = PORT_OPEN_DRAIN;
           
                  // Portların hızları 
                  PD->OSPEEDR.all = 0x000000FF;
	  PD->OSPEEDR.pin.p0 = PORT_HI_SPEED;
	  PD->OSPEEDR.pin.p0 = PORT_FAST_SPEED;
	  PD->OSPEEDR.pin.p0 = PORT_MED_SPEED;
	  PD->OSPEEDR.pin.p0 = PORT_LOW_SPEED;

	  // Pull-Up Pull-Down ayarlamaları
	  PA->PUPDR.pin.p0 = PORT_PULL_DN;
                  PA->PUPDR.pin.p0 = PORT_PULL_UP;
} 

int main()
{
        if(PA->IDR.pin.p0 == 1) PD->ODR.pin.p15 = 1;
        PD->ODR.pin.14 = ! PD->ODR.pin.15;
}


promate

Güzel bir yaklaşım elinize sağlık.TI DSP/DSC header dosyaları geliştiricilere çok kolaylık sunmakta. ARM bu konuda biraz zayıf. Bende TI DSP benzeri ARM nin tüm modülleri için header dosyaları yazmayı düşünüyorum. Vakit buldukça ilerleme kaydedince buradan paylaşırım..

Klein

#2
#include "STM32F4xx.h" 

enum PORTMODES {PORT_INPUT, PORT_OUTPUT, PORT_ALTERNATE_FUNC, PORT_ANALOG};
enum PORTOUTTYPES {PORT_PUSH_PULL,	PORT_OPEN_DRAIN};
enum PORTSPEEDS {PORT_LOW_SPEED, PORT_MED_SPEED, PORT_FAST_SPEED, PORT_HI_SPEED};
enum PORTPUPDSETS {PORT_NOPU_NOPD, PORT_PULL_UP, PORT_PULL_DN, PORT_UNDEFINED};
enum PORTCFGLOCKS {PORT_CFGLOCK_PASSIVE,PORT_CFGLOCK_ACTIVE};

#define PA               ((PORTIO_TypeDef *) GPIOA_BASE)
#define PB               ((PORTIO_TypeDef *) GPIOB_BASE)
#define PC               ((PORTIO_TypeDef *) GPIOC_BASE)
#define PD               ((PORTIO_TypeDef *) GPIOD_BASE)
#define PE               ((PORTIO_TypeDef *) GPIOE_BASE)
#define PF               ((PORTIO_TypeDef *) GPIOF_BASE)
#define PG               ((PORTIO_TypeDef *) GPIOG_BASE)
#define PH               ((PORTIO_TypeDef *) GPIOH_BASE)
#define PI               ((PORTIO_TypeDef *) GPIOI_BASE)

typedef union
{
  __IO uint16_t all;
  	struct {
  		__IO uint16_t p0:1;	
  		__IO uint16_t p1:1;	
  		__IO uint16_t p2:1;	
  		__IO uint16_t p3:1;	
  		__IO uint16_t p4:1;	
  		__IO uint16_t p5:1;	
  		__IO uint16_t p6:1;	
  		__IO uint16_t p7:1;	
  		__IO uint16_t p8:1;	
  		__IO uint16_t p9:1;	
  		__IO uint16_t p10:1;	
  		__IO uint16_t p11:1;	
  		__IO uint16_t p12:1;	
  		__IO uint16_t p13:1;	
  		__IO uint16_t p14:1;	
  		__IO uint16_t p15:1;	
    }pin;
}T_uint16_BitType;

typedef union
{
  __IO uint32_t all;
  	struct {
  		__IO uint32_t p0:1;	
  		__IO uint32_t p1:1;	
  		__IO uint32_t p2:1;	
  		__IO uint32_t p3:1;	
  		__IO uint32_t p4:1;	
  		__IO uint32_t p5:1;	
  		__IO uint32_t p6:1;	
  		__IO uint32_t p7:1;	
  		__IO uint32_t p8:1;	
  		__IO uint32_t p9:1;	
  		__IO uint32_t p10:1;	
  		__IO uint32_t p11:1;	
  		__IO uint32_t p12:1;	
  		__IO uint32_t p13:1;	
  		__IO uint32_t p14:1;	
  		__IO uint32_t p15:1;	
  		__IO uint32_t :16;	
    }pin;
}T_uint32_BitType;

typedef union
{
  __IO uint32_t all;
  	struct {
  		__IO uint32_t p0:2;	// 00 input(reset state) , 01 gp out, 10 Alternate , 11 Analog
  		__IO uint32_t p1:2;	
  		__IO uint32_t p2:2;	
  		__IO uint32_t p3:2;	
  		__IO uint32_t p4:2;	
  		__IO uint32_t p5:2;	
  		__IO uint32_t p6:2;	
  		__IO uint32_t p7:2;	
  		__IO uint32_t p8:2;	
  		__IO uint32_t p9:2;	
  		__IO uint32_t p10:2;	
  		__IO uint32_t p11:2;	
  		__IO uint32_t p12:2;	
  		__IO uint32_t p13:2;	
  		__IO uint32_t p14:2;	
  		__IO uint32_t p15:2;	
    }pin;
}T_uint32_2BitType;

typedef union
{
  __IO uint64_t all;
 __IO uint32_t all32_lo;
 __IO uint32_t all32_hi;
  	struct {
  		__IO uint64_t p0:4;	// 00 input(reset state) , 01 gp out, 10 Alternate , 11 Analog
  		__IO uint64_t p1:4;	
  		__IO uint64_t p2:4;	
  		__IO uint64_t p3:4;	
  		__IO uint64_t p4:4;	
  		__IO uint64_t p5:4;	
  		__IO uint64_t p6:4;	
  		__IO uint64_t p7:4;	
  		__IO uint64_t p8:4;	
  		__IO uint64_t p9:4;	
  		__IO uint64_t p10:4;	
  		__IO uint64_t p11:4;	
  		__IO uint64_t p12:4;	
  		__IO uint64_t p13:4;	
  		__IO uint64_t p14:4;	
  		__IO uint64_t p15:4;	
    }pin;
}T_uint64_4BitType;

typedef struct
{
    T_uint32_2BitType MODER;    /*!< GPIO port mode register,               Address offset: 0x00      */
  	T_uint32_BitType OTYPER;   /*!< GPIO port output type register,        Address offset: 0x04      */
  	T_uint32_2BitType OSPEEDR;  /*!< GPIO port output speed register,       Address offset: 0x08      */
  	T_uint32_2BitType PUPDR;    /*!< GPIO port pull-up/pull-down register,  Address offset: 0x0C      */
  	T_uint32_BitType IDR; 		 /*!< GPIO port input data register,         Address offset: 0x10      */
  	T_uint32_BitType ODR;     	 /*!< GPIO port output data register,         Address offset: 0x14      */
  	T_uint16_BitType BSRRL;    /*!< GPIO port bit set/reset low register,  Address offset: 0x18      */
  	T_uint16_BitType BSRRH;    /*!< GPIO port bit set/reset high register, Address offset: 0x1A      */
  	T_uint32_BitType LCKR;     /*!< GPIO port configuration lock register, Address offset: 0x1C      */
  	T_uint64_4BitType AFR;   /*!< GPIO alternate function registers,     Address offset: 0x24-0x28 */
} PORTIO_TypeDef;

Erhan YILMAZ

Hocam elinize sağlık çok faydalı bi kütüphane olmuş. Bilmediğimden soruyorum kodda geçen __IO uint16_t p0:1; ((PORTIO_TypeDef *) GPIOA_BASE) gibi ifadelerin anlamı tam olarak nedir. __IO ifadesi ve sonlarına eklediğiniz 1,2,4 gibi sayılar tam olarak ne için. uint32_t 32 bit işaretsiz sayıyı mı gösteriyor? Birde union tipi tam olarak ne iş yapar struct'tan farkı nedir? Çoğu kütüphanelerde rastlıyorum bu tip ifadelere aydınlatırsanız çok memnun olurum hocam.

Klein

Her ne kadar hafıza tek parça da olsa, derleyici bu hafızayı çeşitli şekillerde bölerek organize eder. örneğin stack için ayırdığı yeri __stack, heap için ayrılan bölgeyi __heap, kullanıcı verisinin olduğu bölgeyi  __data , kod segmentini  __code , IO segmentini de __IO şeklinde adlandırır. Tüm derleyiciler aynı şekilde adlandırmasa da yapı benzerdir. Biz bir değişken tanımladığımızda o değişken default olarak __data segmentine konumlandırırlır. bir const tanımladığımızda _code segmentine yerleştirilir. Bazen bunu derleyicinin tercikine bırakmk iztemeyiz. Bunun için de tanımın başına __IO , __DATA, __EEPROM, __FLASH , __CODE gibi eklemeler yaparız.

uint16_t p0:1; Nedir?
struct'un en güzel özelliklerinden biri.

struct bir çeşit depo. biz bu deponun içerisine int, char , array gibi değişkenleri atarak düzenli bir yapı oluştururuz. struct'un bu güzel özelliği ise , bu alanları bit bit veya bir kaç bitlik guruplar halinde bölebiliyor olmaktır.

örn:
bir RTC aygıtımız olsun. bunun da 16 bitlik tarih registeri olsun.
0. bit Registere yazma isteği olsun.  (0 okuma , 1 yazma)
1. 2. 3. 4. ve 5. Bitler gün olsun.
6,7,8,9  ay
10,11,12,13,14 ve 15. bitler de yıl olsun.

Struct kullanmazsak  bunları tek bir 16 bitlik alanda toplamak için şöyle yapmamız gerekecek.
register = (0x8000) | (gün << 10) | ( ay << 6) | ( yıl )

Struct kullanarak , bu işi daha kolay yoldan şöyle yaparız. (int 16 bit kabul ediyoruz)
struct{
    unsigned int write_req:1;  // write_req değişkenimizin 1 bit olduğunu deklare ettik.
    unsigned int gün:5;  // gün değişkenimizin 1 bit olduğunu deklare ettik.
    unsigned int ay:4;  // ay değişkenimizin 1 bit olduğunu deklare ettik.
    unsigned int yıl:6;  // yıl değişkenimizin 1 bit olduğunu deklare ettik.
} tarih;

tarih.write_req =1;
tarih.gün = 24;
tarih.ay = 11;
tarih.yıl = 12;
dediğimizde 
16 bitlik tarih yapımızın
0. bitine 1 yazar diğer bitlere dokunmaz. (tabi 1 bitten büyük bir değer vermezsek)
1,2,3,4,5. bitlerine 24
6,7,8,9. bitlerine 11
10,11,12,13,14,15. bitlerine de sayısını yazar. 
Aslında kaydırma işlemini bizim yerimize derleyici yapar.

Union nedir.
union struct gibi bir depolama yapısıdır. Struct'tan farkı ise, struct'ta deklare ettiğimiz değişkenlerin her birinin bağımsız alanları vardır.
union de ise , hepsi aynı alanı kullanır.
örnek:

struct{
  int a;
  int b;
  char c;
} struct_type;

union{
  int a;
  int b;
  char c;
} union_type;

Bu yapıların bellekte 0 adresinden başladığını düşünelim.
struct_type yapımız bellekte toplam 5 byte yer kaplayacaktır.
0 ve 1. adresler a
2 ve 3. adresler b
4. adres ise c için kullanılır.

struct_type.a= 36728; yaptığımda bu işlemden sadece a değişkeni etkilenir. yani 0. ve 1. adresler.

union ise aynı belleği kullanır. union_type yapımız bellekte toplam 2 byte yer kaplar. Union da kullanılacak alan , içindeki değişkenin en büyüğünün boyuna göre ayrılır. Bu durumda bizim bellekte 2 byte yerimiz var.
a 0 ve 1. adreste,
b 0 ve 1. adreste
c 0. adreste bulunur.

union_type.a= 36728; işleminden 0. ve 1. baytlar etkilenir. Ama b ve c de aynı adresi kullandığı için, b yi okumak istediğimde 36728 okurum.
c'yi okumak istersem de, c tek byte olduğu için 78 okurum.

Neden header dosyasında struct yerine union kullandım?
struct kullansaydım bitlere ayrı ayrı ulaşmak yerine bitlerin tümüne birden ulaşmak istesem, (uint32_t *) gibi bir kasıt operatörü kullanmam gerekecekti. Bu da işi basitleştirme , anlaşılır yapma amacımın dışına çıkacaktı.
PD->ODR.all  veya PD->IDR.all diyerek tüm bitlere tek seferde ulaşmak daha anlaşılır olduğu için böyle kullandım.

evet uint_32_t işaretsiz 32 bit tamsayıyı ifade ediyor. Geliştiriciler neden unsigned int yerine böyle bir tanım kullanıyor?
int  boyutu işlemciye göre değişebiliyor. 8,16 bit işlemcilerde 16 bit olurken , 32 bit işlemcilerde 32 bit olabiliyor. Sanırım derleyici opsiyonları ile bile değişebiliyor. Değişkenin her ortamda aynı kalabilmesini sağlamak için  bu tip tanımlamalar kullanılıyor.



Klein

NVIC konfigürasyonunda sorun yaşayan , veya benim gibi bit saymaya üşenenler NVIC konfigürasyonunu aşağıdaki şekilde yapabilirle.

"core_cm4.h" içerisinde NVIC konfigürasyonunu kolaylaştıran bazı fonksiyonlar var. "core_cm4.h" dosyasını ayrıca include etmenize gerek yok. "stm32f4xx.h" dosyasını include ettiğiniz de o da include ediliyor.

yapmanız gereken, "stm32f4xx.h" içerisinde interruptlara verilen isimleri bulıp , bu isimleri fonksiyonlara parametre olarak geçmek.

NVIC_EnableIRQ(TIM7_IRQn); // timer 7 interrupt aktif et
NVIC_EnableIRQ(USART3_IRQn); //usart 3 global kesmesini aktif et

NVIC_DisableIRQ(TIM7_IRQn); // timer 7  kesmesini pasifleştir
NVIC_DisableIRQ(USART3_IRQn); //usart 3 global kesmesini pasifleştir


bu fonksiyonlardan başka prioriti ayarlama gibi başka fonksiyonlar da aynı header dosyasında mevcut.

muhittin_kaplan

aslında hocam bakıyorum da yavaştan bu CMIS a da girmek gerek sanırım.
Ön Ayak Olacak birileri gerek.

Erhan YILMAZ

Hocam açıklamalarınız için çok teşekkür ederim gerçekten çok açıklayıcı oldu bi çok soruma yanıt buldum. Rtc örneğinde yine bi kopyala yapıştır hatası oldu sanırım. :)

    unsigned int write_req:1;  // write_req değişkenimizin 1 bit olduğunu deklare ettik.
    unsigned int gün:5;  // gün değişkenimizin 1 bit olduğunu deklare ettik.
    unsigned int ay:4;  // ay değişkenimizin 1 bit olduğunu deklare ettik.
    unsigned int yıl:6;  // yıl değişkenimizin 1 bit olduğunu deklare ettik.

Klein

Klavyeden bu tuşlar kaldırılmalı. :)   ( muhtemelen program yazmayı bırakırdım. :)  )

Erhan YILMAZ

#9
:) Hocam peki T_uint32_BitType unionda en sonda 16bitlik bi tanımlama yapılmış __IO uint32_t :16; bu ifade diğer boşta kalan bitleri mi temsil ediyor yazılmak zorunda mı? Birde T_uint32_4BitType union toplam 64 bit ediyor all değişkenine değer yazınca ilk 32 bitemi yazılıyor değer? Bide (PORTIO_TypeDef *) GPIOA_BASE yapılan type casting olayından bahseder misiniz tam mantığı nedir? Çok soru sordum ama mazur görün hocam. :)

CoşkuN

Şu header dosyalarını bu şekilde neden hazırlamazlar da bizi uğraştırırlar anlamadım doğrusu. Güzel bir çalışma olmuş, emeğinize sağlık...

bocek

benim STM32 konusunda bilgim yok ama şurdaki araçlar belki işinize yarar:

http://joe-c.de/pages/sonstiges/stm32_tool.php#BOXAconv32

1 ya da 0. işte 'bit'ün mesele..

Klein

evet 64 bit ediyor. orada küçük bir düzeltme yapmam gerekecek. evet ilk 32 bite yazar.
Boşta kalan bitler için bir tanımlama yapmazsan derleyici bir şey demez. Yazmakta fayda var. Başı boş kod parçalarının ne yapacağı belli olmaz.

https://www.picproje.org/index.php/topic,35980.msg271164.html#msg271164
işaretçilerin typecasting meselesinden burada bahsetmiştim.

Klein

Geceden sabaha 2 revizyon geçiren tek header budur herhalde. :)

İlk halinde BASE adreslerine yapılan atıflarda kopyala yapıştır hatası vardı düzeltildi.
ikincisinde ikkatsizlik kaynaklı, AFR registeriyl ilgili tip-boyut uyumsuzluğu hatası vardı düzeltildi.
Veri tabanı şişmesin diye öncekiler üzerinde değiştirdim. yenisini koymadım.





Erhan YILMAZ

Hocam çok teşekkür ederim açıklamalarınız için.