目的
前回、なんとかFON2045E(RT3050)のGPIOを使って、キャラクタ液晶の制御を行ったが、受信が失敗してしまう場合があった。そこで、チェックサムと到達確認(PICマイコンからFONに対して応答)を行うようにした。
結果
チェックサムの導入によって、受信失敗したものは、破棄できるようになった。1秒毎に顔文字「Adeno(^o^)mm-ss」※mm-ssは分-秒
を送信し続けると、おおよそ1分に2回程度チャックサムエラーが発生している模様。
何をやったか
1.チェックサムの導入送信するデータを以下のように変更
[STX][チェックサム][DATA][ETX]
STX : 02h
チェックサム:DATA部の合計値を0〜15(下位4ビット分)
DATA :今まで送っていたデータ
ETX :03h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include "rcv_lib.h" | |
#include "lcd_lib.h" | |
volatile unsigned char rcv_state = 0; | |
volatile unsigned char rcv_poi = 0; | |
volatile unsigned char rcv_cmd = ' '; | |
volatile unsigned char rcv_buf[RCV_SIZE]; | |
volatile unsigned char rcv_timeoutflg = 0; | |
volatile unsigned char rcv_timeout = 0; | |
volatile unsigned char rcv_full = 0; | |
volatile unsigned char rcv_chksum = 0; | |
volatile unsigned char rcv_chksum_base = 0; | |
volatile unsigned char rcv_drv_state = 0; | |
void rcv_init(){ | |
//受信バッファの準備 | |
for(rcv_poi = 0; rcv_poi < RCV_SIZE; rcv_poi++){ | |
rcv_buf[rcv_poi] = ' '; | |
} | |
//drv | |
rcv_drv_state = RCV_DRV_STATE_S0_STXWAIT; | |
rcv_chksum = 0; | |
rcv_chksum_base = 0; | |
//app | |
rcv_full = 0; | |
rcv_state = RCV_STATE_S1_CMDWAIT; | |
rcv_cmd = ' '; | |
} | |
char read_byte(int i){ return rcv_buf[i]; } | |
void clearRCVflg(){ rcv_full = 0; } | |
char getRCVflg(){ return rcv_full; } | |
unsigned char getRCVcmd(){ return rcv_cmd; } | |
void rcv_byte(unsigned char c){ | |
if(rcv_full == 1){ | |
printf("BufFull>%c\r\n",c); | |
}else if(rcv_drv_state == RCV_DRV_STATE_S0_STXWAIT){ | |
if(c == rSTX){ | |
rcv_cmd = ' '; | |
rcv_state = RCV_STATE_S1_CMDWAIT; | |
rcv_drv_state = RCV_DRV_STATE_S1_CHKSUMWAIT; | |
} | |
}else if(rcv_drv_state == RCV_DRV_STATE_S1_CHKSUMWAIT){ | |
rcv_chksum = 0; | |
rcv_chksum_base = c & 0x0f; | |
rcv_drv_state = RCV_DRV_STATE_S2_ETXWAIT; | |
}else if(rcv_drv_state == RCV_DRV_STATE_S2_ETXWAIT){ | |
if(c == rETX){ | |
rcv_chksum = rcv_chksum & 0xf; | |
if(rcv_chksum_base == rcv_chksum){ | |
rcv_buf[rcv_poi] = '\n'; | |
printf("ChkSumOK:%d\r\n",rcv_chksum); | |
rcv_full = 1; | |
}else{ | |
rcv_state = RCV_STATE_S1_CMDWAIT; | |
printf("ChkSumNG:%d:%d\r\n",rcv_chksum_base,rcv_chksum); | |
rcv_full = 2; | |
} | |
rcv_drv_state = RCV_DRV_STATE_S0_STXWAIT; | |
}else{ | |
rcv_chksum+= c; | |
if(rcv_state == RCV_STATE_S1_CMDWAIT){ | |
if(c == 'C'){ | |
rcv_state = RCV_STATE_S2_CMDWAIT2; | |
}else if(c == 'N'){ | |
rcv_poi = 0; | |
rcv_state = RCV_STATE_S3_DATAWAIT; | |
} | |
}else if(rcv_state == RCV_STATE_S2_CMDWAIT2){ | |
//コマンドを一時保存 | |
rcv_cmd = c; | |
rcv_state = RCV_STATE_S1_CMDWAIT; | |
}else if(rcv_state == RCV_STATE_S3_DATAWAIT){ | |
if(c == '\r'){ | |
}else{ | |
rcv_buf[rcv_poi] = c; | |
rcv_poi++; | |
//終了条件2:バッファがいっぱい | |
if(rcv_poi >= RCV_SIZE){ | |
rcv_poi = 0; | |
rcv_state = RCV_STATE_S1_CMDWAIT; | |
printf("End2\r\n"); | |
} | |
} | |
} | |
} | |
} | |
} |
2.受信の追加
送信後に、readしているだけ
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void gpio_test_write_sr(int gpio_clk, int gpio_out,int gpio_in,int delaytime, unsigned char *c){ | |
long gpiomask = 0x00FF1FFF; //0x00FFFFFF; | |
printf("set_dir=%ld\n",gpiomask); | |
gpio_set_dir(gpiomask); | |
int i,d,chksum; | |
printf("gpio_write_sr Start:CLK=%d DATA_OUT=%d DATA_IN=%d\n",gpio_clk,gpio_out,gpio_in); | |
struct timeval s,f; | |
gettimeofday(&s,NULL); | |
chksum = 0; | |
unsigned char RSTX = 0x02; | |
unsigned char RETX = 0x03; | |
gpio_write_byte3(gpio_clk,gpio_out,RSTX); | |
for(i=0;i<17;i++){ | |
if(*(c+i) == '\0'){ /*chksum += '\n';*/ break; | |
}else{ chksum += *(c+i); } | |
} | |
unsigned char RCHKSUM = (unsigned char)(chksum & 0xf); | |
gpio_write_byte3(gpio_clk,gpio_out,RCHKSUM); | |
for(i=0;i<17;i++){ | |
if(*(c+i) == '\0'){ | |
/*gpio_write_byte3(gpio_clk,gpio_out,'\n');*/ | |
break; | |
}else{ | |
gpio_write_byte3(gpio_clk,gpio_out,*(c+i)); | |
} | |
} | |
gpio_write_byte3(gpio_clk,gpio_out,RETX); | |
printf("ChkSum=%d\n",RCHKSUM); | |
gpio_set_dir(RALINK_GPIO_DIR_ALLIN); | |
gpio_read_bit(gpio_in, &d); | |
printf("Input--------------------->%d\n", d); | |
gettimeofday(&f,NULL); | |
printf("Total Time=%dms\n",(f.tv_sec-s.tv_sec)*1000+(f.tv_usec-s.tv_usec)/1000); | |
} |
PICからの戻りは画面に表示しているだけだけど、
今後は、再送とか実装していきたい。
0 件のコメント:
コメントを投稿