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.

TM4C123GXL launchpad的TM4C123GH6PM的硬件SPI控制无线模块nrf24l01

因为对SPI的控制这方面的资料比较少,所以不知道这么做对不对。发射模块返回的状态寄存器STATUS值一直为0x07,按照附件的调试方法,返回的应该是0x2e。我想问一下关于SPI的使用有没有问题,代码如下。

#include <stdint.h>
#include <stdbool.h>
#include "inc/tm4c123gh6pm.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_ssi.h"
#include "driverlib/ssi.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/rom_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "nrf24l01.h"

#define SSI_BitRate 1000000
// Define a static TX address
uint8_t TX_ADDRESS[TX_ADR_WIDTH]  = {0x34,0x43,0x10,0x10,0x01}; 
uint8_t RX_ADDRESS[RX_ADR_WIDTH]  = {0x34,0x43,0x10,0x10,0x01};
uint8_t Tx_Buf[TX_PLOAD_WIDTH]={0xfe,0xfd,0xfb,0xf7};
uint8_t statusx;
//*********************************************************************
//SPI initialization,配置TM4C123GH6PM的SPI硬件
void SPI_TM4C123_init(void)
{
	SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);

	GPIOPinConfigure(GPIO_PA2_SSI0CLK);
	GPIOPinConfigure(GPIO_PA3_SSI0FSS);
	GPIOPinConfigure(GPIO_PA4_SSI0RX);
	GPIOPinConfigure(GPIO_PA5_SSI0TX);
	GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_5|GPIO_PIN_4|GPIO_PIN_3|GPIO_PIN_2);

	SSIConfigSetExpClk(SSI0_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0,SSI_MODE_MASTER,SSI_BitRate,SSI_CR0_DSS_8);
                
	SSIEnable(SSI0_BASE);
	ROM_SysCtlDelay(10000);
}
 //********************************************************************
 //用SPI配置nrf24l01的寄存器函数
uint8_t SPI_Write_register(uint8_t WriteReg,uint8_t Value)//WriteReg要写的寄存器地址,Value要写的寄存器值
{
	uint32_t ui32Data;
	uint8_t ui8Data;
	SSIDataPut(SSI0_BASE, WriteReg);
	SSIDataGet(SSI0_BASE, &ui32Data);
	SSIDataPut(SSI0_BASE, Value);
	SSIDataGet(SSI0_BASE, &ui32Data);
	while (SSIBusy(SSI0_BASE)){}
    ui8Data = ui32Data & 0xff;
    return(ui8Data);
}
//**********************************************************************
uint8_t SPI_Write_Buf(uint8_t WriteReg, uint8_t *pBuf, uint8_t bytes)
{
	uint8_t i,ui8Data;
	uint32_t ui32Data;
  	SSIDataPut(SSI0_BASE,WriteReg);    // Select register to write to and read status byte
  	SSIDataGet(SSI0_BASE, &ui32Data);
  	for(i=0; i<bytes; i++) // then write all byte in buffer(*pBuf)
    	{SSIDataPut(SSI0_BASE,*pBuf++);SSIDataGet(SSI0_BASE, &ui32Data);}
  	ui8Data = ui32Data & 0xff;
  	return(ui8Data);
}
//***********************************************************************
void nrf24l01init(void)
{
	GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_6,0);    // 处于待机模式一,所以可以写寄存器
	SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);    // Writes TX_Address to nRF24L01
	//SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH);
	SPI_Write_register(WRITE_REG+EN_AA,0X00);//失能通道0自动应答,方便单独调试
	SPI_Write_register(WRITE_REG+EN_RXADDR,0X00);//失能接受通道0,方便单独调试发送模块
	SPI_Write_register(WRITE_REG+SETUP_RETR,0x00);//失能自动重发
	SPI_Write_register(WRITE_REG + RF_CH, 0x02);        // Select RF channel 40
	SPI_Write_register(WRITE_REG +RX_PW_P0,RX_PLOAD_WIDTH);
	SPI_Write_register(WRITE_REG + RF_SETUP, 0x07);   // TX_PWR:0dBm, Datarate:1Mbps, LNA:HCURR
	SPI_Write_register(WRITE_REG + CONFIG, 0x0e);      //
}
//*************************************************************************
void nrf24l01TxMode(void)//参考功能使用文档设置
{
	uint32_t ui32Loop;
	GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_6,0);    // 待机模式一chip enable
  	SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH);
  	SPI_Write_Buf(WR_TX_PLOAD, Tx_Buf, TX_PLOAD_WIDTH); // Writes data to TX payload
  	GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_6,GPIO_PIN_6);
  	for(ui32Loop = 0; ui32Loop < 2000000; ui32Loop++){}//延时
  	GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_6,0);//CE从高到低
}
//*************************************************************************
uint8_t SPIReadStatus(uint8_t reg)
{
	uint32_t ui32Data;
	uint8_t ui8Data;
	SSIDataPut(SSI0_BASE, reg);
	SSIDataPut(SSI0_BASE, 0);
	SSIDataGet(SSI0_BASE, &ui32Data);
	ui8Data = ui32Data & 0xff;
	return(ui8Data);
}
//***************************************************************************
//检测是否发射成功,成功红色的灯闪一下
void testTXWin(void)
{
	uint32_t ui32Loop;
	int8_t status,FIFOStatus;
	status=SPIReadStatus(STATUS);
	FIFOStatus=SPIReadStatus(FIFO_STATUS);
	if(status==0x2e&&FIFOStatus==0x11)//红色灯亮
	{
		SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
		GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE,GPIO_PIN_1);
		GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1,GPIO_PIN_1);
		for(ui32Loop = 0; ui32Loop < 2000000; ui32Loop++){}
		GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1,0);
		for(ui32Loop = 0; ui32Loop < 2000000; ui32Loop++){}
	}
}
//***************************************************************************
int main(void)
{
	uint8_t statusx;
	SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
	GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE,GPIO_PIN_6);
	GPIOPinTypeGPIOInput(GPIO_PORTA_BASE,GPIO_PIN_7);
	SPI_TM4C123_init();
	nrf24l01init();
	nrf24l01TxMode();
	//进入一直发射状态
	while(1)
		{
			nrf24l01TxMode();
			statusx=SPIReadStatus(STATUS);
			testTXWin();
			while(SSIBusy(SSI0_BASE)){}
		}
}

调试的方法见文档附件。

我在TI的英文支持版块找到这个参考,一定要像它这样写吗

http://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/t/349051

另外一个参考是来自TIVAWARE的SPI_flash.c


 

 

 

文档.zip
  • 在这里下载TM4C129的参考例程

    https://github.com/coon42/NRF24L01P

  • //*********************************************************************
    //* spi_nrf24l01.c
    //*********************************************************************
    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_memmap.h"
    #include "driverlib/ssi.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/gpio.h"
    #include "driverlib/uart.h"
    #include "utils/uartstdio.h"
    #include "nrf24l01.h"
    
    #define SSI_BitRate 1000000
    // Define a static TX address
    uint8_t TX_ADDRESS[TX_ADR_WIDTH]  = {0x34,0x43,0x10,0x10,0x01};
    uint8_t RX_ADDRESS[RX_ADR_WIDTH]  = {0x34,0x43,0x10,0x10,0x01};
    uint8_t TX_Buf[TX_PLOAD_WIDTH]={'s','p','i','s','t'};
    uint8_t RX_Buf[TX_PLOAD_WIDTH];
    //*********************************************************************
    //SPI initialization,配置TM4C123GH6PM的SPI硬件
    void SPI_TM4C123_init(void)
    {
    
    	uint32_t ui32Data;
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    
    	GPIOPinConfigure(GPIO_PA2_SSI0CLK);
    	GPIOPinConfigure(GPIO_PA3_SSI0FSS);
    	GPIOPinConfigure(GPIO_PA4_SSI0RX);
    	GPIOPinConfigure(GPIO_PA5_SSI0TX);
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);
    	GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_5|GPIO_PIN_4|GPIO_PIN_3|GPIO_PIN_2);
    
    	SSIConfigSetExpClk(SSI0_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0,SSI_MODE_MASTER,SSI_BitRate,8);
    	SSIEnable(SSI0_BASE);
        while(SSIDataGetNonBlocking(SSI0_BASE, &ui32Data)){}
    }
    //*********************************************************************************
    //UART初始化
    void InitConsole(void)
    {
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
        GPIOPinConfigure(GPIO_PA0_U0RX);
        GPIOPinConfigure(GPIO_PA1_U0TX);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
        UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
        GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
        UARTStdioConfig(0, 115200, 16000000);
    }
    //**********************************************************************
    //
    uint8_t SPI_RW(uint8_t value)
    {
    	uint32_t ui32Data;
    	uint8_t ui8Data;
    	SSIDataPut(SSI0_BASE,value);
    	while (SSIBusy(SSI0_BASE)){}
    	SSIDataGet(SSI0_BASE, &ui32Data);
    	ui8Data = ui32Data & 0xff;
    	return(ui8Data);
    }
    //********************************************************************
    //用SPI配置nrf24l01的寄存器函数
    uint8_t SPI_Write_register(uint8_t WriteReg,uint8_t Value)//WriteReg要写的寄存器地址,Value要写的寄存器值
    {
    	UARTprintf("\nSPI_Wreg ->\n");
    	uint8_t status;
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    	GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE,GPIO_PIN_3);
    	GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_3,0);
    	status=SPI_RW(WriteReg);
    	SPI_RW(Value);
        UARTprintf("'%x' ", status);
        GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_3,GPIO_PIN_3);
        return(status);
    }
    //**********************************************************************
    uint8_t SPI_Write_Buf(uint8_t WriteReg, uint8_t *pBuf, uint8_t bytes)
    {
    	uint8_t i,status;
    	UARTprintf("\nSPI_WBuf ->\n");
    	GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_3,0);
      	status=SPI_RW(WriteReg);
      	for(i=0; i<bytes; i++) // then write all byte in buffer(*pBuf)
        {
      		SPI_RW(*pBuf++);
        }
        GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_3,GPIO_PIN_3);
      	return(status);
    }
    //*************************************************************************
    uint8_t SPIReadStatus(uint8_t reg)
    {
    	uint8_t status;
    	UARTprintf("\nRead Status ->\n");
    	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);
    	UARTprintf("'%x' ", status);
    	return(status);
    }
    //***********************************************************************
    void nrf24l01init(void)
    {
    	GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_6,0);    // 处于待机模式一,所以可以写寄存器
    	SPI_Write_register(FLUSH_TX,0x00);
    	SPI_Write_register(WRITE_REG+EN_AA,0X00);//失能通道0自动应答,方便单独调试
    	SPI_Write_register(WRITE_REG+EN_RXADDR,0X00);//失能接受通道0,方便单独调试发送模块
    	SPI_Write_register(WRITE_REG+SETUP_RETR,0x00);//失能自动重发
    	SPI_Write_register(WRITE_REG + RF_CH, 0x02);        // Select RF channel 40
    	SPI_Write_register(WRITE_REG +RX_PW_P0,RX_PLOAD_WIDTH);
    	SPI_Write_register(WRITE_REG + RF_SETUP, 0x07);   // TX_PWR:0dBm, Datarate:1Mbps, LNA:HCURR
    	SPI_Write_register(WRITE_REG+STATUS,0xff);
    	GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_6,GPIO_PIN_6);
    	SysCtlDelay(235);//
    }
    //*************************************************************************
    void nrf24l01TxMode(void)//参考功能使用文档设置
    {
    	GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_6,0);
    	SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);    // Writes TX_Address to nRF24L01
    	SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH);
    	SPI_Write_register(FLUSH_TX,0x00);
    	SPI_Write_Buf(WR_TX_PLOAD, TX_Buf, TX_PLOAD_WIDTH); // Writes dat
    	SPI_Write_register(WRITE_REG + CONFIG, 0x0e);
    	GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_6,GPIO_PIN_6);
      	SysCtlDelay(185);//10us多点
      	GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_6,0);
    }
    
    //***************************************************************************
    //检测是否发射成功,成功红色的灯闪一下
    void testTXWin(void)
    {
    	uint32_t ui32Loop;
    	uint8_t status,FIFOStatus;
    	status=SPIReadStatus(STATUS);
    	FIFOStatus=SPIReadStatus(FIFO_STATUS);
    	if(status==0x2e&&FIFOStatus==0x11)//红色灯亮
    	{
    		SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    		GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE,GPIO_PIN_1);
    		GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1,GPIO_PIN_1);
    		for(ui32Loop = 0; ui32Loop < 2000000; ui32Loop++){}
    		GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1,0);
    		for(ui32Loop = 0; ui32Loop < 2000000; ui32Loop++){}
    	}
    }
    //***************************************************************************
    int main(void)
    {
    	SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);
        InitConsole();
        UARTprintf("SSI ->\n");
        UARTprintf("  Mode: SPI\n");
        UARTprintf("  Data: 8-bit\n\n");
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    	GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE,GPIO_PIN_6);
    	GPIOPinTypeGPIOInput(GPIO_PORTA_BASE,GPIO_PIN_7);
    	GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_6,0);
    	SPI_TM4C123_init();
    
    	nrf24l01init();
    	//进入一直发射状态
    	while(1)
    		{
    			nrf24l01TxMode();
    			testTXWin();
    			SPI_Write_register(WRITE_REG+STATUS,0xff);
    
    		}
    }
    

    这个是调试成功的发射模块,没有管接收模块。调试方法见一楼附件。此前调试失败的原因,以为SSIData函数的Fnss已经满足时序,其实没有。

  • 谢谢楼主分享,楼主好人

  • 这边所写的#include "nrf24l01.h"是官方库里面的还是自己写的。可以提供一下吗?

  • 我也有 去这个看一下  http://www.deyisupport.com/question_answer/microcontrollers/tiva_arm_cortex/f/96/t/91804.aspx

  • 好的。多谢了,正在调试中

  • 请问,能把24l01.h文件发我一下吗?刚接触这个板子还不熟悉发我一下吧,不胜感激啊!!
  • 大神能发我一下nrf2401.h吗?这个应该不是官方库里有的,谢谢了!
  • .h一般是和.c配套的。我也不用这个好久了,我记得在论坛上传过的,你搜索找找看。

  • 你好  请问 无线模块与TM4C123 是怎么连接的 ?有没有电路图啊?求分享 谢谢

  • GPIOPinConfigure(GPIO_PA2_SSI0CLK);

        GPIOPinConfigure(GPIO_PA3_SSI0FSS);
        GPIOPinConfigure(GPIO_PA4_SSI0RX);
        GPIOPinConfigure(GPIO_PA5_SSI0TX);
  • 这是SSI的配置 那么与24L01模块怎么接线的 谢谢

  • 兄弟 你的无线模块是怎么和tm4c123连的?求电路图啊,谢谢

  • 刚接触这个板子 ,没有原理图,能告诉我NRF24L01模块是怎么和TM4C123 具体引脚连接的吗?谢谢 

  • SPI的四根线连在一起,其他几个引脚接IO就OK了。如果IO模拟的话,随便接IO可以可以的。

    给你个其他模块的接线方式

  • spi的4根线与nrf24l01的连接能具体一点吗?拜托拜托,

  • 找到TM4C123x的四根线,连上,另外几个引脚随便连接IO即可。SPI的四根引脚可以参考下面这个图