STM32F407 Cortex M4 şamataları

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

z

#315
@taneryilmaz

Alıntı Yap
TIM7_CR1=0x00000080
TIM7_PSC=0x0000A410
TIM7_ARR=0x000003E8
TIM7_DIER=0x00000001
TIM7_CR1=0x00000081

Benim verdigim degerlerle sizin verdiginiz degerler ayni. Ben bazilarini decimal yazdim siz hex.

Sadece TIM7_CR1 e 01 yukledigimiz halde 0x81 okumana anlam veremedim.
Bunu bir ara arastiracagim.

Kartla calisiyorsun değilmi?


@madpic

TIM7->DIER=0x0001;                // Hey Timer7 !!!,  int uretmene izin veriyorum demek

NVIC->ISER[1] =0x00800000;   // Hey NVIC !!!, Sana TIMER7 INT yollarsa bune degerlendir demek

0x800000 de set edilen bit 0 dahil 23. bit.
NVIC_ISER[0] da da 32 bit var yani 53.bit

TIMER 7 int da zaten external int siralamasinda 53. sirada.

Alıntı Yap
TIM7 ile ilgili kodları debug ettiğimde TIM7_CNT de değer değişimi gözlemleyemiyorum.
keille alakalı bir durum mu yoksa benimlemi

Kartla calismiyorsaniz bir sey diyemem.

Ote yandan TIMER7 ile kartla calisirken bazi gariplikler yasadik ve bunu tartistik. Gozden kacan bir sey de olabilir. Su anda hic bir fikrim yok.

Interrupt yazilimi haric digerlerini anladiysaniz cok iyi. INT konusunu aciklayacak bir seyler yazmamiz gerekecek zaten.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

taneryilmaz

Alıntı yapılan: bunalmis - 29 Ekim 2011, 12:24:41

Benim verdigim degerlerle sizin verdiginiz degerler ayni. Ben bazilarini decimal yazdim siz hex.

Sadece TIM7_CR1 e 01 yukledigimiz halde 0x81 okumana anlam veremedim.
Bunu bir ara arastiracagim.

Kartla calisiyorsun değilmi?

hocam kartsız çalışıyorum keil debuger de   
    RCC->APB1ENR|=0x00000020;      
 >  TIM7->CR1=0x0080;
    TIM7->PSC =42000;
    TIM7->ARR =1000;     
    TIM7->DIER=0x0001;            
    NVIC->ISER[1] = 0X00800000;      
 >  TIM7->CR1|=0x0001;
 

TIM7_CR1 e ilk önce 0x80 yüklüyoruz sonra TIM7_CR1 | = 0x01 le or luyoruz  sonra 0x81 gördüm ekranda

taneryilmaz

merhaba arkadaşlar  rehber dosyamızın 50. sayfasında  register adreslerinin verildigi sayfada aklıma birşey takıldı

0x4002 2000 - 0x4002 23FF GPIOI
0x4002 1C00 - 0x4002 1FFF GPIOH
0x4002 1800 - 0x4002 1BFF GPIOG
0x4002 1400 - 0x4002 17FF GPIOF
0x4002 1000 - 0x4002 13FF GPIOE
0X4002 0C00 - 0x4002 0FFF GPIOD
0x4002 0800 - 0x4002 0BFF GPIOC
0x4002 0400 - 0x4002 07FF GPIOB
0x4002 0000 - 0x4002 03FF GPIOA

şeklinde bir tablo var  burada mesela 0x4002 0000 - 0x4002 03FF arasının GPIOA  ya ait olduğu yazıyor.
GPIOA  neden bu kadar çok registeri meşgal ediyor anlamadım ?


mcan

#318
Alıntı yapılan: bunalmis - 24 Ekim 2011, 02:18:23

Bu nedenle bir registere doğrudan veri yüklemek yerine,

1. Registeri oku
2. Değiştirilmesi gereken bit haricindeki bitleri maskele
3. Değişmesi gereken bitleri yerine koy
4. Sonucu registere yaz olmalıdır.

Bunu da bu vesileyle hatırlatayım. Dokümanlarda bu uyarı sık sık yapılır.

Merhaba bu gün dökümanı karıştırırken güzel bir özellik hakkında yazı okudum ve uyguladım.

Eğer benim gibi alışkanlıklardan dolayı maskeleme yada yukarıdaki gibi 4 adımlı işlem yapmak istemiyorsak bit banding tam bize göre. :) Ayrıca hızlı.

Tüm arm'larda varmı bilmiyorum ancak bizimkinde ve c3 de var.

Olay kısaca şöyle sram deki ve çevre ünitelerindeki sınırlar içinde kalan her bir bit, bir word(32 bit) e aynalanmış.
Örnek olarak 9 byte ram'miz olsun . 1 byte ram kullanılabilir değişken için ve geri kalan 8 byte ise 1. baytın her bir bitini temsil etsin.
2 numaralı bayta 1 yazmak aslında, 1 numaralı baytın 0 numaralı bitine yazmakla aynı işlem.
Yöntem eğer elimizdeki ram ve adres az sayıda ise çok mantıksız gibi görünüyor ancak işlemcimiz 32 bitlik 4 gb adresleyebiliyor çoğu mikrokontrolcünün ise maximum 1-2 mb internal remi var geri kalan boş adresleri böyle değerlendirmişler. Bu şekilde aynı pic deki gibi bit bit işlem yapabiliyoruz .


Mesela aynı adresdeki 16 biti set ediceksek bu işlem yerine maskeleme daha hızlı sonuç verecektir diye düşünüyorum.Ayrıca şuna dikkat etmekde yarar var .Çevrebirimlerinin yazmaçları dökümanda 32 bitlik gibi verilmiş, ancak dökümanda ayrıca offsett değerleri de var ve genelde 4 er 4 er artıyor. Yani her 1 byte ın adresi var.Bu sebeple mesela RCC_CR yazmaçı içindeki HSEON biti için bit_banding kullanmak istiyorsak RCC_CR(0x4202 1000)'nin adresinin 16.biti yerine  RCC_CR'nin adresinin bir fazlasının(0x4202 1001) 7 numaralı biti demek doğru oluyor. Bit numaraları 0 ile 7 arasında,0 ve 7 dahil.

Önceden örnek olarak verdiğim kodu bu şekilde değiştirdim

#include "STM32F10x.h"

//SRAM_BB_BASE  sram için bitband bölge adresi, SRAM_BASE ise sram in gerçek adresi .Bu tanımlamalar .h dosyasının içindeydi

#define BIT_LEVEL_SRAM(a,b) ((SRAM_BB_BASE + (a-SRAM_BASE)*32 + (b*4)))
#define BIT_LEVEL_PERI(a,b) ((PERIPH_BB_BASE + (a-PERIPH_BASE)*32 + (b*4)))
#define	RCC_APB2ENR	(RCC_BASE+0x018) //0x18 adresini Soft dökümanında RCC register map adlı konu başlığının altındaki tablodan aldım. 

#define GPIO_C_ENABLE *((volatile unsigned int *)(BIT_LEVEL_PERI(RCC_APB2ENR,4))) // 4.bit GPIO_C_ENABLE biti

void delay(unsigned int);
static int ih;
int zg;

void TIM7_IRQHandler(void)
{
		
	   if (ih == 0)
	   	ih=1;
	   else
	   	ih=0;

		TIM7->SR  = 0x0;
		//TIM7->SR  = 0x0;
		//TIM7->SR  = 0x0;
		

}

void SystemInit (void)
{
	GPIO_C_ENABLE = 1 ;//RCC->APB2ENR |= 0x00000016;    önceki durumda bu şekilde maskeliyorduk.

        GPIOC->CRL = 0x33333333;     // GPIOD nin 15, 14, 13, 12 pinleri cikis tanimlandi (Ledler bu pinlerde)
	GPIOC->CRH = 0x33333333;

	RCC->CR |= 0x0010000;	   			// HSE ON
	RCC->CFGR = 0x001D0000;	   			// PLL ayarla
	RCC->CR  |= 0x001000000;	   		// PLL aç
	FLASH->ACR =  0x32;					// Flash gecikme ayarı
	RCC->CFGR = 0x001D0402;	   			// SİNYAL KAYNAĞI PLL	 APB1 HCLK/16

	RCC->APB1ENR |= 0x00000020;		    //Timer7 ye clock verelim
	TIM7->DIER = 0x1;
	TIM7->PSC = 0x1FF;			  		//182=B6  182*5= H393
	TIM7->ARR = 0xFFFF;
	TIM7->CR1  = 0x85;
	NVIC->ISER[1] = 0X00800000;        // NVIC de Timer 7 interrupta izin verelim

} 
																										   
void delay(unsigned int i)
{   unsigned int z;
    for(z=0;z<i;z++);
	 
}
 
 
int main()
{
    while(1)
   {
     if(ih ==0)
	 	GPIOC->ODR= 0x20;     // Ledler yansin
	 else
	 	GPIOC->ODR= 0x200;     // Ledler yansin
	 delay(0x40000);
     GPIOC->ODR= 0x00000000;     // Ledler sonsun
	 delay(0x40000);
   } 
}

CLR

#319
Eğer C'de iyileşirseniz çoğu yüke onun üzerine yıkabilirsiniz. Aşağıdaki program yazım tekniği ile hatasız kod yazılabilir.
Yoksa 32bitlik sayılarla uğraşılması gerekir.

LcdGpio->Bits.Data4bit = da_ta >> 4;    // high order nibble'ı gönder

LcdGpio->Bits.RS=1;
LcdWr(da_ta);
LcdGpio->Bits.RS=0;
AfioRegs->mapr.bits.CAN_REMAP = PinNo;// CanRx_PB8_CanTX_PB9 gibi PB8(CanRX),PB9(CanTX)
LcdGpio->Bits.ENB=1;

CanRegs->sFilterRegister[CanFilterId].fr1.b32=CanMsgId;    // 32bit ID
CanRegs->sFilterRegister[CanFilterId].fr2.b32=CanMsgId;    // 32bit ID

CanRegs->sTxMailBox[0].tir.bits.STID |= Msg->ID.Std;    // 11bit

GpiodOdrReg->Bits.LCD_CS=0;
GpiodOdrReg->Bits.LCD_RS=0;
GpiodOdrReg->Bits.LCD_RD=1;

Tmrx->egr.bits.UG=1;
Tmrx->sr.bits.UIF=0;
Tmrx->dier.bits.UIE=1;

UsartxRegs->cr1.bits.TE = 1;    // Tx enable
UsartxRegs->cr1.bits.RE = 1;    // Rx enable

while(Spix->sr.bits.BSY);
Spix->dr.b16.low = SpiData;

gpioa_crh.bits.MODE9=GpioMODE_50mhz_out;    // 50mhz out
gpioa_crh.bits.CNF9=GpioCNF_PUPD_in_APP_out;  // alternate pushpull




void SystemOscInit(void)
{
// önce rcc dahili osc'ye ayarlanır ve tüm çarpanlar ve interruptlar silinir
    RccRegs->cr.bits.HSION=1;
    while(RccRegs->cr.bits.HSIRDY == 0);
// Dahili osc bölen ve çarpanları resetle
    RccRegs->cfgr.b32 &= 0xF8FF0000; //Reset SW[1:0], HPRE[3:0], PPRE1[2:0], PPRE2[2:0], ADCPRE[1:0] and MCO[2:0]
// HSEON,CSSON,PLLON bitleri clear
    RccRegs->cr.b32 &= 0xFEF6FFFF;
// HSEBYP bit clear    
    RccRegs->cr.b32 &= 0xFFFBFFFF;
// PLLSRC, PLLXTPRE, PLLMUL[3:0] and USBPRE bits clear
    RccRegs->cfgr.b32 &= 0xFF80FFFF;
// tüm interruptlar off
    RccRegs->cir.b32 = 0;
// Buraya kadar dahili osc seçtik ve tüm diğer ayarları sildik
// şimdi high speed external osc'yi seçip ayarlayacağız
    RccRegs->cr.bits.HSERDY=0;
    RccRegs->cr.bits.HSEON=1;              // harici osc enable
    while(RccRegs->cr.bits.HSERDY == 0);   // hazırlanıncaya kadar bekle  
// HCLK=SYSCLK 
    RccRegs->cfgr.bits.HPRE=0;           // sysclk bölünmez, 8 için 2'ye, 9 için 4'e,.......F için 512'ye bölünür
//  RccRegs->cfgr.bits.HPRE=0x8;         
// PCLK2 = HCLK/1 =72mhz'e ayarlayacağız (max 72mhz olur)
// burada 56Mhz
    RccRegs->cfgr.bits.PPRE2=0;          // 0 için bölünmez, 4,5,6,7 için sırasıyla HCLK/2,HCLK/4,8,16'ya bölünebilir
// PCLK1 = HCLK/2 maxsimum 36mhz olabilir, 0 için bölünmez(kullanılamaz,72mhz olamıyacağı için) 
// 56/2=28Mhz
// timerlar ise rcc_cfgr.bits.PPRE1=1; olmadığı durumlarda x2 olur (bu durumda yine 56Mhz)
// 4'e bölünmüş olsaydı(rcc_cfgr.bits.PPRE1=5;) PCLK1=56/4=16Mhz olur  timerlar ise 16x2=32Mhz'de sayardı 
    RccRegs->cfgr.bits.PPRE1=4;          // 2'ye böl. (4,5,6,7 için sırasıyla HCLK/2,HCLK/4,8,16'ya bölünebilir)
// ADCCLK = PCLK2/6 =72/6=12mhz (en fazla 14mhz olabiliyor)
// 56/8=7Mhz'de çalışsın , acelesi yok :)
    RccRegs->cfgr.bits.ADCPRE=3;         // 0,1,2,3 sırasıyla PCLK2/2,PCLK2/4,PCLK2/6,PCLK2/8
/* 
Flash latency için aşağıdaki şart gerekli  
000 Zero wait state, if 0<SYSCLK<=24MHz
001 One wait state, if 24MHz<SYSCLK<=48 MHz
010 Two wait states, if 48MHz<SYSCLK<=72 MHz 
*/
    
    FlashRegs->acr.b32&=((u32)0x00000038);
    FlashRegs->acr.bits.LATENCY=2;       // yüksek frekans olduğu için 2
    FlashRegs->acr.bits.PRFTBE=1;        // Prefetch buffer enable, flash'a yazmak için gerekli 
// Pllclk=8mhz*7mhz=56mhz
    RccRegs->cfgr.bits.PLLXTPRE=0;       // xtal'i bölme, 1 için HSE/2 olur
    RccRegs->cfgr.bits.PLLSRC=1;         // PLL'e HSE'yi bağla
//  RccRegs->cfgr.bits.PLLMUL=7;         // 7+2 kadar HSE'yi çarpar 9x8mhz, 
    RccRegs->cfgr.bits.PLLMUL=5;         // 5+2 kadar HSE'yi çarpar 7x8mhz=56Mhz, 
// pll nable
    RccRegs->cr.bits.PLLON=1;
    while(!RccRegs->cr.bits.PLLRDY);     // pll hazır oluncaya kadar bekle
// system clk olrak pll bağla
//	RccRegs->cfgr.bits.SW=0;
    RccRegs->cfgr.bits.SW=2;             // 0-HSI,1-HSE(pll'siz),2-PLL, PLL'i bağla
    while(RccRegs->cfgr.bits.SWS!=2);    // PLL sistem clk kaynağı oluncaya kadar bekle
}
Knowledge and Experience are Power

mcan

#320
@Bunalmis hocam ben timer7 kesme olayını araştırıyorum , şöyle bişeyle karşılaştım
void TIM7_IRQHandler(void)
{
	   if (ih == 0)
	   	ih=1;
	   else
	   	ih=0;
	TIM7->SR  = 0x0;
	   //ipb = DAC->CR;
	   for( ii=0;ii<1;ii++){}
		

}
Timer 7 ile aynı busda olan başka bir çevre birimini okuduğumda (burdaki örnekde dac) yada ufak bir gecikme sağladığımda da interrupt flag siliniyor. Eğer zamanınız olursa sizdeki kittede deneyebilirmisiniz .Bende for döngüsüne 1 koymak yetti, 0 koyarsam gene olmuyor. Belki sizin kartda 2-3 gerekebilir.
Ek:
One potential issue with M3 designs is a pipeline hazard with the peripheral vs NVIC. If you clear the interrupt as the last thing before exiting an interrupt handler the pipelining, write buffers and disparity in clocks will create a condition where the peripheral is still signalling the interrupt when the M3 decides to tail-chain, causing the handler to reenter (priorities may impact which) and the peripheral will have cleared when you look at it. To avoid this be sure to clear the interrupt upon entry. ie Check source, dismiss, process, leave

As to your issue about knowing which epoch of the 16-bit timer you're looking at. Take a look at using the core cycle counter for a long term timebase, the 32-bit counter has an epoch >1min. The cycle counter is part of the trace unit, and is present in all STM32 parts I've checked.
İnternette karıştırır-araştırıken forumun birinde bu yazıya rastladım.

CLR


Bit Banding'i keil ve iar'da denemiştim, zamanlama anlamında büyük bir avantaj getirmiyor. Maskele ile aynı sonuçları almıştım. Ama tabii belki sizi bit maskelemekten kurtarır fakat aynı şeyi güzel bir macro ile sizde yazabilirsiniz.
Knowledge and Experience are Power

z

#322
Alıntı Yap
void TIM7_IRQHandler(void)
{
      if (ih == 0)
         ih=1;
      else
         ih=0;
      TIM7->SR  = 0x0;
//    ipb = DAC->CR;
      for( ii=0;ii<1;ii++){}
}     

Timer 7 ile aynı busda olan başka bir çevre birimini okuduğumda (burdaki örnekde dac) yada ufak bir gecikme sağladığımda da interrupt flag siliniyor. Eğer zamanınız olursa sizdeki kittede deneyebilirmisiniz .Bende for döngüsüne 1 koymak yetti, 0 koyarsam gene olmuyor. Belki sizin kartda 2-3 gerekebilir.

TI urunlerinde soyle bir uyari bulunurdu. Aklimdan cikmis, bu durumda STM de de ise yarar gorunuyor.

Uyarı şöyle; Bir porta bir sey yazdiktan sonra tekrar okumak gerekirse iki nop isletin oyle okuyun denmekte.

STMde 2 değilde 3 der 4 der bilmiyorum. Fakat STM dokumanlarinda simdilik boyle bir uyariyla karsilasmadim.

Bana e^st de diyebilirsiniz.   www.cncdesigner.com

z

#323
Hem sıfır yazma hem de okuma saçmalığı halloldu.

void TIM7_IRQHandler()
{
volatile short i;
static char LedFlag=0;


TIM7->SR=0;                                        // Timer Int Flagý silelim
    LedFlag=(LedFlag+1)&1;
    if (LedFlag) GPIOD->ODR= 0x0000F000;     // Ledler yansin
    else GPIOD->ODR= 0x00000000;              // Ledler sonsun
}


Evet sorun anlaşıldı.

Rutinin en sonunda Timer7 int flağı silip interrupt rutininden çıkarsak sorun oluşuyor. İlk başlarda önce okuyup ardından da silerek buna çözüm bulmuştuk.

Yukarıdaki çözümde ise int rutinine girer girmez flağı siliyoruz ardından da int rutininde asıl kodlarımız var. Böylece flag, int rutininden çıkmadan önce silinecek vakti buluyor ve sorunun ortaya çıkışını engelliyor.

Önceki örneklerimizde TIM7->SR=0;    silme komutunu veriyoruz. Fakat hemen altında da int rutininden çıkıyorduk. Sil komutu derhal işleme alınmıyor çünkü APB hızı CPU dan düşük.

(Sorun donanım bazında ve çok alt seviyelerde.)

Ya yukarıdaki örnekteki gibi yapın yada int flağı sildikten sonra bir kaç tane NOP koyun. Yada flağın silindiğini yazılımsal olarak kontrol edin.

Alıntı YapOne potential issue with M3 designs is a pipeline hazard with the peripheral vs NVIC. If you clear the interrupt as the last thing before exiting an interrupt handler the pipelining, write buffers and disparity in clocks will create a condition where the peripheral is still signalling the interrupt when the M3 decides to tail-chain, causing the handler to reenter (priorities may impact which) and the peripheral will have cleared when you look at it. To avoid this be sure to clear the interrupt upon entry. ie Check source, dismiss, process, leave

As to your issue about knowing which epoch of the 16-bit timer you're looking at. Take a look at using the core cycle counter for a long term timebase, the 32-bit counter has an epoch >1min. The cycle counter is part of the trace unit, and is present in all STM32 parts I've checked.

@MCAN bu uyarıyı nereden buldun ?

Bana e^st de diyebilirsiniz.   www.cncdesigner.com

mcan

#324
St nin kendi sayfasında bir forum var orda aktif bir kullanıcının biri yazmış,forumdan okuduğum kadarıyla sadece timer da değil adc vs.. ile yapılan kesmelerde de problem oluyormuş...
Link1

Ayrıca foruma açtığım başlığa cpu pipelined cpu dur diye not düşmüşler,evet sorun kesinlikle anlattığınız gibi.
Link2


O uyarının benzerini okurken wiki den buldum olayın genelini özünü bu şekilde anlatmış;
Alıntı YapWhen a programmer (or compiler) writes assembly code, they make the assumption that each instruction is executed before execution of the subsequent instruction is begun. This assumption is invalidated by pipelining. When this causes a program to behave incorrectly, the situation is known as a hazard. Various techniques for resolving hazards such as forwarding and stalling exist.

Anladığım kadarıyla  arm  işlemcideki  ,ilk başlarda  anlam veremediğim, bazı status bitlerinin bir kısmı sanırım bu işlere de yarıyor.

@Bunalmis hocam sizin vga probleminin acaba bununla bir alakası olabilirmi?
A non-pipelined processor will have a stable instruction bandwidth. The performance of a pipelined processor is much harder to predict and may vary more widely between different programs.


İlerde kullanılmak üzere , arm başlıklarının birine işe yarar c kütüphanelerini barındıran bir başlık açsak olmazmı?Lcd ,sd ,ethernet,sensörler vs... gibi kütüphaneler.

z

Alıntı yapılan: eemkutay - 30 Ekim 2011, 23:06:21
Bit Banding'i keil ve iar'da denemiştim, zamanlama anlamında büyük bir avantaj getirmiyor. Maskele ile aynı sonuçları almıştım. Ama tabii belki sizi bit maskelemekten kurtarır fakat aynı şeyi güzel bir macro ile sizde yazabilirsiniz.

Sadece bir değişken yada bir register üzerindeki bit manuplasyonu olarak ele alırsak haklısın. Fakat bilmem neredeki bir biti bilmem neredeki bir bitle AND le sonucu bilmem neredeki bite yerleştir tarzında bir işlemi, bir klasik yolla birde bit banding özelliğini kullanarak yaparsan aradaki fark şaşırtıcı olacaktır.

https://www.picproje.org/index.php/topic,36040.msg258436/topicseen.html#msg258436 başlığındaki bitbanding konusuna gözatmanı öneririm.

Bana e^st de diyebilirsiniz.   www.cncdesigner.com

CLR

Alıntı yapılan: bunalmis - 02 Kasım 2011, 07:30:55

Sadece bir değişken yada bir register üzerindeki bit manuplasyonu olarak ele alırsak haklısın. Fakat bilmem neredeki bir biti bilmem neredeki bir bitle AND le sonucu bilmem neredeki bite yerleştir tarzında bir işlemi, bir klasik yolla birde bit banding özelliğini kullanarak yaparsan aradaki fark şaşırtıcı olacaktır.

https://www.picproje.org/index.php/topic,36040.msg258436/topicseen.html#msg258436 başlığındaki bitbanding konusuna gözatmanı öneririm.

Bit bandingi registerin bir bitini set/reset için denedim ve benim derleyicinin ve C özelliklerini kullanarak yazdığım bit library'yi kullanıp karşılaştırdım.  Komut işleme zamanı olarak hemen hemen aynı sonuçlar aldım. Bit banding için sen pointer'e üzerinden işlem yapmışsın bense define ile tanımlama yazdım, yani doğrudan register adresini kullandım, normalde benim yazdığım kod daha optimize olacaktır. Çünkü derleyici daha derlemeden herşeyi hesaplıyor. Ayrıca sen hep A registeri üzerinde işlem yaptığın için başlangıç şartlarını derleyici 1 kez hesaba katıyor.

Senin bahsettiğin gibi bit banding ile 2-3 farklı registerin farklı bitlerini kullanarak bit üzerinden işlem yapmayı denemedim ama büyük bir fark olacağını sanmıyorum. Çünkü tek bit için ne yapması gerekiyorsa diğerleri içinde aynısını yapmalı ama tek bit üzerinde bir avantajı olsaydı kullanırdım.

Zaten eğer mesele optimizasyon ise, ST library'yi incelerseniz adamlar hiç optimize edelim, asm'ye yakın olsun diye hiç uğraşmamış, önemli olan anlaşılır, görsel, doğru ve hızlı yazılabilecek kodlama tekniği kullanmışlar. Gereksiz ram, pointer kullanımı tavan yapmış ama işte böyle büyük projeler yapılabilir yoksa çok yavaşlarsınız. Eğer kritik zamanlama gerekiyorsa asm kullanmak daha mantıklı. Bu söylediklerim (gereksiz ve fazladan kullanım) eski bir asm'ciye anlaşılması zor gelecektir ama ben daha önce bu durumu yaşamıştım. 

Akşam siteye girebilirsem denediğim bit banding tanımlamasını eklerim.
Knowledge and Experience are Power

z

#327
Linkini verdiğim programda init aşaması geçildikten sonra, bit atamalarını sadece tek makine cycle'ında yapıyor.

Örneğin 10 adet biti tek tek set yada reset edeceksen bu sadece 10 makine cycle'ı demek. Bundan daha hızlı bit manuplasyonu da olmaz. (Her clockta bir bit set yada reset)


Bana e^st de diyebilirsiniz.   www.cncdesigner.com

fahri-

Hocam sırasımıdır ama;
Pic lerde data set değerlerimizi saklayabileceğimiz eeprom yapısı ARM larda yok sanırım. Bu durumu flash hafızayı kullanarak mı çözeceğiz yoksa harici eeprom mu kullanacağız?

z

4KB lık pilli ram var. O kullanılabilir. Flash'da kullanılabilir fakat bu konuda bilgim yok.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com