This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

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

Other Parts Discussed in Thread: TM4C123GH6PM
#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_REG        0x00  //读配置寄存器,低5位为寄存器地址
#define 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 NOP             0xFF  //空操作,可以用来读状态寄存器
/**********  NRF24L01寄存器地址   *************/
#define CONFIG          0x00  //配置寄存器地址
#define EN_AA           0x01  //使能自动应答功能
#define EN_RXADDR       0x02  //接收地址允许
#define SETUP_AW        0x03  //设置地址宽度(所有数据通道)
#define SETUP_RETR      0x04  //建立自动重发
#define RF_CH           0x05  //RF通道
#define RF_SETUP        0x06  //RF寄存器
#define STATUS          0x07  //状态寄存器
#define OBSERVE_TX      0x08  // 发送检测寄存器
#define CD              0x09  // 载波检测寄存器
#define RX_ADDR_P0      0x0A  // 数据通道0接收地址
#define RX_ADDR_P1      0x0B  // 数据通道1接收地址
#define RX_ADDR_P2      0x0C  // 数据通道2接收地址
#define RX_ADDR_P3      0x0D  // 数据通道3接收地址
#define RX_ADDR_P4      0x0E  // 数据通道4接收地址
#define RX_ADDR_P5      0x0F  // 数据通道5接收地址
#define TX_ADDR         0x10  // 发送地址寄存器
#define RX_PW_P0        0x11  // 接收数据通道0有效数据宽度(1~32字节)
#define RX_PW_P1        0x12  // 接收数据通道1有效数据宽度(1~32字节)
#define RX_PW_P2        0x13  // 接收数据通道2有效数据宽度(1~32字节)
#define RX_PW_P3        0x14  // 接收数据通道3有效数据宽度(1~32字节)
#define RX_PW_P4        0x15  // 接收数据通道4有效数据宽度(1~32字节)
#define RX_PW_P5        0x16  // 接收数据通道5有效数据宽度(1~32字节)
#define FIFO_STATUS     0x17  // FIFO状态寄存器
/*————————————————————————————————————————————————————————————————————*/

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

/*********     24L01发送接收数据宽度定义	  ***********/
#define TX_ADR_WIDTH    5     //5字节地址宽度
#define RX_ADR_WIDTH    5     //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,因为只在是看不懂,所以不知道该如何配置和移植,有没有稍微能够解释或者帮我修改一下的,刚接触有很多东西都还是糊的,然后就肯定很多都是错的。

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

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

    1.TM4C123 SPI功能的配置

    2.使用SPI写NRF24L01的驱动

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

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

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

  • 嗯嗯,今天测试的时候把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);
    }
  • 今天在调试的时候发现,这个函数调用是紧接着模式设置的,所以这个延时实际是CE拉高后的延时,我的固件为TM4C123GH6PM,设置时钟为

    SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);

    即为50MHz,将发射模式配置中的延迟改为SysCtlDelay(3000),即180us后,而非网上常说的10us,便能正常工作

    谢谢苦行僧的解答,结贴~~

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

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

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

x 出现错误。请重试或与管理员联系。