STM32F407 Cortex M4 şamataları

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

z

Klein 8 ve ) yanyana gelince yok oluyor. Bu sorun diğer kodlarda da karşınıza çıkabilir.
Daha önce konuşuldu çözüm olarak  gülümseme kullanma kutusunu tıkla dendi fakat unutuyorum.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

Klein

:) Evet benim da başıma gelmişti. Ben de unutmuşum.
Kodları halen çalıştıramadım.
Debug ediyorum. 
Döngüye giriyor. Demekki "Who_Am_I"  cevabı geliyor.
Ama "Status" registeri hep 0 döndürüyor.  LIS302DL Bozuk olabilir diye diğer kartları denedim. Onlarda da durum aynı.
Bir de debug ederken  Hardware monitörden SPI1'i izlemeye aldığımda
while(!(SPI1->SR&1));

döngüsünde takılıp kalıyor. Eğer monitörü kapatırsam döngüyü geçiyor.

z

Bu durum benim de başıma geldi. Hatta bugün bir arkadaş maille aynı durumdan bahsetmiş.

Kodlarda bazen çalışamama gibi bir sorun var o zaman. Fakat kodları ben çalışıtırdım. Öte yandan bahsettiğiniz sorun aynen başıma gelmişti.

Bu durumda init edilmesi gereken bir değişken vs olabilir. Yada gözden kaçan bir başka durum.

Akşam ben de bakayım.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

Klein

#648
Biraz daha kurcaladım.

SPI CTRL1 registerine yazamıyor.
Write kodunu adım adım işletirsem yazma gerçekleşiyor. Sonrasında sorun yok.


Ekleme:
Kodu aşağıdaki şekilde düzeltince halloldu.
SPI TX Empity bayrağı muhtemelen TX bitince değil , Data donanıma gönderilince çekiliyor. Bu yüzden Gönderme daha tamamlanmadan okuma yaptığımız için sorun oluyor. TX Empity yerine BSY bayrağını kontrol edersek sorun yok.
void Write(char Adr,unsigned char Data)
{
      GPIOE->BSRRH=0x0008;            // LIS302DL CS=0
      SPI1->DR=(unsigned short) (((Adr&0x3F)<<8 )|Data);
      while(!(SPI1->SR&0x80));
      GPIOE->BSRRL=0x0008;            // LIS302DL CS=1
}   
Malesef düzeldiğini sanmıştım ama düzelmemiş. Kartın enerjisini kesmeyi unuttuğum için register değeri saklı kalmış.

[/color]

Klein

Ancak bu şekilde çözüm bulabildim.  Neden haberleşmenin bitmesini beklemiyor anlamış değilim. Datasheet'e gömülmek gerekecek sanırım.

void delay(unsigned int time){
	while(time--);
}
void Write(char Adr,unsigned char Data)
{
      GPIOE->BSRRH=0x0008;            // LIS302DL CS=0
      SPI1->DR= (unsigned short)(((Adr&0x3F)<<8)|Data);
      while(!(SPI1->SR&2 ));
	  delay(10000);
      GPIOE->BSRRL=0x0008;            // LIS302DL CS=1
}   

ErsinErce

vs1003 ile uğraşırken bu soruna bende denk geldim
çözüm alma işleminin bitmesini beklemek, kullandığım kod;
void putc_spi2(unsigned char c){
	while(!(SPI2->SR&0x02));
	SPI2->DR=c;
	while(!(SPI2->SR&0x01));
	c=SPI2->DR;				/* OVR hatası almamak için gelen bilgiyyi oku*/
}
unsigned char getc_spi2(unsigned char c){
	while(!(SPI2->SR&0x02));
	SPI2->DR=c;
	while(!(SPI2->SR&0x01));
	return SPI2->DR;
}

z

#651
Problemin kaynagi oldukca basitmis ama kok sokturdu. 

TXE flagi,  Transmit bitti değil, TxBuffer bosaldi anlamina geliyor. Programda, bufferin bosaldigini gorur gormez cipi, CE bacagindan pasif hale getiriyoruz. Halbuki bu esnada Tx Bufferdaki bilgi shift registere alinmis ve yollanmaya baslamisti. CE pasif edilince o anda gonderilmekte olan veri yarida kesilmis daha acik ifadeyle transmit islemi iptal edilmis oluyor.

TXE ye değil BSY flagina bakmaliydik. Write rutinini asagidaki gibi duzeltirseniz sorun kalmayacak.

TXE flagi, makineli tufek gibi ardarda veri yollarken ise yarar.

void Write(char Adr,unsigned char Data)
{
      GPIOE->BSRRH=0x0008;            // LIS302DL CS=0
      SPI1->DR=((Adr&0x3F)<< 8) |Data;
      while(SPI1->SR&0x40);
      GPIOE->BSRRL=0x0008;            // LIS302DL CS=1


TXE ile BSY arasindaki farki gormek icin blok semada timing diagrama bakin Rehber 672.

Peki bu hatali kodu neden ornek programlara ekledim?

Yazdigim kodlari isletirken aslinda bir tuhaflik vardi. Kodlar uzerinde ufak degisiklikler yapip debug ettigime daha acik ifade ile F11 ile adim adim yuruttugumde
kodlar calisti. Aslinda SPI a data yukleyen satiri F11 ile yuruttugumde bir alt satirdaki TXE flagi setmi diye ikinci kez F11 e bastigimda data coktan gitmis oluyordu.
F5 ile kodu kosturunca da program dogru calisiyor gorunuyordu. Bende kodun duzene girdigini dusunup yayinladim.

Program bir kez calistiktan sonra karti reset butonu ile resetlesem bile MEMS cipi resetlenmediginden bufferina yazilmis olan veri. daha sonraki yazma cabalarimizla
degismediginden (cunku programin yazma rutini hatali) daha sonraki F5 (run) islemi kodlarin duzgun calistigi yanilgisina neden oluyordu. Halbuki karti resetlemek
yerine kartin usb kablosunu sokup taksaydim kodlarda hata oldugunu anlayacaktim.

Aslini sorarsaniz programdaki bu mantik hatasi guzel bir ornek oldu.



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

Klein

#652
Dün BSY bayrağına bakmıştım. Hatta BSY bayrağına bakınca sorun düzeldi diye yazdım. Ama sonra sorunun düzelmediğini görüp yazdıklarımın üzerine çizik atmıştım. BSY bayrağı bende neden sorunu çözmedi bir bakayım.
Alıntı YapEkleme:
Kodu aşağıdaki şekilde düzeltince halloldu.
SPI TX Empity bayrağı muhtemelen TX bitince değil , Data donanıma gönderilince çekiliyor. Bu yüzden Gönderme daha tamamlanmadan okuma yaptığımız için sorun oluyor. TX Empity yerine BSY bayrağını kontrol edersek sorun yok.


Ekleme:
Son kodunuzda BSY bayrağına değil OVR bayrağına bakmışsınız hocam.



İkinci ekleme:
BSY bayrağı ile tekrar denedim malesef sorun halen düzelmedi.
Sizin kodunuzdaki gibi OVR bayrağını da denedim yine olmadı.
Sorunun TX bitmeden çipi pasif yapmak olduğu kesin. Ama BSY neden çözemedi anlamadım.

z

Evet 0x40 yerine 0x80 olmalıydı yanlış yazmışım. Fakat işin kötüsü kodda da 0x40 yazdım. Bu durumda kodda 0x80 yazıp tekrar denemek gerekiyor. OVR flağına bakmışım. Program 0x40 ile çalışıyor olsa da bu kabul edilir bir çözüm değil. Çünkü tek write yaptığımız için sorunsuz çalışıyor.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

Klein

Kötü olan şu ki; Bende OVR bayrağına bakmak da bir çözüm getirmedi. Aynı şekilde BSY de işe yaramıyor.

z

İlginç bir şey dün gece defalarca denediğim kod şimdi çalışmıyor. Üstelik her defasında kartın enerjisinide kesiyordum.

Yalnız işyerinde kodları buradaki sayfadan copy past ile aldım. Acaba gene kodlarda bazı karakterler mi uçtu. Evdeki kodu tekrar denemem gerekecek.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

ErsinErce

Hocam reference manual sayfa 665 Receive sequence bölümüne bakarak yukarıdaki kodu eklemiştim
ayrıda sayfa 672 deki figure 248 de bakarsanız daha net görülüyor ama 16 bit aktarım için durum nasıl tam incelemedim

ErsinErce

hatta 1.kenar 2.kenar farkı gözetmeksizin kullanmak için kodu şu şekilde değiştirirsek tam olacak gibi
void putc_spi2(unsigned char c){
    while(!(SPI2->SR&0x02));
    SPI2->DR=c;
    while(!(SPI2->SR&0x01));
    while(SPI2->SR&0x01);
    c=SPI2->DR;				/* OVR hatası almamak için gelen bilgiyi oku*/
}

Klein

Alıntı yapılan: ErsinErce - 05 Ocak 2012, 17:42:07
hatta 1.kenar 2.kenar farkı gözetmeksizin kullanmak için kodu şu şekilde değiştirirsek tam olacak gibi
void putc_spi2(unsigned char c){
    while(!(SPI2->SR&0x02));
    SPI2->DR=c;
    while(!(SPI2->SR&0x01));
    while(SPI2->SR&0x01);
    c=SPI2->DR;				/* OVR hatası almamak için gelen bilgiyi oku*/
}


Buradaki sorun şu:
SR&0x01 Status 0. biti. Bu bit de  RX bayrağı. Tx döngüsünün sonunu beklemek için RX bayrağını okumak bana anlamlı gelmedi.

Diğer sorun ise :
kodun başında TX_Empity bayrağını okumak. TX tamponu boş ama SPI RX durumundaysa bu bayrak çekilir alttaki kodlar işletilir. Kaldı ki Veri TX donanımına gönderilir gönderilmez bu bayrak çekiliyor zaten.

Bir başka mesele de peşpeşe yapılan RXNE kontrolü.
    while(!(SPI2->SR&0x01));
    while(SPI2->SR&0x01);

Diyelim ki program ilk satırda biraz bekledi.
RXNE 1 oldu ve döngüden çıkıldı.
Peşindeki döngü RXNE 1 olduğu sürece işletilir. Bizim RXNE bayrağımız 1 olduğuna göre program burada takılır kalır.

ErsinErce

hocam numarasını verdiğim şekile bakarsanız bu bayrak normalde 0 son bit alınırken 1 olup daha sonra tekrar 0 oluyor
gönderim sırasında alma bayrağını kontrol etmek spi için mantıklı çünkü çift yönlü alışveriş söz konusu ve master olarak saat darbesini biz çıkartıyoruz

şuan vs1003 sorunsuz bir şekilde çalışıyor, yaklaşık 20K veri yolluyorum

debug yaparken o satırları atlatmak lazım tabi