⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nrf2401v1.0.c

📁 MSP430F149上NRF2401的程序demo
💻 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 + -