MSP430單片機多機通信總結

1、硬件條件:MSP430F149;

2、編譯環境:IAR5.3;

3、過程中所發現的問題

(1)串口配置所存在的問題

 主機的程序也需要設定爲多機模式,並且主機也需要有地址 !

a)、主機串口配置程序

void usart1_init(void)
{
  U1CTL |=SWRST;  //SWRST復位,USART允許
  U1CTL=CHAR+MM;  //8位數據位,1位停止位,地址位模式,0x01
//  U1CTL=CHAR;
//  U1BR0=0X03;     //0x03位9600,0x06時爲4800
//  U1BR1=0X00;
//  U1MCTL=0X4A;    //使用32KHZ晶振時,波特率爲9600bps時爲0x4A,波特率爲4800bps時爲0x6f
//  UTCTL1=0X10;
  //11520
  U1BR0=0X45;
  U1BR1=0X00;
  U1MCTL=0X00;
  U1TCTL|= SSEL1;
  
  U1CTL &= ~SWRST;//  設置完成
  
  U1RCTL |= URXWIE;//只有地址字符使URXIFG置位
  
  ME2 |= UTXE1 + URXE1;//允許串口接收與發送
  P3SEL |=0XC0;   //P3.6、P3.7由USART1發送模塊佔用
  P3DIR |=0X40;   //P3.6輸出,P3.7輸入
  IE2 |=URXIE1;   //接收中斷
  _EINT();        //不要忘了開中斷
}

b)、主機發送數據過程

先發送地址,再發送數據。主機向從機發送數據的程序如下:

//**************************************************//
//address表示從機地址
//*pBuffer表示要發送數據的指針
//n_byteb表示數據長度
//**************************************************//
void USART1_Send(uchar addr,uchar *pBuffer,uchar n_byte)
{
  unsigned int i;
  
  UTCTL1 |=TXWAKE;
  TXBUF1=addr;
  while((UTCTL1&0X01)==0); //查詢等待一次發送完畢 
  UTCTL1&=~TXWAKE;
  for(i=0;i<n_byte;i++)
  {
    while((UTCTL1&0X01)==0);
    TXBUF1=*pBuffer;
    pBuffer++;        
  }
}

c)、主機串口接收中斷

先把接收到的第一個數據與本機的地址進行對比,如果地址一致,說明數據是發給本機的,通過設置U1RCTL&=~URXWIE;,後面接收的爲數據;如果不死本機的地址,則仍然處於接收地址狀態,後面從機發送的數據將不會觸發本接收中斷。程序如下:

//接收中斷服務函數

#pragma vector=UART1RX_VECTOR 
__interrupt void USART1_RXIRQ (void) 
{
  Data1[NRxBuff++]=RXBUF1;
  if(URCTL1&URXWIE) //接收爲地址方式時,等待正確地址出現,URXWIE,RXWAKE
  {
    if(RXBUF1==ADDRESS) //地址正確,改變接收爲數據方式,準備接受
    {
      U1RCTL&=~URXWIE;
      flag=1;
    }
    else
    {
      U1RCTL |= URXWIE;   //不是本機地址,則以後接收到數據不產生中斷
    }
  }
  if((flag==1)&&(!(URCTL1&URXWIE)))
  {
      num++;
      if(num>1)//避免把地址作爲第一位數據  
        Data1[NRxBuff++]=RXBUF1; //數據存入Data數組中
      if(NRxBuff==N_XY_BAO)
      {
        USART0_SendUint(RXBUF1);
        NRxBuff=0;
        flag_send=1;
        flag=0;
        num=0;    
        URCTL1|=URXWIE; //改變接收爲地址方式,URXWIE        
        for(j1=0;j1<N_XY_BAO;j1++)
          aRxBuff[j1]=Data1[j1]; //複製字符串
        memset(Data1,0,36);//數組清零
      }
    }
  
    else
    {
      URCTL1|=URXWIE; //改變接收爲地址方式,URXWIE
      memset(Data1,0,36);//數組清零
      NRxBuff=0;
    }

}


d)、從機串口配置程序

void usart1_init(void)
{
  P3SEL |=0XC0;   //P3.6、P3.7由USART1發送模塊佔用
  P3DIR |=0X40;   //P3.6輸出,P3.7輸入
  UCTL1 |=CHAR+MM+SWRST;   //8位數據位,1位停止位,地址位模式,0x01,
//  UCTL1 |=CHAR+SWRST;
//  U1BR0=0X03;     //0x03位9600,0x06時爲4800
//  U1BR1=0X00;
//  U1MCTL=0X4A;    //使用32KHZ晶振時,波特率爲9600bps時爲0x4A,波特率爲4800bps時爲0x6f
//  U1TCTL=0x10;    //選定ACLK(32KHZ晶振)爲時鐘源,0x1 
  //115200
  U1BR0=0X45;
  U1BR1=0X00;
  U1MCTL=0X00;
  U1TCTL|= SSEL1;  
  
  U1RCTL|=URXWIE; //改變接收爲地址方式
  U1CTL &= ~SWRST;
  ME2 |= UTXE1 + URXE1;//允許串口接收與發送  
  IE2 |=URXIE1;   //接收中斷
  //_EINT();      //開總中斷  ,工程中其他的程序已經打開了總中斷
}

從機的數據發送與串口接收中斷的程序基本一致,在此就不再贅述。

2)多個從機接在一塊,通訊仍不正常

通過測試發現是從機串口的TxD造成的,在不發數據的狀態下,TxD爲高電平,造成整個總線上的電平不準確,所以從機需要在發送完數據後把串口的TxD設置爲普通IO口,並且設置爲輸入狀態!

3)當主機程序存在多箇中斷時,通訊有可能不能正常進行

最近在做一個項目,主機用到了3箇中斷:timeB定時溢出中斷、usart0和usart1的串口接收中斷。這樣串口就很有可能不能接收到正確和完整的數據。解決辦法有:

a)、在串口接收到本機地址後關閉其他中斷,待數據接收完後立即打開其他中斷;

b)、如果其他中斷比較重要,不能隨便的關閉,這是就需要對串口接收的數據做好容錯處理,要去判斷接收數據是否完成,接收過程中是否被打斷過,等等。

 

 

 

 

          

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章