//tabは8文字 //コンパイルツール は GCC Developer Lite // // long:32bit // int :16bit // char: 8bit // #include <3664.h> //▼▼▼プロトタイプなんたら volatile void wait(volatile unsigned int); void numToStr(unsigned char,char str[3]); void tSCI3(unsigned char); void tsSCI3(unsigned char *); void tSPI(unsigned char); unsigned char rSPI(void); unsigned char MMC_CMD(unsigned char,unsigned long); void MMC_getData(void); unsigned char MMC_setData(void); void MMC_init(void); void makeCommand(unsigned char); void writeData(unsigned char); void setRWAdress(unsigned int); void setSAdress(unsigned int); void setData(unsigned char); //▼▼▼グローバルな構造体・変数 union BITFIELD{ unsigned char BYTE; struct { unsigned char B7:1; unsigned char B6:1; unsigned char B5:1; unsigned char B4:1; unsigned char B3:1; unsigned char B2:1; unsigned char B1:1; unsigned char B0:1; } BIT; }; unsigned char status=0; //SCI3割り込みのswitch参照 static unsigned char text[256]="なる研";//表示すべき文字列 struct { unsigned int RWA; //読み出し、書き込みアドレス unsigned int SA; //表示開始アドレス unsigned int speed; } VFD; struct { unsigned char block[512]; unsigned long adress; } MMC; //▼▼▼ウェイト volatile void wait(volatile unsigned int i){ for(;i;i--); } //▼▼▼数値の文字列化 void numToStr(unsigned char num,char str[3]){ unsigned char tmp; tmp=(num&0xf0)>>4; str[0]=tmp|0x30; if(tmp>=10) str[0]+=(0x07); tmp=num&0x0f; str[1]=tmp|0x30; if(tmp>=10) str[1]+=(0x07); str[2]='\0'; } //▼▼▼文字列の数値化 unsigned char strToNum(char c){ switch (c){ case '0': return 0; case '1': return 1; case '2': return 2; case '3': return 3; case '4': return 4; case '5': return 5; case '6': return 6; case '7': return 7; case '8': return 8; case '9': return 9; case 'a': return 10; case 'b': return 11; case 'c': return 12; case 'd': return 13; case 'e': return 14; case 'f': return 15; } return 0; } //▼▼▼ SCI送信 void tSCI3(unsigned char data){ //一文字 for(;!SCI3.SSR.BIT.TDRE;); SCI3.TDR=data; } void tsSCI3(unsigned char *data){ //文字列 unsigned int i; for(i=0;data[i]!='\0';i++){ for(;!SCI3.SSR.BIT.TDRE;); SCI3.TDR=data[i]; } } //▼▼▼【割り込み】 SCI受信 void int_sci3(){ static unsigned int gCnt; //汎用カウンタ unsigned int i; unsigned char data; if(SCI3.SSR.BIT.RDRF); if(SCI3.SSR.BIT.OER) SCI3.SSR.BIT.OER=0; if(SCI3.SSR.BIT.FER) SCI3.SSR.BIT.FER=0; if(SCI3.SSR.BIT.PER) SCI3.SSR.BIT.PER=0; data = SCI3.RDR; switch(status){ case 'f': //▼フォント転送状態 MMC.block[gCnt]=data; gCnt++; if(gCnt==512){ gCnt=0; for(;MMC_CMD(24,MMC.adress);); MMC_setData(); //時間がかかる MMC.adress+=512; } break; case 's': VFD.speed=strToNum(data); status=0; break; case 'w': //▼追記(S-JISコード入力) if(data=='\n'){ tsSCI3(text); status=0; break; } for(i=0;text[i]>=0x40 && i<254;i++); text[i]=data; text[i+1]='\0'; break; case 'a': //▼MMC内容をまんまVFDへ表示 for(MMC.adress=0;MMC.adress<0xffffff;MMC.adress+=512){ for(;MMC_CMD(17,MMC.adress);); MMC_getData(); for(gCnt=0;gCnt<512;gCnt++){ setData(MMC.block[gCnt]); if((++VFD.RWA & 0x0007)==0x0004){ VFD.RWA+=4; setRWAdress(VFD.RWA); } } } case 't': //▼そのままVFD送信状態 setData(data); if((++VFD.RWA & 0x0007)==0x0004){ VFD.RWA+=4; setRWAdress(VFD.RWA); } break; case 'm': //▼MMC内容をSCI3から出す { unsigned char res[3]; for(MMC.adress=0;MMC.adress<0xff00;MMC.adress+=512){ for(;(res[0]=MMC_CMD(17,MMC.adress));); MMC_getData(); numToStr(res[0],res); tsSCI3(res); tsSCI3("data: "); for(i=0;i<512;i++) tSCI3(MMC.block[i]); tsSCI3("\n"); } } status=0; break; default : //▼アイドル状態(コマンド待機) if(data=='0' || data=='\0') status=0; if(data=='c') {text[0]=0x81;text[1]=0x40;text[2]='\0'; status=0;} if(data=='r') tsSCI3(text); status=0; if(data=='f') { tsSCI3("フォント転送モード\n"); MMC.adress=0; IENR1.BIT.IEN0=0; //IRQ0割り込みdisable } if(data=='d'){ //▼先頭を1文字削除 for(i=0;i<254;i++) text[i]=text[i+2]; status=0; } if(data=='b'){ //▼末尾を一文字削除 for(i=0;text[i]>=0x40 && i<254;i++); if(i>=2)text[i-2]='\0'; status=0; } if(data != '\n' ) status=data; gCnt=0; break; } } //▼▼▼MMC_ポート #define IO_MMC_DO IO.PDR2.BIT.B0 //O データアウト(MMCのDIへ) #define IO_MMC_DI IO.PDR7.BIT.B4 //I データイン(MMCのDOへ) #define IO_MMC_CL IO.PDR7.BIT.B5 //O クロック #define IO_MMC_CS IO.PDR7.BIT.B6 //O カードセレクト //▼▼▼MMC_SPI送信 void tSPI(unsigned char data){ union BITFIELD tData; DI; tData.BYTE=data; IO_MMC_CL=0; IO_MMC_DO=tData.BIT.B7; IO_MMC_CL=1; IO_MMC_CL=0; IO_MMC_DO=tData.BIT.B6; IO_MMC_CL=1; IO_MMC_CL=0; IO_MMC_DO=tData.BIT.B5; IO_MMC_CL=1; IO_MMC_CL=0; IO_MMC_DO=tData.BIT.B4; IO_MMC_CL=1; IO_MMC_CL=0; IO_MMC_DO=tData.BIT.B3; IO_MMC_CL=1; IO_MMC_CL=0; IO_MMC_DO=tData.BIT.B2; IO_MMC_CL=1; IO_MMC_CL=0; IO_MMC_DO=tData.BIT.B1; IO_MMC_CL=1; IO_MMC_CL=0; IO_MMC_DO=tData.BIT.B0; IO_MMC_CL=1; EI; } //▼▼▼MMC_SPI受信 unsigned char rSPI(void){ union BITFIELD rData; DI; IO_MMC_CL=0; IO_MMC_CL=1; rData.BIT.B7=IO_MMC_DI; IO_MMC_CL=0; IO_MMC_CL=1; rData.BIT.B6=IO_MMC_DI; IO_MMC_CL=0; IO_MMC_CL=1; rData.BIT.B5=IO_MMC_DI; IO_MMC_CL=0; IO_MMC_CL=1; rData.BIT.B4=IO_MMC_DI; IO_MMC_CL=0; IO_MMC_CL=1; rData.BIT.B3=IO_MMC_DI; IO_MMC_CL=0; IO_MMC_CL=1; rData.BIT.B2=IO_MMC_DI; IO_MMC_CL=0; IO_MMC_CL=1; rData.BIT.B1=IO_MMC_DI; IO_MMC_CL=0; IO_MMC_CL=1; rData.BIT.B0=IO_MMC_DI; EI; return rData.BYTE; } //▼▼▼MMC_CMD コマンド unsigned char MMC_CMD(unsigned char cmd,unsigned long argument){ for(;!IO_MMC_DI;) tSPI(0xff); tSPI(0xff); tSPI(0xff); tSPI(cmd | 0x40); //コマンド tSPI((argument & 0xff000000)>>24); //引数 tSPI((argument & 0x00ff0000)>>16); //引数 tSPI((argument & 0x0000ff00)>> 8); //引数 tSPI((argument & 0x000000ff)>> 0); //引数 tSPI(0x95); //CRC for(;IO_MMC_DI;){ //スタートビット待ち IO_MMC_CL=0; IO_MMC_CL=1; } return rSPI()>>1; //レスポンス } //▼▼▼MMC_データブロック受け取り void MMC_getData(void){ unsigned int i=0; for(;IO_MMC_DI;){ //スタートビット待ち IO_MMC_CL=0; IO_MMC_CL=1; } for(i=0;i<512;i++) MMC.block[i]=rSPI(); rSPI(); rSPI(); } //▼▼▼MMC_データブロック送信 unsigned char MMC_setData(void){ unsigned int i; tSPI(0xff); tSPI(0xff); tSPI(0xfe); //スタートブロック for(i=0;i<512;i++){ tSPI(MMC.block[i]); } tSPI(0xff); //ダミーCRC tSPI(0xff); //ダミーCRC for(;IO_MMC_DI;){ //スタートビット待ち IO_MMC_CL=0; IO_MMC_CL=1; } return rSPI()>>1; } //▼▼▼MMC_初期化 void MMC_init(void){ unsigned char i; unsigned char res[3]; IO_MMC_DO=1; IO_MMC_CS=1; for(i=0;i<15;i++){ tSPI(0xff); } IO_MMC_CS=0; tsSCI3(" CMD0 0x"); if((i=MMC_CMD(0,0))!=0x01) ; numToStr(i,res);tsSCI3(res); for(i=1;i;){ tsSCI3(" CMD1 0x"); i=MMC_CMD(1,0); numToStr(i,res); tsSCI3(res); } } //▼▼▼VFD_ポート #define IO_VFD_WR IO.PDR1.BIT.B0 // O ~write #define IO_VFD_RD IO.PDR1.BIT.B1 // O ~read #define IO_VFD_CS IO.PDR1.BIT.B2 // O ~cardSelect #define IO_VFD_INT IO.PDR1.BIT.B4//I display refresh signal #define IO_VFD_CD IO.PDR1.BIT.B5 // O command or ~data #define IO_VFD_DATA IO.PDR5.BYTE //IO D0-D7 //▼▼▼VFD_コマンド void makeCommand(unsigned char command){ IO_VFD_CD=1; //コマンド IO_VFD_WR=0; //書き込み sage IO_VFD_DATA=command; //コマンド IO_VFD_WR=1; //書き込み age } //▼▼▼VFD_でーた書き込み void writeData(unsigned char data){ IO_VFD_CD=0; //データ IO_VFD_WR=0; //書き込み sage IO_VFD_DATA=data; //データ IO_VFD_WR=1; //書き込み age } //▼▼▼VFD 読み出し、書き込みアドレスの変更 void setRWAdress(unsigned int adress){ IO_VFD_CD=1; //コマンド IO_VFD_DATA=0x04; //表示スタートアドレスL IO_VFD_WR=0; //書き込み sage IO_VFD_WR=1; //書き込み age IO_VFD_CD=0; //データ IO_VFD_WR=0; //書き込み sage IO_VFD_DATA=adress & 0x00ff;//アドレスL IO_VFD_WR=1; //書き込み age IO_VFD_CD=1; //コマンド IO_VFD_DATA=0x05; //表示スタートアドレスH IO_VFD_WR=0; //書き込み sage IO_VFD_WR=1; //書き込み age IO_VFD_CD=0; //データ IO_VFD_WR=0; //書き込み sage IO_VFD_DATA=(adress>>8)&0x001f;//アドレスH IO_VFD_WR=1; //書き込み age } //▼▼▼VFD表示開始アドレスの変更 void setSAdress(unsigned int adress){ IO_VFD_CD=1; //コマンド IO_VFD_DATA=0x07; //表示スタートアドレスL IO_VFD_WR=0; //書き込み sage IO_VFD_WR=1; //書き込み age IO_VFD_CD=0; //データ IO_VFD_WR=0; //書き込み sage IO_VFD_DATA=adress & 0x00ff;//表示スタートアドレスL IO_VFD_WR=1; //書き込み age IO_VFD_CD=1; //コマンド IO_VFD_DATA=0x08; //表示スタートアドレスH IO_VFD_WR=0; //書き込み sage IO_VFD_WR=1; //書き込み age IO_VFD_CD=0; //データ IO_VFD_WR=0; //書き込み sage IO_VFD_DATA=(adress>>8)&0x001f; //表示スタートアドレスH IO_VFD_WR=1; //書き込み age } //▼▼▼VFD表示データの変更 void setData(unsigned char data){ data=((data&0x01)<<7) | ((data&0x02)<<5) | ((data&0x04)<<3) | ((data&0x08)<<1) | ((data&0x10)>>1) | ((data&0x20)>>3) | ((data&0x40)>>5) | ((data&0x80)>>7); IO_VFD_CD=1; //コマンド IO_VFD_DATA=0x02; //表示データ書き込み IO_VFD_WR=0; //書き込み sage IO_VFD_WR=1; //書き込み age IO_VFD_CD=0; //データ IO_VFD_WR=0; //書き込み sage IO_VFD_DATA=data; //表示データ IO_VFD_WR=1; //書き込み age } //▼▼▼ s-jisをアドレスに変換 unsigned long sjisToAdress(unsigned long sjis){ unsigned char U; U=sjis>>8; if(sjis<0x8140) return 0; //エラー if(sjis<0x8740) return 128*(sjis-0x8140 -(0x40*(U-0x81)) ); if(sjis<0xE040) return 128*(sjis-0x8740+0x0300 -(0x40*(U-0x87)) ); if(sjis<0xED40) return 128*(sjis-0xE040+0x0300+0x12C0 -(0x40*(U-0xE0)) ); if(sjis<0xEA40) return 128*(sjis-0xED40+0x0300+0x12C0+0x0840 -(0x40*(U-0xED)) ); return 128*(sjis-0xEA40+0x0300+0x12C0+0x0840+0x0180 -(0x40*(U-0xEA)) ); } //▼▼▼【割り込み】 IRQ0(VFD_フレームタイミング) void int_irq0(){ static unsigned char cursor; //表示中の文字(番目) static unsigned char cnt1; static unsigned char cnt2; if(++cnt1>=VFD.speed){ //▼スクロール cnt1=0; VFD.SA+=8; if(VFD.SA>=0xE000){ //ちょっと誤魔化し VFD.SA-=0xC000; VFD.RWA-=0xC000; } setSAdress(VFD.SA); //表示開始アドレス if(status==0 && ++cnt2==32){ //▼文字表示 unsigned int sjis; unsigned long adress; unsigned int i; unsigned char tmp[4]; cnt2=0; for(;VFD.RWA<=VFD.SA+0x0900;){ if(text[cursor*2]=='\0' || text[cursor*2+1]=='\0'){ cursor=0; sjis=0; }else{ sjis=text[cursor*2]<<8|text[cursor*2+1]; //文字列から文字コード取り出し cursor++; } adress=sjisToAdress(sjis); for(;(tmp[4]=MMC_CMD(17,(adress/512)*512));){//シングルブロックリード numToStr(tmp[4],tmp); tsSCI3(tmp); }//for MMC_getData(); adress%=512; for(i=0;i<128;i++){ setData(MMC.block[adress+i]); if((++VFD.RWA & 0x0007)==0x0004){ VFD.RWA+=4; setRWAdress(VFD.RWA); }//if }//for }//for }//if } IRR1.BIT.IRRI0=0; } //▼▼▼ //▼▼▼ リセット void main(){ DI; //▼▼▼ ポートの初期化 IO.PCR5=0xff; //対VFDモジュール双方向データ線 IO.PCR1=0x27; //対VFDモジュール制御線 IO.PDR1.BYTE=0x27; //0 1 ~WR 書き込み //1 1 ~RD 読み出し //2 1 ~CS チップセレクト //3 0 //4 0 INT フレームタイミング //5 1 C/~D コマンド/データ //6 0 //7 0 IO.PCR7=0x60; IO.PDR7.BYTE=0x60; //4 I DI 対MMCデータイン //5 O 1 CLK 対MMCクロック //6 O 1 CS 対MMCチップセレクト IO.PCR2=0x01; IO.PDR2.BYTE=0x01; //2 O 1 DO 対MMCデータアウト //▼▼▼ SCI初期化 SCI3.SCR3.BIT.RE=0; //受信Disable SCI3.SCR3.BIT.TE=0; //送信信Disable SCI3.SMR.BIT.CKS=0; //SCI3.BRR=25; //19200bps SCI3.BRR=12; //38400bps wait(0xffff); SCI3.SCR3.BIT.RIE=1; //受信割り込みEnable SCI3.SCR3.BIT.RE=1; //受信Enable SCI3.SCR3.BIT.TE=1; //送信Enable IO.PMR1.BIT.TXD=1; //送信Enable tsSCI3("なる研\n"); //▼▼▼ VDFモジュール初期化 IO.PMR1.BIT.IRQ0=1; //割り込みポート IEGR1.BIT.IEG0=1; //立ち上がり割り込み IO_VFD_CS=0; //チップセレクト makeCommand(0x00); //RWアドレスオートインクリメント makeCommand(0x06); //輝度 writeData(0x0d); // for(VFD.RWA=0;VFD.RWA<=0x1fff;VFD.RWA++){ setData(0x00); //表示初期化 } VFD.RWA=0x0000; VFD.SA=0x0000; VFD.speed=2; setRWAdress(VFD.RWA); //読み書きアドレス setSAdress(VFD.SA); //表示開始アドレス makeCommand(0x10); //電源ON tsSCI3("VFDモジュール起動\n"); MMC_init(); tsSCI3("SPIモード移行完了\n"); EI; IENR1.BIT.IEN0=1; //IRQ0割り込みenable for(;;); } // (c) なる研