Uart TX kesmesi

Başlatan Faruk53, 27 Kasım 2017, 13:49:38

Faruk53

Arkadaşlar merhaba;

Seri Portla ilgili küçük bir sorum olacak;

Seri Porttan veri yollarken işlemcinin beklememesi için ne yapılabilir? Yani;
void putch(char data)
{
   while(!TXSTA1bits.TRMT); // Transfer tamponu boşalana kadar bekle   
   TXREG1 = data; // Tek byte gönderiliyor   
}


Yukarıdaki döngü ile Printf komutu birlikte kullanılıp seri portttan bilgi gönderebilme imkanımız var. Fakat transfer tamponunun boşalana kadar geçen sürede işlemci "while" sebebi ile hiçbir işlem yapmıyor. Bu da diğer işlemlerde örn: Ekran taramasında Ekranların titremesine yol açıyor. Bu döngüyü başka türlü yazma şansımız var mı?

Araştırmalarımda herkesin RX kesmesinde sorun aynı sorunu yaşadığını gördüm. Bende işler tam tersi  :D
RX kesmesinde gelen bilgiyi bir buffera atıp sonra okuyorum problem kalmıyor. Ama TX'de bunu yapamıyorum. Çünkü yazıcağım veri önce tampona yazılıyor,gönderim yapıldıktan sonra kesme bayrağım aktif oluyor.

RX kesme rutinim aşağıdaki gibi;
void interrupt high_priority UART1(void) //
{
    if(PIE1bits.RC1IE && PIR1bits.RC1IF) //uart1 RX ucuna bilgi geldi mi?
    {
    karakterler=UartOku(); // Buffera gelen karakterleri okuyor.
    if(index<cevap)
    {
     buffer[index]=karakterler;
     index++;
     }
    if(karakterler==13) // Sonlandırma karakteri geldiğinde;
    {
     index=0;
     string_alindi=1;
    }
    }
}


Yukarıdaki RX kesme rutinine benzer birşeyi Gönderme içinde yapabilirsem hiçbirşekilde işlemcim beklemeyecek. Tarama da bozulmayacak. Böyle bir problemle karşılaşan var mı?

hasankara

int putch(char data)
{
   while(!TXSTA1bits.TRMT) return 1; // Transfer tamponu dolu oldugu surece 1 ile cik 
   TXREG1 = data; // Tek byte gönderiliyor   
   return 0; // Data gonderildiginde 0 ile cik
}
f


Kullanim şekli için state machine konusunu araştırmalısın.

ferdem

RX kesmesindeki kolaylık TX kesmesi için de geçerli.  Nasıl ki RX kesme içinde index++  yapıp buffer a diziyorsunuz TX kesmesinde sıradaki veriyi TX buffer a yazacaksınız, kesme kullandığınız için while da bekleme(verinin gönderilmesini bekleme) söz konusu değil. Fark ne göremedim!
İşlemciyi hiç meşgul etmeyeyim derseniz dma üzerinden de veriyi aktarmak mümkün olsa gerek.

Faruk53

ferdem hocam merhabalar. Rx interruptıda sizden öğrenmiştim hocam :)
Hocam DMA kısmını biliyorum ama kullandığım işlemcide o özellik yok malesef ve değiştirmem de pek mümkün değil. Döngüyü bir türlü kuramadım. TXIF interupt flagı buffer dolunca değil karakteri gönderdikten sonra lojik 1 seviyesine geldiği için interrupta  sokamadım bi türlü hocam. Kaçırdığım veya yanlış bildiğim bi nokta var muhtemelen.

ferdem

TX kesmeyi hiç kullanmadığımdan denenmiş bir kod veremiyorum, temel olarak şöyle olur: Gönderilecek byte dizisinin başlangıç adresini ve kaç eleman gönderileceğini bir fonksiyona gönderirsiniz(gönderim_baslat(char *bas_adres,int sayi)), TXREG e ilk byte ı direkt yazar, TX kesmeyi aktif eder kaçar. Geri kalan byte lar oluşacak kesmeler içinde gönderilir.
//Gerekli global değişkenler
char *tx_buffer, int transmit_size, int index;

void gönderim_baslat(char *bas_adres, int sayi){
tx_buffer=bas_adres;
index=0;
PIE1bits.TXIE=1; //kesme aktif edilir
TXREG=tx_buffer[0]; //ilk transferi başlat, geri kalanlar oluşan kesmelerle gidecek

}


void interrupt UART1(void) {
if(PIR1bits.TXIF){
if(index<transmit_size){
PIR1bits.TXIF=0; // ??  TXIF temizlenir
index++;
TXREG=tx_buffer(index);

}else{
PIR1bits.TXIF=0; // ??  TXIF temizlenir
PIEbits.TXIE=0; //kesme pasif edilir
}
}
}

Adım adım gitmek lazım,
1) Bir byte gönderildiğinde TX kesmesi içinde bir led toggle yapsın.
2) LED toggle değil TXREG e yeni bir byte yazsın, dummy++ değişkeni mesela.
3) TXREG e istenen diziden sıradaki byte ı yazsın ve bunu belirtilen sayı kadar tekrarlasın.

Kabil ATICI

MPLABX üzerinden  kodlama yaptığınızı varsayarsak;
Tools>Embeded>MPLAB Code configurator
üzerinden gidildiğinde , işlemciniz listede varsa, EUSART bölümünde istediğiniz seçeneklere uygun olarak kod üretmeniz de size yardımcı olacaktır. 
Seçenekleri incelerseniz RX ve Tx için hazır tampon bellek seçeneklerini görebilirsiniz ve bu kod sizin için oluşturulacaktır. Sonra istediğiniz gibi değişikliği veya eklemeyi yapabilirsiniz.
ambar7