USART Haberleşme

Başlatan OxfordBlue, 17 Ağustos 2015, 16:51:20

OxfordBlue

Microdenetleyici: Pic 18F4620
Baudrate: 9600( baud rate = bit/saniye)

Merhabalar Timer1=200us olarak set ettim ve programin bir döngüsü timer1 taşması kadar 200us sürüyor..


her 200us de bir seri haberleşme için yazdığım fonksiyonuna giriyor ve 1 byte data gönderiyor.

Bunun daha hızlı yolu var mı ? örnek 100 bytı bu txreg gibi bir değişkene yükleyip hiç durmadan gönderme şansı var mı 9600 baudrate hızında.

quarko

9600 baudrate demek, 1 sn de 9600 bit gönderebilme hızına sahip olmak demektir. Yani bir byte göndermek için start ve stop biti ile birlikte toplamda 10 bit göndermeniz gerekiyor. Buda demek oluyor ki; usart ile 1 byte göndermek demek 9600bps hızında yaklaşık olarak 1.04ms sürecek. Bu durumda 200us de bir byte göndermeniz mümkün değil. Hızınızı artırmalısınız.

Usart tan iki şekilde veri gönderirsiniz. Birincisi göndereceğiniz paketin byte larını sırayla usart a yazıp gidip gitmediğini kontrol etmek, gittiyse yenisi yazmak. Bu paralel olarak çalışan işlemleriniz varsa onları bloke edeceğinden pek tavsiye edilmez. İkincisi usart tx interrupt ını aktif etmektir. Bir byte gönderimi tamamlandığında tx interrupt ı alırsınız. Interrupt rutininde bir sonraki byte ı buffer a yazıp diğer işlemlerinize dönebilirsiniz. Bu size processor ün gücünü daha efektif bir şekilde kullanmanızı sağlayacaktır.
"Aslanlar kendi hikayelerini yazmadıkça, avcıların kahramanlık hikayelerini dinlemek zorundayız."

OxfordBlue

#2
Alıntı yapılan: quarko - 17 Ağustos 2015, 17:07:47
9600 baudrate demek, 1 sn de 9600 bit gönderebilme hızına sahip olmak demektir. Yani bir byte göndermek için start ve stop biti ile birlikte toplamda 10 bit göndermeniz gerekiyor. Buda demek oluyor ki; usart ile 1 byte göndermek demek 9600bps hızında yaklaşık olarak 1.04ms sürecek. Bu durumda 200us de bir byte göndermeniz mümkün değil. Hızınızı artırmalısınız.

Usart tan iki şekilde veri gönderirsiniz. Birincisi göndereceğiniz paketin byte larını sırayla usart a yazıp gidip gitmediğini kontrol etmek, gittiyse yenisi yazmak. Bu paralel olarak çalışan işlemleriniz varsa onları bloke edeceğinden pek tavsiye edilmez. İkincisi usart tx interrupt ını aktif etmektir. Bir byte gönderimi tamamlandığında tx interrupt ı alırsınız. Interrupt rutininde bir sonraki byte ı buffer a yazıp diğer işlemlerinize dönebilirsiniz. Bu size processor ün gücünü daha efektif bir şekilde kullanmanızı sağlayacaktır.

200us sabit program döngüsü süresi, bu yazılım sadece usart haberleşmesi yapmıyor, diğer işlemleride içeriyor.
200us yi değiştirmek söz konusu değil.

Aşağıdaki kodlarda temelde durumu anlattım . Bu iş acil ve çözmem gerekiyor.

bu haberleşme nasıl hızlandırabilirim.

  
void interrupt isr(void)
{
  if (PIR1bits.TMR1IF && PIE1bits.TMR1IE)
  {
    PIR1bits.TMR1IF = 0;
    TMR1 = 63538;
    SerialComm();
   //diğer işlemler
}
void SerialComm(void)
{
   switch(SerialFlag)
    {
            case 0:
                SerialComm_Receive();
            break;
            case 1:
                SerialComm_Send();
                break;
    }
}
void SerialComm_Receive(void)
{
    if(RCIF==0){goto SerReceiveFinished_1;}
    if(OERR==1){CREN=0;__delay_us(1);CREN=1;goto SerReceiveFinished_1;}
    if(FERR==1){Trash=RCREG;                              goto SerReceiveFinished_1;}
    RCIF=0;
    Rx_Reg++;
           switch(Rx_Reg)
        {
                case 1:
                    Gelen0=RCREG;
                    if(Gelen0==65){break;}
                    else{Rx_Reg=0;break;}

                case 2:
                    Gelen1=RCREG;
                    break;

                case 3:
                    Gelen2=RCREG;
                    Rx_Reg=0;
                    SerialFlag=1;
                    break;
        }
           SerReceiveFinished_1:
            __delay_us(1);
}

void SerialComm_Send(void)
{
     if(TXIF==0){goto SerSendFinished_1;}
     Tx_Reg++;
     switch(Tx_Reg)
     {
         case 1:
                 TXREG=Giden1;
                 break;
         case 2:
                 TXREG=Giden2;
                 SerialFlag=0;
                 Tx_Reg=0;
                 break;
                 
     }
     SerSendFinished_1:
     __delay_us(1);
}

quarko

Alıntı yapılan: OxfordBlue - 17 Ağustos 2015, 16:51:20
her 200us de bir seri haberleşme için yazdığım fonksiyonuna giriyor ve 1 byte data gönderiyor.

Böyle bir ifade kullandığın için başka türlü anlamak mümkün değil maalesef. Hızlanmak istiyorsan, baudrate i artırmalısın. 256kbps ile bir byte data gönderimi ortalama 39us de tamamlanır mesela. Bu da senin için yeterlidir umarım.
"Aslanlar kendi hikayelerini yazmadıkça, avcıların kahramanlık hikayelerini dinlemek zorundayız."

OxfordBlue

hocam baud rate : 9600 olarak ayarlı üstttede yazmıştım .

benim yazılımımdan daha güçlü yazılımla bu baud rateden efektif olarak faydalanmayı umuyorum.

ben şu an her 200us de bir byte gönderebiliyorum. bunu daha hızlandırmak istiyorum.

quarko

Alıntı yapılan: OxfordBlue - 17 Ağustos 2015, 17:34:41
hocam baud rate : 9600 olarak ayarlı üstttede yazmıştım .

benim yazılımımdan daha güçlü yazılımla bu baud rateden efektif olarak faydalanmayı umuyorum.

ben şu an her 200us de bir byte gönderebiliyorum. bunu daha hızlandırmak istiyorum.

9600 baudrate de 200us de 1byte gönderemezsiniz. !!!! (1byte = 10 bit = 1.04ms @9600bps )
"Aslanlar kendi hikayelerini yazmadıkça, avcıların kahramanlık hikayelerini dinlemek zorundayız."

ceyhanan

timer kesmesi yerine TX interrupt kullanın, TXREG boşaldığında kesme üretir. Siz değeri yüklersiniz bu sırada gönderim devam eder. Gönderimde olan datadan sonra TXREG e yüklediğini data gönderilir. Çalışma çevrimi bu şekilde yani arada hiç boşluk vermemiş olursunuz.

OxfordBlue

 quarko hocam tskler.

Peki 115200 baud rate çıkarmak istersem ne yaparım ?
9600u anladım daha hızlı olması durumu için ayrı bir formül arıyorum

quarko

Alıntı yapılan: OxfordBlue - 17 Ağustos 2015, 18:04:49
quarko hocam tskler.

Peki 115200 baud rate çıkarmak istersem ne yaparım ?
9600u anladım daha hızlı olması durumu için ayrı bir formül arıyorum

115200bps de bir byte gönderimi yaklaşık 86.8us de tamamlanır. Dolayısıyla 200us içerisinde gönderim tamamlanmış olur. Ve sağlıklı olarak verilerinizi göndermiş olursunuz. 115200bps ye çıkmak için, kullandığınız mikrodenetleyicinin baudrate ile ilgili register ine gerekli değeri yazman gerekir, o kadar.
"Aslanlar kendi hikayelerini yazmadıkça, avcıların kahramanlık hikayelerini dinlemek zorundayız."