CH592F 2.4G 低功耗

发布时间:2026/9/23 22:58:08

CH592F 2.4G 低功耗 2.4G私有协议低功耗传输tx按一下按键按键发送数据到rxrx 1s内启动10ms接收窗口进行接收。代码从github上拉取官方的代码GitHub - openwch/ch592: The SDK and HDK for RISC-V Bluetooth LE BLE5.4 CH591/CH592 · GitHub例程是ch592\EVT\EXAM\BLE\RF_PHY配置开启 HAL_SLEEP然后替换下面3个文件RF_PHY.h/********************************** (C) COPYRIGHT ******************************* * File Name : rf_phy.h * Author : WCH * Version : V1.0 * Date : 2018/11/12 * Description : ********************************************************************************* * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. * Attention: This software (modified or not) and binary are used for * microcontroller manufactured by Nanjing Qinheng Microelectronics. *******************************************************************************/ #ifndef CENTRAL_H #define CENTRAL_H #ifdef __cplusplus extern C { #endif #define SBP_RF_RX_OPEN_EVT 0x0001 // 打开RX并启动接收窗口 #define SBP_RF_RX_CLOSE_EVT 0x0002 // 关闭RX并进入低功耗等待 #define SBP_RF_RX_RESTART_EVT 0x0004 // 基本模式收包后重新启动RX #define SBP_RF_TX_SEND_EVT 0x0008 // 发送一包TX数据 #define SBP_RF_TX_RX_DATA_EVT 0x0010 // 在TMOS任务中处理并打印应答数据 #define SBP_RF_KEY_IRQ_EVT 0x0020 // PA4下降沿中断投递事件 #define SBP_RF_KEY_CHECK_EVT 0x0040 // 延时10ms后检查按键电平 #define SBP_RF_TX_TIMEOUT_EVT 0x0080 // 连续发送3秒仍无应答则停止 #define LLE_MODE_ORIGINAL_RX (0x80) //如果配置LLEMODE时加上此宏则接收第一字节为原始数据原来为RSSI extern void RF_Init(void); #ifdef __cplusplus } #endif #endifRF_main.c/********************************** (C) COPYRIGHT ******************************* * File Name : main.c * Author : WCH * Version : V1.0 * Date : 2020/08/06 * Description : ********************************************************************************* * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. * Attention: This software (modified or not) and binary are used for * microcontroller manufactured by Nanjing Qinheng Microelectronics. *******************************************************************************/ /******************************************************************************/ /* 头文件包含 */ #include CONFIG.h #include HAL.h #include RF_PHY.h /********************************************************************* * GLOBAL TYPEDEFS */ __attribute__((aligned(4))) uint32_t MEM_BUF[BLE_MEMHEAP_SIZE / 4]; #if(defined(BLE_MAC)) (BLE_MAC TRUE) const uint8_t MacAddr[6] {0x84, 0xC2, 0xE4, 0x03, 0x02, 0x02}; #endif /********************************************************************* * fn Main_Circulation * * brief 主循环 * * return none */ __HIGH_CODE __attribute__((noinline)) void Main_Circulation() { while(1) { TMOS_SystemProcess(); } } /********************************************************************* * fn main * * brief 主函数 * * return none */ int main(void) { #if(defined(DCDC_ENABLE)) (DCDC_ENABLE TRUE) PWR_DCDCCfg(ENABLE); #endif SetSysClock(CLK_SOURCE_PLL_60MHz); #if(defined(HAL_SLEEP)) (HAL_SLEEP TRUE) GPIOA_ModeCfg(GPIO_Pin_All, GPIO_ModeIN_PU); GPIOB_ModeCfg(GPIO_Pin_All, GPIO_ModeIN_PU); #endif #ifdef DEBUG GPIOA_SetBits(bTXD1); GPIOA_ModeCfg(bTXD1, GPIO_ModeOut_PP_5mA); UART1_DefInit(); #endif PRINT(start.\n); PRINT(%s\n, VER_LIB); CH59x_BLEInit(); HAL_Init(); RF_RoleInit(); RF_Init(); Main_Circulation(); } /******************************** endfile main ******************************/RF_PHY.c/********************************** (C) COPYRIGHT ******************************* * File Name : main.c * Author : WCH * Version : V1.0 * Date : 2020/08/06 * Description : ********************************************************************************* * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. * Attention: This software (modified or not) and binary are used for * microcontroller manufactured by Nanjing Qinheng Microelectronics. *******************************************************************************/ /******************************************************************************/ /* 头文件包含 */ #include CONFIG.h #include RF_PHY.h #define RF_DEVICE_ROLE_RX 0 #define RF_DEVICE_ROLE_TX 1 #define RF_DEVICE_ROLE RF_DEVICE_ROLE_TX #if(RF_DEVICE_ROLE ! RF_DEVICE_ROLE_RX) \ (RF_DEVICE_ROLE ! RF_DEVICE_ROLE_TX) #error Invalid RF_DEVICE_ROLE #endif /********************************************************************* * GLOBAL TYPEDEFS */ #define RF_AUTO_MODE_EXAM 1 #define RF_RX_PERIOD MS1_TO_SYSTEM_TIME(1000) #define RF_RX_WINDOW MS1_TO_SYSTEM_TIME(10) #define RF_KEY_DEBOUNCE_TIME MS1_TO_SYSTEM_TIME(10) #define RF_TX_TIMEOUT_TIME MS1_TO_SYSTEM_TIME(3000) #define RF_KEY_PIN GPIO_Pin_4 typedef struct { int8_t rssi; uint8_t len; uint8_t data[251]; } rfRxPacket_t; uint8_t taskID; uint8_t ACK_DATA[2] {o, k}; uint8_t TX_DATA[10] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}; volatile uint8_t tx_end_flag0; volatile uint8_t rx_end_flag0; static volatile uint8_t rx_window_openFALSE; static volatile uint8_t rx_first_packetFALSE; static volatile uint8_t rx_ack_status0; static rfRxPacket_t rx_packet; static rfRxPacket_t tx_rx_packet; static volatile uint8_t tx_runningFALSE; #if(RF_DEVICE_ROLE RF_DEVICE_ROLE_TX) /********************************************************************* * fn HAL_KeyIrqInit * * brief 配置PA4上拉输入、下降沿中断和睡眠唤醒 */ void HAL_KeyIrqInit(void) { GPIOA_ModeCfg(RF_KEY_PIN, GPIO_ModeIN_PU); GPIOA_ITModeCfg(RF_KEY_PIN, GPIO_ITMode_FallEdge); GPIOA_ClearITFlagBit(RF_KEY_PIN); PFIC_EnableIRQ(GPIO_A_IRQn); PWR_PeriphWakeUpCfg(ENABLE, RB_SLP_GPIO_WAKE, Long_Delay); } /********************************************************************* * fn HAL_KeyIrqGet * * return 0-按下非0-释放 */ uint32_t HAL_KeyIrqGet(void) { return GPIOA_ReadPortPin(RF_KEY_PIN); } /********************************************************************* * fn GPIOA_IRQHandler * * brief PA4下降沿中断只投递事件不在中断中消抖 */ __attribute__((interrupt(WCH-Interrupt-fast))) __attribute__((section(.highcode))) void GPIOA_IRQHandler(void) { uint16_t flag R16_PA_INT_IF; if(flag RF_KEY_PIN) { GPIOA_ClearITFlagBit(RF_KEY_PIN); tmos_set_event(taskID, SBP_RF_KEY_IRQ_EVT); } } #endif /********************************************************************* * fn RF_Wait_Tx_End * * brief 手动模式等待发送完成自动模式等待发送-接收完成必须在RAM中等待等待时可以执行用户代码但需要注意执行的代码必须运行在RAM中否则影响发送 * * return none */ __HIGH_CODE __attribute__((noinline)) void RF_Wait_Tx_End() { uint32_t i0; while(!tx_end_flag) { i; __nop(); __nop(); // 约5ms超时 if(i(FREQ_SYS/1000)) { tx_end_flag TRUE; } } } /********************************************************************* * fn RF_Wait_Rx_End * * brief 自动模式等待应答发送完成必须在RAM中等待等待时可以执行用户代码但需要注意执行的代码必须运行在RAM中否则影响发送 * * return none */ __HIGH_CODE __attribute__((noinline)) void RF_Wait_Rx_End() { uint32_t i0; while(!rx_end_flag) { i; __nop(); __nop(); // 约5ms超时 if(i(FREQ_SYS/1000)) { rx_end_flag TRUE; } } } /********************************************************************* * fn RF_2G4StatusCallBack * * brief RF 状态回调此函数在中断中调用。注意不可在此函数中直接调用RF接收或者发送API需要使用事件的方式调用 * 在此回调中直接使用或调用函数涉及到的变量需注意此函数在中断中调用。 * * param sta - 状态类型 * param crc - crc校验结果 * param rxBuf - 数据buf指针 * * return none */ void RF_2G4StatusCallBack(uint8_t sta, uint8_t crc, uint8_t *rxBuf) { switch(sta) { case TX_MODE_TX_FINISH: { #if(!RF_AUTO_MODE_EXAM) tx_end_flag TRUE; #endif break; } case TX_MODE_TX_FAIL: { tx_end_flag TRUE; #if(RF_DEVICE_ROLE RF_DEVICE_ROLE_TX) if(tx_running) { tmos_set_event(taskID, SBP_RF_TX_SEND_EVT); } #endif break; } case TX_MODE_RX_DATA: { #if(RF_AUTO_MODE_EXAM) tx_end_flag TRUE; #if(RF_DEVICE_ROLE RF_DEVICE_ROLE_TX) if((crc 0) (rxBuf[1] sizeof(ACK_DATA)) (rxBuf[2] ACK_DATA[0]) (rxBuf[3] ACK_DATA[1])) { uint8_t rx_len; tx_rx_packet.rssi (int8_t)rxBuf[0]; rx_len rxBuf[1]; if(rx_len sizeof(tx_rx_packet.data)) { rx_len sizeof(tx_rx_packet.data); } tmos_memcpy(tx_rx_packet.data, rxBuf[2], rx_len); tx_rx_packet.len rx_len; tmos_set_event(taskID, SBP_RF_TX_RX_DATA_EVT); } else { if(tx_running) { tmos_set_event(taskID, SBP_RF_TX_SEND_EVT); } } #endif #endif break; } case TX_MODE_RX_TIMEOUT: // Timeout is about 200us { #if(RF_AUTO_MODE_EXAM) tx_end_flag TRUE; #if(RF_DEVICE_ROLE RF_DEVICE_ROLE_TX) if(tx_running) { tmos_set_event(taskID, SBP_RF_TX_SEND_EVT); } #endif #endif break; } case RX_MODE_RX_DATA: { if((crc 0) rx_window_open !rx_first_packet) { uint8_t rx_len; rx_first_packet TRUE; rx_packet.rssi (int8_t)rxBuf[0]; rx_len rxBuf[1]; if(rx_len sizeof(rx_packet.data)) { rx_len sizeof(rx_packet.data); } tmos_memcpy(rx_packet.data, rxBuf[2], rx_len); rx_packet.len rx_len; #if(RF_AUTO_MODE_EXAM) RF_Wait_Rx_End(); #endif } #if(!RF_AUTO_MODE_EXAM) if(rx_window_open) { tmos_set_event(taskID, SBP_RF_RX_RESTART_EVT); } #endif break; } case RX_MODE_TX_FINISH: { #if(RF_AUTO_MODE_EXAM) rx_end_flag TRUE; if(rx_first_packet) { rx_ack_status 1; tmos_set_event(taskID, SBP_RF_RX_CLOSE_EVT); } #endif break; } case RX_MODE_TX_FAIL: { #if(RF_AUTO_MODE_EXAM) rx_end_flag TRUE; if(rx_first_packet) { rx_ack_status 2; tmos_set_event(taskID, SBP_RF_RX_CLOSE_EVT); } #endif break; } } } /********************************************************************* * fn RF_ProcessEvent * * brief RF 事件处理 * * param task_id - 任务ID * param events - 事件标志 * * return 未完成事件 */ uint16_t RF_ProcessEvent(uint8_t task_id, uint16_t events) { if(events SYS_EVENT_MSG) { uint8_t *pMsg; if((pMsg tmos_msg_receive(task_id)) ! NULL) { // Release the TMOS message tmos_msg_deallocate(pMsg); } // return unprocessed events return (events ^ SYS_EVENT_MSG); } #if(RF_DEVICE_ROLE RF_DEVICE_ROLE_TX) if(events SBP_RF_KEY_IRQ_EVT) { tmos_stop_task(taskID, SBP_RF_KEY_CHECK_EVT); tmos_start_task(taskID, SBP_RF_KEY_CHECK_EVT, RF_KEY_DEBOUNCE_TIME); return events ^ SBP_RF_KEY_IRQ_EVT; } if(events SBP_RF_KEY_CHECK_EVT) { if(HAL_KeyIrqGet() 0) { PRINT(PA4 key pressed\n); if(!tx_running) { tx_running TRUE; tmos_start_task(taskID, SBP_RF_TX_TIMEOUT_EVT, RF_TX_TIMEOUT_TIME); tmos_set_event(taskID, SBP_RF_TX_SEND_EVT); } } return events ^ SBP_RF_KEY_CHECK_EVT; } if(events SBP_RF_TX_TIMEOUT_EVT) { tx_running FALSE; RF_Shut(); tx_rx_packet.len 0; tmos_clear_event(taskID, SBP_RF_TX_SEND_EVT | SBP_RF_TX_RX_DATA_EVT); PRINT(TX timeout, no ACK in 3s\n); return events ~(SBP_RF_TX_TIMEOUT_EVT | SBP_RF_TX_SEND_EVT | SBP_RF_TX_RX_DATA_EVT); } if(events SBP_RF_TX_RX_DATA_EVT) { uint8_t i; if(tx_rx_packet.len) { PRINT(tx recv ACK, rssi: %d\n, tx_rx_packet.rssi); PRINT(len:%d-, tx_rx_packet.len); for(i 0; i tx_rx_packet.len; i) { PRINT(%x , tx_rx_packet.data[i]); } PRINT(\n); tx_rx_packet.len 0; } tx_running FALSE; tmos_stop_task(taskID, SBP_RF_TX_TIMEOUT_EVT); RF_Shut(); PRINT(TX success, ACK received\n); return events ^ SBP_RF_TX_RX_DATA_EVT; } if(events SBP_RF_TX_SEND_EVT) { uint8_t state; if(!tx_running) { return events ^ SBP_RF_TX_SEND_EVT; } RF_Shut(); tx_end_flag FALSE; state RF_Tx(TX_DATA, sizeof(TX_DATA), 0xFF, 0xFF); if(state ! SUCCESS) { PRINT(TX start failed.state %x\n, state); tmos_start_task(taskID, SBP_RF_TX_SEND_EVT, MS1_TO_SYSTEM_TIME(1)); } return events ^ SBP_RF_TX_SEND_EVT; } #else /* Close RX first if close and restart events arrive together. */ if(events SBP_RF_RX_CLOSE_EVT) { uint8_t i; rx_window_open FALSE; tmos_stop_task(taskID, SBP_RF_RX_CLOSE_EVT); RF_Shut(); if(rx_packet.len) { PRINT(rx recv, rssi: %d\n, rx_packet.rssi); PRINT(len:%d-, rx_packet.len); for(i 0; i rx_packet.len; i) { PRINT(%x , rx_packet.data[i]); } PRINT(\n); rx_packet.len 0; } if(rx_ack_status 1) { PRINT(ACK sent, RX closed early\n); } else if(rx_ack_status 2) { PRINT(ACK failed, RX closed early\n); } return events ^ SBP_RF_RX_CLOSE_EVT; } if(events SBP_RF_RX_OPEN_EVT) { uint8_t state; rx_window_open TRUE; rx_first_packet FALSE; rx_ack_status 0; rx_packet.len 0; rx_end_flag FALSE; RF_Shut(); state RF_Rx(ACK_DATA, sizeof(ACK_DATA), 0xFF, 0xFF); PRINT(RX window open.state %x\n, state); tmos_start_task(taskID, SBP_RF_RX_CLOSE_EVT, RF_RX_WINDOW); tmos_start_task(taskID, SBP_RF_RX_OPEN_EVT, RF_RX_PERIOD); return events ^ SBP_RF_RX_OPEN_EVT; } #endif return 0; } /********************************************************************* * fn RF_Init * * brief RF 初始化 * * return none */ void RF_Init(void) { uint8_t state; rfConfig_t rf_Config; tmos_memset(rf_Config, 0, sizeof(rfConfig_t)); taskID TMOS_ProcessEventRegister(RF_ProcessEvent); rf_Config.accessAddress 0x71764129; // 禁止使用0x55555555以及0xAAAAAAAA ( 建议不超过24次位反转且不超过连续的6个0或1 ) rf_Config.CRCInit 0x555555; rf_Config.Channel 39; rf_Config.Frequency 2480000; #if(RF_AUTO_MODE_EXAM) rf_Config.LLEMode LLE_MODE_AUTO; #else rf_Config.LLEMode LLE_MODE_BASIC | LLE_MODE_EX_CHANNEL; // 使能 LLE_MODE_EX_CHANNEL 表示 选择 rf_Config.Frequency 作为通信频点 #endif rf_Config.rfStatusCB RF_2G4StatusCallBack; rf_Config.RxMaxlen 251; state RF_Config(rf_Config); PRINT(rf 2.4g init: %x\n, state); #if(RF_DEVICE_ROLE RF_DEVICE_ROLE_TX) tx_rx_packet.len 0; tx_running FALSE; HAL_KeyIrqInit(); #else rx_window_open FALSE; tmos_set_event(taskID, SBP_RF_RX_OPEN_EVT); #endif } /******************************** endfile main ******************************/
延伸阅读

更多相关文章

2026/9/23 22:56:50

MIPI-DSI信号测量实战:从示波器基础到眼图分析

1. 从“看见”到“看懂”:示波器在MIPI-DSI信号测量中的角色定位当一块手机屏幕点亮,或者一块智能手表的界面流畅滑动时,其背后是高速串行总线在无声地传输着海量的像素数据。MIPI-DSI(Mobile Industry Processor Interface Displ…

2026/9/22 14:59:19

SAP STRUST SSL/TLS证书管理:从X.509原理到运维实战全解析

1. 项目概述:为什么STRUST远不止“导入”那么简单?如果你在SAP Basis或者安全运维的岗位上待过一段时间,大概率会接触到一个叫STRUST的事务代码。很多初级教程会把它简单定义为“导入SSL证书的地方”,这其实是一个巨大的误解。我见…

2026/9/20 6:27:38

口碑好的消防设施操作员培训资源排名

引言随着消防安全意识的提升,消防设施操作员的需求日益增长,相关培训资源也如雨后春笋般涌现。对于想要考取消防设施操作员证书的人来说,选择一个口碑好的培训资源至关重要。下面为你介绍一些口碑较好的消防设施操作员培训资源排名情况。襄阳…

2026/9/23 22:55:15

内容创作失败的三大根源:选题、转化与交付

1. 这个标题不是玩笑,是内容创作者的真实生存切片“1024,鸽了1024篇博文的我……”——看到这个标题,我下意识点开,不是因为好奇,而是心头一紧:这数字太熟了。不是程序员节那个1024,而是我电脑里…

2026/9/23 22:55:15

软考高项257个记忆点:分类刷法、易混考点与避坑指南

简介:面向信息系统项目管理师(软考高项)考生整理的高频考点浓缩笔记,将散布在多本教材中的重点知识汇总为257个要点,覆盖项目管理、系统开发、计算机网络、数据安全、多媒体技术、企业信息化等常考方向。每个知识点以短…

2026/9/23 22:55:15

DeepSeek-R1技术报告解读:GRPO强化学习训练与复现指南

简介:DeepSeek-R1技术报告论文面向大模型研究者、算法工程师及对强化学习推理方向感兴趣的进阶学习者,系统呈现了如何通过大规模强化学习激发大语言模型推理能力。报告围绕DeepSeek-R1-Zero与DeepSeek-R1两代模型展开,前者在无监督微调前提下…

2026/9/23 22:55:15

交换机路由器Console初始配置避坑指南

简介:本资源是一份面向网络工程初学者与高职院校实训学生的交换机与路由器基础配置实验指导文档,聚焦带外管理(Console线连接超级终端配置)与带内远程管理(Telnet/Web/TFTP/SNMP)两大核心能力培养。文档系统…

2026/9/23 12:07:00

GAMP 5 基于风险的计算机化系统验证:软件分类与审计追踪实践

简介:《A Risk-Based Approach to Compliant GxP Computerized Systems》即业内熟知的GAMP 5指南,面向制药企业质量与IT合规人员、验证工程师及计算机化系统管理者,用于解决GxP法规环境下系统合规性难以科学落地的问题。文档以风险管理为主线…

2026/9/23 12:06:55

安全托管MSSP实战:从静态防御到人机协同的攻防运营与应急响应

简介:这份PPT围绕互联网业务安全托管服务展开,面向企业安全负责人、IT运维人员及关注MSSP/MSS选型的读者,重点回应传统安全过度依赖人工、碎片化静态防御难以对抗产业化攻击等痛点。资源共1个pptx文件,包体约30.63MB,以…

2026/9/23 0:01:54

3个实战技巧搞定形式英语:从看教程到跑通性能优化

3个实战技巧搞定形式英语:从看教程到跑通性能优化 看了一堆教程还是不会写项目?别慌,这种“眼高手低”的困境在开发者圈子里太常见了。很多人以为卡点在语法,其实真正拦路虎是缺乏将知识点串联成完整链路的能力。今天咱们不聊虚的,直接拿【形式英语】这…

2026/9/22 16:34:32

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/22 20:01:30

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/22 13:25:41

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码