Other Parts Discussed in Thread: Z-STACK
As a novice user of the CC2530, I recently encountered a problem that I couldn't solve; Firstly, I carried out the work based on three terminals and one coordinator(ZStack-2.5.1). The aim was to achieve voltage acquisition at a rate of 30Hz or higher (at the terminals), and then send the data to the coordinator in a point-to-point manner. The coordinator would then print out the data via the serial port.
Currently, the solution I am adopting is that the coordinator sends AD acquisition commands to the three terminals in a cyclic manner through point-to-point polling; after receiving the data returned by the current terminal, it then sends an AD acquisition command to the next terminal to have it upload the data; if I want to achieve a sampling rate of 30Hz, then the time for one polling cycle (polling the three terminals) by the coordinator needs to be 30ms; however, at present, the time for the coordinator to poll all three terminals is approximately 100ms (as shown in the figure1).
I have tried many methods, including modifying the parameters in files such as f8wCoord.cfg, f8wConfig.cfg and f8wEndev.cfg(as shown in the figure2,3,4). Eventually, I could only increase the sampling rate to around 10Hz.Below, I have provided the core code for implementing this function.
I really need everyone's help to solve this problem. If you could offer me some suggestions, I would be extremely grateful.




/*********************************************************************
* INCLUDES
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "AF.h"
#include "OnBoard.h"
#include "OSAL_Tasks.h"
#include "SampleApp.h"
#include "ZDApp.h"
#include "ZDObject.h"
#include "ZDProfile.h"
#include "hal_drivers.h"
#include "hal_key.h"
#if defined ( LCD_SUPPORTED )
#include "hal_lcd.h"
#endif
#include "hal_led.h"
#include "hal_uart.h"
#include "hal_adc.h"
#include "OSAL_PwrMgr.h"
/*********************************************************************
* MACROS
*/
/*********************************************************************
* CONSTANTS
*/
#if !defined( SAMPLE_APP_PORT )
#define SAMPLE_APP_PORT 0
#endif
#if !defined( SAMPLE_APP_BAUD )
#define SAMPLE_APP_BAUD HAL_UART_BR_115200
#endif
// When the Rx buf space is less than this threshold, invoke the Rx callback.
#if !defined( SAMPLE_APP_THRESH )
#define SAMPLE_APP_THRESH 64
#endif
#if !defined( SAMPLE_APP_RX_SZ )
#define SAMPLE_APP_RX_SZ 128
#endif
#if !defined( SAMPLE_APP_TX_SZ )
#define SAMPLE_APP_TX_SZ 128
#endif
// Millisecs of idle time after a byte is received before invoking Rx callback.
#if !defined( SAMPLE_APP_IDLE )
#define SAMPLE_APP_IDLE 6
#endif
// Loopback Rx bytes to Tx for throughput testing.
#if !defined( SAMPLE_APP_LOOPBACK )
#define SAMPLE_APP_LOOPBACK FALSE
#endif
// This is the max byte count per OTA message.
#if !defined( SAMPLE_APP_TX_MAX )
#define SAMPLE_APP_TX_MAX 80
#endif
#define SAMPLE_APP_RSP_CNT 4
#define ADC_CHANNEL_COUNT 5 // 采集5路AD
const uint8 adcChannels[ADC_CHANNEL_COUNT] =
{
HAL_ADC_CHANNEL_0, // P0_0
HAL_ADC_CHANNEL_4, // P0_4
HAL_ADC_CHANNEL_5, // P0_5
HAL_ADC_CHANNEL_6, // P0_6
HAL_ADC_CHANNEL_7 // P0_7
};
// This list should be filled with Application specific Cluster IDs.
const cId_t SampleApp_ClusterList[SAMPLE_MAX_CLUSTERS] =
{
SAMPLEAPP_P2P_CLUSTERID,
SAMPLEAPP_FLASH_CLUSTERID,
SAMPLEAPP_ADDR_CLUSTERID
};
const SimpleDescriptionFormat_t SampleApp_SimpleDesc =
{
SAMPLEAPP_ENDPOINT, // int Endpoint;
SAMPLEAPP_PROFID, // uint16 AppProfId[2];
SAMPLEAPP_DEVICEID, // uint16 AppDeviceId[2];
SAMPLEAPP_DEVICE_VERSION, // int AppDevVer:4;
SAMPLEAPP_FLAGS, // int AppFlags:4;
SAMPLE_MAX_CLUSTERS, // byte AppNumInClusters;
(cId_t *)SampleApp_ClusterList, // byte *pAppInClusterList;
SAMPLE_MAX_CLUSTERS, // byte AppNumOutClusters;
(cId_t *)SampleApp_ClusterList // byte *pAppOutClusterList;
};
endPointDesc_t SampleApp_epDesc =
{
SAMPLEAPP_ENDPOINT,
&SampleApp_TaskID,
(SimpleDescriptionFormat_t *)&SampleApp_SimpleDesc,
noLatencyReqs
};
/*********************************************************************
* TYPEDEFS
*/
/*********************************************************************
* GLOBAL VARIABLES
*/
devStates_t SampleApp_NwkState;
uint8 SampleApp_TaskID; // Task ID for internal task/event processing.
uint8 SampleApp_TransID; // This is the unique message ID (counter)
/*********************************************************************
* EXTERNAL VARIABLES
*/
/*********************************************************************
* EXTERNAL FUNCTIONS
*/
/*********************************************************************
* LOCAL VARIABLES
*/
static uint8 SampleApp_MsgID;
afAddrType_t SampleApp_Periodic_DstAddr; //广播
afAddrType_t SampleApp_Flash_DstAddr; //组播
afAddrType_t SampleApp_P2P_DstAddr; //点播
static afAddrType_t SampleApp_TxAddr;
static uint8 SampleApp_TxSeq;
static uint8 SampleApp_TxBuf[SAMPLE_APP_TX_MAX+1];
static uint8 SampleApp_TxLen;
static afAddrType_t SampleApp_RxAddr;
static uint8 SampleApp_RxSeq;
static uint8 SampleApp_RspBuf[SAMPLE_APP_RSP_CNT];
//重要,定时终端ID
//范围:1~MAX_DEVICE,不同的终端或者协调器,要修改此值
uint8 deviceId = 1;
DEVICES mDevice[MAX_DEVICE];
/*********************************************************************
* LOCAL FUNCTIONS
*/
static void SampleApp_ProcessMSGCmd( afIncomingMSGPacket_t *pkt );
void SampleApp_CallBack(uint8 port, uint8 event);
static void SampleApp_Send_ADC_Message( void );
static void floatToStr(float vol, char *result, int maxLen);
static void reverse(char *str, int len);
static void intToStr(int num, char *str, int *index);
void SendMsgToShortAddr(uint8* buff, uint8 len, uint16 addr);
void SendShortAddrToCoor();
void SendAckToCoordinator(void);
#define SAMPLEAPP_CMD_TRIGGER_ADC 0x01 // 触发ADC采集的指令
#define SAMPLEAPP_COORDINATOR 0x0000 // 协调器短地址
#define MAX_CONNECTED_DEVICES 10 // 最大连接设备数
#define CMD_SEND_INTERVAL 5 // 指令发送间隔(ms)
#define RESPONSE_TIMEOUT_MS 1000 // 响应超时时间(ms)
static uint8 connectedDevices[MAX_CONNECTED_DEVICES]; // 存储已连接设备ID
static uint8 deviceCount = 0; // 已连接设备数量
static uint8 currentDeviceIndex = 0; // 当前轮询的设备索引
static uint8 isCoordinator = FALSE; // 是否为协调器
//static uint8 ADsuccess = 0; // 是否为协调器
static uint8 isWaitingForResponse = FALSE; // 新增:是否在等待终端响应
static uint16 currentTargetAddr = 0; // 当前发送目标地址
/*********************************************************************
* @fn SampleApp_Init
*
* @brief This is called during OSAL tasks' initialization.
*
* @param task_id - the Task ID assigned by OSAL.
*
* @return none
*/
void SampleApp_Init( uint8 task_id )
{
halUARTCfg_t uartConfig;
SampleApp_TaskID = task_id;
SampleApp_RxSeq = 0xC3;
SampleApp_NwkState = DEV_INIT;
SampleApp_TransID = 0;
MT_UartInit(); //串口初始化
MT_UartRegisterTaskID(task_id); //注册串口任务
afRegister( (endPointDesc_t *)&SampleApp_epDesc );
RegisterForKeys( task_id );
osal_pwrmgr_device(PWRMGR_ALWAYS_ON);
for(uint8 i=0; i<MAX_DEVICE; i++)
{
mDevice[i].id=i+1;//1~MAX_DEVICE
mDevice[i].shortAddr=0;//短地址清0
}
// 初始化已连接设备列表
memset(connectedDevices, 0, sizeof(connectedDevices));
deviceCount = 0;
currentDeviceIndex = 0;
SampleApp_Periodic_DstAddr.addrMode = (afAddrMode_t)AddrBroadcast;//广播
SampleApp_Periodic_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
SampleApp_Periodic_DstAddr.addr.shortAddr = 0xFFFF;
// Setup for the flash command's destination address - Group 1
SampleApp_Flash_DstAddr.addrMode = (afAddrMode_t)afAddrGroup;//组播
SampleApp_Flash_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
SampleApp_Flash_DstAddr.addr.shortAddr = SAMPLEAPP_FLASH_GROUP;
SampleApp_P2P_DstAddr.addrMode = (afAddrMode_t)Addr16Bit; //点播
SampleApp_P2P_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
SampleApp_P2P_DstAddr.addr.shortAddr = 0x0000; //发给协调器
}
/*********************************************************************
* @fn SampleApp_ProcessEvent
*
* @brief Generic Application Task event processor.
*
* @param task_id - The OSAL assigned task ID.
* @param events - Bit map of events to process.
*
* @return Event flags of all unprocessed events.
*/
UINT16 SampleApp_ProcessEvent( uint8 task_id, UINT16 events )
{
(void)task_id; // Intentionally unreferenced parameter
if ( events & SYS_EVENT_MSG )
{
afIncomingMSGPacket_t *MSGpkt;
while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID )) )
{
switch ( MSGpkt->hdr.event )
{
case AF_INCOMING_MSG_CMD:
SampleApp_ProcessMSGCmd( MSGpkt );
break;
case ZDO_STATE_CHANGE:
SampleApp_NwkState = (devStates_t)(MSGpkt->hdr.status);
if (SampleApp_NwkState == DEV_ZB_COORD)
{
// 标识当前设备为协调器
isCoordinator = TRUE;
HalUARTWrite(0, "Coordinator started\r\n", 20);
// 启动设备轮询定时器
osal_start_timerEx( SampleApp_TaskID,
SAMPLEAPP_POLL_DEVICES_EVT,
CMD_SEND_INTERVAL );
}
else if ((SampleApp_NwkState == DEV_ROUTER) ||
(SampleApp_NwkState == DEV_END_DEVICE))
{
// 终端设备入网后发送自身ID给协调器
SendShortAddrToCoor();
osal_pwrmgr_device(PWRMGR_ALWAYS_ON);
}
else
{
}
break;
default:
break;
}
osal_msg_deallocate( (uint8 *)MSGpkt );
}
return ( events ^ SYS_EVENT_MSG );
}
// 协调器轮询设备事件
if ( events & SAMPLEAPP_POLL_DEVICES_EVT && isCoordinator )
{
if (deviceCount > 0 && !isWaitingForResponse)
//if (deviceCount > 0 )
{
// 发送ADC采集指令给当前设备
uint8 cmd = SAMPLEAPP_CMD_TRIGGER_ADC;
uint16 targetAddr = 0;
//ADsuccess = 0;
// 查找当前设备的短地址
for(uint8 i=0; i<MAX_DEVICE; i++)
{
if(mDevice[i].id == connectedDevices[currentDeviceIndex])
{
targetAddr = mDevice[i].shortAddr;
break;
}
}
// 发送指令
if(targetAddr != 0)
{
char log[32];
char send[] = "sended\r\n";
sprintf(log, "Sending ADC cmd to device %d\r\n", connectedDevices[currentDeviceIndex]);
HalUARTWrite(0, log, strlen(log));
SendMsgToShortAddr(&cmd, 1, targetAddr);
//HalUARTWrite(0, send, strlen(send));
isWaitingForResponse = TRUE; // 标记为等待响应状态
currentTargetAddr = targetAddr; // 保存当前目标地址
// 启动响应超时定时器
osal_start_timerEx(SampleApp_TaskID, SAMPLEAPP_RESPONSE_TIMEOUT_EVT, RESPONSE_TIMEOUT_MS);
}
// 更新索引,循环轮询
currentDeviceIndex = (currentDeviceIndex + 1) % deviceCount;
}
// 重新启动定时器
osal_start_timerEx( SampleApp_TaskID,
SAMPLEAPP_POLL_DEVICES_EVT,
CMD_SEND_INTERVAL );
return (events ^ SAMPLEAPP_POLL_DEVICES_EVT);
}
// 触发下一个设备轮询
//if (events & SAMPLEAPP_NEXT_DEVICE_EVT && isCoordinator)
//{
// 切换到下一个设备
//currentDeviceIndex = (currentDeviceIndex + 1) % deviceCount;
// 触发下一次轮询
//osal_start_timerEx(SampleApp_TaskID, SAMPLEAPP_POLL_DEVICES_EVT, 5); // 短延迟后轮询下一个
//return (events ^ SAMPLEAPP_NEXT_DEVICE_EVT);
//}
// 响应超时事件处理
if (events & SAMPLEAPP_RESPONSE_TIMEOUT_EVT && isCoordinator)
{
if (isWaitingForResponse)
{
// 超时处理
char log[64];
sprintf(log, "Response timeout from device at address 0x%X\r\n", currentTargetAddr);
HalUARTWrite(0, log, strlen(log));
// 重置等待状态,继续轮询
isWaitingForResponse = FALSE;
currentTargetAddr = 0;
// 继续轮询下一个设备
currentDeviceIndex = (currentDeviceIndex + 1) % deviceCount;
}
return (events ^ SAMPLEAPP_RESPONSE_TIMEOUT_EVT);
}
return ( 0 ); // Discard unknown events.
}
/*********************************************************************
* @fn SerialApp_ProcessMSGCmd
*
* @brief Data message processor callback. This function processes
* any incoming data - probably from other devices. Based
* on the cluster ID, perform the intended action.
*
* @param pkt - pointer to the incoming message packet
*
* @return TRUE if the 'pkt' parameter is being used and will be freed later,
* FALSE otherwise.
*/
void SampleApp_ProcessMSGCmd( afIncomingMSGPacket_t *pkt )
{
uint8 buff[64]={0};
char addrBuf[6] = {0};
switch ( pkt->clusterId )
{
case SAMPLEAPP_P2P_CLUSTERID:
{
// 协调器接收终端发送的ADC数据
if(isCoordinator)
{
uint16 srcShortAddr = pkt->srcAddr.addr.shortAddr;
sprintf(addrBuf, "0x%X", srcShortAddr);
HalUARTWrite(0, "Received data from ", 18);
HalUARTWrite(0, addrBuf, osal_strlen(addrBuf));
HalUARTWrite(0, ": ", 2);
HalUARTWrite(0, pkt->cmd.Data, pkt->cmd.DataLength);
HalUARTWrite(0, "\r\n", 2);
// 取消超时定时器
osal_stop_timerEx(SampleApp_TaskID, SAMPLEAPP_RESPONSE_TIMEOUT_EVT);
isWaitingForResponse = FALSE;
currentTargetAddr = 0;
//osal_start_timerEx(SampleApp_TaskID, SAMPLEAPP_NEXT_DEVICE_EVT, 5); // 短延迟后处理下一个
}
}
break;
case SAMPLEAPP_FLASH_CLUSTERID:
// 终端接收协调器的ADC采集指令
if(pkt->cmd.Data[0] == SAMPLEAPP_CMD_TRIGGER_ADC)
{
SendAckToCoordinator();
// 执行ADC采集并发送给协调器
SampleApp_Send_ADC_Message();
}
break;
case SAMPLEAPP_ADDR_CLUSTERID:
// 协调器处理终端发送的ID和地址信息
if(isCoordinator)
{
uint8 deviceId = pkt->cmd.Data[0];
uint16 shortAddr = BUILD_UINT16(pkt->cmd.Data[1], pkt->cmd.Data[2]);
// 存储设备信息
for(uint8 i=0; i<MAX_DEVICE; i++)
{
if(mDevice[i].id == deviceId)
{
mDevice[i].shortAddr = shortAddr;
// 如果是新设备,添加到已连接设备列表
bool isNewDevice = TRUE;
for(uint8 j=0; j<deviceCount; j++)
{
if(connectedDevices[j] == deviceId)
{
isNewDevice = FALSE;
break;
}
}
if(isNewDevice && deviceCount < MAX_CONNECTED_DEVICES)
{
connectedDevices[deviceCount++] = deviceId;
char log[32];
sprintf(log, "New device connected: %d\r\n", deviceId);
HalUARTWrite(0, log, strlen(log));
}
break;
}
}
}
break;
// 新增:处理终端发送的确认消息
case SAMPLEAPP_ACK_CLUSTERID:
if(isCoordinator)
{
uint16 srcShortAddr = pkt->srcAddr.addr.shortAddr;
sprintf(addrBuf, "0x%X", srcShortAddr);
HalUARTWrite(0, "Received ACK from ", 17);
HalUARTWrite(0, addrBuf, osal_strlen(addrBuf));
HalUARTWrite(0, "\r\n", 2);
}
break;
default:
break;
}
}
/*********************************************************************
* @fn SampleApp_CallBack
*
* @brief Send data OTA.
*
* @param port - UART port.
* @param event - the UART port event flag.
*
* @return none
*/
void SampleApp_CallBack(uint8 port, uint8 event)
{
(void)port;
if ((event & (HAL_UART_RX_FULL | HAL_UART_RX_ABOUT_FULL | HAL_UART_RX_TIMEOUT)) &&
#if SAMPLE_APP_LOOPBACK
(SampleApp_TxLen < SAMPLE_APP_TX_MAX))
#else
!SampleApp_TxLen)
#endif
{
SampleApp_TxLen += HalUARTRead(SAMPLE_APP_PORT, SampleApp_TxBuf+SampleApp_TxLen+1,
SAMPLE_APP_TX_MAX-SampleApp_TxLen);
}
}
/*********************************************************************
*********************************************************************/
/*********************************************************************
* @fn SampleApp_Send_ADC_Message
*
* @brief point to point.
*
* @param none
*
* @return none
*/
void SampleApp_Send_ADC_Message( void )
{
byte str_adc[64]={0};
//char *str_adc = "V:";
float voltages[ADC_CHANNEL_COUNT] = {0.0}; // 存储各通道电压
uint16 adcValues[ADC_CHANNEL_COUNT] = {0}; // 存储各通道原始值
byte len=19;
//osal_memset(str_adc, ' ', 63);
for (uint8 i = 0; i < ADC_CHANNEL_COUNT; i++)
{
// 读取ADC值(参考电压使用AVDD,即3.3V)
char str_vol[20] = {0};
adcValues[i] = HalAdcRead(adcChannels[i], HAL_ADC_RESOLUTION_14);
if(adcValues[i]>=8192)
{
sprintf(str_adc,"error\r\n");
}
else
{// 计算电压(14位ADC,最大值8192)
voltages[i] = (float)(adcValues[i] * 3.3)/ 8192.0;
floatToStr(voltages[i], str_vol, sizeof(str_vol));
strcat(str_vol,"\r\n");
strcat(str_adc, str_vol);
//str_adc = concatDynamic(str_adc, str_vol);
}
}
//for (uint8_t i = 0; i < ADC_CHANNEL_COUNT; i++)
//{
// 格式化当前通道数据并追加到字符串
// 格式:"Vx:1.234 "(x为通道号,保留3位小数)
//strLen += sprintf(&str_adc[strLen], "V%d:%.3f ",
// (adcChannels[i] + 1), // 通道号从1开始显示
// voltages[i]);
//}
//
len=osal_strlen(str_adc);//计算长度
// 确保数据发送给协调器
SampleApp_P2P_DstAddr.addr.shortAddr = SAMPLEAPP_COORDINATOR;
if ( AF_DataRequest( &SampleApp_P2P_DstAddr, &SampleApp_epDesc,
SAMPLEAPP_P2P_CLUSTERID,
len,
str_adc,
&SampleApp_MsgID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
{
// free(str_adc);
}
else
{
//free(str_adc); // Error occurred in request to send.
}
}
void SendShortAddrToCoor()
{
char buff[5]={0};
afAddrType_t DstAddr;
uint16 addr=NLME_GetShortAddr();
//点播,协调器的短地址为0
DstAddr.addrMode = (afAddrMode_t)Addr16Bit;
DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
DstAddr.addr.shortAddr = 0x0;
//填发送的数据
buff[0]=deviceId;//第一个字节,终端编号
buff[1]=LO_UINT16(addr);//第二个字节,终端短地址低字节
buff[2]=HI_UINT16(addr);//第三个字节,终端短地址高字节
//
//发送
if ( AF_DataRequest( &DstAddr, &SampleApp_epDesc,
SAMPLEAPP_ADDR_CLUSTERID,
3,
buff,
&SampleApp_TransID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
{
}
else
{
// Error occurred in request to send.
}
}
void SendAckToCoordinator(void)
{
uint8 ackMsg[] = "Received"; // 确认消息内容
afAddrType_t dstAddr;
dstAddr.addrMode = Addr16Bit;
dstAddr.endPoint = SAMPLEAPP_ENDPOINT;
dstAddr.addr.shortAddr = SAMPLEAPP_COORDINATOR; // 目标为协调器
if ( AF_DataRequest(&dstAddr, &SampleApp_epDesc,
SAMPLEAPP_ACK_CLUSTERID,
sizeof(ackMsg) - 1, // 不包含字符串结束符
ackMsg,
&SampleApp_TransID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS) == afStatus_SUCCESS )
{
}
else
{ // Error occurred in request to send.
}
}
const char* afStatusStr[] = {
"afStatus_SUCCESS", // 0: 成功
"afStatus_FAILED", // 1: 失败
"afStatus_INVALID_PARAMETER",// 2: 参数无效
"afStatus_NO_ROUTE", // 3: 无路由
"afStatus_NO_RESOURCES", // 4: 资源不足
"afStatus_NOT_SUPPORTED", // 5: 不支持
"afStatus_TIMEOUT" // 6: 超时(根据实际枚举扩展)
// ... 其他状态码
};
void SendMsgToShortAddr(uint8* buff, uint8 len, uint16 addr)
{
afAddrType_t DstAddr;
SampleApp_TransID++;
//点播
DstAddr.addrMode = (afAddrMode_t)Addr16Bit;
DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
DstAddr.addr.shortAddr = addr;
afStatus_t status = AF_DataRequest( &DstAddr, &SampleApp_epDesc,
SAMPLEAPP_FLASH_CLUSTERID,
len,
buff,
&SampleApp_TransID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS );
// 准备打印缓冲区(存储状态码和描述)
char uartBuf[64];
uint16 bufLen;
//发送
if ( status == afStatus_SUCCESS )
{
char send[] = "sended\r\n";
HalUARTWrite(0, send, strlen(send));
}
else
{
if (status < sizeof(afStatusStr)/sizeof(afStatusStr[0]))
{
sprintf(uartBuf, "AF_DataRequest status: %d (%s)\r\n", status, afStatusStr[status]);
}
else
{
sprintf(uartBuf, "AF_DataRequest status: %d (Unknown)\r\n", status);
}
HalUARTWrite(0, (uint8*)uartBuf, strlen(uartBuf));
}
}
// 共用体
union FloatUnion {
float f;
unsigned char bytes[4]; // float占4字节
};
// 反转字符串
void reverse(char *str, int len) {
int i = 0, j = len - 1;
char temp;
while (i < j) {
temp = str[i];
str[i] = str[j];
str[j] = temp;
i++;
j--;
}
}
// 整数转换
void intToStr(int num, char *str, int *index) {
int i = 0;
// 处理0的特殊情况
if (num == 0) {
str[(*index)++] = '0';
return;
}
// 提取每一位数字
while (num != 0) {
int rem = num % 10;
str[i++] = (rem > 9) ? (rem - 10) + 'a' : rem + '0';
num = num / 10;
}
// 反转得到正确顺序
reverse(str + *index, i);
*index += i;
}
// 浮点数转为字符串
void floatToStr(float vol, char *result, int maxLen) {
union FloatUnion u;
u.f = vol;
int index = 0;
// 检查缓冲区是否足够
if (maxLen < 10) {
result[0] = '\0';
return;
}
// 处理符号位
if (vol < 0) {
result[index++] = '-';
vol = -vol; // 转为正数处理
}
// 分离整数部分和小数部分
int intPart = (int)vol;
float fracPart = vol - intPart;
// 转换整数部分
intToStr(intPart, result, &index);
// 添加小数点
result[index++] = '.';
// 转换小数部分(保留3位)
for (int i = 0; i < 3; i++) {
fracPart *= 10;
int fracDigit = (int)fracPart;
result[index++] = fracDigit + '0';
fracPart -= fracDigit;
}
// 添加字符串结束符
result[index] = '\0';
}