STM32F407 Cortex M4 şamataları

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

Klein

#660
Okurken tamam. ama yaz dediğimizde karşıdaki adam bize yazdım ya da yazdığım veri şu gibi bir bilgi göndermiyor ki. Bu yüzden yazma sonunda RX bayrağını kontrol etmek anlamsız.
Böyle düşünüyor olmama rağmen yine de kodunu denedim. düşündüğüm gibi
      while(!(SPI1->SR&0x1));    
      while((SPI1->SR&0x1));    
ikinci while satırında takıldı kaldı.


Ekleme :
İkinci while satırını kaldırınca kod çalışıyor. Hem de çalışması gerektiği gibi. Ama yine de aklıma yatmadı.
REF Manuel'e göre BSY bayrağı ile RXNE bayrağı aynı anda çekiliyor. Bu durumda RXNE ile çalışıp BSY ile çalışmaması çok saçma.
Ya da Manuel'de banim kaçırdığım birşey var.

ErsinErce

#661
karşıdan gelen anlamlı bir veri olmasa bile bu bit 8.bit okunduğunda(yazılma tamamlandığında) (8.clock gönderildiğinde)aktif oluyor
BSY NSS bitine göre hareket ediyor olabilir Chip Select işini donanıma bırakmadığımızdan bu bitini kontrol etmek sorun çıkartıyor olabilir

bende de 2 while çalışmıyormuş program atamamışım pardon =/
tek while ile düzgün çalışıyor

hocam affınıza sığınarak SPI hakkında bir açıklama yapmak istiyorum
SPI da yazma veya okuma diye bir kavram yok aslında yazmaçların aktarımı söz konusu
her clk darbesinde bitler bir yazmaçtan diğerine aktarılıyor, bu yüzden okuma işlemi tamamlandığında veri aktarımı tamamlanmıştır diyorum


Ek: 16 bit modunda 16.bitte mi aktif oluyor birazdan test edeceğim

Klein

Sayfa 678'de BSY bayrağının kullanılması ile ilgili kuralları açıklamış.  Her iletişimde kullanmayın TXE ve RXNE bayrağını kullanın diye de not düşmüş.
Bu programdaki kullanım şekli anlatılan prosödüre aykırı değil ama yine de olmuyor.

@ErsinErce
Evet MOSI/MISO döngüsüne dikkat etmemiştim. RXE kullanmak mantıklı görünüyor. Zaten SPI1'i monitör ettiğimde bariz biçinde değişen tek bayrağın RXE olduğu görülüyor.

ErsinErce

RXNE SPIx->DR yi okuma ile sıfırlanıyormuş, 2.while da çakılma sebebimizi de öğrendim,
BSY sürekli veri aktarımında hep aktif olduğundan dediğiniz gibi kullanımı sakıncalı hocam
BSY'i ancak ayarladığımız clk frekansının bitiminde kontrol edersek işimize yarar olduğundan işimize pek yaramıyor

ayrıca not düşelim Full dublex çalışırken bu bayrakları kontrol etmek lazım, sadece gönderim ya da sadece alım yapacaksak (o şekilde ayarladıysak)
sayfa 679daki SPI Disable anlatımına dikkat etmek lazım tabi SPI'ı kapatma kısmını yapmadan ;)

16 bit olayını test edemedim malesef gölge registerlar kullanıldığından dışardan gözlemlemek gerekecek galiba

z

Iki gundur baska isler nedeniyle sabahliyorum ve kafami toplayip soruna tam egilemedim. SPI init den itibaren tum register atamalarina tekrardan bakmak gerekecek.

Rehberde BSY flagini surekli test etmekten kacinin once TXE ye bakin soonra busy ye bakin gibisinden uyari gordum.

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

M_B

Hocam kodlarınızı inceliyordum da kafama takılan anlayamadıgım bir yer var.
İzah edebilirmisiniz.

GPIOE->BSRRH=0x0008;            // LIS302DL CS=0 

Hocam burda E portunun 3. bitini High (Set) yapması gerekmiyormu. Sizin acıklamanızda 0 (sıfır) oldugunu yazmıssınız.
GPIOE->BSRRL=0x0008;            // LIS302DL CS=1 

Hocam burda E portunun 3. bitini High (Low) yapması gerekmiyormu. Sizin acıklamanızda 1 (High) oldugunu yazmıssınız.

BSRRH: GPIOx port bit set/reset high register
BSRRL : GPIOx port bit set/reset low register
Bu registerin calışma mantıgı nasıl?

Teşekkürler



İmkanın sınırlarını görmek için imkansızı denemek lazım.                                                             Fatih Sultan Mehmet

muhittin_kaplan

bende inceledim.
Orada CS0 yada CS1 yazmasının sebebi 32f400 e bağlı olan ivmeölçerin CS girişinin değiştirilmesidir.
O giriş ile
0 da I2C 1 ile SPI mode seçiliyormuş.

Bunalmış Hocam neden ivmeölçerin SPI/I2C seçimini değiştiriyoruz ? Devamlı SPI da kalsa ?

Klein

Buradaki H ve L  lojik Hi ve lojik Lo ifade etmiyor.
BSRR registeri 32 bitlik kaydedici. H üst 16 bitlik bölümü L de düşük 16 bitlik bölümü ifade ediyor.

BSRRL'nin  bir bitini set ettiğinizde o portun ilgili pini Set ediliyor.
aynı şekilde BSRRH nin bitini set edince port Reset oluyor.

muhittin_kaplan

yok denemediğim kalmadı.
Rehber 679 da Disable SPI da bazı sıralamalar vermiş. Denedim Olmadı.
Yine Debug da Çalışıyor ama Enerjiyi kesip tekrar verdiğimde çalışmıyor.

Klein

Alıntı yapılan: muhittin_kaplan - 06 Ocak 2012, 00:39:49
Bunalmış Hocam neden ivmeölçerin SPI/I2C seçimini değiştiriyoruz ? Devamlı SPI da kalsa ?

O pin hem I2C seçimihem de SPI CS pini. eğer aynı hatta birden fazla SPI aygıt varsa okuma/yazma yapmak istediğimiz çipi aktif etmek için CS pinini Low yapmamız gerekiyor. Aynı zamanda CS pinini HI yaptığımızda çipin haberleşmesini de resetlemiş oluyoruz. Eğer CS hep aktif kalırsa
çip sürekli veri okunacak veya yazılacakmış gibi davranıp bizim verdiğimiz adres dizisini register adresi gibi kabul edebilir.

Ama akselerometre çipinde hem I2C hem de SPI olduğu için adam pin sayısından kazanmak için o pini hem SPI CS hem de I2C seçim pini olarak tasarlamış.


Klein

Alıntı yapılan: muhittin_kaplan - 06 Ocak 2012, 02:12:35
yok denemediğim kalmadı.
Rehber 679 da Disable SPI da bazı sıralamalar vermiş. Denedim Olmadı.
Yine Debug da Çalışıyor ama Enerjiyi kesip tekrar verdiğimde çalışmıyor.
Şimdi denedim bir sorun yok. SPI disable yapınca SPI çalışmayı durduruyor. son okudupumuz veri ne ise ledler o şekilde kalıyor.

void SPI_Disable(void){
      while(!(SPI1->SR&0x01));	  
      while(!(SPI1->SR&0x02));	  
      while((SPI1->SR&0x80));
	  SPI1->CR1=0x00000B3F;	  
	
}

int main()
{
int i;
modsel();
      if(Read(0x0F)==0x3B)   // Who are you ?
       {
          Write(0x20,0x47);  // Data Rate=100Hz, Full Scale=2g, Activate, x,y,z enable
          while(1)
            {
               who=Read(0x27); // Statusu ogrenelim. Kim hazir kim de?il?
               if (who&1) 
                {
                  x=(Read(0x29)+xo);
                  xo=x>>1;
                  if (x>=0) PWM[0]=x;
                  else PWM[2]=-x;				  	   
                }  
               if (who&2) 
                {
                  y=Read(0x2B)+yo;
                  yo=y>>1;
                  if (y>=0) PWM[1]=y;
                  else PWM[3]=-y;
                }  
               if (who&4) 
                {
                  z=Read(0x2D);
                } 
				SPI_Disable();              }
       }
       
      //TIM7->DIER=0x0000;              // Update Int disable
      while(1)
       {
         for(i=0;i<0x100;i++);
         GPIOD->ODR^=0x0000F000;
       }  
       
}

z

Nihayet istedigim gibi oldu.

char  SPI_CMD(short DAT)    
{
char RxDat;
      GPIOE->BSRRH=0x0008;      // LIS302DL CS=0
      RxDat=SPI1->SR;           // AMAC DELAY (kalmasinda fayda var)
      SPI1->DR=DAT;             // Komutu yukle
      while(!(SPI1->SR&0x01));  // RX BUF bos ise beklemede kal  
      while(SPI1->SR&0x80);     // BSY durumu varsa kalkmasini bekleyelim
      RxDat=SPI1->DR;           // Cipten gelen veriyi oku 
      while(SPI1->SR!=0x02);    // CS=1 yapmadan once cipin orjinal duruma donmeyi bekleyelim
      GPIOE->BSRRL=0x0008;      // LIS302DL CS=1
      return(RxDat);
}   
char Write(char Adr,unsigned char Data)
{
      return(SPI_CMD(((Adr&0x3F)<< 8 )|Data));
}
char Read(char Adr)
{
      return(SPI_CMD(((Adr&0x3F)|0x80)<< 8 ));
}
 
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

ErsinErce

bekleme için TXE yi kontrol etseydiniz daha "cool" gözükürdü hocam kimse silmek istemezdi, ister istemez elim delete'e doğru gidiyor =)

z

RXBUF bos flagini bekleme kismini diyorsan;

Gonderilen dataya karsilik shift register yapisindan dolayi ayni cercevede data geliyor zaten.
RXNE flaginin set edilmesi TXE flaginin degisiminden daha sonra gerceklestigi icin bu ve benzeri uygulamalar icin TXE flagini kontrol etmenin gereksizligine karar verdim.

Ornek program kismindaki uygulamayi da duzelttim. Zaten PWM degerlerini olusturmayla ilgili hata varmis.

(Biz cipten veri okumak da istesek yazmak da istesek her durumda zaten cipten veri aliyoruz. Yazma asamasinda 0xFF aliyoruz baska mesele.)
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

ErsinErce

yok hocam, aşağıdaki kısım için demiştim, biraz şamata olsun diye =)
RxDat=SPI1->SR;           // AMAC DELAY (kalmasinda fayda var)