#include "ESP32_WROOM_32D.h" #include #include #include #include extern int Flag3S; #define g_uMsgCmdFrameLen (6) extern uint8_t Devicenum; extern uint8_t g_wifi_rx_buf[WIFI_RX_BUF_SIZE]; extern uint32_t g_wifi_rx_last; extern uint32_t g_wifi_rx_head; uint8_t wifi_tx_buf[WIFI_TX_BUF_SIZE]; uint16_t wifi_tx_len; static int wifi_state = 0; //WiFi模块当前状态 static int wifi_ack_delay = 0; //WiFi应答等待 static int wifi_set_ssid = 0; //WiFi应答SSID设置 uint32_t unlink_time = 0; extern uint32_t pc_link_timeout; uint32_t connectTcpFlag = 0; char TCP_IP_PORT[8] = {"8001"}; char MAC_ADDR[20] = {0}; uint32_t broadDevFlag = 0; extern uint8_t pc_channel_recv; static int resendtime = 0; uint16_t WriteComm2(char *data, uint16_t len) { //return UART_Write(UART2, data, len); HAL_UART_Transmit((UART_HandleTypeDef *)sysinf.ESPUart,(const uint8_t *)data, len,1000); // HAL_UART_Transmit_DMA((UART_HandleTypeDef *)sysinf.ESPUart,(const uint8_t *)data, len); return 0; } /*WIFI单次发送指令*/ void ESP32_Send_AT_Cmd(char *cmd,uint32_t time) { char buff[100] = {0}; strcpy(buff, cmd); strcat(buff, "\r\n"); Van_Device_Printf(VAN_LOG_WIFI,"\nW--> %s", buff); WriteComm2(buff, strlen(buff)); wifi_ack_delay = time; } void ESP32_AT(void) { ESP32_Send_AT_Cmd("AT",5000); } /*恢复出厂设置*/ void ESP32_AT_Restore(void) { ESP32_Send_AT_Cmd("AT+RESTORE",500); } /*复位*/ void ESP32_AT_RST(void) { ESP32_Send_AT_Cmd("AT+RST",8000); } /*上电自动连接AP*/ void ESP32_AT_AUTOCONN(void) { ESP32_Send_AT_Cmd("AT+CWAUTOCONN=0",5000); } /*WIFI AP/STA/AP+STA模式选择*/ void ESP32_Net_Mode_Choose(ENUM_Net_ModeTypeDef enumMode) { switch ( enumMode ) { case STA: ESP32_Send_AT_Cmd ( "AT+CWMODE=1", 5000 ); break; case AP: ESP32_Send_AT_Cmd ( "AT+CWMODE=2", 5000 ); break; case STA_AP: ESP32_Send_AT_Cmd ( "AT+CWMODE=3", 5000 ); break; default: break; } } /*WIFI加入AP*/ void ESP32_JoinAP( char * pSSID, char * pPassWord, char * pMacAddr) { char cCmd [80]; my_sprintf ( cCmd, sizeof(cCmd), "AT+CWJAP=\"%s\",\"%s\",\"%s\"", pSSID, pPassWord,pMacAddr); ESP32_Send_AT_Cmd( cCmd,5000 ); } /*WIFI建立AP*/ void ESP32_SetupAP( char * pSSID, char * pPassWord) { char cCmd [40]; my_sprintf ( cCmd,sizeof(cCmd), "AT+CWSAP=\"%s\",\"%s\"", pSSID, pPassWord ); ESP32_Send_AT_Cmd( cCmd, 5000 ); } /*WIFI查询IP*/ void ESP32_GetIp(void) { ESP32_Send_AT_Cmd( "AT+CIPSTA?", 5000 ); } /*WIFI禁止自动连接*/ void ESP32_DisAutoLink(void) { ESP32_Send_AT_Cmd( "AT+CWAUTOCONN=0", 5000 ); } void ESP32_CWLAP(char * pSSID) { char cCmd [80]; my_sprintf ( cCmd, sizeof(cCmd), "AT+CWLAP=\"%s\"", pSSID); ESP32_Send_AT_Cmd( cCmd, 5000 ); } /*WIFI关闭回显*/ void ESP32_EchoOff(void) { ESP32_Send_AT_Cmd( "ATE0", 5000 ); } /*WIFI初始化*/ void ESP32_Init(void) { ESP32_Send_AT_Cmd( "+++", 5000 ); } /*WIFI 单/多连接*/ void ESP32_Enable_MultipleId (uint8_t enumEnUnvarnishTx ) { char cCmd [20]; my_sprintf ( cCmd, sizeof(cCmd), "AT+CIPMUX=%d", ( enumEnUnvarnishTx ? 1 : 0 ) ); ESP32_Send_AT_Cmd ( cCmd, 5000 ); } /*WIFI AP作为服务端开启或关闭,1---开启服务:0---关闭服务*/ void ESP32_AP_Server (uint8_t open) { char cCmd [40]; my_sprintf ( cCmd,sizeof(cCmd), "AT+CIPSERVER=%d", open); ESP32_Send_AT_Cmd( cCmd, 5000 ); } /*WIFI STA选择TCP或UDP协议*/ void ESP32_Link_Server(ENUM_NetPro_TypeDef enumE, char * ip, char * ComNum, ENUM_ID_NO_TypeDef id) { char cStr [100] = { 0 }, cCmd [60]; switch ( enumE ) { case enumTCP: my_sprintf ( cStr, sizeof(cCmd), "\"%s\",\"%s\",%s,6", "TCP", ip, ComNum ); break; case enumUDP: my_sprintf ( cStr,sizeof(cCmd), "\"%s\",\"%s\",%s,9090,0", "UDP", ip, ComNum ); break; default: break; } if ( id < 5 ) my_sprintf ( cCmd,sizeof(cCmd), "AT+CIPSTART=%d,%s", id, cStr); else my_sprintf ( cCmd, sizeof(cCmd), "AT+CIPSTART=%s", cStr ); ESP32_Send_AT_Cmd ( cCmd,5000 ); } /*WIFI透传*/ void ESP32_UnvarnishSend ( void ) { ESP32_Send_AT_Cmd( "AT+CIPMODE=1", 5000 );//设置透传模式 } /*WIFI停止TCP*/ void ESP32_STOPTCP ( ENUM_ID_NO_TypeDef id ) { char cCmd [60]; my_sprintf ( cCmd,sizeof(cCmd), "AT+CIPCLOSE=%d", id); ESP32_Send_AT_Cmd ( cCmd, 20000 ); } /*退出透传*/ void ESP32_ExitUnvarnishSend( void ) { ESP32_Send_AT_Cmd("+++", 5000); } ///*设置默认波特率为460800*/ //void ESP32_SET_BUAR(void) //{ // ESP32_Send_AT_Cmd("AT+UART_DEF=460800,8,1,0,0","OK",NULL,500); //} /******************************************************************** * int WIFI_Send_Data(uint8_t *data, uint8_t len, uint8_t flag) * *描述:通过WIFI发送数据,异步 *参数:data:数据 *参数:len:数据长度 *参数:flag:1:立即发送,0:暂存 *返回:无 *其他:无 *-------------------------------------------------------------------- *记录: ********************************************************************/ int WIFI_Send_Data(uint8_t *data, uint16_t len, uint8_t flag) { char cStr [40] = {0}; if (wifi_state < WIFI_TRANS) return -1; if(wifi_ack_delay > 0) return -2; if(wifi_tx_len) return -3; if(len > WIFI_TX_BUF_SIZE){ Van_Device_Printf(VAN_LOG_WIFI,"WIFI_Send len:%d error ", len); return -1; } memcpy(&wifi_tx_buf[wifi_tx_len], data, len); wifi_tx_len += len; if(flag) { wifi_ack_delay = 3000; my_sprintf ( cStr, sizeof(cStr),"AT+CIPSEND=0,%d", wifi_tx_len ); ESP32_Send_AT_Cmd ( cStr, 3000 ); return wifi_tx_len; } return 0; } int WIFI_Send_MSG(uint8_t*msgHead,uint8_t *data, uint8_t * crc, uint16_t len) { char cStr [40] = {0}; if (wifi_state != WIFI_TRANS) return -1; if(wifi_ack_delay > 0) return -2; if(wifi_tx_len > 0) return -3; memcpy(&wifi_tx_buf[0], msgHead, g_uMsgCmdFrameLen); memcpy(&wifi_tx_buf[g_uMsgCmdFrameLen], data, len); memcpy(&wifi_tx_buf[g_uMsgCmdFrameLen+len], crc, 2); wifi_tx_len = g_uMsgCmdFrameLen+len+2; wifi_ack_delay = 3000; my_sprintf ( cStr, sizeof(cStr),"AT+CIPSEND=0,%d", wifi_tx_len ); ESP32_Send_AT_Cmd ( cStr, 3000 ); return wifi_tx_len; } int WIFI_SendIlde(void){ if(wifi_tx_len == 0) return 0; if (wifi_state < WIFI_TRANS) return 0; if(wifi_ack_delay > 0) return 0; return 1; } int WIFI_ReSend(void) { char cStr [40] = {0}; if(wifi_tx_len == 0) return 0; if (wifi_state < WIFI_TRANS) return -1; if(wifi_ack_delay > 0) return -2; wifi_ack_delay = 3000; my_sprintf ( cStr, sizeof(cStr),"AT+CIPSEND=0,%d", wifi_tx_len ); ESP32_Send_AT_Cmd ( cStr, 3000 ); return 0; } //wifi修改SSID void WIFI_set_ssid(void) { wifi_ack_delay = 0; wifi_state = WIFI_POWEROFF; wifi_set_ssid = 1; if(wifi_tx_len > 0) { WriteComm2((char *)wifi_tx_buf, wifi_tx_len); wifi_tx_len = 0; } } //wifi修改SSID void WIFI_set_CloseConnect(void) { wifi_state = WIFI_CLOSE; } // //在内存中查找字符串 // char* find_str(void *src, int size, char *str) // { // char *p = (char*)src; // int len = strlen((const char *)str); // if(len < 1) // return p; // for(int i = 0; i < size; i++) // { // if(p[i] == *str) // { // if( 0 == memcmp(&p[i], str, len)) // { // return &p[i]; // } // } // } // return NULL; // } //在内存中查找字符串 char* find_str_loop(void *src, int size, uint32_t *start, uint32_t end, char *str) { if (src == NULL || start == NULL || str == NULL || size <= 0) return NULL; unsigned char *buf = (unsigned char*)src; int head = *start; int len = strlen(str); // 空串直接返回当前位置(不移动头指针) if (len == 0) { return (char*)(buf + head); } // 计算有效数据长度 int valid_len; if (end >= head) valid_len = end - head; else valid_len = (size - head) + end; // 若有效数据长度小于目标串长度,不可能匹配 if (valid_len < len) return NULL; // 从 head 开始遍历所有可能的起始位置(不包括 end) int pos = head; while (pos != end) { // 检查从 pos 开始的 len 个字节是否与 str 匹配 int i; for (i = 0; i < len; i++) { int idx = (pos + i) % size; if (buf[idx] != (unsigned char)str[i]) break; } if (i == len) { // 完全匹配 // 更新头指针为匹配串之后的位置 *start = (pos + len) % size; return (char*)(buf + pos); } // 移动到下一个起始位置 pos = (pos + 1) % size; // 如果移动后到达 end,提前终止(有效数据遍历完毕) // 但 while 条件会处理,可省略 } // 未找到 return NULL; } /******************************************************************** * WIFI_recv_deal() * *描述:接收帧解析 *参数:无 *返回:无 *其他:无 *-------------------------------------------------------------------- *记录: ********************************************************************/ void WIFI_recv_deal(void) { char *p; int data_len = g_wifi_rx_last>g_wifi_rx_head?(g_wifi_rx_last-g_wifi_rx_head):(WIFI_RX_BUF_SIZE+g_wifi_rx_last-g_wifi_rx_head); // int udp_data_len = 0; char* data = (char*)g_wifi_rx_buf; if(data_len < 5) return; //判断是否接收完成 if(wifi_state > WIFI_LISTEN) { if(data[g_wifi_rx_last-1] != '\n' && data[g_wifi_rx_last-2] != '\n') { return; } } switch (wifi_state) { //指令模式 case WIFI_POWEROFF: case WIFI_ERROR: if(NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE ,&g_wifi_rx_head, g_wifi_rx_last,"ready") || NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE ,&g_wifi_rx_head, g_wifi_rx_last,"boot")) { wifi_state = WIFI_POWERON; wifi_ack_delay = 0; memset(wifi_tx_buf,0,sizeof(wifi_tx_buf)); wifi_tx_len = 0; // wifi_receive_clear(); } break; case WIFI_POWERON: case WIFI_INIT: case WIFI_STATION: case WIFI_DISAUTO: case WIFI_LINK_AP: case WIFI_GET_IP: case WIFI_SETMUX: case WIFI_LISTEN: if(NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE ,&g_wifi_rx_head, g_wifi_rx_last, "OK\r\n")) { Van_Device_Printf(VAN_LOG_WIFI,"\nW<-- %s", data); wifi_ack_delay = 0; if(WIFI_LISTEN == wifi_state){ /*上电需要广播地址*/ broadDevFlag = 1; sysinf.s10_flag = 1; if(sysinf.connectTcpFlag == 1){ if(wifi_tx_len){ char cStr [40] = {0}; my_sprintf ( cStr,sizeof(cStr), "AT+CIPSEND=0,%d", wifi_tx_len ); ESP32_Send_AT_Cmd ( cStr, 3000 ); } sysinf.pc_link_timeout = 0; sysinf.pc_channel_recv = PC_CONNECT_TYPE_WIFI; } } wifi_state++; resendtime = 0; HAL_Delay(1000); // wifi_receive_clear(); } break; case WIFI_CWLAP:{ char* strStart = find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE ,&g_wifi_rx_head, g_wifi_rx_last,sysinf.wifiname); uint32_t apHeader = g_wifi_rx_head; if(NULL != strStart) { if(NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE ,&g_wifi_rx_head, g_wifi_rx_last, "OK\r\n")){ /*循环始终需要OK,找到OK后,恢复APhead位置,重新搜寻mac*/ g_wifi_rx_head = apHeader; Van_Device_Printf(VAN_LOG_WIFI,"\nW<-- %s", data); wifi_ack_delay = 0; strStart+=strlen(sysinf.wifiname); strStart =find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE ,&g_wifi_rx_head, g_wifi_rx_last,",\""); unsigned int startPos = ((unsigned int)strStart-(unsigned int)g_wifi_rx_buf + 2)%WIFI_RX_BUF_SIZE;/*跳过,\*/ for(unsigned i=0;i<17;i++){ MAC_ADDR[i] = g_wifi_rx_buf[(i+startPos)%WIFI_RX_BUF_SIZE]; } MAC_ADDR[18] = 0; wifi_state++; } // wifi_receive_clear(); } } break; //数据模式 case WIFI_TRANS: //收到AT+CIPSEND回应,可发送数据 if(NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE ,&g_wifi_rx_head, g_wifi_rx_last, "CLOSED")) { Van_Device_Printf(VAN_LOG_WIFI,"\nW<-- %d %s", data_len,data); wifi_state = WIFI_LISTEN; wifi_ack_delay = 0;//从发送写指令,到此才算发送完成 broadDevFlag = 0; } else if ((NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE ,&g_wifi_rx_head, g_wifi_rx_last, "ERROR"))|| (NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE ,&g_wifi_rx_head, g_wifi_rx_last,"SEND FAIL"))) { if(resendtime < MAX_RESEND_TIME){ char cStr [40] = {0}; my_sprintf ( cStr,sizeof(cStr), "AT+CIPSEND=0,%d", wifi_tx_len ); ESP32_Send_AT_Cmd ( cStr, 3000 ); resendtime ++; }else{ wifi_state = WIFI_POWEROFF; wifi_ack_delay = 0; } // wifi_receive_clear(); } else if(NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE ,&g_wifi_rx_head, g_wifi_rx_last, "SEND OK")) { //收到AT+CIPSEND回应,可发送数据 Van_Device_Printf(VAN_LOG_WIFI,"\n--> SEND OK", wifi_tx_len); wifi_ack_delay = 0;//从发送写指令,到此才算发送完成 wifi_tx_len = 0; resendtime = 0; wifi_tx_len = 0; memset(wifi_tx_buf, 0, sizeof(wifi_tx_buf)); // wifi_receive_clear(); } else if(NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE ,&g_wifi_rx_head, g_wifi_rx_last, "OK\r\n")) { // wifi_receive_clear(); Van_Device_Printf(VAN_LOG_WIFI,"\n--> OK W %d", wifi_tx_len); WriteComm2((char *)wifi_tx_buf, wifi_tx_len+1); wifi_ack_delay = 3000; } if(NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE ,&g_wifi_rx_head, g_wifi_rx_last, "DISCONNECT")) { Van_Device_Printf(VAN_LOG_WIFI,"\nW--> %s", data); wifi_state = WIFI_POWEROFF; wifi_ack_delay = 0; } //收到PC数据 p = find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE ,&g_wifi_rx_head, g_wifi_rx_last, "+IPD,0,"); if(NULL != p) { int iProcLen = DecodeNew(&uart0_massage,uart0_data,g_wifi_rx_buf, &g_wifi_rx_head,g_wifi_rx_last,WIFI_RX_BUF_SIZE); if (iProcLen > 0) { sysinf.pc_channel_recv = PC_CONNECT_TYPE_WIFI; sysinf.pc_link_timeout = 0; uart0_massage.data = (char *)uart0_data; query_pc_cmd(&uart0_massage); } // wifi_receive_clear(); // set_pc_chanel_recv(1); // b2b_recv_data(p, udp_data_len); } break; case WIFI_CLOSE:{ if(NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE ,&g_wifi_rx_head, g_wifi_rx_last, "CLOSED\r\n")) { wifi_state = WIFI_LISTEN; wifi_ack_delay = 0; } } break; default: break; } wifi_receive_clear(); } void WIFI_send_deal(void) { static uint8_t try_count = 0; static uint8_t try_con = 0; static uint32_t wifi_start_delay = 0; static uint8_t res_count = 0; uint8_t wifi_result = 0; //启动超时 if(wifi_state < WIFI_LISTEN && wifi_start_delay++ > 120*10) { wifi_start_delay = 0; wifi_state = WIFI_POWEROFF; wifi_ack_delay = 0; } //等待模块应答 if(wifi_ack_delay > 0) { wifi_ack_delay -= 100; return; } if(resendtime >= MAX_RESEND_TIME){ wifi_state = WIFI_POWEROFF; } if((WIFI_TRANS != wifi_state )|| ((WIFI_TRANS == wifi_state)&& wifi_tx_len )){ resendtime++; } switch (wifi_state) { case WIFI_POWEROFF: case WIFI_ERROR: ESP32_AT_RST(); wifi_start_delay = 0; resendtime = 0; try_count = 0; if(sysinf.connectTcpFlag){ /*持续5次均不能链接到tcp,状态回退,重启链接udp*/ res_count++; if(res_count > 5){ sysinf.connectTcpFlag = 0; } } break; case WIFI_POWERON: ESP32_AT(); break; case WIFI_INIT: ESP32_EchoOff(); break; case WIFI_STATION: ESP32_Net_Mode_Choose(STA); break; case WIFI_DISAUTO: ESP32_DisAutoLink(); try_count = 0; break; case WIFI_CWLAP: ESP32_CWLAP(sysinf.wifiname); if(try_count++ > 7) { wifi_state = WIFI_POWEROFF; if(wifi_set_ssid == 1) { wifi_set_ssid = 0; wifi_result = 0xff; data_send_to_pc(PC_CMD_SETWIFI, (char *)&wifi_result, 1); } } try_con = 0; break; case WIFI_LINK_AP: ESP32_JoinAP(sysinf.wifiname, sysinf.password,MAC_ADDR); if(try_con++ >= 5) { wifi_state = WIFI_POWEROFF; if(wifi_set_ssid == 1) { wifi_set_ssid = 0; wifi_result = 0xfe; data_send_to_pc(PC_CMD_SETWIFI, (char *)&wifi_result, 1); } } break; case WIFI_GET_IP: ESP32_GetIp(); if(wifi_set_ssid == 1) { wifi_set_ssid = 0; wifi_result = 1; data_send_to_pc(PC_CMD_SETWIFI, (char *)&wifi_result, 1); } break; case WIFI_SETMUX: ESP32_Enable_MultipleId(1); break; case WIFI_LISTEN: if(sysinf.connectTcpFlag){ if(resendtime < MAX_RESEND_TIME) { ESP32_Link_Server(enumTCP,sysinf.TCP_IP_Addr, TCP_IP_PORT, Multiple_ID_0); }else{ /*多次TCP未链接,链接UDP*/ // connectTcpFlag = 0; // resendtime = 0; wifi_tx_len = 0; memset(wifi_tx_buf, 0, sizeof(wifi_tx_buf)); } }else{ if(resendtime < MAX_RESEND_TIME) { ESP32_Link_Server(enumUDP,User_ESP32_UDPServer_IP, User_ESP32_UDPServer_PORT, Multiple_ID_0); } } break; case WIFI_TRANS: if(resendtime < MAX_RESEND_TIME) { if(wifi_tx_len){ char cStr [40] = {0}; my_sprintf ( cStr,sizeof(cStr),"AT+CIPSEND=0,%d", wifi_tx_len ); ESP32_Send_AT_Cmd ( cStr, 3000 ); } } if(sysinf.connectTcpFlag){ /*tcp链接上,复位计数清零*/ res_count = 0; } break; case WIFI_CLOSE: ESP32_STOPTCP(Single_ID_0); break; default: wifi_state = WIFI_ERROR; break; } } //wifi任务 void WIFI_process() { if(sysinf.pc_channel_recv == 2 && wifi_state > WIFI_SETMUX){ /*串口状态下,不走wifi处理*/ return; } WIFI_recv_deal(); WIFI_send_deal(); } static uint32_t m_pow_n(uint32_t m, int32_t n) { uint32_t i = 0, ret = 1; if (n < 0) return 0; for (i = 0; i < n; i++) { ret *= m; } return ret; } // 返回值为打印字符的个数 // 支持%d,%o, %x,%s,%c,%f(只打印6位数字) int my_sprintf(char *pdes,unsigned int len, const char* str, ...) { if (str == NULL) return -1; uint32_t ret_num = 0;// 返回打印字符的个数 char* pStr = (char*)str;// 指向str int ArgIntVal = 0; // 接收整型 uint32_t ArgHexVal = 0;// 接十六进制 char* ArgStrVal = NULL; // 接收字符型 double ArgFloVal = 0.0; // 接受浮点型 uint32_t val_seg = 0; // 数据切分 uint32_t val_temp = 0; // 临时保存数据 int cnt = 0; // 数据长度计数 int cnt_float = 0; // 数据长度计数 va_list pArgs; // 定义va_list类型指针,用于存储参数的地址 va_start(pArgs, str); // 初始化pArgs while (*pStr != '\0') { switch (*pStr) { case ' ': case '\r': case '\n': *pdes++ = (*pStr); ret_num++; break; case '\t': *pdes++ =(*pStr); ret_num += 4; break; case '%': pStr++; // % 格式解析 if('.' == *pStr) { pStr++; cnt_float = *pStr - '0';// %.Nf,输出指定位数小数 pStr++; } switch (*pStr) { case '%': *pdes++ =('%');// %%,输出% ret_num++; pStr++; continue; case 'c': ArgIntVal = va_arg(pArgs, int);// %c,输出char *pdes++ =((char)ArgIntVal); ret_num++; pStr++; continue; case 'd': // 接收整型 ArgIntVal = va_arg(pArgs, int); if (ArgIntVal < 0)// 如果为负数打印,负号 { ArgIntVal = -ArgIntVal;// 取相反数 *pdes++ =('-'); ret_num++; } val_seg = ArgIntVal;// 赋值给 val_seg处理数据 // 计算ArgIntVal长度 if (ArgIntVal) { while (val_seg) { cnt++; val_seg /= 10; } } else cnt = 1;// 数字0的长度为1 ret_num += cnt;// 字符个数加上整数的长度 // 将整数转为单个字符打印 while (cnt) { val_seg = ArgIntVal / m_pow_n(10, cnt - 1); ArgIntVal %= m_pow_n(10, cnt - 1); *pdes++ =((char)val_seg + '0'); cnt--; } pStr++; continue; case 'o': // 接收整型 ArgIntVal = va_arg(pArgs, int); if (ArgIntVal < 0)// 如果为负数打印,负号 { ArgIntVal = -ArgIntVal;// 取相反数 *pdes++ =('-'); ret_num++; } val_seg = ArgIntVal;// 赋值给 val_seg处理数据 // 计算ArgIntVal长度 if (ArgIntVal) { while (val_seg) { cnt++; val_seg /= 8; } } else cnt = 1;// 数字0的长度为1 ret_num += cnt;// 字符个数加上整数的长度 // 将整数转为单个字符打印 while (cnt) { val_seg = ArgIntVal / m_pow_n(8, cnt - 1); ArgIntVal %= m_pow_n(8, cnt - 1); *pdes++ =((char)val_seg + '0'); cnt--; } pStr++; continue; case 'x': // 接收16进制 ArgHexVal = va_arg(pArgs, uint32_t); val_seg = ArgHexVal; // 计算ArgIntVal长度 if (ArgHexVal) { while (val_seg) { cnt++; val_seg /= 16; } } else cnt = 1;// 数字0的长度为1 ret_num += cnt;// 字符个数加上整数的长度 // 将整数转为单个字符打印 while (cnt) { val_seg = ArgHexVal / m_pow_n(16, cnt - 1); ArgHexVal %= m_pow_n(16, cnt - 1); if (val_seg <= 9) *pdes++ =((char)val_seg + '0'); else { //*pdes++ =((char)val_seg - 10 + 'a'); //小写字母 *pdes++ =((char)val_seg - 10 + 'A'); } cnt--; } pStr++; continue; case 'b': // 接收整型 ArgIntVal = va_arg(pArgs, int); val_seg = ArgIntVal; // 计算ArgIntVal长度 if (ArgIntVal) { while (val_seg) { cnt++; val_seg /= 2; } } else cnt = 1;// 数字0的长度为1 ret_num += cnt;// 字符个数加上整数的长度 // 将整数转为单个字符打印 while (cnt) { val_seg = ArgIntVal / m_pow_n(2, cnt - 1); ArgIntVal %= m_pow_n(2, cnt - 1); *pdes++ =((char)val_seg + '0'); cnt--; } pStr++; continue; case 's': // 接收字符 ArgStrVal = va_arg(pArgs, char*); ret_num += (uint32_t)strlen(ArgStrVal); while (*ArgStrVal) { *pdes++ =(*ArgStrVal); ArgStrVal++; } pStr++; continue; case 'f': // 接收浮点型 保留6为小数,不采取四舍五入 ArgFloVal = va_arg(pArgs, double); val_seg = (uint32_t)ArgFloVal;// 取整数部分 val_temp = val_seg; // 临时保存整数部分数据 ArgFloVal = ArgFloVal - val_seg;// 得出余下的小数部分 // 计算整数部分长度 if (val_seg) { while (val_seg) { cnt++; val_seg /= 10; } } else cnt = 1;// 数字0的长度为1 ret_num += cnt;// 字符个数加上整数的长度 // 将整数转为单个字符打印 while (cnt) { val_seg = val_temp / m_pow_n(10, cnt - 1); val_temp %= m_pow_n(10, cnt - 1); *pdes++ =((char)val_seg + '0'); cnt--; } // 打印小数点 *pdes++ =('.'); ret_num++; // printf("\r\n %f\r\n", ArgFloVal); if(cnt_float == 0) cnt_float = 6; // 开始输出小数部分 //ArgFloVal *= 1000000; ArgFloVal *= m_pow_n(10, cnt_float); val_temp = (int)ArgFloVal;// 取整数部分 while (cnt_float) { val_seg = val_temp / m_pow_n(10, cnt_float - 1); val_temp %= m_pow_n(10, cnt_float - 1); *pdes++ =((char)val_seg + '0'); cnt_float--; } ret_num += 6; pStr++; continue; default:// % 匹配错误,暂输出空格 *pdes++ =(' '); ret_num++; break; } break; default: *pdes++ =(*pStr); ret_num++; break; } pStr++; if(ret_num > len){ break; } } va_end(pArgs);// 结束取参数 *pdes++ = 0; return ret_num; }