nrf52832的radio外设
目前国内大多ble外设都是都是直接将ble的controller封死的,导致无法直接利用芯片的
radio(射频)外设,直接去模拟广播。
nordic系列都可以直接控制radio外设,可以通过直接配置寄存器来模拟广播,其寄存器
可以查看其芯片手册,也可以看俺关于radio的讲解,哈哈

广播协议格式
任何一些都有其格式,不同格式表示的含义不同。下面就是BLE广播的格式。
从左往右以此:
1、前导码 不需要懂它、也不用用管它,固定的,由芯片自行设置
2、接入地址 广播信道固定地址,用于表示广播的。
3、报头、长度就不用说了,每个位置表示各自含义。
4、数据载荷就是承载的数据。
数据载荷的格式,第一个字节表示长度,后面表示数据。数据又可以自定义格式。哈哈,for example:
02 11 15 02表示长度,11 15就是数据,至于11 15表示什么含义,可以自己定义或者遵循别人协议。
更具体的看俺的蓝牙广播格式帖子哦

寄存器设置和代码编写
通过设置其寄存器之后,然后使用其event事件去触发发送。其寄存器主要代码是:
void radio_init(void){
//这里设置8个逻辑地址的实际地址,因为我们只是做广播,所以把全部地址都设置成0x8E89BED6,
NRF_RADIO->BASE0 = (0x89BED600);
NRF_RADIO->BASE1 = (0x89BED600);
NRF_RADIO->PREFIX0 = 0x8E8E8E8E;
NRF_RADIO->PREFIX1 = 0x8E8E8E8E;
NRF_RADIO->TXADDRESS = 0; //使用逻辑地址0
NRF_RADIO->CRCCNF = (3<<0) | (1<<8); //3字节crc,计算不包括接入地址部分
NRF_RADIO->CRCPOLY = 0x100065b;//crc多项式为 x^24+x^10+x^9+x^6+x^4+x^3+x^1+x^0
NRF_RADIO->CRCINIT = 0x555555; //广播信道的数据包中crc初始值为0x555555
NRF_RADIO->PACKETPTR = (uint32_t)&adv_array[0];
NRF_RADIO->FREQUENCY = 2; //链路层信道编号 37:2402MHz, 38:2426MHz, 39:2480MHz
NRF_RADIO->TXPOWER = 0x04;
NRF_RADIO->MODE = 0x03; //ble_1Mbit
//8bit长度的LENGTH 1字节长度的S0,不需要s1,因为广播格式里面负载数据前面只需要2字节头,一个是报头,一个是长度。
//length 1 s01 payload length ?? address 4 4+1+1+??
//
NRF_RADIO->PCNF0 = (8<<0) | (1<<8);
//payload最大长度37,没有静态长度,基础地址为3字节,所以加一字节头后为四字节,就是蓝牙规范中接入地址.字节序为小端(CRC不在这里设置)
//使能数据白化
//46 40数据 4地址 1s0 1 length
//0到7为MAXLEN也就是payload的长度 8-15为statlen static length 16-18为base address 24为s0 length s1 payload
//的小端或者大端 25为是否白化
//NRF_RADIO->PCNF1 = (30<<0)|(20<<8) | (3<<16) | (1<<25) ; 那个static是自动加到payload后面的,这里只是设置
//每个(s0,s1,length ,static)的长度或者其他东西,与实际传输的长度无关。
//实际传输中的长度由length决定payload(所以这个得启用,至少在这里例子里是)
//static在payload,手册中说了ble中其长度为0,所以static长度基本不用,加上这个手机搜不出来 原因是static后面回覆盖
//CRC,emmm
NRF_RADIO->PCNF1 = (31<<0) |(0<<8)|(3<<16) | (1<<25) ;
NRF_RADIO->DATAWHITEIV = 0x25;//0x25; //初始值由报文所在链路层信道号决定,这里为37
}
让广播占领整个广播信道
这里来个有趣的,既然可以模拟广播了,那就尝试占领整个信道。其实简单的说就是模拟超多不同MAC
地址哈哈。其实很简单的哦。用nrf connect来查看下效果。
其主要代码如下所示,代码写的很曹凑合看吧。
void radio(){
init_clock();
radio_init();
set_advdata();
while(1){
for(int j=0;j<100;j++) {
//nrf_delay_ms(10);
for(int i=0;i<0xFF;i++){
device_add[0]=j;
device_add[1]=(i+1)%0xFF;
device_add[2]=(i+2)%0xFF;
device_add[3]=(i+3)%0xFF;
device_add[4]=(i+4)%0xFF;
device_add[5]=(i+5)%0xFF;
for(int i=0;i<3;i++){
send_data();
}
}
for(int i=0;i<0xFF;i++){
device_add[0]=j+2;
device_add[1]=(i+1)%0xFF;
device_add[2]=(i+2)%0xFF;
device_add[3]=(i+3)%0xFF;
device_add[4]=(i+4)%0xFF;
device_add[5]=(i+5)%0xFF;
for(int i=0;i<3;i++){
send_data();
}
}
for(int i=0;i<0xFF;i++){
device_add[0]=j+3;
device_add[1]=(i+1)%0xFF;
device_add[2]=(i+2)%0xFF;
device_add[3]=(i+3)%0xFF;
device_add[4]=(i+4)%0xFF;
device_add[5]=(i+5)%0xFF;
for(int i=0;i<3;i++){
send_data();
}
}
for(int i=0;i<0xFF;i++){
device_add[0]=j+4;
device_add[1]=(i+1)%0xFF;
device_add[2]=(i+2)%0xFF;
device_add[3]=(i+3)%0xFF;
device_add[4]=(i+4)%0xFF;
device_add[5]=(i+5)%0xFF;
for(int i=0;i<3;i++){
send_data();
}
}
}
}
}

一个大胆的想法,就是干扰信道。
就是上边的哦,通过在广播PDU中声明大量的MAC地址。

结果与总结
结果就是上边那个长图,如果是只是广播一个设备,只要要一个MAC地址了。多个不同广播,就多个MAC地址。
项目上传到CSDN吧,只需要在keil中烧录,然后在nrf connect中查看想过就行。
https://download.csdn.net/download/beidideshu/86341416
版权声明:本文为beidideshu原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。