2015年4月25日土曜日

FON2405EのGPIOでキャラクタ液晶を制御する(受信機能追加)

目的

前回、チェックサムと送達確認(PICマイコンからFONに対して応答)を行うようにした。
 今回は、送達確認を拡張して受信機能(PICマイコンからFONに対してコマンドを出せる)ようにした。

概要

チェックサムOKの場合に、FONに対してACKを送信する。
 シリアル通信のクロックはFON側で生成しているので、
 イメージとしてはSPI通信に近いと思う。

結果

前回同様に1秒毎に顔文字「Adeno(^o^)mm-ss」※mm-ssは分-秒を送信し続けると、
 400回のコマンド送信に対して、送信NGは15回
  80回のときは、2回 2〜3%くらい?
 結果は地味だけど、PIC→FON方向の通信ができるようになったのは大きい


何をやったか

・フォーマット
1.データを送信するとき
  種類   方向
  クロック FON→PIC 385us
  送信データ      [STX][チェックサム][DATA][ETX]
  受信データPIC→FON  1byte前に対する受信結果

2.送信結果を確認するとき
  種類   方向
  クロック FON→PIC 385us
  送信データ      [ENQ]
  受信データPIC→FON  1byte前に対する受信結果

黄色・・・クロック
水色・・・受信データ(PIC→FON)この場合はACK(0x06)

------------------------------------------------
gpio_write_sr Start:CLK=12 DATA_OUT=11 DATA_IN=14
Send:[STX][CHKSUM = 14][DATA][ETX]<-4ms->[ENQ]
Input      = 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6
RcvChk     = OK
Total Time = 307ms
------------------------------------------------

・FON側
int gpio_io_byte(int port_clk,int port_in,int port_out,unsigned char *cin,unsigned char cout){
int shift_clk = port_clk-8;
int shift_out = port_out-8;
unsigned char mask = 1 << 7;
int idx=1,fd,req_w,req_r,i,j,value,tmp;
int in_val=0;
*cin = 0;
fd = open(GPIO_DEV, O_RDONLY);
if (fd < 0) {
perror(GPIO_DEV);
return -1;
}
if (0L <= port_in && port_in < RALINK_GPIO_DATA_LEN
&& shift_clk >= 0 && shift_out >= 0){
req_w = RALINK_GPIO_WRITE_BYTE | (idx << RALINK_GPIO_DATA_LEN);
req_r = RALINK_GPIO_READ_BIT | (port_in << RALINK_GPIO_DATA_LEN);
} else {
close(fd);
printf("gpio_io_byte: out of range\n");
}
for(i=0;i<8;i++){
value = 0;
tmp = 0;
if((cout & mask)>0){ value = 1;}
//clk reset(L) 1 with data set
for(j=0;j<385;j++){ //1.4us x 275 = 385us
tmp = (1<<shift_clk);
tmp |= (value<<shift_out);
tmp &= 0xff;
if (ioctl(fd, req_w, tmp) < 0) { perror("ioctl"); close(fd); return -1; }
}
//clk set(H) 0 with data set
for(j=0;j<385;j++){
tmp = (value<<shift_out);
tmp &= 0xff;
if (ioctl(fd, req_w, tmp) < 0) { perror("ioctl"); close(fd); return -1; }
}
//data read
if(ioctl(fd,req_r,&in_val,0) < 0){ perror("ioctl"); close(fd); return -1; }
if(in_val == 0)
*cin = (*cin << 1);
else
*cin = (*cin << 1)+1;
//next mask
mask = mask >>1;
}
//clk set(H) 0 with data set aftertime
for(j=0;j<4000;j++){
tmp = (value<<shift_out);
tmp &= 0xff;
if (ioctl(fd, req_w, tmp) < 0) { perror("ioctl"); close(fd); return -1; }
}
close(fd);
return 0;
}
view raw gpio_io_byte.c hosted with ❤ by GitHub
・PIC側
受信処理の後、に送信したいものを出力するだけ
↓受信処理
sr_buf = ((sr_buf<<1) & 0xFE) | (0x01 & DATA_PORT);
↓送信処理
 //DATA 出力
 if((sr_out & sr_out_mask) == 0){
   DATA_OUT_PORT = 0;
}else{
         DATA_OUT_PORT = 1;
 }
 sr_out_mask = sr_out_mask >> 1;

・エラー発生回数測定用スクリプト
#!/bin/sh
myvar=1
errvar=0
sndvar=0
retval=0
while [ $myvar -ne $1 ]
do
echo ==================================================== SeqNo.$myvar
./mygpio5a.exe s 12 11 14 1000 "C2"
if [ $? -eq 2 ]; then
errvar=`expr $errvar + 1`
fi
sndvar=`expr $sndvar + 1`
usleep 100000
./mygpio5a.exe s 12 11 14 1000 "NAdeno(-_-)"`date +%M-%S`
if [ $? -eq 2 ]; then
errvar=`expr $errvar + 1`
fi
sndvar=`expr $sndvar + 1`
usleep 400000
./mygpio5a.exe s 12 11 14 1000 "C2"
if [ $? -eq 2 ]; then
errvar=`expr $errvar + 1`
fi
sndvar=`expr $sndvar + 1`
usleep 100000
./mygpio5a.exe s 12 11 14 1000 "NAdeno(^o^)"`date +%M-%S`
if [ $? -eq 2 ]; then
errvar=`expr $errvar + 1`
fi
sndvar=`expr $sndvar + 1`
usleep 400000
myvar=`expr $myvar + 1`
done
echo TotalSend=$sndvar
echo ErrSend=$errvar
view raw lcdloop2.sh hosted with ❤ by GitHub
今日はここまで、次回は、PICからなにかデータを送信させてみるか

0 件のコメント:

コメントを投稿