ESP8266:C語言常用知識點
阿新 • • 發佈:2018-11-08
ESP8266:C語言常用知識點
ESP8266開發過程中,常常用到字串處理,HEX轉ASCII, IP地址處理,定時任務處理,TCP/UDP等。特此進行整理,以備不時之需。
字串處理
定義字串
uint8 uart_buff[256]; //定義字串或記憶體空間,長度256,uart_buff指向首地址
uint8 *pdata; //定義字串指標,指向字串
建立字串
memset(uart_buff,0,sizeof(tcp_send_buff));//字串清空 sprintf(uart_buff,"%c%c%c",A,B,C);//將A,B,C(巨集定義)內容寫入字串 memcpy(uart_buff,pdata,strlen(pdata)) //將pdata指向字串複製到uart_buff中
查詢字串內容
#define NULL (void *)0
uint8 * p_result=NULL;
p_result = strstr(pdata, (const char *)"CMD1"); //查詢字串中是否包含CMD1,並指向其位置
if(p_rsult!=NULL){ //如果查詢到,則進行處理
}
比較字串內容
uint8 *pdata;
uint8 char_buff[16];
memcpy(pdata,char_buff,strlen(char_buff)); //比較char_buff和pdata內容,如果相同,則返回0
HEX轉換為ASCII
HEX轉換為字串,其中pData指向需要轉換的字元;pRusult指向轉換後的字元,如果輸入為0x01,則轉換為ASCII 01, 如果輸出0x5A則轉換為ASCII 5A
void Hex2ASCII(uint8* pResult,uint8* pData){ uint8 i,temp_h,teml_l; for(i=0;i<strlen(pData);i++){ /**轉換高位**/ temp_h = pData[i]/16; //轉換高位,例如,0x5A/16 = 5; if(temp_h>=0&&temp_h<=9) //在0~9之間 temp = temp_h+48; //數字轉換為ASCII碼 else if(temp_h>=10&&temp_h<=15) temp = temp_h+55; //數字轉換為大寫字元,例如A,B,C,D pResult[i*2] = temp; //存入高位 /**轉換低位**/ temp_l = pData[i]%16; //轉換低位,例如,0x5A%16 = 0XA; if(temp_l>=0&&temp_l<=9) //在0~9之間 temp = temp_l+48; //數字轉換為ASCII碼 else if(temp_l>=10&&temp_l<=15) temp = temp_l+55; //數字轉換為大寫字元,例如A,B,C,D pResult[i*2+1] = temp; //存入低位 } }
IP地址處理
//把數字轉換為IP地址
struct ip_addr {
uint32 addr;
};
#define IP4_ADDR(ipaddr, a,b,c,d) \
(ipaddr)->addr = ((uint32)((d) & 0xff) << 24) | \
((uint32)((c) & 0xff) << 16) | \
((uint32)((b) & 0xff) << 8) | \
(uint32)((a) & 0xff)
//構建server_ip
struct ip_addr sever_ip;
uint8 sever_ip[4]={0};
//將數字組合為ip地址
IP4_ADDR(&sever_ip, sever_ip[0], sever_ip[1], sever_ip[2], sever_ip[3]);
#define IP2STR(ipaddr) ip4_addr1_16(ipaddr), \
ip4_addr2_16(ipaddr), \
ip4_addr3_16(ipaddr), \
ip4_addr4_16(ipaddr)
/*IP2STR例子,將ip地址轉換為4個數字*/
printf("%d.%d.%d.%d\r\n",IP2STR(&info.ip));
/*將ip地址轉換為字串*/
sprintf(send_buff,"{\"ipaddr\":\"%d.%d.%d.%d\"}\r\n",IP2STR(&info.ip));
定時任務
在定時迴圈中,對計數器計數;
task_cnt++;
在執行迴圈中,檢查計數器,當計數器達到間隔時
if(task_cnt>100){
exeTask();
task_cnt=0;
}
條件定時任務
當條件滿足時,開始執行的定時任務;
//定時迴圈中
if(condition_flag) task_cnt++;
//任務迴圈中
if(task_cnt>100){
exeTask(); //執行任務;
task_cnt=0; //請定時器
}
大小迴圈定時任務
程式描述:每隔5S執行一次任務,每次執行時,相同的任務執行5次,每次間隔200ms,例如:設定LED的閃燈方式,每隔5S閃爍一次,每次閃爍時,用200MS間隔閃5次;
程式思路:大迴圈記錄5S時間間隔;小迴圈記錄任務之間間隔;5S時間到,開始小迴圈計數;小迴圈200ms時間到,檢查執行次數,如果沒有超出,則執行任務。否則清除標誌位
//大迴圈定時,在定時任務中檢查
if(loop1_flag) loop1_cnt++; //大迴圈計數器
//小迴圈定時,在定時任務中檢查並計數
if(loop2_flag) loop2_cnt++; //小迴圈計數器
//一下程式碼在執行任務中執行
//大迴圈標誌位
if(loop1_cnt>500){
loop2_flag=1; //定時時間到,設定小迴圈標誌
loop1_cnt = 0; //清零loop1計數器
}
//小迴圈執行
if(loop2_cnt>20){ //小迴圈計時器時間到
if(task_exe_cnt<5){ //執行次數未到
exeTask(); //執行任務
task_exe_cnt++; //記錄執行次數
loop2_cnt=0; //計數器清零
}else{ //任務已經完成了5次
task_exe_cnt=0; //任務次數計時器清零
loop2_cnt = 0;
loop2_flag=0; //計數器標誌清零,停止執行
}
}
字元轉換為16進位制數
物聯網應用中,網路傳輸資料通常為字串格式,而MCU中執行命令通常為HEX格式,因此需要把字串轉換為16進位制。例如:字串格式的1f中,1為低位數字,f為高位數字,需要將其組合為0x1f這樣的數字。
for(i=0; i<CMD_LEN; i++){
if((*(pdata+i*2)>='0') && (*(pdata+i*2)<='9')){
temp = (*(pdata+i*2)-'0')<<4;
}
if((*(pdata+i*2)>='a') && (*(pdata+i*2)<='f')){
temp = (*(pdata+i*2)-'a'+10)<<4;
}
if((*(pdata+i*2)>='A') && (*(pdata+i*2)<='F')){
temp = (*(pdata+i*2)-'A'+10)<<4;
}
if((*(pdata+i*2+1)>='0') && (*(pdata+i*2+1)<='9')){
temp += (*(pdata+i*2+1)-'0')&0xff;
}
if((*(pdata+i*2+1)>='a') && (*(pdata+i*2+1)<='f')){
temp += (*(pdata+i*2+1)-'a'+10)&0xff;
}
if((*(pdata+i*2+1)>='A') && (*(pdata+i*2+1)<='F')){
temp += (*(pdata+i*2+1)-'A'+10)&0xff;
}
cmd_buff[i] = temp;
temp=0;
os_printf("cmd:%x\r\n",cmd_buff[i]);
}
這樣,*pdata中的字串就轉換為cmd_buff中的16進位制資料了。