这种SPI程序用51单片机的I/O口线很好模拟的,仔细看芯片的文档,下面这个是用在NRF905的:uchar bdata DATA_BUF;sbit flag =DATA_BUF^7;sbit flag1 =DATA_BUF^0;////function SpiWrite();void SpiWrite(uchar byte){ uchar i; DATA_BUF=byte; // Put function's parameter into a bdata variable for (i=0;i<8;i++) // Setup byte circulation bits { if (flag) // Put DATA_BUF7 on data line MOSI_nRF905=1; else MOSI_nRF905=0; SCK=1; // Set clock line high DATA_BUF=DATA_BUF<<1; // Shift DATA_BUF SCK=0; // Set clock line low } MOSI_nRF905=1;}////function SpiRead();uchar SpiRead(void){ uchar i; for (i=0;i<8;i++) // Setup byte circulation bits { DATA_BUF=DATA_BUF<<1; // Right shift DATA_BUF SCK=1; // Set clock line high if (MISO_nRF905) flag1=1; // Read data else flag1=0; SCK=0; // Set clock line low } MISO_nRF905=1; return DATA_BUF; // Return function parameter}
NRF5340-QKAA-AB0-R是蓝牙51芯片,一款RF片上系统 - SoC。
属性
类型: Bluetooth, Zigbee
核心: ARM Cortex M33
输出功率: 3 dBm
工作电源电压: 17 V to 55 V
程序存储器大小: 256 kB, 1 MB
数据 RAM 大小: 64 kB, 512 kB
数据 Ram 类型: RAM
接口类型: I2C, SPI, UART, USB
安装风格: SMD/SMT
输入/输出端数量: 48 I/O
ADC分辨率: 12 bit
最大时钟频率: 32 MHz
最大工作温度: + 105 C
最小工作温度: - 40 C
定时器数量: 6 x 32 bit
你好:
状态字是当前NRF发送中断、接收中断、重发最大次数中断等的标志。
一个调试好的NRF,状态字个人感觉用处不大,但是在调试期间作用相当大,以此判断是发送的问题还是接收的问题。
是的,当然是先选择寄存器,再写值。
希望我的回答能帮助到你。
我有一完整的程序,由于担心单片机实验板上的5V电压会损坏24L01,加上需两块单片机协调工作,因此也没敢试,如果你有条件,帮我试一下,我不要积分,只告诉我实验结果就行
#include "reg52h"
#include "intrinsh" //_nop_();延时函数用
#define uchar unsigned char
#define uint unsigned int
sbit DATA=P1^1; //发送方管脚配置
sbit CLK1=P1^2;
sbit CS=P1^3;
sbit CE=P1^4;
sbit DR1=P1^5;
sbit PWR_UP=P1^6;
sbit led1=P1^0;
sbit diol=P2^5;
/sbit DATA=P2^1; //接收方管脚配置
sbit CLK1=P2^2;
sbit CS=P2^3;
sbit CE=P2^4;
sbit DR1=P2^5;
sbit PWR_UP=P1^6;
sbit led1=P3^7;
sbit diol=P2^0;//没用/
sbit BIT0=ACC^0;
sbit BIT7=ACC^7;//
uchar TXData[14];
uchar RXData[10];
uchar Data1=0xff;
uchar code table1[]={0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
uchar code table2[]={0x99,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
delay1ms(int t)
{
uint i;
uint j;
for(i=0;i<t;i++)
for(j=0;j<116;j++);
}
void delay10us(void)
{
uchar y;
for(y=0;y<10;y++)
_nop_();
}
void delay100us(void)
{
uchar y;
for(y=0;y<100;y++)
_nop_();
}
/
/函数:write( uchar byte)
/功能:通过IO口写入一个字节到NRF24L01
//
void write(uchar byte)
{
uchar i;
ACC=byte;
i=8;
while(i)
{
DATA=BIT7;
CLK1=1; // output 'uchar', MSB to MOSI
_nop_();
_nop_(); // shift next bit into MSB
ACC<<=1;
CLK1=0; // Set SCK high
i--; // then set SCK low again
}
}
/
/函数:Read(uchar reg)
/功能:NRF24L01的读时序
//
uchar Read(void)
{
uchar i;
i=8;
while(i)
{
CLK1=1; // output 'uchar', MSB to MOSI
_nop_();
_nop_(); // shift next bit into MSB
ACC<<=1;
BIT0=DATA ;
CLK1=0; // Set SCK high
i--; // then set SCK low again
}
return ACC; // return register value
}
//
/功能:NRF24L01初始化控制结构体
//
struct RFConfig
{
uchar n;
uchar buf[15];
};
typedef struct RFConfig RFConfig;
#define ADDR_INDEX 8 //地址起始号为 8
#define ADDR_COUNT 4 //地址占4字节
code RFConfig tconf= //发射时配置字
{
15,//配置字长度15
0x50,//接收通道2数据长度80bit(10byte)
0x50,//接收通道1数据长度80bit(10byte)
0x00,0x00,0x00,0x00,0x00,//接收通道2地址最多40bit(5byte)
0x00,0xaa,0xbb,0x12,0x34,//接收通道1地址最多40bit(5byte)
0x83,//32bit地址长度,16bit crc校验
0x6f,//单通道接收
0x04//02频道发射
};
code RFConfig rconf=//接收时配置字
{
15,
0x50,
0x50,
0x00,0x00,0x00,0x00,0x00,
0x00,0xaa,0xbb,0x12,0x34,
0x83,
0x6f,
0x05//2频道接收
};
void nrf2401_on()
{
CE=0;
CS=0;
PWR_UP=1;
delay1ms(3);
}
void nrf2401init_receiver(void)//接收初始化
{
uchar b;
CE=0;
CS=1;
delay10us();
for(b=0;b<rconfn;b++)//rconfn=15
{
write(rconfbuf[b]);
}
CE=1;
CS=0;
}
void nrf2401init_transmitter(void)//发射初始化
{
uchar b;
CE=0;
CS=1;
delay10us();
for(b=0;b<rconfn;b++)//rconfn和tconfn相等
{
write(tconfbuf[b]);
}
CS=0;
}
void nrf2401set_rxmode(void)//接收初始化后快速进入接收状态
{
CE=0;
CS=1;
delay10us();
write(rconfbuf[14]);//写入命令0x05
CE=1;
CS=0;
}
void nrf2401set_txmode(void)//发射初始化后快速进入发射状态
{
CE=0;
CS=1;
delay10us();
write(tconfbuf[14]);//写入命令0x04
CE=1;
CS=0;
}
void tx_packet(uchar m)//m=1发射数据包选table1,m=2选table2
{
uchar i ;
TXData[0]=0xaa;//要不要补1个地址码0x00不用,前面已设32bit地址长度,
TXData[1]=0xbb;
TXData[2]=0x12;
TXData[3]=0x34;
if (m==1)
{
for(i=4;i<14;i++)
{TXData[i]=table1[i-4];}
}
else
{
for(i=4;i<14;i++)
{TXData[i]=table2[i-4];}
}
CS=0;CE=1;
delay10us();
for(i=0;i<14;i++)
{
write(TXData[i]);
}
CE=0;
}
/void tx_packet(void)//发射数据包
{
uchar i ;
TXData[0]=0xaa;//要不要补1个地址码0x00不用,前面已设32bit地址长度,
TXData[1]=0xbb;
TXData[2]=0x12;
TXData[3]=0x34;
for(i=4;i<14;i++)
{TXData[i]=table2[i-4];}
CS=0;CE=1;
delay10us();
for(i=0;i<14;i++)
{
write(TXData[i]);
}
CE=0;
}/
void recevice_packet(void)//接收数据包
{
uchar i ;
for(i=0;i<10;i++)
{
RXData[i]=Read();
}
}
//发射方先发一个数据包,其中第5个数据(TXData[4])为0x88,然后进入接收状态,若收到的数据包第5个数是0x99,则点亮发光二极管
//接收方先进入接收状态,若收到的数据包第5个数是0x88,则点亮LED并发送一个数据包,其中第5个是0x99
void main(void)//发射方主程序
{
nrf2401_on();
nrf2401init_transmitter();
nrf2401set_txmode;//进入发射状态
tx_packet(1);//发射数据包1第4个数据为0x88
nrf2401init_receiver();
nrf2401set_rxmode();//进入接收状态
while(DR1!=1);
recevice_packet();//接收数据包
diol=1;//开通锁存器
if(RXData[4]==0x99)//如果收到正确遥数据0x99,则灯亮说明通信成功
{
led1=0;
}
while(1);
}
/void main(void)//接收方主程序
{
nrf2401_on();
nrf2401init_receiver();
nrf2401set_rxmode();//进入接收状态
while(DR1!=1);
recevice_packet();//接收数据包
diol=1;//开通锁存器
if(RXData[4]==0x88)//如果收到正确遥数据0x88,则灯亮说明通信成功
{
led1=0;
}
nrf2401init_transmitter();
nrf2401set_txmode;//进入发射状态
delay1ms(10);//延时,让发送方准备好
tx_packet(2);//发射数据包2,第4个数据为0x99
while(1);
}/
1一般要先检查硬件是不是有问题哈,一定要仔细,特别是芯片的供电,单片机供电,然后是之间的连接
2确认硬件无故障之后,你可以整个最最简单的程序,发送1bit数据,然后用8个led把发送的data显示出来,接收端也同样处理。看看是否运行顺利。
3如果在不行,还是用最简单的程序,然后用示波器依次检查nRF的引脚信号是否正确,特别是把CE、SCK、CSN以及MOSI、MISO对照着看,是否和nRF说明书上的时序一致,这样虽然麻烦 但肯定能找到问题。
注:很多中午PDF资料上内容不全,连接收、发送的时序也没。建议看英文厂商原版的资料;我附了ShockBurst模式下的发送、接收时序图,你可以直接参考下~
希望我的回答对你有所帮助哈~
1信号较弱,导致断连:天线匹配度不好、发射功率低、灵敏度差导致信号较弱;收发模块之间距离太远导致的信号弱;天线收设备的屏蔽等影响导致的信号弱。
2传输的数据量大,数据流高,程序内部有可能会跑飞,导致断连。
3蓝牙频段(24频段)存在大量其他无线信号,可能会导致串扰而造成断连。
SKYLAB的蓝牙模块所用的芯片就是nRF51822的,所以想了解更多关于蓝牙模块这方面的问题,可以去官网上去咨询,很高兴为你解答!
以上就是关于parmispi的程序编程步骤全部的内容,包括:parmispi的程序编程步骤、NRF5340-QKAA-AB0-R是什么芯片性能如何、关于无线nrf24l01的一句程序语句 status = SPI_RW(reg); // 选择寄存器,同时返回状态字等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)