📄 nrf2401v1.0.c
字号:
//***********************************************************/
//*NRF2401自发自收程序
//***********************************************************/
#include <MSP430X14X.h>
#define CE BIT0 //P5.0
//#define DATA (BIT1+BIT2) //P5.1,P5.2
#define CLK1 BIT3 //P5.3
#define CS BIT5 //P5.5
#define PWR BIT6 //P5.6
#define DR1 BIT0 //P1.0
#define LED1 BIT2 //P1.2
#define LED2 BIT3 //P1.3
#define ADDR_INDEX 8
#define ADDR_COUNT 4 //发送\接收地址长度
void CE_HI(void);
void CE_LO(void);
void CS_HI(void);
void CS_LO(void);
void PWR_UP_HI(void);
void PWR_UP_LO(void);
void Init_CLK(void);
void Port_Init(void);
void Init_SPI (void);
void Delay_us(unsigned long nValue);
void Delay_ms(unsigned long nValue);
void Init_RF2401(void);
char ReceivePacket(void);
void TransmitPacket(unsigned char nVal);
void flash2(void);
void flash3(void);
//定义串口操作变量
unsigned char UART1_TX_BUF[25]; // 串口 0 的发送缓冲区
int nTX1_Len;
char nTX1_Flag;
int nSend_TX1;
int nDR;
char n_Rev;
/*
*************************************************************
* nRF2401 Configuration *
* 保存2401 的配置信息 *
*************************************************************
*/
/*=====<RF-Configuration-Register 配置信息>=====*/
//芯片测试用,无需修改,暂时不用
#define TEST_2 0x8E //MSB D143~D136
#define TEST_1 0x08 // D135~D128
#define TEST_0 0x1C // D127~D120
/* 注意: DATAx_W + ADDRx_W + CRC 的值必须小于256 ! 单个数据包的大小必须小于32 字节(256 位) */
#define DATA2_W 0x08 //0x10=2 字节 //频道2 发送/接收数据长度(单位:Bit)
#define DATA1_W 0x28 //0x20=4 字节 //频道1 发送/接收数据长度(单位:Bit)
/* 注意:2401 忽略ADDR 中超过ADDR_W设定宽度的那些位,同时地址不能全部设置为0 */
//频道2 接收地址 <- 频道2 未启用
#define ADDR2_4 0x00
#define ADDR2_3 0x00
#define ADDR2_2 0x00
#define ADDR2_1 0x00
#define ADDR2_0 0x00
//频道1 接收地址 (当前模块地址) <- 只使用到频道1
#define ADDR1_4 0x00
#define ADDR1_3 0x87
#define ADDR1_2 0x65
#define ADDR1_1 0x43
#define ADDR1_0 0x21
#define ADDR_W 0x20 //0x20=4 字节 //发送/接收地址宽度(单位:Bit)
#define CRC_L 0x1 //CRC 模式 0:8 位 1:16 位
#define CRC_EN 0x1 //CRC 校验 0:禁用 1:启用
#define RX2_EN 0x0 //双频道功能 0:禁用 1:启用
#define CM 0x1 //0:Direct mode 1:ShockBurst mode
#define RFDR_SB 0x0 //传输速率 0:250kbps 1:1Mbps (250kbps 比1Mbps 传输距离更远)
#define XO_F 0x3 //16M //nRF2401 晶振频率(具体设置见数据手册)
#define RF_PWR 0x0 //信号发射功率(具体设置见数据手册)
#define RF_CH 0x2 //Channel RF 频率设置//Channel = 2400MHz + RF_CH * 1.0MHz
#define RXEN 0x0 //0:Tx 1:Rx
#define TXEN 0x0 //0:Tx 1:Rx
//<将设置信息组合成每个字节的数据信息,此区域无需修改>
#define RFConfig_Bit0 TEST_2
#define RFConfig_Bit1 TEST_1
#define RFConfig_Bit2 TEST_0
//以上部分未使用
#define RFConfig_Bit3 DATA2_W
#define RFConfig_Bit4 DATA1_W
#define RFConfig_Bit5 ADDR2_4
#define RFConfig_Bit6 ADDR2_3
#define RFConfig_Bit7 ADDR2_2
#define RFConfig_Bit8 ADDR2_1
#define RFConfig_Bit9 ADDR2_0
#define RFConfig_Bit10 ADDR1_4
#define RFConfig_Bit11 ADDR1_3
#define RFConfig_Bit12 ADDR1_2
#define RFConfig_Bit13 ADDR1_1
#define RFConfig_Bit14 ADDR1_0
#define RFConfig_Bit15 (ADDR_W<<2 | CRC_L<<1 | CRC_EN)
#define RFConfig_Bit16 (RX2_EN<<7 | CM<<6 | RFDR_SB<<5 | XO_F <<2 | RF_PWR)
#define RFConfig_Bit17 (RF_CH<<1 | RXEN)
#define RFConfig_Bit18 (RF_CH<<1 | TXEN)
//------------------------------------------------------
//通过宏定义将18 字节的寄存器参数按照各个功能分解,以便于参数的调整
unsigned char rxConfig[15] ={
RFConfig_Bit3,
RFConfig_Bit4,
RFConfig_Bit5, RFConfig_Bit6, RFConfig_Bit7, RFConfig_Bit8,RFConfig_Bit9,
RFConfig_Bit10, RFConfig_Bit11, RFConfig_Bit12, RFConfig_Bit13, RFConfig_Bit14,
RFConfig_Bit15,
RFConfig_Bit16,
RFConfig_Bit17
};
unsigned char txConfig[15] ={
RFConfig_Bit3,
RFConfig_Bit4,
RFConfig_Bit5, RFConfig_Bit6, RFConfig_Bit7, RFConfig_Bit8,RFConfig_Bit9,
RFConfig_Bit10, RFConfig_Bit11, RFConfig_Bit12, RFConfig_Bit13, RFConfig_Bit14,
RFConfig_Bit15,
RFConfig_Bit16,
RFConfig_Bit18
};
//unsigned char rxConfig[15] = {
//0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x87, 0x65, 0x43, 0x21, 0x83, 0x6c, 0x05
//};
//unsigned char txConfig[15] = {
//0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// 0x87, 0x65, 0x43, 0x21, 0x83, 0x6c, 0x04
//};
void flash(void)
{ unsigned int i;
P1OUT = 0x01; //设置P1.0输出为1
for (i = 0x10; i > 0; i--)
{ //循环
P1DIR = 0x01; // 使能P1.0为输出
P1OUT ^= 0x01; // 对输出置反
Delay_ms(30); // 延时
}
P1OUT ^= 0x01;
}
void flash2(void) //led1闪灯程序
{ unsigned int i;
P1OUT = 0x04; //设置P1.2输出为1
for (i = 0x10; i > 0; i--)
{ //循环
P1DIR = 0x04; // 使能P1.2为输出
P1OUT ^= 0x04; // 对输出置反
Delay_ms(30); // 延时
}
P1OUT ^= 0x04;
}
void flash3(void) //led2闪灯程序
{ unsigned int i;
P1OUT = 0x08; //设置P1.3输出为1
for (i = 0x10; i > 0; i--)
{ //循环
P1DIR = 0x08; // 使能P1.3为输出
P1OUT ^= 0x08; // 对输出置反
Delay_ms(30); // 延时
}
P1OUT ^= 0x08;
}
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // 关闭看门狗
_DINT(); // 关闭中断
Init_CLK();
Port_Init();
Init_SPI();
_EINT(); // 打开中断
Init_RF2401();
while(1)
{
TransmitPacket(3);
Delay_ms(3);
n_Rev = ReceivePacket();
}
}
void Port_Init(void)
{
//P1DIR&=0;
//P1DIR|=LED1+LED2;//LED显示配置
P1IE=0;
P1IES=0;
P1IFG=0; //将中断寄存器清零
P1IE|=DR1; //管脚 P1.0使能中断
P1IES&=~DR1; //对应的管脚由低到高电平跳变使相应的标志置位
P5DIR|=CE+CS+PWR;//设置CE,CS,PWR为输出管脚
P5SEL=0;//将P5口所有的管脚设置为一般I/O口
P5SEL=CLK1+BIT1+BIT2;//P5.1 P5.2 P5.3被分配为SPI口
P5DIR|=BIT1; //P5.1输出
P5DIR|=CLK1; //P5.3输出
return;
}
void Init_SPI (void)
{
ME2|=USPIE1; //SPI1模块允许
UCTL1 =0X00; //将寄存器的内容清零
UCTL1|=CHAR+SYNC+MM; //数据为8比特,选择SPI模式,单片机为主机模式
UTCTL1=0X00; //将寄存器的内容清零
UTCTL1=CKPH+SSEL1+SSEL0+STC; // 时钟源为SMCLK,选择3线模式
UBR01=0X20;
UBR11=0X03; //传输时钟为SMCLK / 800
UMCTL1=0X00; //调整寄存器,没有调整
IE2|=UTXIE1; //发送中断允许
}
void CE_HI(void)
{
P5OUT |= CE;
return;
}
void CE_LO(void)
{
P5OUT &= ~CE;
return;
}
void CS_HI(void)
{
P5OUT |= CS;
return;
}
void CS_LO(void)
{
P5OUT &= ~CS;
return;
}
void PWR_UP_HI(void)
{
P5OUT |=PWR;
return;
}
void PWR_UP_LO(void)
{
P5OUT &= ~PWR;
return;
}
void Init_CLK(void)
{
unsigned int i;
BCSCTL1 = 0X00; //将寄存器的内容清零
//XT2震荡器开启
//LFTX1工作在低频模式
//ACLK的分频因子为1
do
{
IFG1 &= ~OFIFG; // 清除OSCFault标志
for (i = 0x20; i > 0; i--);
}
while ((IFG1 & OFIFG) == OFIFG); // 如果OSCFault =1
BCSCTL2 = 0X00; //将寄存器的内容清零
BCSCTL2 += SELM1; //MCLK的时钟源为TX2CLK,分频因子为1
BCSCTL2 += SELS; //SMCLK的时钟源为TX2CLK,分频因子为1
}
#pragma vector=USART1TX_VECTOR
__interrupt void SPI1_TX_ISR(void)
{
if(nTX1_Len != 0)// 表示缓冲区里的数据没有发送完
{
nTX1_Flag = 0;
nSend_TX1= 0;
TXBUF1 = UART1_TX_BUF[nSend_TX1];
nSend_TX1 += 1;
if(nSend_TX1 >= nTX1_Len)
{
nSend_TX1 = 0;
nTX1_Len = 0;
nTX1_Flag = 1;
}
}
}
#pragma vector=PORT1_VECTOR
__interrupt void DR_ISR(void)
{
if(P1IFG&DR1)
{
nDR = 1;
P1IFG&=~DR1; // 清除中断标志位
}
}
void Delay_ms(unsigned long nValue)//毫秒为单位,8MHz为主时钟
{
unsigned long nCount;
int i;
unsigned long j;
nCount = 2667;
for(i = nValue;i > 0;i--)
{
for(j = nCount;j > 0;j--);
}
return;
}
void Delay_us(unsigned long nValue)//微秒为单位,8MHz为主时钟
{
int nCount;
int i;
int j;
nCount = 3;
for(i = nValue;i > 0;i--)
{
for(j = nCount;j > 0;j--);
}
return;
}
void Init_RF2401(void)
{
int i;
nDR = 0;
PWR_UP_HI();//激活nRF2401
flash2(); //LED1闪
Delay_ms(4);//延迟
CS_HI();
Delay_us(100);
CE_LO();
Delay_us(100);
//发送配置信息
for(i = 0;i < 15;i++)
{
UART1_TX_BUF[i] = rxConfig[i];
}
nTX1_Len = 15;
IFG2|= UTXIFG1; // 设置中断标志,进入发送中断程序
flash3(); //LED2闪
}
void TransmitPacket(unsigned char nVal)
{
unsigned char i;
CS_HI();
Delay_us(10);
TXBUF1 = 0x05;
CS_LO();
Delay_us(300);
CE_HI();
Delay_us(10);
//写入接收地址
for(i = 0;i < ADDR_COUNT;i++)
{
UART1_TX_BUF[i] = rxConfig[ADDR_INDEX + i];
}
UART1_TX_BUF[i] = nVal;//写入发送内容
nTX1_Len = ADDR_COUNT + 1;
IFG2|= UTXIFG1; // 设置中断标志,进入发送中断程序
CE_LO();
Delay_us(300);//延迟
}
char ReceivePacket(void)
{
char nVal;
CS_HI();
Delay_us(10);
TXBUF1= 0x04;
CS_LO();
Delay_us(300);
CE_HI();
while(1)
{
if(nDR == 1)
{
break;
}
}
TXBUF1 = 0x0;
while ((IFG2|= UTXIFG1) == 0) ;
nVal = RXBUF1;
CE_LO();
Delay_us(300);//延迟
return nVal;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -