TI中文支持网
TI专业的中文技术问题搜集分享网站

TIVA C 加NRF24L01的程序问题,想要让tiva c上电以后就发送一串数据出来。

#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"//预定义在配置里找到predifned预定义,添加 PART_芯片名(如PART_TM4C123GH6PM)
#include "driverlib/ssi.h"

#define uchar unsigned char
#define uint  unsigned int

/**********  NRF24L01寄存器操作命令  ***********/
#define READ_REG0x00  //读配置寄存器,低5位为寄存器地址
#define WRITE_REG0x20  //写配置寄存器,低5位为寄存器地址
#define RD_RX_PLOAD0x61  //读RX有效数据,1~32字节
#define WR_TX_PLOAD0xA0  //写TX有效数据,1~32字节
#define FLUSH_TX0xE1  //清除TX FIFO寄存器.发射模式下用
#define FLUSH_RX0xE2  //清除RX FIFO寄存器.接收模式下用
#define REUSE_TX_PL0xE3  //重新使用上一包数据,CE为高,数据包被不断发送.
#define NOP0xFF  //空操作,可以用来读状态寄存器
/**********  NRF24L01寄存器地址*************/
#define CONFIG0x00  //配置寄存器地址
#define EN_AA0x01  //使能自动应答功能
#define EN_RXADDR0x02  //接收地址允许
#define SETUP_AW0x03  //设置地址宽度(所有数据通道)
#define SETUP_RETR0x04  //建立自动重发
#define RF_CH0x05  //RF通道
#define RF_SETUP0x06  //RF寄存器
#define STATUS0x07  //状态寄存器
#define OBSERVE_TX0x08  // 发送检测寄存器
#define CD0x09  // 载波检测寄存器
#define RX_ADDR_P00x0A  // 数据通道0接收地址
#define RX_ADDR_P10x0B  // 数据通道1接收地址
#define RX_ADDR_P20x0C  // 数据通道2接收地址
#define RX_ADDR_P30x0D  // 数据通道3接收地址
#define RX_ADDR_P40x0E  // 数据通道4接收地址
#define RX_ADDR_P50x0F  // 数据通道5接收地址
#define TX_ADDR0x10  // 发送地址寄存器
#define RX_PW_P00x11  // 接收数据通道0有效数据宽度(1~32字节)
#define RX_PW_P10x12  // 接收数据通道1有效数据宽度(1~32字节)
#define RX_PW_P20x13  // 接收数据通道2有效数据宽度(1~32字节)
#define RX_PW_P30x14  // 接收数据通道3有效数据宽度(1~32字节)
#define RX_PW_P40x15  // 接收数据通道4有效数据宽度(1~32字节)
#define RX_PW_P50x16  // 接收数据通道5有效数据宽度(1~32字节)
#define FIFO_STATUS0x17  // FIFO状态寄存器
/*————————————————————————————————————————————————————————————————————*/

/******STATUS寄存器bit位定义*******/
#define MAX_TX  	0x10//达到最大发送次数中断
#define TX_OK	0x20//TX发送完成中断
#define RX_OK	0x40//接收到数据中断
/*——————————————————————————————————————————————————*/

/*********24L01发送接收数据宽度定义***********/
#define TX_ADR_WIDTH5//5字节地址宽度
#define RX_ADR_WIDTH5//5字节地址宽度
#define TX_PLOAD_WIDTH  32//32字节有效数据宽度
#define RX_PLOAD_WIDTH  32//32字节有效数据宽度

const uchar TX_ADDRESS[TX_ADR_WIDTH]={0xFF,0xFF,0xFF,0xFF,0xFF}; //发送地址
const uchar RX_ADDRESS[RX_ADR_WIDTH]={0xFF,0xFF,0xFF,0xFF,0xFF}; //发送地址

void delay_us(uchar num)
{
	uchar i;
	for(i=0;i>num;i++);
}
void delay_150us()
{
	uint i;

	for(i=0;i>150;i++);
}

/*******************************************************************/
uchar SPI_RW(uchar byte)
{
//	uchar bit_ctr;
	SSIDataPutNonBlocking(SSI1_BASE, byte);
/*	for(bit_ctr=0;bit_ctr<8;bit_ctr++)  // 输出8位
	{
		NRF_MOSI=(byte&0x80); 			// MSB TO MOSI
		byte=(byte<<1);					// shift next bit to MSB
		NRF_SCK=1;
		byte|=NRF_MISO;		// capture current MISO bit
		NRF_SCK=0;
	}
*/
	return byte;
}

/*********************************************/
/* 函数功能:给24L01的寄存器写值(一个字节) */
/* 入口参数:reg要写的寄存器地址*/
/*value 给寄存器写的值*/
/* 出口参数:status 状态值*/
/*********************************************/
uchar NRF24L01_Write_Reg(uchar reg,uchar value)
{
	uchar status;

	GPIOPinWrite(GPIO_PORTF_BASE , GPIO_PIN_1 , 0);//CSN=0;	status = SPI_RW(reg);		//发送寄存器地址,并读取状态值
	SPI_RW(value);
	GPIOPinWrite(GPIO_PORTF_BASE , GPIO_PIN_1 , GPIO_PIN_1);//CSN=1;

	return status;
}

/*************************************************/
/* 函数功能:读24L01的寄存器值 (一个字节)*/
/* 入口参数:reg  要读的寄存器地址*/
/* 出口参数:value 读出寄存器的值*/
/*************************************************/
uchar NRF24L01_Read_Reg(uchar reg)
{
 	uchar value;	GPIOPinWrite(GPIO_PORTF_BASE , GPIO_PIN_1 , 0);//CSN=0;	SPI_RW(reg);			//发送寄存器值(位置),并读取状态值
	value = SPI_RW(NOP);
	GPIOPinWrite(GPIO_PORTF_BASE , GPIO_PIN_1 , GPIO_PIN_1);	//CSN=1;

	return value;
}

/*********************************************/
/* 函数功能:读24L01的寄存器值(多个字节)*/
/* 入口参数:reg寄存器地址*/
/**pBuf 读出寄存器值的存放数组*/
/*len数组字节长度*/
/* 出口参数:status 状态值*/
/*********************************************/
uchar NRF24L01_Read_Buf(uchar reg,uint32_t *pBuf,uchar len)
{
	uchar status;
	//uchar status,u8_ctr;
	GPIOPinWrite(GPIO_PORTF_BASE , GPIO_PIN_1 , 0);	//CSN=0	status=SPI_RW(reg);				//发送寄存器地址,并读取状态值	SSIDataGetNonBlocking(SSI1_BASE, pBuf);
 	//for(u8_ctr=0;u8_ctr<len;u8_ctr++)
	//pBuf[u8_ctr]=SPI_RW(0XFF);		//读出数据
 	GPIOPinWrite(GPIO_PORTF_BASE , GPIO_PIN_1 , GPIO_PIN_1);		//CSN=1	return status;			//返回读到的状态值
}

/**********************************************/
/* 函数功能:给24L01的寄存器写值(多个字节)  */
/* 入口参数:reg  要写的寄存器地址*/
/**pBuf 值的存放数组*/
/*len数组字节长度*/
/**********************************************/
uchar NRF24L01_Write_Buf(uchar reg, uchar *pBuf, uchar len)
{
	uchar status,u8_ctr;
	GPIOPinWrite(GPIO_PORTF_BASE , GPIO_PIN_1 , 0);	status = SPI_RW(reg);			//发送寄存器值(位置),并读取状态值	for(u8_ctr=0; u8_ctr<len; u8_ctr++)
	SPI_RW(*pBuf++); 				//写入数据	GPIOPinWrite(GPIO_PORTF_BASE , GPIO_PIN_1 , GPIO_PIN_1);	return status;		//返回读到的状态值
}

/*********************************************/
/* 函数功能:24L01接收数据*/
/* 入口参数:rxbuf 接收数据数组*/
/* 返回值: 0成功收到数据*/
/*1没有收到数据*/
/*********************************************/
uchar NRF24L01_RxPacket(uint32_t *rxbuf)
{
	uchar state;

	state=NRF24L01_Read_Reg(STATUS);  			//读取状态寄存器的值
	NRF24L01_Write_Reg(WRITE_REG+STATUS,state); //清除TX_DS或MAX_RT中断标志
	if(state&RX_OK)								//接收到数据
	{
		GPIOPinWrite(GPIO_PORTD_BASE , GPIO_PIN_7 , 0);
		NRF24L01_Read_Buf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//读取数据
		NRF24L01_Write_Reg(FLUSH_RX,0xff);					//清除RX FIFO寄存器
		GPIOPinWrite(GPIO_PORTD_BASE , GPIO_PIN_7 , GPIO_PIN_7);
		delay_150us();
		return 0;
	}
	return 1;//没收到任何数据
}

/**********************************************/
/* 函数功能:设置24L01为发送模式*/
/* 入口参数:txbuf  发送数据数组*/
/* 返回值; 0x10达到最大重发次数,发送失败*/
/*0x20成功发送完成*/
/*0xff发送失败*/
/**********************************************/
uchar NRF24L01_TxPacket(uchar *txbuf)
{
	uchar state;

	GPIOPinWrite(GPIO_PORTD_BASE , GPIO_PIN_7 , 0);												//CE拉低,使能24L01配置	NRF24L01_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);	//写数据到TX BUF  32个字节	GPIOPinWrite(GPIO_PORTD_BASE , GPIO_PIN_7 , GPIO_PIN_7);												//CE置高,使能发送
	while(GPIOPinRead(GPIO_PORTD_BASE, GPIO_PIN_6));										//等待发送完成
	state=NRF24L01_Read_Reg(STATUS);  						//读取状态寄存器的值
	NRF24L01_Write_Reg(WRITE_REG+STATUS,state); 			//清除TX_DS或MAX_RT中断标志
	if(state&MAX_TX)										//达到最大重发次数
	{
		NRF24L01_Write_Reg(FLUSH_TX,0xff);					//清除TX FIFO寄存器
		return MAX_TX;
	}
	if(state&TX_OK)											//发送完成
	{
		return TX_OK;
	}
	return 0xff;											//发送失败
}

void NRF24L01_RT_Init(void)
{
	GPIOPinWrite(GPIO_PORTD_BASE , GPIO_PIN_7 , 0);	NRF24L01_Write_Reg(WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//选择通道0的有效数据宽度
	NRF24L01_Write_Reg(FLUSH_RX,0xff);									//清除RX FIFO寄存器	NRF24L01_Write_Buf(WRITE_REG+TX_ADDR,(uchar*)TX_ADDRESS,TX_ADR_WIDTH);//写TX节点地址	NRF24L01_Write_Buf(WRITE_REG+RX_ADDR_P0,(uchar*)RX_ADDRESS,RX_ADR_WIDTH); //设置TX节点地址,主要为了使能ACK	NRF24L01_Write_Reg(WRITE_REG+EN_AA,0x01);//使能通道0的自动应答	NRF24L01_Write_Reg(WRITE_REG+EN_RXADDR,0x01); //使能通道0的接收地址	NRF24L01_Write_Reg(WRITE_REG+SETUP_RETR,0x1a);//设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次	NRF24L01_Write_Reg(WRITE_REG+RF_CH,0);//设置RF通道为2.400GHz  频率=2.4+0GHz	NRF24L01_Write_Reg(WRITE_REG+RF_SETUP,0x0F);  //设置TX发射参数,0db增益,2Mbps,低噪声增益开启	NRF24L01_Write_Reg(WRITE_REG+CONFIG,0x0f);//配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式,开启所有中断	GPIOPinWrite(GPIO_PORTD_BASE , GPIO_PIN_7 , GPIO_PIN_7);//CE置高,使能发送
}

void SEND_BUF(uchar *buf)
{
	GPIOPinWrite(GPIO_PORTD_BASE , GPIO_PIN_7 , 0);
	NRF24L01_Write_Reg(WRITE_REG+CONFIG,0x0e);
	GPIOPinWrite(GPIO_PORTD_BASE , GPIO_PIN_7 , GPIO_PIN_7);
	delay_us(15);
	NRF24L01_TxPacket(buf);
	GPIOPinWrite(GPIO_PORTD_BASE , GPIO_PIN_7 , 0);
	NRF24L01_Write_Reg(WRITE_REG+CONFIG, 0x0f);
	GPIOPinWrite(GPIO_PORTD_BASE , GPIO_PIN_7 , GPIO_PIN_7);
}

void InitSPI(void)
{
	SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI1);
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
	GPIOPinConfigure(GPIO_PD0_SSI1CLK);//PD0_CLK//GPIOPinConfigure(GPIO_PD1_SSI2FSS);//PD1_FSS
	GPIOPinConfigure(GPIO_PD2_SSI1RX);//PD2_RX
	GPIOPinConfigure(GPIO_PD3_SSI1TX);//PD3_TX
	GPIOPinTypeSSI(GPIO_PORTD_BASE, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);
	SSIConfigSetExpClk(SSI1_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0,SSI_MODE_MASTER,2000000,16);
	SSIEnable(SSI1_BASE);
	NRF24L01_RT_Init();
}

int main (void)
{
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);//使能PE端口
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);//使能PF端口
	unsigned char rece_buf[4];
	SysCtlClockSet(SYSCTL_SYSDIV_40 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);
	GPIOPinTypeGPIOOutput(GPIO_PORTD_BASE, GPIO_PIN_5 | GPIO_PIN_7);
	GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1 );
	GPIOPinTypeGPIOInput(GPIO_PORTD_BASE, GPIO_PIN_6 );
	InitSPI();
	rece_buf[1]='1';
	rece_buf[2]='2';
	rece_buf[3]='3';
	rece_buf[0]=3;					//一共要发送3个字节,rece_buf[0]必须是3!!!!!!
	SEND_BUF(rece_buf);


}


以上是代码,不知道是不是配置错,网上都是51的程序,上面就是移植的程序,使用了spi,因为只在是看不懂,所以不知道该如何配置和移植,有没有稍微能够解释或者帮我修改一下的,刚接触有很多东西都还是糊的,然后就肯定很多都是错的。

xyz549040622:

你找的这个驱动程序已经写得很好了,你想要移植,还是需要弄懂基本的一些东西才成。

xyz549040622:

可以参考下这个帖子http://stackoverflow.com/questions/23404535/tiva-c-series-problems-with-i2c-interface

1.TM4C123 SPI功能的配置

2.使用SPI写NRF24L01的驱动

Wensheng Cheng:

http://www.deyisupport.com/question_answer/microcontrollers/tiva_arm_cortex/f/96/t/84531.aspx

以上是可用的模块,亲测可用,楼主可以看看,只是在调试时,发现必须要有UART模块,否则不能正常发送,求大神解答~~

xyz549040622:

回复 Wensheng Cheng:

应该两者是不会关联的,会不会是程序中的UARTprintf充当了延时的作用呢。可以加个延时看看

Wensheng Cheng:

回复 xyz549040622:

嗯嗯,今天测试的时候把UART相关的都删了,发现必须在SPIReadStatus()中加上延时语句,且还需要较长的延时,才能正常发送 ,不知道这是为什么,烦请解惑~~

以下为代码

uint8_t SPIReadStatus(uint8_t reg)
{
uint8_t status;
// UARTprintf("\nRead Status ->\n");
SysCtlDelay(10000);
GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_3,0);
SPI_RW(reg);
status=SPI_RW(0);
GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_3,GPIO_PIN_3);
return(status);
}

xyz549040622:

回复 Wensheng Cheng:

我估计就是延时的问题。一般时序满足手册上说的就可以了。你这个怎么会多了18倍的时间呢?你试试SysCtlDelay(3000)就是180us么?

ning zhang6:

兄弟  你这个程序调通了吗  可以给下源码吗?  我写的老是接收不到发送的数据  谢谢了

ning zhang6:

回复 Wensheng Cheng:

兄弟  你有和这个发送模块配套的接收程序吗   我写的老是接收不到发送的数据啊  谢谢

赞(0)
未经允许不得转载:TI中文支持网 » TIVA C 加NRF24L01的程序问题,想要让tiva c上电以后就发送一串数据出来。
分享到: 更多 (0)