一、所用材料
1、TI官方的 MSPM0L1306
2、NRF24L01
二、实现功能
两块单片机之间通过NRF24L01实现无线通信,其中单片机与NRF24L01之间用的是SPI通信协议
三、实现过程
3.1 CCS配置
1、新建工程
2、引脚配置
NRF24L01 2.4G 通讯模块采用 SPI 通信,引脚如下:
1、CSN:芯片的片选线,低电平芯片工作;
2、SCK:芯片控制的时钟线(SPI的时钟);
3、MISO:芯片控制数据线(SPI的MISO);
4、MOSI:芯片控制数据线(SPI的MOSI);
5、IRQ:中断信号,NRF24L01芯片收到数据、或者发送完数据等等一些情况会产生下降沿中断;
6、CE:芯片的模式控制线,决定了芯片的工作状态。
这里我们选择选用硬件SPI通信,在sysconfig中打开SPI
因为NRF24L01芯片收到数据、或者发送完数据等等一些情况会产生下降沿的中断信号IRQ,所以用一个引脚用于接收这个下降沿中断;
可以将红色LED的引脚配置开启,通过LED灯的闪烁来指示IRQ的下降沿中断
这里我们需要打开串口,帮助我们判断NRF24L01与单片机之间的连接情况
3、创建文件
同样的方式将以下四组文件准备好
4、编写代码
在board.c中添加以下代码
#include "board.h"
#include "stdio.h"
volatile unsigned int delay_times = 0;
volatile unsigned char uart_data = 0;
void board_init(void)
{
// SYSCFG初始化
SYSCFG_DL_init();
//清除串口中断标志
NVIC_ClearPendingIRQ(UART_0_INST_INT_IRQN);
//使能串口中断
NVIC_EnableIRQ(UART_0_INST_INT_IRQN);
printf("Board Init [[ ** LCKFB ** ]]\r\n");
}
//搭配滴答定时器实现的精确us延时
void delay_us(unsigned long __us)
{
uint32_t ticks;
uint32_t told, tnow, tcnt = 38;
// 计算需要的时钟数 = 延迟微秒数 * 每微秒的时钟数
ticks = __us * (32000000 / 1000000);
// 获取当前的SysTick值
told = SysTick->VAL;
while (1)
{
// 重复刷新获取当前的SysTick值
tnow = SysTick->VAL;
if (tnow != told)
{
if (tnow < told)
tcnt += told - tnow;
else
tcnt += SysTick->LOAD - tnow + told;
told = tnow;
// 如果达到了需要的时钟数,就退出循环
if (tcnt >= ticks)
break;
}
}
}
//搭配滴答定时器实现的精确ms延时
void delay_ms(unsigned long ms)
{
delay_us( ms * 1000 );
}
void delay_1us(unsigned long __us){ delay_us(__us); }
void delay_1ms(unsigned long ms){ delay_ms(ms); }
//串口发送单个字符
void uart0_send_char(char ch)
{
//当串口0忙的时候等待,不忙的时候再发送传进来的字符
while( DL_UART_isBusy(UART_0_INST) == true );
//发送单个字符
DL_UART_Main_transmitData(UART_0_INST, ch);
}
//串口发送字符串
void uart0_send_string(char* str)
{
//当前字符串地址不在结尾 并且 字符串首地址不为空
while(*str!=0&&str!=0)
{
//发送字符串首地址中的字符,并且在发送完成之后首地址自增
uart0_send_char(*str++);
}
}
#if !defined(__MICROLIB)
//不使用微库的话就需要添加下面的函数
#if (__ARMCLIB_VERSION <= 6000000)
//如果编译器是AC5 就定义下面这个结构体
struct __FILE
{
int handle;
};
#endif
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
void _sys_exit(int x)
{
x = x;
}
#endif
//printf函数重定义
int fputc(int ch, FILE *stream)
{
//当串口0忙的时候等待,不忙的时候再发送传进来的字符
while( DL_UART_isBusy(UART_0_INST) == true );
DL_UART_Main_transmitData(UART_0_INST, ch);
return ch;
}
//串口的中断服务函数
void UART_0_INST_IRQHandler(void)
{
//如果产生了串口中断
switch( DL_UART_getPendingInterrupt(UART_0_INST) )
{
case DL_UART_IIDX_RX://如果是接收中断
//接发送过来的数据保存在变量中
uart_data = DL_UART_Main_receiveData(UART_0_INST);
//将保存的数据再发送出去
uart0_send_char(uart_data);
break;
default://其他的串口中断
break;
}
}
在board.h中 添加以下代码
#ifndef __BOARD_H__
#define __BOARD_H__
#include "ti_msp_dl_config.h"
void board_init(void);
void delay_us(unsigned long __us);
void delay_ms(unsigned long ms);
void delay_1us(unsigned long __us);
void delay_1ms(unsigned long ms);
void uart0_send_char(char ch);
void uart0_send_string(char* str);
#endif
在drv_spi.c中添加以下代码
#include "drv_spi.h"
#include <stdio.h>
/** 硬件SPI */
#define SPI_WAIT_TIMEOUT ((uint16_t)0xFFFF)
/**
* @brief :SPI初始化(硬件)
* @param :无
* @note :无
* @retval:无
*/
void drv_spi_init( void )
{
}
/**
* @brief :SPI收发一个字节
* @param :
* @TxByte: 发送的数据字节
* @note :非堵塞式,一旦等待超时,函数会自动退出
* @retval:接收到的字节
*/
uint8_t drv_spi_read_write_byte( uint8_t TxByte )
{
uint8_t l_Data = 0;
uint16_t timeOut = 1000;
//发送数据
DL_SPI_transmitData8(SPI_INST, TxByte);
//等待SPI总线空闲
while(DL_SPI_isBusy(SPI_INST))
{
if(timeOut <= 0)
{
printf("TransmitData TIMEOUT!! : %d\r\n",__LINE__);
break;
}
timeOut--;
delay_us(2);
}
l_Data = DL_SPI_receiveData8(SPI_INST);//读取接收数据
timeOut = 500;
//等待SPI总线空闲
while(DL_SPI_isBusy(SPI_INST))
{
if(timeOut <= 0)
{
printf("ReceiveData TIMEOUT!! : %d\r\n",__LINE__);
break;
}
timeOut--;
delay_us(2);
}
return l_Data; //返回
}
/**
* @brief :SPI收发字符串
* @param :
* @ReadBuffer: 接收数据缓冲区地址
* @WriteBuffer:发送字节缓冲区地址
* @Length:字节长度
* @note :非堵塞式,一旦等待超时,函数会自动退出
* @retval:无
*/
void drv_spi_read_write_string( uint8_t* ReadBuffer, uint8_t* WriteBuffer, uint16_t Length )
{
spi_set_nss_low( );//拉低片选
while( Length-- )
{
*ReadBuffer = drv_spi_read_write_byte( *WriteBuffer ); //收发数据
ReadBuffer++;
WriteBuffer++; //读写地址加1
}
spi_set_nss_high( );//拉高片选
}
在drv_spi.h中添加以下代码
#ifndef __DRV_SPI_H__
#define __DRV_SPI_H__
#include "board.h"
#define spi_set_nss_high( ) DL_GPIO_setPins(GPIO_PORT, GPIO_CS_PIN)
#define spi_set_nss_low( ) DL_GPIO_clearPins(GPIO_PORT, GPIO_CS_PIN)
void drv_spi_init( void );
uint8_t drv_spi_read_write_byte( uint8_t TxByte );
void drv_spi_read_write_string( uint8_t* ReadBuffer, uint8_t* WriteBuffer, uint16_t Length );
#endif
在NRF24L01.c中添加以下代码
#include "NRF24L01.h"
const char *g_ErrorString = "RF24L01 is not find !...";
void drv_delay_500Ms( unsigned int ms)
{
while(ms--)
{
delay_ms(500);
}
}
/**
* @brief :NRF24L01读寄存器
* @param :
@Addr:寄存器地址
* @note :地址在设备中有效
* @retval:读取的数据
*/
uint8_t NRF24L01_Read_Reg( uint8_t RegAddr )
{
uint8_t btmp;
RF24L01_SET_CS_LOW( ); //片选
drv_spi_read_write_byte( NRF_READ_REG | RegAddr ); //读命令 地址
btmp = drv_spi_read_write_byte( 0xFF ); //读数据
RF24L01_SET_CS_HIGH( ); //取消片选
return btmp;
}
extern uint8_t g_RF24L01RxBuffer[30];
void Buff_Clear(void)
{
for(int i = 0; i < 30; i++)
{
g_RF24L01RxBuffer[i] = 0;
}
}
void RF24L01_Set_Mode( nRf24l01ModeType Mode )
{
uint8_t controlreg = 0;
controlreg = NRF24L01_Read_Reg( CONFIG );
if( Mode == MODE_TX )
{
controlreg &= ~( 1<< PRIM_RX );
}
else
{
if( Mode == MODE_RX )
{
controlreg |= ( 1<< PRIM_RX );
}
}
NRF24L01_Write_Reg( CONFIG, controlreg );
}
void RF24L01_Init( void )
{
uint8_t addr[5] = {INIT_ADDR};
RF24L01_SET_CE_HIGH( );
NRF24L01_Clear_IRQ_Flag( IRQ_ALL );
NRF24L01_Write_Reg( DYNPD, ( 1 << 0 ) ); //使能通道1动态数据长度
NRF24L01_Write_Reg( FEATRUE, 0x07 );
NRF24L01_Read_Reg( DYNPD );
NRF24L01_Read_Reg( FEATRUE );
NRF24L01_Write_Reg( CONFIG, /*( 1<<MASK_RX_DR ) |*/ //接收中断*/
( 1 << EN_CRC ) | //使能CRC 1个字节
( 1 << PWR_UP ) ); //开启设备
NRF24L01_Write_Reg( EN_AA, ( 1 << ENAA_P0 ) ); //通道0自动应答
NRF24L01_Write_Reg( EN_RXADDR, ( 1 << ERX_P0 ) ); //通道0接收
NRF24L01_Write_Reg( SETUP_AW, AW_5BYTES ); //地址宽度 5个字节
NRF24L01_Write_Reg( SETUP_RETR, ARD_4000US |
( REPEAT_CNT & 0x0F ) ); //重复等待时间 250us
NRF24L01_Write_Reg( RF_CH, 00 ); //初始化通道
NRF24L01_Write_Reg( RF_SETUP, 0x26 );
NRF24L01_Set_TxAddr( &addr[0], 5 ); //设置TX地址
NRF24L01_Set_RxAddr( 0, &addr[0], 5 ); //设置RX地址
}
void NRF24L01_check( void )
{
uint8_t i;
uint8_t error = 0;
uint8_t buf[5]={ 0XA5, 0XA5, 0XA5, 0XA5, 0XA5 };
uint8_t read_buf[ 5 ] = { 0 };
while( 1 )
{
NRF24L01_Write_Buf( TX_ADDR, buf, 5 ); //写入5个字节的地址
NRF24L01_Read_Buf( TX_ADDR, read_buf, 5 ); //读出写入的地址
for( i = 0; i < 5; i++ )
{
if( buf[ i ] != read_buf[ i ] )
{
break;
}
}
if( 5 == i )
{
break;
}
else
{
error++;
if( error >= 3 )
{
break;
}
//测试错误
printf("NRF24L01 ERROR FILE:NRF24L01.C LINE = %d\r",__LINE__);
}
drv_delay_500Ms( 2 );
}
printf("Successful configuration\r");
}
void NRF24L01_Gpio_Init_transmit( void )
{
NVIC_EnableIRQ(GPIO_MULTIPLE_GPIOA_INT_IRQN);//开启按键引脚的GPIOA端口中断
RF24L01_SET_CE_LOW( );
RF24L01_SET_CS_HIGH( );
}
uint8_t NRF24L01_TxPacket( uint8_t *txbuf, uint8_t Length )
{
uint8_t l_Status = 0;
uint16_t l_MsTimes = 0;
RF24L01_SET_CS_LOW( ); //片选
drv_spi_read_write_byte( FLUSH_TX );
RF24L01_SET_CS_HIGH( );
RF24L01_SET_CE_LOW( );
NRF24L01_Write_Buf( WR_TX_PLOAD, txbuf, Length ); //写数据到TX BUF 32字节 TX_PLOAD_WIDTH
RF24L01_SET_CE_HIGH( ); //启动发送
while( 0 != RF24L01_GET_IRQ_STATUS( ))
{
delay_ms( 5 );
// printf("error-1\r\n");
if( 500 == l_MsTimes++ ) //500ms还没有发送成功,重新初始化设备
{
NRF24L01_Gpio_Init_transmit( );
RF24L01_Init( );
RF24L01_Set_Mode( MODE_TX );
break;
}
}
l_Status = NRF24L01_Read_Reg(STATUS); //读状态寄存器
NRF24L01_Write_Reg( STATUS, l_Status ); //清除TX_DS或MAX_RT中断标志
if( l_Status & MAX_TX ) //达到最大重发次数
{
NRF24L01_Write_Reg( FLUSH_TX,0xff ); //清除TX FIFO寄存器
return MAX_TX;
}
if( l_Status & TX_OK ) //发送完成
{
return TX_OK;
}
return 0xFF; //其他原因发送失败
}
void NRF24L01_Write_Buf( uint8_t RegAddr, uint8_t *pBuf, uint8_t len )
{
uint8_t i;
RF24L01_SET_CS_LOW( ); //片选
drv_spi_read_write_byte( NRF_WRITE_REG | RegAddr ); //写命令 地址
for( i = 0; i < len; i ++ )
{
drv_spi_read_write_byte( *( pBuf + i ) ); //写数据
}
RF24L01_SET_CS_HIGH( ); //取消片选
}
void NRF24L01_Write_Reg( uint8_t RegAddr, uint8_t Value )
{
RF24L01_SET_CS_LOW( ); //片选
drv_spi_read_write_byte( NRF_WRITE_REG | RegAddr ); //写命令 地址
drv_spi_read_write_byte( Value ); //写数据
RF24L01_SET_CS_HIGH( ); //取消片选
}
void NRF24L01_Set_TxAddr( uint8_t *pAddr, uint8_t len )
{
len = ( len > 5 ) ? 5 : len; //地址不能大于5个字节
NRF24L01_Write_Buf( TX_ADDR, pAddr, len ); //写地址
}
void NRF24L01_Set_RxAddr( uint8_t PipeNum, uint8_t *pAddr, uint8_t Len )
{
Len = ( Len > 5 ) ? 5 : Len;
PipeNum = ( PipeNum > 5 ) ? 5 : PipeNum; //通道不大于5 地址长度不大于5个字节
NRF24L01_Write_Buf( RX_ADDR_P0 + PipeNum, pAddr, Len ); //写入地址
}
uint8_t NRF24L01_Clear_IRQ_Flag( uint8_t IRQ_Source )
{
uint8_t btmp = 0;
IRQ_Source &= ( 1 << RX_DR ) | ( 1 << TX_DS ) | ( 1 << MAX_RT ); //中断标志处理
btmp = NRF24L01_Read_Status_Register( ); //读状态寄存器
RF24L01_SET_CS_LOW( ); //片选
drv_spi_read_write_byte( NRF_WRITE_REG + STATUS ); //写状态寄存器命令
drv_spi_read_write_byte( IRQ_Source | btmp ); //清相应中断标志
RF24L01_SET_CS_HIGH( ); //取消片选
return ( NRF24L01_Read_Status_Register( )); //返回状态寄存器状态
}
uint8_t NRF24L01_Read_Status_Register( void )
{
uint8_t Status;
RF24L01_SET_CS_LOW( ); //片选
Status = drv_spi_read_write_byte( NRF_READ_REG + STATUS ); //读状态寄存器
RF24L01_SET_CS_HIGH( ); //取消片选
return Status;
}
void NRF24L01_Read_Buf( uint8_t RegAddr, uint8_t *pBuf, uint8_t len )
{
uint8_t btmp;
RF24L01_SET_CS_LOW( ); //片选
drv_spi_read_write_byte( NRF_READ_REG | RegAddr ); //读命令 地址
for( btmp = 0; btmp < len; btmp ++ )
{
*( pBuf + btmp ) = drv_spi_read_write_byte( 0xFF ); //读数据
}
RF24L01_SET_CS_HIGH( ); //取消片选
}
在NRF24L01.h中添加以下代码
#ifndef __NRF24L01_H__
#define __NRF24L01_H__
#include "drv_spi.h"
/** 配置和选项定义 */
#define DYNAMIC_PACKET 1 //1:动态数据包, 0:固定
#define FIXED_PACKET_LEN 32 //包长度
#define REPEAT_CNT 15 //重复次数
#define INIT_ADDR 0x34,0x43,0x10,0x10,0x01
/** 口线操作函数定义 */
#define RF24L01_SET_CE_HIGH( ) DL_GPIO_setPins(GPIO_PORT, GPIO_CE_PIN)
#define RF24L01_SET_CE_LOW( ) DL_GPIO_clearPins(GPIO_PORT, GPIO_CE_PIN)
#define RF24L01_SET_CS_HIGH( ) spi_set_nss_high( )
#define RF24L01_SET_CS_LOW( ) spi_set_nss_low( )
#define RF24L01_GET_IRQ_STATUS( ) ( ( ( DL_GPIO_readPins(GPIO_PORT,GPIO_IRQ_PIN) & GPIO_IRQ_PIN ) > 0 ) ? 1 : 0 ) //IRQ状态
typedef enum ModeType
{
MODE_TX = 0,
MODE_RX
}nRf24l01ModeType;
typedef enum SpeedType
{
SPEED_250K = 0,
SPEED_1M,
SPEED_2M
}nRf24l01SpeedType;
typedef enum PowerType
{
POWER_F18DBM = 0,
POWER_F12DBM,
POWER_F6DBM,
POWER_0DBM
}nRf24l01PowerType;
/** NRF24L01定义 */
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//寄存器操作命令
#define NRF_READ_REG 0x00 //读配置寄存器,低5位为寄存器地址
#define NRF_WRITE_REG 0x20 //写配置寄存器,低5位为寄存器地址
#define RD_RX_PLOAD 0x61 //读RX有效数据,1~32字节
#define WR_TX_PLOAD 0xA0 //写TX有效数据,1~32字节
#define FLUSH_TX 0xE1 //清除TX FIFO寄存器,发射模式下使用
#define FLUSH_RX 0xE2 //清除RX FIFO寄存器,接收模式下使用
#define REUSE_TX_PL 0xE3 //重新使用上一包数据,CE为高,数据包被不断发送
#define R_RX_PL_WID 0x60
#define NOP 0xFF //空操作,可以用来读状态寄存器
#define W_ACK_PLOAD 0xA8
#define WR_TX_PLOAD_NACK 0xB0
//SPI(NRF24L01)寄存器地址
#define CONFIG 0x00 //配置寄存器地址,bit0:1接收模式,0发射模式;bit1:电选择;bit2:CRC模式;bit3:CRC使能;
//bit4:中断MAX_RT(达到最大重发次数中断)使能;bit5:中断TX_DS使能;bit6:中断RX_DR使能
#define EN_AA 0x01 //使能自动应答功能 bit0~5 对应通道0~5
#define EN_RXADDR 0x02 //接收地址允许 bit0~5 对应通道0~5
#define SETUP_AW 0x03 //设置地址宽度(所有数据通道) bit0~1: 00,3字节 01,4字节, 02,5字节
#define SETUP_RETR 0x04 //建立自动重发;bit0~3:自动重发计数器;bit4~7:自动重发延时 250*x+86us
#define RF_CH 0x05 //RF通道,bit0~6工作通道频率
#define RF_SETUP 0x06 //RF寄存器,bit3:传输速率( 0:1M 1:2M);bit1~2:发射功率;bit0:噪声放大器增益
#define STATUS 0x07 //状态寄存器;bit0:TX FIFO满标志;bit1~3:接收数据通道号(最大:6);bit4:达到最多次重发次数
//bit5:数据发送完成中断;bit6:接收数据中断
#define MAX_TX 0x10 //达到最大发送次数中断
#define TX_OK 0x20 //TX发送完成中断
#define RX_OK 0x40 //接收到数据中断
#define OBSERVE_TX 0x08 //发送检测寄存器,bit7~4:数据包丢失计数器;bit3~0:重发计数器
#define CD 0x09 //载波检测寄存器,bit0:载波检测
#define RX_ADDR_P0 0x0A //数据通道0接收地址,最大长度5个字节,低字节在前
#define RX_ADDR_P1 0x0B //数据通道1接收地址,最大长度5个字节,低字节在前
#define RX_ADDR_P2 0x0C //数据通道2接收地址,最低字节可设置,高字节,必须同RX_ADDR_P1[39:8]相等
#define RX_ADDR_P3 0x0D //数据通道3接收地址,最低字节可设置,高字节,必须同RX_ADDR_P1[39:8]相等
#define RX_ADDR_P4 0x0E //数据通道4接收地址,最低字节可设置,高字节,必须同RX_ADDR_P1[39:8]相等
#define RX_ADDR_P5 0x0F //数据通道5接收地址,最低字节可设置,高字节,必须同RX_ADDR_P1[39:8]相等
#define TX_ADDR 0x10 //发送地址(低字节在前),ShockBurstTM模式下,RX_ADDR_P0与地址相等
#define RX_PW_P0 0x11 //接收数据通道0有效数据宽度(1~32字节),设置为0则非法
#define RX_PW_P1 0x12 //接收数据通道1有效数据宽度(1~32字节),设置为0则非法
#define RX_PW_P2 0x13 //接收数据通道2有效数据宽度(1~32字节),设置为0则非法
#define RX_PW_P3 0x14 //接收数据通道3有效数据宽度(1~32字节),设置为0则非法
#define RX_PW_P4 0x15 //接收数据通道4有效数据宽度(1~32字节),设置为0则非法
#define RX_PW_P5 0x16 //接收数据通道5有效数据宽度(1~32字节),设置为0则非法
#define NRF_FIFO_STATUS 0x17 //FIFO状态寄存器;bit0:RX FIFO寄存器空标志;bit1:RX FIFO满标志;bit2~3保留
//bit4:TX FIFO 空标志;bit5:TX FIFO满标志;bit6:1,循环发送上一数据包.0,不循环
#define DYNPD 0x1C
#define FEATRUE 0x1D
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//位定义
#define MASK_RX_DR 6
#define MASK_TX_DS 5
#define MASK_MAX_RT 4
#define EN_CRC 3
#define CRCO 2
#define PWR_UP 1
#define PRIM_RX 0
#define ENAA_P5 5
#define ENAA_P4 4
#define ENAA_P3 3
#define ENAA_P2 2
#define ENAA_P1 1
#define ENAA_P0 0
#define ERX_P5 5
#define ERX_P4 4
#define ERX_P3 3
#define ERX_P2 2
#define ERX_P1 1
#define ERX_P0 0
#define AW_RERSERVED 0x0
#define AW_3BYTES 0x1
#define AW_4BYTES 0x2
#define AW_5BYTES 0x3
#define ARD_250US (0x00<<4)
#define ARD_500US (0x01<<4)
#define ARD_750US (0x02<<4)
#define ARD_1000US (0x03<<4)
#define ARD_2000US (0x07<<4)
#define ARD_4000US (0x0F<<4)
#define ARC_DISABLE 0x00
#define ARC_15 0x0F
#define CONT_WAVE 7
#define RF_DR_LOW 5
#define PLL_LOCK 4
#define RF_DR_HIGH 3
//bit2-bit1:
#define PWR_18DB (0x00<<1)
#define PWR_12DB (0x01<<1)
#define PWR_6DB (0x02<<1)
#define PWR_0DB (0x03<<1)
#define RX_DR 6
#define TX_DS 5
#define MAX_RT 4
//for bit3-bit1,
#define TX_FULL_0 0
#define RPD 0
#define TX_REUSE 6
#define TX_FULL_1 5
#define TX_EMPTY 4
//bit3-bit2, reserved, only '00'
#define RX_FULL 1
#define RX_EMPTY 0
#define DPL_P5 5
#define DPL_P4 4
#define DPL_P3 3
#define DPL_P2 2
#define DPL_P1 1
#define DPL_P0 0
#define EN_DPL 2
#define EN_ACK_PAY 1
#define EN_DYN_ACK 0
#define IRQ_ALL ( (1<<RX_DR) | (1<<TX_DS) | (1<<MAX_RT) )
uint8_t NRF24L01_Read_Reg( uint8_t RegAddr );
void NRF24L01_Read_Buf( uint8_t RegAddr, uint8_t *pBuf, uint8_t len );
void NRF24L01_Write_Reg( uint8_t RegAddr, uint8_t Value );
void NRF24L01_Write_Buf( uint8_t RegAddr, uint8_t *pBuf, uint8_t len );
void NRF24L01_Flush_Tx_Fifo ( void );
void NRF24L01_Flush_Rx_Fifo( void );
void NRF24L01_Reuse_Tx_Payload( void );
void NRF24L01_Nop( void );
uint8_t NRF24L01_Read_Status_Register( void );
uint8_t NRF24L01_Clear_IRQ_Flag( uint8_t IRQ_Source );
uint8_t RF24L01_Read_IRQ_Status( void );
uint8_t NRF24L01_Read_Top_Fifo_Width( void );
uint8_t NRF24L01_Read_Rx_Payload( uint8_t *pRxBuf );
void NRF24L01_Write_Tx_Payload_Ack( uint8_t *pTxBuf, uint8_t len );
void NRF24L01_Write_Tx_Payload_NoAck( uint8_t *pTxBuf, uint8_t len );
void NRF24L01_Write_Tx_Payload_InAck( uint8_t *pData, uint8_t len );
void NRF24L01_Set_TxAddr( uint8_t *pAddr, uint8_t len );
void NRF24L01_Set_RxAddr( uint8_t PipeNum, uint8_t *pAddr, uint8_t Len );
void NRF24L01_Set_Speed( nRf24l01SpeedType Speed );
void NRF24L01_Set_Power( nRf24l01PowerType Power );
void RF24LL01_Write_Hopping_Point( uint8_t FreqPoint );
void RF24L01_Set_Mode( nRf24l01ModeType Mode );
void NRF24L01_check( void );
uint8_t NRF24L01_TxPacket( uint8_t *txbuf, uint8_t Length );
uint8_t NRF24L01_RxPacket( uint8_t *rxbuf );
void NRF24L01_Gpio_Init_transmit( void );
void NRF24L01_Gpio_Init_receive( void );
void RF24L01_Init( void );
void Buff_Clear(void);
void Rocker_Mode(void);
char Get_NRF24L01_ConnectFlag(void);
#endif
在empty.c中添加以下代码
#include <ti/driverlib/m0p/dl_interrupt.h>
#include "ti_msp_dl_config.h"
#include "string.h"
#include "stdio.h"
#include <string.h>
#include <stdarg.h>
#include "NRF24L01.h"
#include "board.h"
#include "drv_spi.h"
#include "keypad.h"
#define RECEIVING_MODE 0 // 1:接收模式 0:发送模式
uint8_t g_RF24L01RxBuffer[30];
int main(void)
{
//开发板初始化
board_init();
//SPI初始化
drv_spi_init( );
#if RECEIVING_MODE
NRF24L01_Gpio_Init_receive( );
//检测nRF24L01
NRF24L01_check( );
//NRF初始化
RF24L01_Init( );
RF24L01_Set_Mode( MODE_RX );//NRF接收模式 .
printf("MODE_RX\r\n");
while(1)
{
if( 0 != g_RF24L01RxBuffer[0])
{
printf("Data = %s\r\n",g_RF24L01RxBuffer);
Buff_Clear();
}
delay_ms(50);
}
#else
NRF24L01_Gpio_Init_transmit( );
//检测nRF24L01
NRF24L01_check( );
//NRF初始化
RF24L01_Init( );
RF24L01_Set_Mode( MODE_TX );//NRF发送模式 .
printf("MODE_TX\r\n");
while(1)
{
NRF24L01_TxPacket((uint8_t*)"hello LCKFB!\r\n",13);//NRF发送数据
printf("Send\r\n");
delay_ms(100);
}
#endif
}
四、结语
这篇博客所做的只是帮助大家在ccs中配置NRF24L01模块,具体的接收端可以参考下面的博客,里面也有对NRF24L01模块更详细的说明,这篇博客主要是参考了嘉立创提供的模块移植手册,我在此做了整合和修改,链接附下: