基于NRF24L01的CAN数据透传

    闲谈:

    闲来无聊,恰好公司又经常用CAN数据的传输,自己觉得要是用无线传送多好,然后,就是一个奇想,就想做一个无线数据的透传,恰好身边又有NRF24L01,那就行动吧!

下面是NRF24L01 SPI1 的初始化程序:

void NRF24L01_Init(void)
{ 	
	GPIO_InitTypeDef GPIO_InitStructure;
  SPI_InitTypeDef  SPI_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOA, ENABLE);	 //使能PB,G端口时钟
    	
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;				 //PB12上拉 防止W25X的干扰
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
 	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 	GPIO_Init(GPIOC, &GPIO_InitStructure);	//初始化指定IO

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;	//PG8 7 推挽 	  
 	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化指定IO
  
	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_5;   
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PG6 输入  
	GPIO_Init(GPIOC, &GPIO_InitStructure);

	GPIO_ResetBits(GPIOA,GPIO_Pin_4);//PA4上拉					 
	GPIO_ResetBits(GPIOC,GPIO_Pin_4|GPIO_Pin_5);//PC4,5上拉		 
  SPI1_Init();    		//初始化SPI	 
 
	SPI_Cmd(SPI1, DISABLE); // SPI外设不使能

	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //SPI设置为双线双向全双工
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;		//SPI主机
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;		//发送接收8位帧结构
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;		//时钟悬空低
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;	//数据捕获于第1个时钟沿
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;		//NSS信号由软件控制
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;		//定义波特率预分频的值:波特率预分频值为16
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;	//数据传输从MSB位开始
	SPI_InitStructure.SPI_CRCPolynomial = 7;	//CRC值计算的多项式
	SPI_Init(SPI1, &SPI_InitStructure);  //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
 
	SPI_Cmd(SPI1, ENABLE); //使能SPI外设
			 
	NRF24L01_CE=0; 			//使能24L01
	NRF24L01_CSN=1;			//SPI片选取消  
	 		 	 
}

这里是NRF24L01数据读取
 

/检测24L01是否存在
//返回值:0,成功;1,失败	
u8 NRF24L01_Check(void)
{
	u8 buf[5]={0XA5,0XA5,0XA5,0XA5,0XA5};
	u8 i;
	SPI1_SetSpeed(SPI_BaudRatePrescaler_4); //spi速度为9Mhz(24L01的最大SPI时钟为10Mhz)   	 
	NRF24L01_Write_Buf(NRF_WRITE_REG+TX_ADDR,buf,5);//写入5个字节的地址.	
	NRF24L01_Read_Buf(TX_ADDR,buf,5); //读出写入的地址  
	for(i=0;i<5;i++)if(buf[i]!=0XA5)break;	 							   
	if(i!=5)return 1;//检测24L01错误	
	return 0;		 //检测到24L01
}	 	 
//SPI写寄存器
//reg:指定寄存器地址
//value:写入的值
u8 NRF24L01_Write_Reg(u8 reg,u8 value)
{
	u8 status;	
   	NRF24L01_CSN=0;                 //使能SPI传输
  	status =SPI1_ReadWriteByte(reg);//发送寄存器号 
  	SPI1_ReadWriteByte(value);      //写入寄存器的值
  	NRF24L01_CSN=1;                 //禁止SPI传输	   
  	return(status);       			//返回状态值
}
//读取SPI寄存器值
//reg:要读的寄存器
u8 NRF24L01_Read_Reg(u8 reg)
{
	u8 reg_val;	    
 	NRF24L01_CSN = 0;          //使能SPI传输		
  	SPI1_ReadWriteByte(reg);   //发送寄存器号
  	reg_val=SPI1_ReadWriteByte(0XFF);//读取寄存器内容
  	NRF24L01_CSN = 1;          //禁止SPI传输		    
  	return(reg_val);           //返回状态值
}	
//在指定位置读出指定长度的数据
//reg:寄存器(位置)
//*pBuf:数据指针
//len:数据长度
//返回值,此次读到的状态寄存器值 
u8 NRF24L01_Read_Buf(u8 reg,u8 *pBuf,u8 len)
{
	u8 status,u8_ctr;	       
  	NRF24L01_CSN = 0;           //使能SPI传输
  	status=SPI1_ReadWriteByte(reg);//发送寄存器值(位置),并读取状态值   	   
 	for(u8_ctr=0;u8_ctr<len;u8_ctr++)pBuf[u8_ctr]=SPI1_ReadWriteByte(0XFF);//读出数据
  	NRF24L01_CSN=1;       //关闭SPI传输
  	return status;        //返回读到的状态值
}
//在指定位置写指定长度的数据
//reg:寄存器(位置)
//*pBuf:数据指针
//len:数据长度
//返回值,此次读到的状态寄存器值
u8 NRF24L01_Write_Buf(u8 reg, u8 *pBuf, u8 len)
{
	u8 status,u8_ctr;	    
    NRF24L01_CSN = 0;          //使能SPI传输
  	status = SPI1_ReadWriteByte(reg);//发送寄存器值(位置),并读取状态值
  	for(u8_ctr=0; u8_ctr<len; u8_ctr++)SPI1_ReadWriteByte(*pBuf++); //写入数据	 
  	NRF24L01_CSN = 1;       //关闭SPI传输
  	return status;          //返回读到的状态值
}				   
//启动NRF24L01发送一次数据
//txbuf:待发送数据首地址
//返回值:发送完成状况
u8 NRF24L01_TxPacket(u8 *txbuf)
{
	u8 sta;
 	SPI1_SetSpeed(SPI_BaudRatePrescaler_8);//spi速度为9Mhz(24L01的最大SPI时钟为10Mhz)   
	NRF24L01_CE=0;
  NRF24L01_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);//写数据到TX BUF  32个字节
 	NRF24L01_CE=1;//启动发送	   
	while(NRF24L01_IRQ!=0);//等待发送完成
	sta=NRF24L01_Read_Reg(STATUS);  //读取状态寄存器的值	   
	NRF24L01_Write_Reg(NRF_WRITE_REG+STATUS,sta); //清除TX_DS或MAX_RT中断标志
	if(sta&MAX_TX)//达到最大重发次数
	{
		NRF24L01_Write_Reg(FLUSH_TX,0xff);//清除TX FIFO寄存器 
		return MAX_TX; 
	}
	if(sta&TX_OK)//发送完成
	{
		return TX_OK;
	}
	return 0xff;//其他原因发送失败
}
//启动NRF24L01发送一次数据
//txbuf:待发送数据首地址
//返回值:0,接收完成;其他,错误代码
u8 NRF24L01_RxPacket(u8 *rxbuf)
{
	u8 sta;		    							   
	SPI1_SetSpeed(SPI_BaudRatePrescaler_8); //spi速度为9Mhz(24L01的最大SPI时钟为10Mhz)   
	sta=NRF24L01_Read_Reg(STATUS);  //读取状态寄存器的值    	 
	NRF24L01_Write_Reg(NRF_WRITE_REG+STATUS,sta); //清除TX_DS或MAX_RT中断标志
	if(sta&RX_OK)//接收到数据
	{
		NRF24L01_Read_Buf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//读取数据
		NRF24L01_Write_Reg(FLUSH_RX,0xff);//清除RX FIFO寄存器 
		return 0; 
	}	   
	return 1;//没收到任何数据
}					    
//该函数初始化NRF24L01到RX模式
//设置RX地址,写RX数据宽度,选择RF频道,波特率和LNA HCURR
//当CE变高后,即进入RX模式,并可以接收数据了		   
void NRF24L01_RX_Mode(void)
{
	  NRF24L01_CE=0;	  
  	NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH);//写RX节点地址
	  
  	NRF24L01_Write_Reg(NRF_WRITE_REG+EN_AA,0x01);    //使能通道0的自动应答    
  	NRF24L01_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01);//使能通道0的接收地址  	 
  	NRF24L01_Write_Reg(NRF_WRITE_REG+RF_CH,40);	     //设置RF通信频率		  
  	NRF24L01_Write_Reg(NRF_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//选择通道0的有效数据宽度 	    
  	NRF24L01_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f);//设置TX发射参数,0db增益,2Mbps,低噪声增益开启   
  	NRF24L01_Write_Reg(NRF_WRITE_REG+CONFIG, 0x0f);//配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式 
  	NRF24L01_CE = 1; //CE为高,进入接收模式 
}						 
//该函数初始化NRF24L01到TX模式
//设置TX地址,写TX数据宽度,设置RX自动应答的地址,填充TX发送数据,选择RF频道,波特率和LNA HCURR
//PWR_UP,CRC使能
//当CE变高后,即进入RX模式,并可以接收数据了		   
//CE为高大于10us,则启动发送.	 
void NRF24L01_TX_Mode(void)
{														 
	  NRF24L01_CE=0;	    
  	NRF24L01_Write_Buf(NRF_WRITE_REG+TX_ADDR,(u8*)TX_ADDRESS,TX_ADR_WIDTH);//写TX节点地址 
  	NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH); //设置TX节点地址,主要为了使能ACK	  

  	NRF24L01_Write_Reg(NRF_WRITE_REG+EN_AA,0x01);     //使能通道0的自动应答    
  	NRF24L01_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01); //使能通道0的接收地址  
  	NRF24L01_Write_Reg(NRF_WRITE_REG+SETUP_RETR,0x1a);//设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次
  	NRF24L01_Write_Reg(NRF_WRITE_REG+RF_CH,40);       //设置RF通道为40
  	NRF24L01_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f);  //设置TX发射参数,0db增益,2Mbps,低噪声增益开启   
  	NRF24L01_Write_Reg(NRF_WRITE_REG+CONFIG,0x0e);    //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式,开启所有中断
	NRF24L01_CE=1;//CE为高,

这里是关于stm32can程序:

/******************** 鑫盛电子工作室 ********************
 * 文件名  :can.c
 * 描述    :CAN测试应用函数库。         
 * 实验平台:MINI STM32开发板 基于STM32F103C8T6
 * 硬件连接:-----------------
 *          | 						  |
            |  PB8-CAN-RX     |
 *          |  PB9-CAN-TX     |
 *          |                 |
 *           -----------------
 * 库版本  :ST3.0.0  																										  
 * 淘宝店:http://shop66177872.taobao.com
*********************************************************/
#include "can.h"
//#include "led.h"
#include "stdio.h"
#include "sys.h"
#include "stm32f10x_can.h"
#include "24l01.h"
//#include "os.h"
typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;

/* 在中断处理函数中返回 */
__IO uint32_t ret = 0;

uint8_t CAN_RX_BUFF[17];
volatile TestStatus TestRx;	


static void CAN1_NVIC_Config(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;

	/* 使能接收的中断和中断优先级 */
	NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;  
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
	CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);   //FIFO0消息挂号中断允许.	
}

/****************************************************************************
* Function Name  : CAN1_Config
* Description    : 初始化CAN,波特率设置为450K
* Input          : mode:用来选择要使用的工作模式:主要有四种工作模式:1、正常
*                * 模式:CAN_Mode_Normal;2、CAN_Mode_Silent :静默模式;3、环
*                * 回模式:CAN_Mode_LoopBack;4、静默环回模式:CAN_Mode_Silent
*                * _LoopBack。
* Output         : None
* Return         : None
****************************************************************************/

void CAN1_Config(uint8_t mode)
{

	GPIO_InitTypeDef GPIO_InitStructure;
	CAN_InitTypeDef CAN_InitStructure;

	/* 初始化IO口 */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;   //复用推挽输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;        //PA12
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

	GPIO_Init(GPIOA, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;     //上拉输入
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;        //PA11

	GPIO_Init(GPIOA, &GPIO_InitStructure);

/***************************************************************************/
/********************* CAN设置和初始化 *************************************/
/***************************************************************************/

	/* 打开时钟使能 */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);

    /* 初始化CAN的参数 */

	CAN_DeInit(CAN1);
	CAN_StructInit(&CAN_InitStructure);

	/* CAN 参数初始化 */
	CAN_InitStructure.CAN_TTCM = DISABLE;    //失能时间触发模式
	CAN_InitStructure.CAN_ABOM = ENABLE;    //自动离线管理
	CAN_InitStructure.CAN_AWUM = DISABLE;    //失能睡眠模式通过软件唤醒
	CAN_InitStructure.CAN_NART = DISABLE;    //失能非自动重传输模式(也就是会自动重传输)
	CAN_InitStructure.CAN_RFLM = DISABLE;    //失能接收FIFO锁定模式,新数据会覆盖旧数据
	CAN_InitStructure.CAN_TXFP = DISABLE;    //优先级由报文标识符决定 
	CAN_InitStructure.CAN_Mode = mode;       //有普通模式和拓展模式
	CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; //重新同步跳跃宽度 1 个时间单位

    /* 波特率设置, 当APB1的时钟频率是36MHZ的时候。 波特率的公式为: */
    /* 波特率(Kpbs) = 36M / ((CAN_BS1 + CAN_BS2 + 1) *  CAN_Prescaler) */
	CAN_InitStructure.CAN_BS1 = CAN_BS1_9tq; //时间段 1 为8 个时间单位 
	CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq; //时间段 2 为7 个时间单位
	CAN_InitStructure.CAN_Prescaler = 4;//5;	 波特率改为了100K   20=100k   5=400k

	CAN_Init(CAN1, &CAN_InitStructure);
	

#ifdef CAN_RX0_INT_ENABLE
	CAN1_NVIC_Config();
#endif    

}
/****************************************************************************
* Function Name  : CAN1_SendMesg
* Description    : 发送一个报文
* Input          : id:发送的ID。
*                * len:发送的数据长度(注意发送数据长度不能超过8个字节)
*                * dat:存放数据的指针
* Output         : None
* Return         : None
****************************************************************************/

void CAN1_SendMesg(uint32_t id, uint8_t len, uint8_t *dat)
{
	uint16_t i = 0;
	CanTxMsg TxMessage;

    /* 一次发送只能发送8个字节 */
    if(len > 8)
    {
        return ;
    }
	/* 配置邮箱:设置标识符,数据长度和待发送数据 */
	TxMessage.StdId = (id & 0x7FF); //标准帧ID11位
	TxMessage.ExtId = (id );   //设置扩展标示符(拓展标示符有29位1本来是TxMessage.ExtId = (id >> 11);
	TxMessage.RTR = CAN_RTR_DATA;   //设置为数据帧(或远程帧为CAN_RTR_Remote)
    if((id & 0x7FF) == 0x7FF)       //检测是标准帧还是拓展帧(拓展帧大于11位)
    {
    	TxMessage.IDE = CAN_ID_STD;	//拓展ID   
    }
    else
    {
    	TxMessage.IDE = CAN_ID_EXT;	//标准ID
    }
	TxMessage.DLC = len;	        //发送的数据长度

	/* 将数据放入到邮箱中 */
	for(i=0; i<len; i++)	         
	{
		TxMessage.Data[i] = *dat;
		dat++;	
	}
    
    /* 开始传送数据 */
	CAN_Transmit(CAN1, &TxMessage); 
}

/****************************************************************************
* Function Name  : CAN1_Config16BitFilter
* Description    : 设置CAN接收16两个标准ID(设置ID位数全部相同才能够通过)
* Input          : id1:要接收的一个ID
*                * id2:要接收的一个ID
* Output         : None
* Return         : None
****************************************************************************/

void CAN1_Config16BitFilter(uint16_t id1, uint16_t id2)
{
    CAN_FilterInitTypeDef  CAN_FilterInitStructure;
    uint16_t mask = 0xFFFF;

	/* CAN filter init 屏蔽寄存器初始化 */
	CAN_FilterInitStructure.CAN_FilterNumber = 1;	               //过滤器1
	CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;//ID模式

	/* 寄存器组设置为16位 */
	CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_16bit;
    CAN_FilterInitStructure.CAN_FilterIdHigh = (id1 << 5);    //要接收的ID标示符1		
    CAN_FilterInitStructure.CAN_FilterIdLow =  (id2 << 5);	  //要接收的ID标示符2

	/* 设置为所有ID位都要相同才接收 */	
	CAN_FilterInitStructure.CAN_FilterMaskIdHigh = (mask << 5); //MASK
	CAN_FilterInitStructure.CAN_FilterMaskIdLow  = (mask << 5);
	CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0; //FIFO0
	CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; //使能过滤器1

	CAN_FilterInit(&CAN_FilterInitStructure);
}

/****************************************************************************
* Function Name  : CAN1_Config32BitFilter
* Description    : 设置一个拓展ID的接收
* Input          : id:要接收的ID
* Output         : None
* Return         : None
****************************************************************************/

void CAN1_Config32BitFilter(uint32_t id)
{
//    uint32_t mask = 0x000006D1;//0xFFFFFFFF;   //发送0x00000601    接收0x000006D1
    CAN_FilterInitTypeDef  CAN_FilterInitStructure;

	/* CAN filter init 屏蔽寄存器初始化 */
	CAN_FilterInitStructure.CAN_FilterNumber = 1;	               //过滤器1
	CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;//ID模式

	/* 寄存器组设置为32位 */
	CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
    CAN_FilterInitStructure.CAN_FilterIdHigh =0x0000;// (id >> 13);    //要接收的ID标示符1		
    CAN_FilterInitStructure.CAN_FilterIdLow  =0x0000;//  (id << 3 ) | 4;//要接收的ID标示符2

	/* 设置为所有ID位都要相同才接收 */	
	CAN_FilterInitStructure.CAN_FilterMaskIdHigh =0x0000;// mask >> 13;     //MASK
	CAN_FilterInitStructure.CAN_FilterMaskIdLow  =0x0000;// (mask << 3) | 4;
	CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0; //FIFO0
	CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; //使能过滤器1

	CAN_FilterInit(&CAN_FilterInitStructure);
}

/****************************************************************************
* Function Name  : CAN1_ReceiveMesg
* Description    : 接收一个报文
* Input          : receiveBuff:接收数据的数组指针
* Output         : None
* Return         : None
****************************************************************************/

void CAN1_ReceiveMesg(uint8_t *receiveBuff)
{
	uint8_t i = 0;

	CanRxMsg RxMessage;	//设置接收邮箱

	if((CAN_MessagePending(CAN1, CAN_FIFO0) != 0)) //检查FIFO0里面是否有数据
	{
    	CAN_Receive(CAN1,CAN_FIFO0,&RxMessage); //读取FIFO0里面的数据
    	for(i=0; i<RxMessage.DLC; i++)          //将读取到的数据位赋给CAN_RXSBUF
    	{
    		*receiveBuff = RxMessage.Data[i];
    		receiveBuff++;
    	}
    }			
}



/* 发送两个字节的数据*/

																																																																												void can_tx(u8 Data1,u8 Data2,u8 Data3,u8 Data4,u8 Data5,u8 Data6,u8 Data7,u8 Data8)
{ 
  CanTxMsg TxMessage;  

  TxMessage.StdId=0x0023;	//标准标识符为0x00
  TxMessage.ExtId=0x001C; //扩展标识符0x0000
  TxMessage.IDE=CAN_ID_STD;//使用标准标识符
  TxMessage.RTR=CAN_RTR_DATA;//为数据帧
  TxMessage.DLC=8;	//	消息的数据长度为8个字节
  TxMessage.Data[0]=Data1; //第一个字节数据
  TxMessage.Data[1]=Data2; //第二个字节数据 
  TxMessage.Data[2]=Data3; //第三个字节数据
  TxMessage.Data[3]=Data4; //第一个字节数据
  TxMessage.Data[4]=Data5; //第二个字节数据 
  TxMessage.Data[5]=Data6; //第三个字节数据
  TxMessage.Data[6]=Data7; //第一个字节数据
  TxMessage.Data[7]=Data8; //第二个字节数据 
  CAN_Transmit(CAN1,&TxMessage); //发送数据

}
void can_tx1(u8 Data1,u8 Data2,u8 Data3,u8 Data4,u8 Data5,u8 Data6,u8 Data7,u8 Data8)
{ 
  CanTxMsg TxMessage;  

  TxMessage.StdId=0x22;	//标准标识符为0x00
  TxMessage.ExtId=0x18DADDF1; //扩展标识符0x0000
  TxMessage.IDE=CAN_ID_STD;//使用标准标识符
  TxMessage.RTR=CAN_RTR_DATA;//为数据帧
  TxMessage.DLC=8;	//	消息的数据长度为8个字节
  TxMessage.Data[0]=Data1; //第一个字节数据
  TxMessage.Data[1]=Data2; //第二个字节数据 
  TxMessage.Data[2]=Data3; //第三个字节数据
  TxMessage.Data[3]=Data4; //第一个字节数据
  TxMessage.Data[4]=Data5; //第二个字节数据 
  TxMessage.Data[5]=Data6; //第三个字节数据
  TxMessage.Data[6]=Data7; //第一个字节数据
  TxMessage.Data[7]=Data8; //第二个字节数据 
  CAN_Transmit(CAN1,&TxMessage); //发送数据

}

/* USB中断和CAN接收中断服务程序,USB跟CAN公用I/O,这里只用到CAN的中断。 */
void USB_LP_CAN1_RX0_IRQHandler(void)
{
  
  CanRxMsg RxMessage;
	
  RxMessage.StdId=0x00;
  RxMessage.ExtId=0x00;
  RxMessage.IDE=0;
  RxMessage.DLC=0;
  RxMessage.FMI=0;
  RxMessage.Data[0]=0x00;
  RxMessage.Data[1]=0x00;    

  CAN_Receive(CAN1,CAN_FIFO0, &RxMessage); //接收FIFO0中的数据  

	CAN_RX_BUFF[0]=((RxMessage.StdId)&0x0000ff00)>>8;
	CAN_RX_BUFF[1]=(RxMessage.StdId)&0x000000ff;  //标注0-7ff

	
  CAN_RX_BUFF[2]=((RxMessage.ExtId)&0xff000000)>>24;
  CAN_RX_BUFF[3]=((RxMessage.ExtId)&0x00ff0000)>>16;
	CAN_RX_BUFF[4]=((RxMessage.ExtId)&0x0000ff00)>>8;
	CAN_RX_BUFF[5]=((RxMessage.ExtId)&0x000000ff);
	
  CAN_RX_BUFF[6]=RxMessage.IDE;
  CAN_RX_BUFF[7]=RxMessage.DLC;
	CAN_RX_BUFF[8]=RxMessage.RTR;
	CAN_RX_BUFF[9]=RxMessage.Data[0];
	CAN_RX_BUFF[10]=RxMessage.Data[1];
	CAN_RX_BUFF[11]=RxMessage.Data[2];
	CAN_RX_BUFF[12]=RxMessage.Data[3];
	CAN_RX_BUFF[13]=RxMessage.Data[4];
	CAN_RX_BUFF[14]=RxMessage.Data[5];
	CAN_RX_BUFF[15]=RxMessage.Data[6];
	CAN_RX_BUFF[16]=RxMessage.Data[7];
	
  NRF24L01_TxPacket((u8*)(CAN_RX_BUFF));		
} 


最后得到的实验现象:

 

can数据的接收,出现大量数据接收时,数据发送方大概每0.005s一个数据发送,而接收数据未0.05s一个数据,但由于数据量比较大时,数据的丢包比较明显,所以该无线程序可以使用在数据量比较小时的数据透传;

程序百度云:链接:https://pan.baidu.com/s/1p3n7kVxUlBTIt9rWlx_Q8Q 
提取码:cyx1 
 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值