各位同仁,響應(yīng)版主號召,現(xiàn)就"愛好者"同志提出的<<關(guān)于UART的地址位多機(jī)通訊>>做出本人的見解.希望大家多多指點.在430串口發(fā)送格式中,我們可以看到.一個字節(jié)由1個起始位+7位或8位數(shù)據(jù)位+校驗位+1位或2位停止組成.如果要使用430的地址位多機(jī)協(xié)議.主要是將UxCTL寄存器中的MM位置1,同時將UxRCTL寄存器中的URXWIE置1. 例程如下: 上位機(jī)先用Mark校驗方式.格式為:1個起始位+8位數(shù)據(jù)位+1位校驗位+1位停止位. 發(fā)送5個字節(jié):0x02(地址號) 0x05(命令字節(jié)) 0x00(預(yù)留字節(jié)) 0x07(累加和校驗低字節(jié)) 0x00(累加和校驗高字節(jié)) 單片機(jī)接收程序如下,同時將收到的數(shù)據(jù)再返回給上位機(jī). 程序中所使用的變量.請自行定義.有標(biāo)注說明.
void COM_Init(void) {//---------------------------------串口初始化函數(shù) U0CTL &= ~SWRST; U0TCTL&=~TXWAKE; U0CTL|=CHAR+MM;//8bit+地址位多機(jī)協(xié)議 IFG1&=~(URXIFG0+UTXIFG0);//接收,發(fā)送中斷標(biāo)志清零 ME1|=(UTXE0+URXE0); //使能接收和發(fā)送中斷 U0TCTL|=SSEL0+SSEL1; //時鐘選擇--MCLK UBR10=0x04;//6M/4800 UBR00=0xe2; UMCTL0=0x00;//波特率調(diào)整控制 IE1|=URXIE0;//使能接收中斷 URCTL0|=URXWIE;//只有收到地址字符時才永許中斷
} #pragma vector=USART0RX_VECTOR//接收中斷處理 __interrupt void USART0RX(void) {// addr為本機(jī)地址號 unsigned char date,date1; _EINT(); if((URCTL0&0x21)==BIT0)//RXERR {//出現(xiàn)錯誤且該錯誤非溢出引起 URCTL0=URXWIE;//只有收到地址字符時才允許中斷 ought_receive=0;//應(yīng)接收個數(shù)變量 mling_flag=0; //命令標(biāo)志變量 order=0;//命令變量 date=RXBUF0; } else { date=RXBUF0; URCTL0&=~RXERR;//接收錯誤清零 if(URCTL0&URXWIE)//接受到地址位否? { if(date==addr) { URCTL0&=~URXWIE; jieshou_ljh=date; } order=0; ought_receive=0; mling_flag=0; } else//接受命令、數(shù)據(jù) { date1=date; if((mling_flag&0x01)==0x00) { order=date; jieshou_ljh+=date;//計算累加和 switch(date) { case 0x05://命令 ought_receive=3;//除命令字節(jié)外還要接收3個字節(jié) fmaddr=0; mling_flag|=0x01;//已收到命令字節(jié),下一字節(jié)應(yīng)為數(shù)據(jù) break; default: URCTL0=URXWIE; ought_receive=0; order=0; mling_flag=0; jieshou_ljh=0; P2OUT&=~BIT7; break; } } else { if(ought_receive==0)//接收出錯 { URCTL0|=URXWIE;//只有收到地址字符時才永許中斷 date1=RXBUF0; P2OUT&=~BIT7;//RS485 控制信號 jieshou_ljh=0; order=0; mling_flag=0; } else { if(ought_receive==2)//收到累加和的低位 { ought_receive=1; txy=date; } else if(ought_receive==1)//收到累加和的高位,表示接收完畢,可以處理并發(fā)送數(shù)據(jù) { P2OUT|=BIT7;//RS485 控制信號 ought_receive=0; date1=(unsigned char)txy;//計算累加和. txy=(unsigned int)date; txy<<=8; txy|=date1; _NOP(); if(jieshou_ljh==txy) { IE1&=~URXIE0;//關(guān)閉接收中斷 ME1|=UTXE0;//USART0允許發(fā)送數(shù)據(jù) UTCTL0|=TXWAKE;//USART0發(fā)送地址位 ME1|=UTXE0//USART0允許發(fā)送 IFG1&=~(UTXIFG0+URXIFG0); TXBUF0=addr;//--------------------------------------------------------地址 while((UTCTL0&BIT0)==0);//當(dāng)發(fā)送空時,TXEPT=1 TXBUF0=order;//--------------------------------------------------------命令 while((UTCTL0&BIT0)==0);//當(dāng)發(fā)送空時,TXEPT=1 TXBUF0=0x00;//--------------------------------------------------------預(yù)留 while((UTCTL0&BIT0)==0);//當(dāng)發(fā)送空時,TXEPT=1 TXBUF0=0x07;//--------------------------------------------------------累加和低 while((UTCTL0&BIT0)==0);//當(dāng)發(fā)送空時,TXEPT=1 TXBUF0=0x00;//--------------------------------------------------------累加和高 while((UTCTL0&BIT0)==0);//當(dāng)發(fā)送空時,TXEPT=1 ME1&=~UTXE0;//開始下一次數(shù)據(jù)幀接收 ME1|=URXE0; IE1&=~(UTXIE0+URXIE0); IFG1&=~(UTXIFG0+URXIFG0); ought_receive=0; jieshou_ljh=0; URCTL0=URXWIE; IE1|=URXIE0; mling_flag=0; P2OUT&=~BIT7;//轉(zhuǎn)為收 } } else if(ought_receive>2) { ought_receive--; jieshou_ljh+=date;//計算累加和. receive_buf[fmaddr]=date;//數(shù)據(jù)存放數(shù)組 fmaddr++; } } } } } } |