完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
RF_PHY 是wch提供的一个调用底层2.4g收发器的一个接口,可以通过此接口实现更为灵活的通信方式
这种底层,仅仅是BLE的收发器基础上,这意味着,收发器调制解调参数,包括frequency,deviation,symbol_rate,以及packet_handler(preamble,syncword,length,crc,whitening)都是符合蓝牙的底层规范的. 具体的工程可参考官方SDK对应路径下的工程,如:CH579EVT_2.3EXAMBLERF_PHY 适用芯片 CH577/CH578/CH579 CH571/CH573 使用 初始化 void RF_Init( void ) { uint8 state; rfConfig_t rfConfig; //注册一个task,用于用户调度 taskID = TMOS_ProcessEventRegister( RF_ProcessEvent ); #if defined(CH573) //针对ch573 //这里的 accessAddress 就是preamble后跟的同步字,用于识别一个新包到来,收发设置成一样是是收到包的前提 //这个accessAddress 的设置要符合蓝牙规范,比如禁止使用0x55555555以及0xAAAAAAAA ( 建议不超过24次位反转,且不超过连续的6个0或1 ) rfConfig.accessAddress = 0x8E89BED6; //crc24_ble 的初值,这个收发也要相同,否则一定会在接收完成后产生crc24 错误 rfConfig.CRCInit = 0x555555; #elif defined(CH579) //针对ch579 rfConfig.TxAccessAddress = 0x8E89BED6; rfConfig.RxAccessAddress = 0x8E89BED6; rfConfig.TxCRCInit = 0x555555; rfConfig.RxCRCInit = 0x555555; #else #error "You must define CH573 or CH579 first!" #endif //The channel is mapped to ble channel, ble4.x adv at channel 37/38/39 //这里的信道映射是BLE的信道,如37信道对应2402Mhz,这个值在收发也要相同 rfConfig.Channel = 37; //这里的工作模式有两种LLE_MODE_BASIC和LLE_MODE_AUTO //其中LLE_MODE_BASIC 是基本的收发,而LLE_MODE_AUTO 是带自动回复的,根据实际场景来选择 //另外在最近更新的库里面 增加了两个可配置选项LLE_MODE_NON_RSSI和LLE_MODE_EX_CHANNEL(ch57x m0 系列不支持) rfConfig.LLEMode = LLE_MODE_BASIC; //注册状态回调函数,这里主要是发送完成,接收到数据之类的会进入这个回调函数 rfConfig.rfStatusCB = RF_2G4StatusCallBack; state = RF_Config( &rfConfig ); PRINT("rf 2.4g init state for ble adv test: %xn",state); } 状态回调 //这里的回调函数是在state = RF_Config( &rfConfig ); 注册的 void RF_2G4StatusCallBack( uint8 sta, uint8 crc, uint8 *rxBuf ) { switch( sta ) { case TX_MODE_TX_FINISH://发送完成,LLE_MODE_BASIC,LLE_MODE_AUTO模式都会产生 break; case TX_MODE_TX_FAIL: //发送失败,LLE_MODE_BASIC,LLE_MODE_AUTO模式都会产生 break; case TX_MODE_RX_DATA: //LLE_MODE_AUTO模式下,发送完数据后,接收到了ack信号 if( crc == 1 ) { PRINT("crc errorn"); } else if( crc == 2 ) { PRINT("match type errorn"); //这里的match type 就是再发射接收的时候 传入的match type跟当前接收配置的type对比的结果 } else { uint8 i; PRINT("tx recv,rssi:%dn",(s8)rxBuf[0]); PRINT("len:%d-",rxBuf[1]); for(i=0; i PRINT("n"); } break; case TX_MODE_RX_TIMEOUT: //LLE_MODE_AUTO模式下,发送完数据后,没有接收到ack信号,默认超时是 3 ms break; case RX_MODE_RX_DATA: //接收到数据,LLE_MODE_BASIC,LLE_MODE_AUTO模式都会产生 if( crc == 1 ) { PRINT("crc errorn"); } else if( crc == 2 ) { PRINT("match type errorn"); } else { uint8 i; //rxBuf[0] 默认情况下是rssi,如果 在LLEMode初始化时同时开启了LLE_MODE_NON_RSSI,那这里将会变为PKT_TYPE PRINT("rx recv, rssi: %dn",(s8)rxBuf[0]); //我们还可以通过下面方式获取RSSI,这个不受LLE_MODE_NON_RSSI配置影响: PRINT("rssi:%drn",(int8_t)rxBuf[2+((rxBuf[1]+5)&0xffc)]); //数据部分 PRINT("length: %d:",rxBuf[1]); for(i=0; i PRINT("%02x ",rxBuf[i+2]); } PRINT("n"); } break; case RX_MODE_TX_FINISH: //LLE_MODE_AUTO模式下,接收到数据后,自动ack完成 break; case RX_MODE_TX_FAIL: //LLE_MODE_AUTO模式下,接收到数据后,ack失败,仅仅只是发送失败 break; } PRINT("STA: %xn",sta); } API说明 //RF_PHY内部初始化必须先运行这个再运行后面的RF_Config //这个也可以 在ble初始化以后再加入这个,这样就可以做到2.4g跟ble 同时运行 bStatus_t RF_RoleInit( void ); //初始化,按照上面给你的示例说明 bStatus_t RF_Config( rfConfig_t *pConfig ); /******************************************************************************* * @fn RF_Rx * * @brief rx mode. * * input parameters * * @param txBuf - rx mode tx data * @param txLen - rx mode tx length(0-251) * @param pktRxType - rx mode rx package type * broadcast type(0xFF):receive all matching types, * others:receive match type or broadcast type * @param pktTxType - rx mode tx package type(auto mode) * broadcast type(0xFF):received by all matching types; * others:only received by matching type * * output parameters * * @param None. * * @return 0 - success. */ extern bStatus_t RF_Rx( u8 *txBuf, u8 txLen, u8 pktRxType, u8 pktTxType ); /******************************************************************************* * @fn RF_Tx * * @brief tx mode. * * input parameters * * @param txBuf - tx mode tx data * @param txLen - tx mode tx length(0-251) * @param pktTxType - tx mode tx package type * broadcast type(0xFF):received by all matching types; * others:only received by matching type * @param pktRxType - tx mode rx package type(auto mode) * broadcast type(0xFF):receive all matching types, * others:receive match type or broadcast type * * output parameters * * @param None. * * @return 0 - success. */ extern bStatus_t RF_Tx( u8 *txBuf, u8 txLen, u8 pktTxType, u8 pktRxType ); //关闭TX/RX模式,不建议在状态回调里调用,而是在外面调用 bStatus_t RF_Shut( void ); //设置RF的信道,这里的信道对应的是ble的信道,比如37对应2402Mhz void RF_SetChannel( u8 channel ); 应用 模拟BLE广播 说明 有时候,我们的应用很简单,并不需要建立BLE连接,只需要广播,比如各种beacon应用,而ble的协议栈是比较庞大的,而用2.4G的方式直接写,则可以做到非常的轻量. 本文只实现不可连接的广播,不支持scan_respone的回复包 初始化 void RF_Init( void ) { uint8 state; rfConfig_t rfConfig; taskID = TMOS_ProcessEventRegister( RF_ProcessEvent ); #if defined(CH573) //依据BLE的核心规范,填写Access Address 和 CRC24 的入值. rfConfig.accessAddress = 0x8E89BED6; rfConfig.CRCInit = 0x555555; #elif defined(CH579) rfConfig.TxAccessAddress = 0x8E89BED6; rfConfig.RxAccessAddress = 0x8E89BED6; rfConfig.TxCRCInit = 0x555555; rfConfig.RxCRCInit = 0x555555; #else #error "You must define CH573 or CH579 first!" #endif //The channel is mapped to ble channel, ble4.x adv at channel 37/38/39 rfConfig.Channel = 37; rfConfig.LLEMode = LLE_MODE_BASIC; rfConfig.rfStatusCB = RF_2G4StatusCallBack; state = RF_Config( &rfConfig ); PRINT("rf 2.4g init state for ble adv test: %xn",state); } 构造数据 //ble adv data for RF-PHY test static uint8_t ble_adv_test_data[] = { 0x3c,0x10,0x2D, 0xE4, 0xC2, 0x84, //MAC ADDR 9,0x09,'A','D','V','-','T','E','S','T' //ADV data }; 发送 uint8_t ble_adv_tx(void) { RF_Shut( ); //tx type :0X02 for no connected adv return RF_Tx( ble_adv_test_data,sizeof(ble_adv_test_data), 0x02, 0xFF ); } 接收BLE广播 与BLE工程一起跑 BLE的工作特点是间歇性工作,依据广播间隔/连接间隔协议栈进行定时调用收发器工作,其他时间收发器资源都是释放的,这也是为什么的BLE可以和WIFI,zigbee,thread等协议共用部分射频资源动态共存的原因 鉴于BLE的这种工作特点,wch也把RF_PHY 这种模式与ble可以共存运行. 下面在wch 提供的ble的工程里面加入RF_PHY 工作的初始方式,实际上就是把RF_PHY的初始化函数放在BLE初始化完成后调用即可,但是由于BLE 的存在,所以丢包可能是非常普遍, 如,这边在发射,接收端的射频被BLE短暂占用,就会导致接收不到这一包数据,所以一定差错控制(如ack机制,数据包冗余机制)在实际的应用中,往往是必要的. int main( void ) { #if (defined (DCDC_ENABLE)) && (DCDC_ENABLE == TRUE) PWR_DCDCCfg( ENABLE ); #endif SetSysClock( CLK_SOURCE_PLL_60MHz ); GPIOA_ModeCfg( GPIO_Pin_All, GPIO_ModeIN_PU ); GPIOB_ModeCfg( GPIO_Pin_All, GPIO_ModeIN_PU ); #ifdef DEBUG GPIOA_SetBits(bTXD1); GPIOA_ModeCfg(bTXD1, GPIO_ModeOut_PP_5mA); UART1_DefInit( ); #endif PRINT("%sn",VER_LIB); CH57X_BLEInit( ); HAL_Init( ); GAPRole_PeripheralInit( ); Peripheral_Init( ); //RF_PHY 例程初始化函数 RF_Init(); Main_Circulation(); } |
|
|
|
只有小组成员才能发言,加入小组>>
CH579M+RT-Thread,RTC从Sleep模式唤醒失败是什么原因?
2616 浏览 2 评论
2145 浏览 1 评论
ch554g的板子准备烧录程序,用串口总是显示等待设备连接是为啥
1020浏览 14评论
请问ch32v307用ch-link调试或者读写有什么特殊操作方法吗?
918浏览 13评论
Windows系统下如何确定COM口为CH340/CH341设备?
2252浏览 12评论
694浏览 12评论
CH32V307以太网接近满速后,几秒或几十秒后就死机怎么解决?
1985浏览 11评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-5-11 14:03 , Processed in 0.885036 second(s), Total 78, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号