MSP430系列的多机通信有两种实现方式:一种是用地址位来指示地址字符,另一种是用线路足够长的空闲来指示地址字符。以下的点对多点多机通信实例,采用地址位方式实现主机对多机的寻址。一般从机以总线方式和主机连接。每次主机以某一地址呼叫,只有地址相符的从机能识别呼叫并作出响应。
为以下的多机通讯实例设计的简单的协议:
通信帧结构
随机字节 0xFF0xAA0x55 地址 数据 结束
随机字节:在传输的开始发送的任意字节
先导字段:先导字段有0xFF、0xAA和0x55
地址:取值1—16,即主机可以呼叫16个从机之一,发送时地址位有效
结束:0
主机功能:以从机地址呼叫,接着发送字符串,最后以发送0结束。
从机功能:识别呼叫地址,发现相符时接收后续数据,接收到0时结束。
本例值实现了主机向多个从机发送字符串的功能。如果要实现主机接收从机数据,可以修改以上通信协议,增加以下功能:
主机以特定字符串请求从机发送数据,在帧发完一定时间内等待从机响应。
如果主机在请求从机发送后规定时间内未收到响应,即认为超时错,结束等待。
从机在收到请求发送字符串后,发送数据帧响应,可以仍用以上帧格式。
以下是点对多点通信系统的主程序:
/*******************************/
/*说明:UART点对多点多机通信主机程序 */
/*UART1以9600bps,8位数据,1位地址,1位停止模式发送。 */
/*发送地址位时,地址位为1,接着发送字符串,以字符串末的0结束。*/
/*****************************************************************/
Include <msp430x14x.h>
Void Init(void); //声明UART初始化函数
Char Data[11]=”MSP430 Demo”;
Void main()
{
Unsigned int i;
WDTCTL="WDTPW"+WDTHOLD; //关闭看门狗
Init();
While(1)
{
UTCTL1|=TXWKE;
TXBUF1=0x01;
While((UTCTL1&0x01)==0);
UTCTL&=~TXWAKE;
For(i=0;i<=11;i++)
{
TXBUF1=Data;
While((UTCTL1&0x01)==0);
}
}
}
Void Init(void)
{
UCTL1&=~SWRST; //SWRDT复位,UART允许
UCTL1=0x10+MM; //8位数据位,1位停止位,地址位模式
UBR01=0x03;
UBR11=0x00;
UMCTL1=0x4A; //使用32kHZ晶振,波特率为9600bps
UTCTL1=0x10; //选定ACLK(32kHZ晶振)为时钟源
ME2|=0x30; //UART发送,接收模块允许。
P3SEL=0xC0; //P3.6、P3.7由UART1发送模块占用
P3DIR=0x40; // P3.6输出
}
-------------------------------------------------------------------------------
以下是点对多点通信系统的从程序。
/**************************************************************/
/*说明:UART点对多点多机通信从机程序 */
/*UART1以9600bps,8位数据,1位地址,1位停止模式发送。 */
/*当地址位时,确认呼叫,接收后面字符,并检查结束0。 */
/***************************************************************/
Include <msp430x14x.h>
Void Init(void);
#define ADDR 0x01;
Char Data[20],Buffer[20];
Unsigned charj,count;
Void main()
{
WDTCTL=WDTPW+WDTHOLD; //关闭看门狗
Init();
_EINT();
While(1);
}
Void Init(void)
{
UCTL1&=~SWRST; //SWRDT复位,UART允许
UCTL1=0x10+MM; //8位数据位,1位停止位,地址位模式
UBR01=0x03;
UBR11=0x00;
UMCTL1=0x4A; //使用32kHZ晶振,波特率为9600bps
UTCTL1=0x10; //选定ACLK(32kHZ晶振)为时钟源
ME2|=0x30; //UART发送,接收模块允许。
P3SEL=0xC0; //P3.6、P3.7由UART1发送模块占用
P3DIR=0x40; // P3.6输出
IE2=URXIE1; //接收允许中断
}
#pragma vector="UART1RX"_VECTOR
__interrupt void UART1RX(void)
{
If(URCTL&URXWIE) //接收为地址方式时等待正确的地址出现
{
If(RXBUF1==ADDR) //地址正确,改变为接收数据方式,准备接收
{
URCTL1&=~URXWIE;
Count=0;
}
}
else //接收为数据方式时
{
Data[count]=RXBUF1; //数据存入Data数组中
If(Data[count++]==0) //是否到达末尾
{
URCTL1|=URXWIE; //到达末尾时改变接收为地址方式
For(j=0;j<count;j++)
Buffer[j]=Data[j]; //复制字符串
}
}
} |