Asynchronous (Full duplex)
Synchronous - Master (Half duplex)
Synchronous - Slave (Half duplex)
RCSTA中的SPEN (bit 7) 設為1時,enable serial port功能。
同時要將TRISC<7:6>也就是port C的TX/RX pin設為1。才能將TX/RX pin設定正確。
Baudrate Generator (SPBRG)
Serial port有專屬的8 bit timer用來產生baudrate clock。
Baudrate Generator參考系統的Clock Fosc,當TXSTA 的BRGH設為1時,代表高速,所以Baudrate將系統clock /16作為reference.當BRGH是0時,/ 64。
在Synchronous和Aynchronous時,動作不一樣,現在說明Aynchronous:
實際Baudrate的公式是(X是SPBRG的值):
BRGH=0 (LOW Speed)
Baudrate = Fosc/(64(X+1))
BRGH=1 (HIGH Speed)
Baudrate = Fosc/(16(X+1))
所以使用20MHz Crystal,要達到9600的baudrate時,SPBRG 要設為:
BRGH=0
20,000,000/(64 * 9600) -1 = 33.15
BRGH=1
20,000,000/(16 * 9600) -2 =130.2
- 非同步模式Asynchronous Mode (也就是RS232 模式)
- 將TXSTA bit 4 : SYNC 設為0,代表使用非同步模式
- 傳送的register叫TXREG,當TXREG buffer是空的,會將PIR1 的bit 4 : TXIF設為1.
- 這一個bit可以用來產聲中斷 (將PIE bit 4 : TXIE設為1)。這個interrupt和其他interrupt不同,TXIF只有在有新data放入TXREG時才會被clear掉。
- 將data放入TXREG,data並不會送出去,要將TXSTA bit 5 : TXEN 設為1後才會開始送。
- TXIF代表TXREG的資料已經放入Shift register,可以放入下一筆,但並不帶表data已經送出去。
- 真正代表data送出去的flag是TXSTA bit 1 : TRMT.
- 所以要將TXEN關閉時,不能只檢查TXIF,真正要檢察的是TRMT。
- 如果data在shift register中,還沒送玩,就將TXEN關閉,shift register內剩下的資料會送不出去。
傳送的步驟:
- 設定SPBRG,BRGH,決定Baudrate
- 清除SYNC。
- 設定SPEN
- 依照 需要將TX中斷打開(TXIE=1),或關閉(TXIE=0)。
- 將TXEN設為1,開始傳送動作。(同時會使TXIE=1,因為TXREG是空的)。
- 將要傳送的資料放入TXREG。
- 如果有使用中斷,將GIE和PEIE打開。
SPBRG=130;下面是用中斷作的簡單的tx sending.
BRGH=1;
SPEN=1;
SYNC =0;
TXEN=1;
while(1){
while(!TXIF);
TXREG='A';
}
bit TxOk=0;
char TxBuf[10];
char Txi;
char TxLen;
void interrupt inthandler(void)
{
if(TXIF){
if(Txi < TxLen){
TXREG=TxBuf[Txi];
Txi++;
}else{
TxOk=1;
TXIE=0;
}
}
}
const char *outstr="Hello!";
void main(void)
{
char i;
SPBRG=130;
BRGH =1;
SPEN =1;
SYNC =0;
PEIE=1;
GIE =1;
TXEN=1;
i=0;
TxLen=0;
while(outstr[i]!=0x00){
TxBuf[i]=outstr[i];
TxLen++;
i++;
}
TxOk=0;
TXIE =1;
while(!TxOk);
while(1);
}
接收
Baudrate和Asynchronouse設定跟TX的設定一樣。
- 設定CREG後,Receive Register才開始動作。
- 當收到data後RCIF會被設為1。
- 收到的資料會被放在RCREG。如果有overflow, OERR會被設為1。要清除OERR,要將CREG設為0後再設為1。Reset Receive Logic.
- 當OERR是1,接收動作會停止。
- 當Stop bit收到0時,Framing Error bit : FERR會被設為1,但是一但讀取RCREG後,FERR的值就會倍update掉了,所以在讀取RCREG之前,最好先讀取FERR的值,確認RCREG的內容是正確的
設定接收動作的procedure:
- 設定SPBRG和BRGH bit,決定baudrate
- SYNC=0, SPEN=1.
- 如果要中斷,RCIE=1
- CREN=1,開始接收
- 收到資料後RCIF=1. 如果有設RCIE的話,會中斷
- 讀取RCSTA的FERR好知道stop bit是不是正確。
- 讀取RCREG取得收到的資料
- check error,如果有的話,將CREG=0,再CREG=1
- 如果要中斷,GIE和PEIE要設為1
沒有留言:
張貼留言