//===========================================================================//
// MSP430接收中继端协议——徐方鑫 //
// 通讯协议格式为:16进制发送 //
// 53 09 AA AA AA AA AA AA 45 //
// 53为数据包打头,字符's' //
// 09为字符串长度,char类型 //
// 其后AA AA AA 等为数据内容 //
// 45为数据包结尾,字符'E' //
//===========================================================================//
#include "msp430x54x.h"
#include
#include
#include
#include "PIN_DEF.H"
#define uchar unsigned char
#define uint unsigned int
#define FLL_FACTOR 749 // FLL_FACTOR: DCO倍频系数
#define DATA_BAG_ERROR_MAX 0x5000 //最大数据包长度,int类型,串口所用8位基本都支持
char event; //待机模式事件
uint Data_Bag_Length,Data_Length; //Data_Bag_Leangth接收数据包的长度
char RXBuffer[20]; // 接收缓存
//***************************************************************************//
// //
// 初始化主时钟: MCLK = XT1×(FLL_FACTOR+1) //
// //
//***************************************************************************//
void Init_CLK(void)
{
WDTCTL = WDTPW + WDTHOLD ; // 关看门狗
P7SEL |= 0x03 ; // 端口选择外部低频晶振XT1
UCSCTL6 &=~XT1OFF ; // 使能外部晶振
UCSCTL6 |= XCAP_3 ; // 设置内部负载电容
UCSCTL3 |= SELREF_2 ; // DCOref = REFO
UCSCTL4 |= SELA_0 ; // ACLK = XT1
__bis_SR_register(SCG0) ; // 关闭FLL控制回路
UCSCTL0 = 0x0000 ; // 设置DCOx, MODx
UCSCTL1 = DCORSEL_7 ; // 设置DCO振荡范围
UCSCTL2 = FLLD__1 + FLL_FACTOR ; // Fdco = ( FLL_FACTOR + 1)×FLLRef = (649 + 1) * 32768 = 21.2992MHz
__bic_SR_register(SCG0) ; // 打开FLL控制回路
__delay_cycles(1024000) ;
do
{
UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG); // 清除 XT2,XT1,DCO 错误标志
SFRIFG1 &= ~OFIFG ;
}while(SFRIFG1&OFIFG) ; // 检测振荡器错误标志
}
//***************************************************************************//
// //
// Init_Port(void): 设置IO端口 //
// //
//***************************************************************************//
void Init_Port(void)
{
P5DIR |= POWER ; // 主电源
MAIN_POWER_ON ;
P7DIR |= LED_PWR ; // 发光二极管电源
P7OUT &=~LED_PWR ;
INTERNAL_PULL_UP ; // 使能键盘端口内部上拉电阻
ROW_IN_COL_OUT ; // 设置行输入,列输出0
}
//***************************************************************************//
// //
// Init_UART(void): 初始化USB端口 //
// //
//***************************************************************************//
void Init_UART(void)
{
USB_PORT_SEL |= TXD_U + RXD_U ; // 选择引脚功能
USB_PORT_DIR |= TXD_U ; // 选择引脚功能
UCA1CTL1 = UCSWRST ; // 状态机复位
UCA1CTL1 |= UCSSEL_1 ; // CLK = ACLK
UCA1BR0 = 0x03 ; // 32kHz/9600=3.41
UCA1BR1 = 0x00 ;
UCA1MCTL = UCBRS_3 + UCBRF_0 ; // UCBRSx=3, UCBRFx=0
UCA1CTL1 &= ~UCSWRST ; // 启动状态机
UCA1IE |= UCRXIE ; // 允许接收中断
}
//***************************************************************************//
// //
// UTX_PROC(void): USB端口发送程序 //
// //
//***************************************************************************//
void UTX_PROC(char *tx_buf)
{
unsigned char i,length;
length = strlen(tx_buf);
for(i=0;i
{
UCA1TXBUF = *tx_buf++;
// __delay_cycles(5000);
while (!(UCA1IFG&UCTXIFG));
}
}
//***************************************************************************//
// //
// UTX_PROC(void): USB端口发送程序 //
// //
//***************************************************************************//
void Data_Bag_Send(char *tx_buf)
{
unsigned char i,length_all,length; //声明数据总长度,length_all为转发数据包,length为不带转发数据包
length_all = strlen(tx_buf)+Data_Length; //转发数据包为待发送数据长度+转发数据长度
length = strlen(tx_buf); //length为本身数据长度,当无转发数据时从串口发送
UCA1TXBUF = 'S'; //发送启始指令'S',八进制为0x53
while(!(UCA1IFG&UCTXIFG)); //等待发送完成
if(Data_Length
{
UCA1TXBUF = length_all+3; //发送数据总长度
while(!(UCA1IFG&UCTXIFG)); //等待发送完成
for(i=2;i<2+Data_Length;i++) //发送转发数据包
{
UCA1TXBUF = RXBuffer[i];
while(!(UCA1IFG&UCTXIFG));
}
}
else
{
UCA1TXBUF = length+3; //没有中继数据的时候,直接发送数据包
while(!(UCA1IFG&UCTXIFG));
}
for(i=0;i
{
UCA1TXBUF = *tx_buf++; //发送本地数据包
// __delay_cycles(5000);
while (!(UCA1IFG&UCTXIFG));
}
UCA1TXBUF = 'E'; //发送包尾'E'
}
//***************************************************************************//
// //
// 主函数 //
// //
//***************************************************************************//
void main( void )
{
int i;
WDTCTL = WDTPW + WDTHOLD; //看门狗关闭
Init_CLK(); //时钟初始化
Init_Port(); //IO端口初始化
Init_UART(); //串口初始化
_EINT(); //启动中断
for(;;)
{
if(event)
{
event = 0x00;
UTX_PROC(RXBuffer);
}
if((P6IN&0x0F)!=0x0F) // 检测按键按下
{
//UTX_PROC(Data_Bag);
//UTX_PROC(RXBuffer);
//UTX_PROC(&Data_Length);
Data_Bag_Send("123"); //本地数据包为123
__delay_cycles(5000000);
}
}
}
//***************************************************************************//
// //
// USB接收中断服务程序 //
// //
//***************************************************************************//
#pragma vector=USCI_A1_VECTOR
__interrupt void USCI_A1_ISR(void)
{
static char rx_byte = 0x00; //接收字段初始化
unsigned char temp,event = 0x00; //BUFFER空间,还有待机模式初始化
switch(__even_in_range(UCA1IV,4))
{
case 0:break; // Vector 0 - no interrupt
case 2: // Vector 2 - RXIFG
temp = UCA1RXBUF;
if(rx_byte==0)
{
if(temp=='S')
{
RXBuffer[0] = UCA1RXBUF; //如果首位为's’接收数据
rx_byte++; //计数
}
}
else
{
RXBuffer[rx_byte++] = temp;
if(rx_byte>=RXBuffer[1]) //若数据还在接收范围内部,接收数据
{
Data_Bag_Length = RXBuffer[1]; //数据总长赋值
Data_Length=Data_Bag_Length-3; //数据长赋值
if(RXBuffer[rx_byte-1] == 'E') //如果数据尾巴为E,保存数据
{
rx_byte = 0x00;
event |= 0x01;
}
else //否则,在数据总长不对或者数据尾不对的情况下,删除数据
{
rx_byte = 0x00;
for(temp=0;temp<20;temp++)
RXBuffer[temp] = 0x00; // 通讯有误,清除缓冲区
}
}
}
break;
case 4:break; // Vector 4 - TXIFG
default: break;
}
if(event)
LPM3_EXIT; //唤醒待机模式
}
上一篇:MSP430驱动DDS模块AD9851
下一篇:MSP430F5438无线温度发送
推荐阅读最新更新时间:2024-03-16 15:36