先谢谢“boyyuboy ”,不好意思,我重发一份。情况是PC只能收到第一包。如果屏蔽第一包则只能收到第二包。如果PC重新发别的字符(长度任意`),每次返回来的还是改变发送字符之前的字符,好像PC第一次发送时,程序一直卡在发送第二个包上,所以串口接收计数一直都没清0
[CODE]
#include <msp430x14x.h>
//=================================================================
#define uchar unsigned char
#define uint unsigned int
//==================TXEN,TRX_CE,PWR_0 为收发模式控制端口==========
#define TXEN_0 P6OUT &=~BIT2 // TX_EN输出0
#define TXEN_1 P6OUT |= BIT2 // TX_EN输出1
//=================================================================
#define TRX_CE_0 P6OUT &=~BIT1
#define TRX_CE_1 P6OUT |= BIT1
//==============================================================
#define PWR_0 P6OUT &=~BIT0
#define PWR_1 P6OUT |= BIT0
//================SPI使能端口======================
#define CSN_0 P5OUT &=~BIT0
#define CSN_1 P5OUT |= BIT0
//===下为状态端口========================================
//===============AM 地址匹配================
#define AM P2IN & BIT6
//===============DR 数据接收状态=================
#define DR P2IN & BIT7
//=============CD 载波侦听状态========
#define CD P2IN & BIT5
//================================================
//=============NRF905:SPI指令=========
#define WC 0x00 // 写配置寄存器命令
#define RC 0x10 // 读配置寄存器命令
#define WTP 0x20 // 写TX有效数据命令
#define RTP 0x21 // 读TX有效数据命令
#define WTA 0x22 // 写TX地址命令
#define RTA 0x23 // 读TX地址命令
#define RRP 0x24 // 读接收有效数据命令
uchar TxBuf[96]; // 缓存里32个等发送的字
uchar RxBuf[32]; // 缓存里32个待接收的字
uchar TxAddress[4]={0xE7,0xE7,0xE7,0xE7}; // 4个字节的发送地址
uchar DATA_BUF; // 本字符变量作暂存用
uchar k=0;
//============NRF905:10寄存器配置=================
unsigned char RFConf[11]=
{
WC, //SPI写操作命令
0x4c, //CH_NO,配置频段在430MHZ
0x0C, //输出功率为10db,不重发,节电为正常模式
0x44, //地址宽度设置,为4字节
0x20,0x20, //接收发送有效数据长度为32字节
0xE7,0xE7,0xE7,0xE7, //接收地址
0x5F //CRC充许,8位CRC校验,外部时钟信号输出500K,16M晶振
};
/********************************************************************
系统初始化
*********************************************************************/
void InitSys()
{
uint i;
BCSCTL1 &=~XT2OFF; //启用XT2振荡器
do
{
IFG1 &= ~OFIF; // 清除振荡器失效标志
for (i = 0xFF; i > 0; i--); // 延时,等待XT2起振
}
while ((IFG1 & OFIFG) != 0); // 判断XT2是否起振
BCSCTL2 =SELM1+SELS; // MCLK,SMCLK时钟为XT2
//----LED测试用-----
P4DIR |= BIT6;
P4OUT |= BIT6;
//----串口0设置RS232------
P3SEL |= BIT4+BIT5; //UART0 TX,RX
P3DIR |= BIT4;
ME1 |= UTXE0+URXE0;
U0CTL |= CHAR+SWRST; // 数据位为8位
U0TCTL = SSEL1; //波特率时钟源为SMCLK
UBR0_0 = 0x41; //8M/9.6K
UBR1_0 = 0x03; //
UMCTL_0= 0x49;
//UBR0_0 = 0x82; //8M/4.8K
//UBR1_0 = 0x06; //
//UMCTL_0= 0xAD;
IFG1 &= ~UTXIFG0;
U0CTL &= ~SWRST;
IE1 |= URXIE0; // 使能接收中断
//------串口1设置SPI--------
P5SEL |= BIT3+BIT2+BIT1;// P5.0--STE1 CSN P5.1--SIMO1 P5.2--SOMI1 P5.3--CLK1
P5SEL &= ~BIT0; // P5.0CSN作普通IO
P5DIR |= BIT3+BIT1+BIT0; // 都作输出
P5OUT |= BIT3+BIT1+BIT0; // 都输出高电平
UCTL1 |= SWRST;
UCTL1 |= CHAR+SYNC+MM; // 数据8位,SPI模式,单片主机模式
UTCTL1 &= ~(CKPH|CKPL); // SPI时钟设置
UTCTL1 |= SSEL1+STC; // 时钟源为SMCLK 3线模式
ME2 |= USPIE1; // 使能SPI模块
UBR0_1 = 0x02; // 8M/4M=8 SPI 4M速率
UBR1_1 = 0x00; //
UMCTL_1= 0x00;
U1CTL &= ~SWRST;
//IE2 |= URXIE1+UTXIE1;
}
//=========初始化nRF905===================
void nRF905_IO_set(void)
{
//P5DIR |= BIT0+BIT1+BIT3;// P5.0-CSN,P5.1-MOSI,P5.3-SCK都为输出 P5.2-MISO
P6DIR |= BIT0+BIT1+BIT2; // P6.0-PWR_UP,P6.1-TRX_CE,P6.2-TXEN都为输出
P2DIR &= ~(BIT5+BIT6+BIT7); // P2.5-CD,P2.6-AM,P2.7-DR 都为输入
P2IE |= BIT7; // 使能P2.7 中断并且上升沿触发
CSN_1; // Spi disable
PWR_1; // nRF905上电
TRX_CE_0; // nRF905进入待机模式
TXEN_0; // 进入接收模式
}
//===========10uS延时 (8M主时钟)====================
void delay_10us(uint x)
{
uchar q;
for(uchar i=0;i<x;i++)
{
for(q=17;q>0;q--);
}
}
//===============NRF905 SPI读函数==================
uchar SpiRead(void)
{
U1TXBUF=0;
while(!(U1TCTL&TXEPT));
return U1RXBUF;
}
//==============NRF905 SPI读写函数==================
void SpiWrite(uchar send)
{
U1TXBUF=send;
while(!(U1TCTL&TXEPT)); //等待发送器为空
}
//==============初始化NRF905========================
void Config905(void)
{
uchar i;
CSN_0; // 使能SPI
for (i=0;i<11;i++) // 写配置字,共要写完配置寄存器里的10个字配置字
{
SpiWrite(RFConf[I]);
}
// while(!(IFG2&UTXIFG1));
CSN_1; //关闭SPI
}
//--------定时器A初始化-------------
void Timer_A_init()
{
CCTL0=CCIE; // CCR0中断允许
TACTL=TASSEL_2+TACLR+MC_1+ID1+ID0;//定时器A时钟源为SMCLK并且8分频,计数器清0,增计数模式
}
//===============接收模式===============
void SetRxMode(void)
{
TXEN_0;
TRX_CE_1;
delay_10us(70); // delay for mode change(>=650us)
}
void SetTxMode(void)
{
TXEN_1;
TRX_CE_0;
delay_10us(70); // delay for mode change(>=650us)
}
//=========NRF905装载地址+数据打包+数据发送=============
void TxPacket(uchar a,uchar b)
{
uchar i;
CSN_0; // 使能SPI
SpiWrite(WTA); // 写入地址命令
for (i=0;i<4;i++) // 4字节地址
{
SpiWrite(TxAddress[I]);
}
CSN_1; // 写完后关闭SPI
delay_10us(1);
CSN_0; // 再打开SPI
SpiWrite(WTP); // 写装载TX有效数据命令
for (i=a;i<b;i++) // 写TX有效数据 {
SpiWrite(TxBuf[I]);
//TxBuf[I]=0;
}
CSN_1; // 再关闭SPI
TRX_CE_1; // 开始发射
//delay_10us(2); //10us的脉冲以确保数据发送完。《如果用本句PC只能收一次数据》
while(!(DR)); //若DR为低则一直等待 。??本句等待时间很长,不知为啥??
TRX_CE_0; //905待机
//TXEN_0;
}
//==========数据接收==================
void RxPacket(void)
{
uchar i;
TRX_CE_0;
CSN_0; // SPI使能
SpiWrite(RRP); // SPI读接收有效数据命令
for (i = 0 ;i < 32;i++)
{
RxBuf[I]=SpiRead(); // 从NRF905读数据至数组
}
//while(DR||AM); //等待数DR或AM变低即据接收完毕
CSN_1;
delay_10us(1);
for (i = 0 ;i <32;i++)
{
if(RxBuf[I]!=0)
{
while(!(IFG1&UTXIFG0)); // 等待发送器为空
TXBUF0 = RxBuf[I]; // 将接收的数据通过串口发送至PC或其它设备
//RxBuf[I]=0;
// while(!(U0TCTL&TXEPT)); // 等待发送器为空
}
}
delay_10us(1);
TRX_CE_1;
delay_10us(70); //切换进入接收状态
P4OUT |= BIT6;
}
//===========主函数================
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // 禁止看门狗
InitSys(); // 系统初始化
nRF905_IO_set(); // NRF905初始化
Config905(); // 配置NRF905的配置寄存器
Timer_A_init(); //定时器初始化
SetRxMode(); //接收模式
_EINT(); // 开总中断
while(1)
{
// LPM1;
}
}
#pragma vector = UART0RX_VECTOR
__interrupt void usart0_rx()
{
// LPM1_EXIT;
TACTL &= ~(MC1+MC0); //停止计数器
TACTL |= TACLR+MC0; // 清除计数器内容重新计数
CCR0=1500; // 重新启动增计数模式
TxBuf[k]=RXBUF0; // 接收数据先暂存
k++;
}
#pragma vector = PORT2_VECTOR //905中断接收
__interrupt void PORT2_rx()
{
// LPM1_EXIT;
P2IFG &= ~BIT7; // 清除标志
if((DR)&&(AM)) // 若接收的地址与数据 正确
RxPacket(); // 接收数据包并发送至PC或其它设备
}
#pragma vector = TIMERA0_VECTOR//本中断程序的启动表示本次所有数据串口接收完毕
__interrupt void Timer_A()
{
//LPM1_EXIT;
TACTL &= ~(MC1+MC0); //接收转发完了 停止计数器
if((k>0)&&(k<=32))
{
SetTxMode();
TxPacket(0,32); // 发送数据包
k=0;
}
else if((k>32)&&(k<=64))
{
SetTxMode();
TxPacket(0,32); // 发送数第1包据包
//delay_10us(1000);
TxPacket(32,64); // 发送数第2包据包
k=0;
}
else if((k>64)&&(k<=96))
{
SetTxMode();
TxPacket(0,32); // 发送数第1包据包
// delay_10us(1000);
TxPacket(32,64); // 发送数第2包据包
// delay_10us(1000);
TxPacket(64,96); // 发送数第3包据包
k=0;
}
else if((k>96)&&(k<=128))
{
SetTxMode();
TxPacket(0,32); // 发送数据包
TxPacket(32,64);
TxPacket(64,96);
TxPacket(96,128);
k=0;
}
else if((k>128)&&(k<=160))
{
SetTxMode();
TxPacket(0,32); // 发送数据包
TxPacket(32,64);
TxPacket(64,96);
TxPacket(96,128);
TxPacket(128,160);
k=0;
}
else if((k>160)&&(k<=192)) //暂时就这样
{
SetTxMode();
TxPacket(0,32); // 发送数据包
TxPacket(32,64);
TxPacket(64,96);
TxPacket(96,128);
TxPacket(128,160);
TxPacket(160,192);
k=0;
}
SetRxMode(); // 发送完毕NRF905接收模式
}[/CODE]