|
救命啊!帮忙看看S3C2440上通过SPI接口与nRF24L01无线模块通信的程序!
[复制链接]
以前通过GPIO来模拟SPI是可以正常通信的,但是现在想用原生SPI来实现通信却总是不成功,调了好几天都不行,哪位大侠能帮忙看看啊。。。
/* 无线模块1 */
#define MISO0 11 /* GPE11:SPI输入 */
#define GET_MISO0() ((rGPEDAT & (1<> MISO0)
#define MOSI0 12 /* GPE12:SPI输出 */
#define SET_MOSI0(value) (rGPEDAT = (rGPEDAT & ~(1<
#define SCK0 13 /* GPE13:SPI输出 */
#define SET_SCK0(value) (rGPEDAT = (rGPEDAT & ~(1<
#define CE0 14 /* GPG14:数字输出 */
#define SET_CE0(value) (rGPGDAT = (rGPGDAT & ~(1<
#define GET_CE0() ((rGPGDAT & (1<> CE0)
#define CSN0 2 /* GPG2: SPI输出 */
#define SET_CSN0(value) (rGPGDAT = (rGPGDAT & ~(1<
#define IRQ0 13 /* GPG13: 中断输入 */
#define GET_IRQ0() ((rGPFDAT & (1<> IRQ0)
/* 无线模块2 */
#define MISO1 5 /* GPG5:SPI输入 */
#define GET_MISO1() ((rGPGDAT & (1<> MISO1)
#define MOSI1 6 /* GPG6:SPI输出 */
#define SET_MOSI1(value) (rGPGDAT = (rGPGDAT & ~(1<
#define SCK1 7 /* GPG7:SPI输出 */
#define SET_SCK1(value) (rGPGDAT = (rGPGDAT & ~(1<
#define CE1 0 /* GPG0:数字输出 */
#define SET_CE1(value) (rGPGDAT = (rGPGDAT & ~(1<
#define GET_CE1() ((rGPGDAT & (1<> CE1)
#define CSN1 3 /* GPG3: SPI输出 */
#define SET_CSN1(value) (rGPGDAT = (rGPGDAT & ~(1<
#define IRQ1 11 /* GPG11: 中断输入 */
#define GET_IRQ1() ((rGPGDAT & (1<> IRQ1)
//***************************************NRF24L01寄存器指令*******************************************************
#define READ_REG 0x00 // 读寄存器指令: 000A AAAA
#define WRITE_REG 0x20 // 写寄存器指令: 001A AAAA
#define RD_RX_PLOAD 0x61 // 读取接收数据指令: 0110 0001
#define WR_TX_PLOAD 0xA0 // 写待发数据指令: 1010 0000
#define FLUSH_TX 0xE1 // 冲洗发送 FIFO指令: 1110 0001
#define FLUSH_RX 0xE2 // 冲洗接收 FIFO指令: 1110 0010
#define REUSE_TX_PL 0xE3 // 定义重复装载数据指令: 1110 0011
#define R_RX_PL_WID 0x60 // 读RX缓冲中的RX数据长度: 0110 0000
#define W_ACK_PAYLOAD 0xA8 // 设置带负载应答: 1010 1PPP
#define W_TX_PAYLOAD_NOACK 0xB0 // 为特定数据包关闭自动应答功能:1011 0000
#define NOP 0xFF // 保留: 1111 1111
//*************************************SPI(nRF24L01)寄存器地址****************************************************
#define CONFIG 0x00 // 配置收发状态,CRC校验模式以及收发状态响应方式
#define EN_AA 0x01 // 自动应答功能设置
#define EN_RXADDR 0x02 // 可用信道设置
#define SETUP_AW 0x03 // 收发地址宽度设置
#define SETUP_RETR 0x04 // 自动重发功能设置
#define RF_CH 0x05 // 工作频率设置
#define RF_SETUP 0x06 // 发射速率、功耗功能设置
#define STATUS 0x07 // 状态寄存器
#define OBSERVE_TX 0x08 // 发送监测功能
#define RPD 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接收数据长度
#define RX_PW_P1 0x12 // 接收频道0接收数据长度
#define RX_PW_P2 0x13 // 接收频道0接收数据长度
#define RX_PW_P3 0x14 // 接收频道0接收数据长度
#define RX_PW_P4 0x15 // 接收频道0接收数据长度
#define RX_PW_P5 0x16 // 接收频道0接收数据长度
#define FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器设置
#define DYNPD 0x1C // 使能每个数据通道的动态负载长度功能
#define FEATURE 0x1D // 特性寄存器
void InitPin(void) {
// SPI0
// 初始化GPE GPE11:MISO0(MISO);GPE12:MOSI0(MOSI);GPE13:SPICLK0(SCK)
rGPECON = (rGPECON & ~(3 << MISO0 * 2 | 3 << MOSI0 * 2 | 3 << SCK0 * 2)) |
(2 << MISO0 * 2 | 2 << MOSI0 * 2 | 2 << SCK0 * 2);
// 初始化GPG GPG13:EINT21(IRQ);GPG14:GPG14(CE);GPG2: nSS_SPI0(CSN)
rGPGCON = (rGPGCON & ~(3 << IRQ0 * 2 | 3 << CE0 * 2 | 3 << CSN0 * 2)) |
(2 << IRQ0 * 2 | 1 << CE0 * 2 | 1 << CSN0 * 2);
// 设置上拉寄存器
/*rGPGUP = rGPGUP & ~(1 << CSN0);
rGPEUP = (rGPEUP & ~(1 << MISO0 | 1 << MOSI0 | 1 << SCK0)) |
(1 << MISO0 | 1 << MOSI0 | 1 << SCK0);*/
// SPI1
// 初始化GPG GPG5:MISO1(MISO);GPG6:MOSI1(MOSI);GPG7:SPICLK1(SCK)
// GPG11:EINT19(IRQ);GPG0:GPG0(CE);GPG3: nSS_SPI1(CSN)
rGPGCON = (rGPGCON & ~(3 << IRQ1 * 2 | 3 << MISO1 * 2 | 3 << CE1 * 2 | 3 << CSN1 * 2 | 3 << MOSI1 * 2 | 3 << SCK1 * 2)) |
(2 << IRQ1 * 2 | 3 << MISO1 * 2 | 1 << CE1 * 2 | 1 << CSN1 * 2 | 3 << MOSI1 * 2 | 3 << SCK1 * 2);
// 设置上拉寄存器
/*rGPGUP = rGPGUP & ~(1 << CSN1);
rGPGUP = (rGPGUP & ~(1 << MISO1 | 1 << MOSI1 | 1 << SCK1)) |
(1 << MISO1 | 1 << MOSI1 | 1 << SCK1);*/
printf("无线模块引脚配置完成!");
}
void InitSpi(void) {
int i;
// 设置波特率预定标器寄存器(SPPREn),波特率 = PCLK / 2 / (预定标器值 + 1) = 1MHz
rSPPRE0 = 0x18;
rSPPRE1 = 0x18;
// 设置时钟控制寄存器(CLKCON),使能SPI时钟
rCLKCON = (rCLKCON & ~(1 << 18)) | (1 << 18);
// 设置SPCONn寄存器以正确配置SPI模块
// normal; format A; active high; master; enable; polling mode
rSPCON0 = (rSPCON0 & ~(1 << 0 | 1 << 1 | 1 << 2 | 1 << 3 | 1 << 4 | 3 << 5)) |
(0 << 0 | 0 << 1 | 0 << 2 | 1 << 3 | 1 << 4 | 0 << 5);
rSPCON1 = (rSPCON1 & ~(1 << 0 | 1 << 1 | 1 << 2 | 1 << 3 | 1 << 4 | 3 << 5)) |
(0 << 0 | 0 << 1 | 0 << 2 | 1 << 3 | 1 << 4 | 0 << 5);
// 设置SPI引脚控制寄存器(SPPINn)
// Release; Disable (general purpose)
rSPPIN0 = (rSPPIN0 & ~(1 << 0 | 1 << 2)) | (0 << 0 | 0 << 2);
rSPPIN1 = (rSPPIN1 & ~(1 << 0 | 1 << 2)) | (0 << 0 | 0 << 2);
// 初始化SPI模块,向SPTDATn写入10次0xFF哑数据
for(i = 0; i < 10; i++)
rSPTDAT0=0xFF;
}
void TestNRF24L01(void) {
InitPin();
InitSpi();
SET_CE0(1);
SpiWriteReg(0, WRITE_REG + SETUP_RETR, 0x01);
usDelay(1000, NULL);
usDelay(1000, NULL);
usDelay(1000, NULL);
usDelay(1000, NULL);
usDelay(1000, NULL);
Uart_Printf("\nSETUP_RETR = %x\n", SpiReadReg(0, READ_REG + SETUP_RETR));
SET_CE0(0);
}
|
|