写了一个spi模拟通讯协议,想验证通信协议是否正确,身边就只找到了nrf24l01模块,费了九牛二虎之力撸完代码等待收获成功的喜悦,结果,status寄存器一直返回255,前面对nrf24l01一直没有研究,所以我不知道是spi时序问题还是nrf24l01的问题,下面是spi代码:
#include "SPI.h"
bit CPOL;
bit CPHA;
bit GD;
void Delay10us() //@12MHz
{
unsigned char i;
_nop_();
_nop_();
i = 27;
while (--i);
}
void SPI_init(unsigned char MS_1,bit MS_2){ //MS_1为模式选择(0,1,2,3),MS_2为高低位选择(0:低位在前,1:高位在前)
switch(MS_1){
case 0:
CPOL = 0;
CPHA = 0;
break;
case 1:
CPOL = 0;
CPHA = 1;
break;
case 2:
CPOL = 1;
CPHA = 0;
break;
case 3:
CPOL = 1;
CPHA = 1;
break;
}
GD = MS_2;
SCLK = CPOL;
// CS = 1;
MOSI = 1;
MISO = 1;
}
unsigned char spi_RW(unsigned char spi_data){
unsigned char tval=0x00,i;
// CS = 0;
for(i=0;i<8;i++)
{
if(CPHA)
{
Delay10us();
SCLK = ~CPOL;
if(GD)
MOSI = 0x80&spi_data;
else
MOSI = 0x01&spi_data;
Delay10us();
Delay10us();
SCLK = CPOL;
if(GD)
{
tval <<= 1;
if(MISO)
tval |= 0x01;
spi_data <<= 1;
}
else
{
tval >>= 1;
if(MISO)
tval |= 0x80;
spi_data >>= 1;
}
Delay10us();
}
else
{
if(GD)
MOSI = 0x80&spi_data;
else
MOSI = 0x01&spi_data;
Delay10us();
SCLK = ~CPOL;
if(GD)
{
tval <<= 1;
if(MISO)
tval |= 0x01;
spi_data <<= 1;
}
else
{
tval >>= 1;
if(MISO)
tval |= 0x80;
spi_data >>= 1;
}
Delay10us();
Delay10us();
SCLK = CPOL;
Delay10us();
}
}
// CS = 1;
return tval;
}
上面片选信号在nrf24l01中实现,spi中未用到,下面是spi.h文件
#ifndef ___S____P___I___H__
#define ___S____P___I___H__
#include "STC.h"
#include <intrins.h>
sbit SCLK = P3^6;
sbit MOSI = P2^0;
sbit MISO = P2^2;
//sbit CS = P1^3;
void SPI_init(unsigned char MS_1,bit MS_2); //MS_1为模式选择(0,1,2,3),MS_2为高低位选择(0:低位在前,1:高位在前)
unsigned char spi_RW(unsigned char spi_data); //发送接收函数
#endif
nrf24l01程序有点长,
#include "nrf24l01.h"
unsigned char TX_addr1[]={0xc3,0xe4,0x6a,0xde,0xc6};
void NRF_init(){ //初始化工作
SPI_init(0,1); //SPI工作方式0,高位在前
nrf_cs = 1;
nrf_ce = 0;
}
unsigned char nrf_w_byte(unsigned char commd,unsigned char dat){ //写一个字节,带格式化地址
unsigned char val1;
commd &= 0x1f;
commd |= 0x20;
nrf_cs = 0;
val1 = spi_RW(commd);
spi_RW(dat);
nrf_cs = 1;
return val1;
}
unsigned char nrf_r_byte(unsigned char commd,unsigned char dat){ //读取一个字节 参数为地址,数据(一般是0xff)带地址格式化
unsigned char val1;
commd &= 0x1f;
nrf_cs = 0;
spi_RW(commd);
val1 = spi_RW(dat);
nrf_cs = 1;
return val1;
}
unsigned char nrf_w_str(unsigned char commd,unsigned char *ndat,unsigned char nnum){//写入数组 参数为地址命令,数据数组,数据字节
unsigned char i,val;
nrf_cs = 0;
val = spi_RW(commd);
for(i=0;i<nnum;i++){
spi_RW(ndat[i]);
}
nrf_cs = 1;
return val;
}
unsigned char nrf_r_str(unsigned char commd,unsigned char *ndat,unsigned char nnum){//读取数组,参数同上
unsigned char i,val;
nrf_cs = 0;
val = spi_RW(commd);
for(i=0;i<nnum;i++){
ndat[i] = spi_RW(0xff);
}
nrf_cs = 1;
return val;
}
void NRF_send(unsigned char *dat,unsigned char snum){//准备作为写FIFO函数
nrf_w_str(0xa0,dat,snum);
}
void NRF_accept(unsigned char *dat,unsigned char snum){//准备作为读FIFO函数
nrf_w_str(0x61,dat,snum);
}
void NRF_clear(unsigned char mod_reg){ //FIFO寄存器清除操作参数mod_reg为T表示发送寄存器清0,R为接收寄存器清0
switch(mod_reg){
case 0:
nrf_cs = 0;
spi_RW(0xe1);
spi_RW(0xff);
nrf_cs = 1;
break;
case 1:
nrf_cs = 0;
spi_RW(0xe2);
spi_RW(0xff);
nrf_cs = 1;
break;
}
}
unsigned char NRF_status(){//读取状态寄存器
return nrf_r_byte(0x07,0xff);//status
}
void NRF_TX_MODE(){//发送端设置,注释为对应寄存器名称
nrf_w_byte(0x00,0x0a);//config
nrf_w_byte(0x01,0x3f);//en_aa
nrf_w_byte(0x02,0x01);//en_rx_addr
nrf_w_byte(0x03,0x03);//setup_aw
nrf_w_byte(0x04,0x0a);//setup_retr
nrf_w_byte(0x05,0x3a);//rf_ch
nrf_w_byte(0x06,0x0f);//config
nrf_w_byte(0x07,0x0e);//status
nrf_w_str(0x0a+0x20,TX_addr1,5);//rx_addr_p0
nrf_w_str(0x10+0x20,TX_addr1,5);//tx_addr
NRF_clear(0);
}
如上为所有代码,main函数只做了初始化并一直读取status寄存器数据,但是读取数据一直为0xff,为此我斥巨资35购入一台逻辑分析仪来观测数据时序,结果如图
观测到的mosi波形应该是正确的,但是nrf24l01一直返回0xff就让我非常迷茫
希望大家能指出是什么问题,怎么能正确收到status寄存器值