Ultra Fast Soft UART TX, 8 Mhz Mcu, 333.3 Kbaud

Başlatan Erol YILMAZ, 03 Mayıs 2013, 03:47:24

Erol YILMAZ

Pic Mcu dan hızlı şekilde UART çıkışı almam gerekiyordu,
Donanımsal pinler de pcb çizimi sırasında ayrılmadığı için Soft UART'a mahkum kaldım...

Açıkçası google da aramama rağmen yüksek hızlarda soft uart bulamadım.
"Fast Soft uart" olarak aradığımızda belki de çıkan tek konu başlığı artık bu.

Bu tarz bir kod Başlangıçta basit görünmüştü ama yüksek hızlarda kodlardaki hatalar ortaya çıkmaya başladı.
Logic Analyzer ile incelediğimde 0 ın ve 1'in aynı anda yazılmamasından dolayı 1 ve 0 lı karışık yazmada 1 cycle (0.5 uS) kayma oluyordu.

Cihan'ın yardımı ile bu kodu geliştirdim.
Standart bir hız değil Max hız lazım olduğu için 333.333 Kbaud hızını elde ettim.
Kısaca bir bit 3 uS tutuyor.

1-0 süreleri eşit olması için biraz uğraştık, hoş bir mantık kurduk.

TeraTerm ve Docklight programında istediğiniz Baud rate i yazabiliyorsunuz...
Yalnız Docklight hızlı gönderilerde şişip kilitlendiğini gördüm.
TeraTerm ise sürekli verilerde bile muhteşem çalışıyor...

Hi-tech PICC'de dahili ASM komutlarını kullanmak için de güzel bi referans old. düşünüyorum.
Muhtemelen XC8'de de aynı şekildedir.

CCS'nin soft uartını zorladığımızda benzer şartlarda Max. 120 KBaud hızına ulaşabildik.
-------------------------------------------------------------------------------------------------------------------------
***Aynı düzgünlükte daha kısa sürede halledebilirim diyen varsa kodlarını görmek isterim.

Gönderim hızını değiştirmek isterseniz bit gönderimlerinden sonra istediğiniz kadar NOP ekleyebilirsiniz.


// usart.h
    #ifndef _SERIAL_H_

    #define _SERIAL_H_

    #define	UART_PIN_TX			PORTC,3

    void putch(unsigned char);
#endif


// usart.c

// 3 uS bit süresi ile yaklaşık 333.3 KBaud hızında softUart
// Osc : 8Mhz 

#include <htc.h>
#include <stdio.h>
#include "usart.h"

extern unsigned char i;
extern unsigned char lastGie;

void putch(unsigned char kk){

    i=kk;

    #asm
        #include <aspic.h>

        BANKSEL PORTA

        BCF     _lastGie, 7
        // GIE == 1 ise lastGie = 1
        BTFSC   INTCON, 7
        BSF     _lastGie, 7

        // Her türlü durumda GIE Kapat !
        BCF     INTCON, 7

    	// Start Bit
    	BCF     UART_PIN_TX
        NOP
        NOP

        // LSB
        BTFSC   _i,0
        GOTO    $+4
        NOP
        BCF     UART_PIN_TX
        GOTO    $+4
        BSF     UART_PIN_TX
        NOP
        NOP

        // 1. bit
        BTFSC   _i,1
        GOTO    $+4
        NOP
        BCF     UART_PIN_TX
        GOTO    $+4
        BSF     UART_PIN_TX
        NOP
        NOP

        // 2. bit
        BTFSC   _i,2
        GOTO    $+4
        NOP
        BCF     UART_PIN_TX
        GOTO    $+4
        BSF     UART_PIN_TX
        NOP
        NOP

        // 3. bit
        BTFSC   _i,3
        GOTO    $+4
        NOP
        BCF     UART_PIN_TX
        GOTO    $+4
        BSF     UART_PIN_TX
        NOP
        NOP

        // 4. bit
        BTFSC   _i,4
        GOTO    $+4
        NOP
        BCF     UART_PIN_TX
        GOTO    $+4
        BSF     UART_PIN_TX
        NOP
        NOP

        // 5. bit
        BTFSC   _i,5
        GOTO    $+4
        NOP
        BCF     UART_PIN_TX
        GOTO    $+4
        BSF     UART_PIN_TX
        NOP
        NOP

        // 6. bit
        BTFSC   _i,6
        GOTO    $+4
        NOP
        BCF     UART_PIN_TX
        GOTO    $+4
        BSF     UART_PIN_TX
        NOP
        NOP

        // 7. bit
        BTFSC   _i,7
        GOTO    $+4
        NOP
        BCF     UART_PIN_TX
        GOTO    $+4
        BSF     UART_PIN_TX
        NOP
        NOP
        NOP
        NOP
        NOP

    	// Stop Bit
        BSF     UART_PIN_TX

        // lastGie == 1 ise GIE=1 yap.
        BTFSC   _lastGie,7
        BSF     INTCON, 7

        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
    #endasm

return;
}


NOTLAR :

-  i ve lastGie GLOBAL unsigned char değişkenlerdir.

-  Çıkış pin ve portunu değiştirmek için usart.h içindeki tanımı değiştirmek gerekmektedir.

-  Çıkış, yazılımla sağlandığı için Putch içinde Int. kapatmak durumundayız, Kod içinde otomatik olarak yapılmaktadır.

-  Hi-tech PICC, ASM bloğu içinde sadece global değişkenleri tanıdığı için ASM bloğundaki değişkenler GLOBAL tanımlanmıştır.

-  Hi-tech  PICC Pro 9.65 versiyonu ile derlenmiştir.

-  Printf, putch() fonksiyonuna yönlendirilmiştir.



ISIS simulasyonunda, 0xC7 sayısı gönderilmiştir. Skop :  2 uS / div

Çok fazla deneyemedim, başarılı old. düşünüyorum...

Denedim, bence gayet düzenli çalışıyor...

Bu da logic çıkışı: