PICでUSBを!(知識ゼロからのスタートです)
PIC18F14K50のUSB機能を100%自前のソフトで制御する試みです。しかもアセンブラで!
当記事は2009年12月から「TTLでCPUをつくろう!」というタイトルの もとにほとんど毎日連載をしてきたものを再編集したものです。 |
2011.7.12 前へ 次へ 目次へ戻る ホームページトップへ戻る |
☆PIC18F14K50 PIC18F2550では大きすぎて、計画中のTK80互換マイコンボードND80ZVには組み込めそうにないことがわかりました。 USB機能内蔵のPICにはPIC18F4550、PIC18F2550のほかに20pinのPIC18F14K50があることはちょっと前から知っていました。しかしUSBに関する部分がPIC18F2550とはかなり異なっているようです。 案の定しっかり泥沼にはまってしまいました。 |
[第74回]
●8ビットパラレルデータ伝送(TK80モニタプログラム)
前回はPIC18F2550とZ80CPUとの間での8ビットパラレルデータ伝送について説明をいたしました。
というか、過去記事へのリンクで逃げてしまいました。
今回はその部分のプログラムをお見せすることにいたします。
まずは、Z80版TK80ボード(ND80ZH)の「TK80」モニタプログラムです。
オリジナルのTK80モニタプログラムでは、ここのところは、カセットテープレコーダインターフェイスになっていました。
もちろんいまどきカセットテープではお話しになりませんから、Z80版TK80ボード(ND80ZH)ではそれをPIC16F88を使ってRS232Cインターフェイスにしています。
今回はそこのところを、さらに変更してPIC16F88の代わりにPIC18F2550を使って、RS232Cだけではなくて、USB(HID)での送受信機能が使えるようにしました。
USB(HID)を使うと言っても、実際にその通信部分は全てPIC18F2550がやってくれますから、Z80版TK80ボード(今回の試作ボード)のモニタプログラムは、PIC18F2550との間で、8本のデータラインと4本の制御線を使ってデータをパラレルに送受信すればよく、その方法はPIC16F88でもPIC18F2550でも全く同じです。
そのデータのやり取りの部分をまずZ80版TK80ボード(試作版)の側のプログラムで見てみます。
プログラムサブルーチンの名前はSERIALになっていますが、シリアル送受信を行うのはPIC18F2550ですから、ここのところのPIC18F2550との間でのデータのやり取りはシリアルではなくてパラレルです。
; ;SERIAL OUTPUT ROUTINE ; 027C 4F SOUT:MOV C,A 027D DB98 SOUT2:IN 98 027F E602 ANI 02 0281 CA7D02 JZ SOUT2 0284 79 MOV A,C 0285 D394 OUT 94 0287 3EF9 MVI A,F9; I/Oaddress 94 "out" & STROBE ON 0289 D398 OUT 98 028B DB98 SOUT3:IN 98 028D E602 ANI 02 028F C28B02 JNZ SOUT3 0292 3EFB MVI A,FB; I/Oaddress 94 "out" & STROBE OFF 0294 D398 OUT 98 0296 C9 RET ; ;SERIAL INPUT ROUTINE ; ORG $02A0 ; 02A0 DB98 SIN:IN 98 02A2 0F RRC 02A3 DAA002 JC SIN 02A6 3EFE MVI A,FE;BUSY 02A8 D398 OUT 98 02AA DB94 IN 94 02AC 4F MOV C,A 02AD 3EFF MVI A,FF;READY 02AF D398 OUT 98 02B1 79 MOV A,C 02B2 C9 RET ; |
; ;data out to cpu ; dtoutsub btfss PORTA,1 goto dtoutsub movwf PORTB bcf PORTA,0 dtoutsub2 btfsc PORTA,1 goto dtoutsub2 bsf PORTA,0 return ; ;data in from CPU to READBF ; dtin movf PORTB,w bcf PORTA,2;set busy movwf INDF2 dtin3 btfss PORTA,3;if strobe off goto dtin3 bsf PORTA,2;set ready return ; |
; ;SERIAL OUTPUT ROUTINE ; 027C 4F SOUT:MOV C,A 027D DB98 SOUT2:IN 98 027F E602 ANI 02 0281 CA7D02 JZ SOUT2 0284 CD2603 CALL SOUTSB 0287 3EF9 MVI A,F9; I/Oaddress 94 "out" & STROBE ON 0289 D398 OUT 98 028B DB98 SOUT3:IN 98 028D E602 ANI 02 028F C28B02 JNZ SOUT3 0292 3EFB MVI A,FB; I/Oaddress 94 "out" & STROBE OFF 0294 D398 OUT 98 0296 C9 RET ; ;SERIAL INPUT ROUTINE ; ORG $02A0 ; 02A0 DB98 SIN:IN 98 02A2 0F RRC 02A3 DAA002 JC SIN 02A6 3EFE MVI A,FE;BUSY 02A8 D398 OUT 98 02AA DB94 IN 94 02AC E60F ANI 0F 02AE 4F MOV C,A 02AF 3EFF MVI A,FF;READY 02B1 D398 OUT 98 02B3 DB98 SIN1:IN 98 02B5 0F RRC 02B6 DAB302 JC SIN1 02B9 3EFE MVI A,FE 02BB D398 OUT 98 02BD DB94 IN 94 02BF 07 RLC 02C0 07 RLC 02C1 07 RLC 02C2 07 RLC 02C3 E6F0 ANI F0 02C5 B1 ORA C 02C6 4F MOV C,A 02C7 3EFF MVI A,FF 02C9 D398 OUT 98 02CB 79 MOV A,C 02CC C9 RET ; ; 0326 79 SOUTSB:MOV A,C 0327 D394 OUT 94 0329 3EF9 MVI A,F9 032B D398 OUT 98 032D DB98 SOUTSB2:IN 98 032F E602 ANI 02 0331 C22D03 JNZ SOUTSB2 0334 3EFB MVI A,FB 0336 D398 OUT 98 0338 DB98 SOUTSB3:IN 98 033A E602 ANI 02 033C CA3803 JZ SOUTSB3 033F 79 MOV A,C 0340 0F RRC 0341 0F RRC 0342 0F RRC 0343 0F RRC 0344 D394 OUT 94 0346 C9 RET |
; ;data out to CPU ; dtoutsub btfss PORTA,1 goto dtoutsub movwf datawk movwf PORTB;low 4bits out bcf PORTA,0 dtoutsub2 btfsc PORTA,1 goto dtoutsub2 bsf PORTA,0 dtoutsub3 btfss PORTA,1 goto dtoutsub3 rrncf datawk rrncf datawk rrncf datawk rrncf datawk,w movwf PORTB;high 4bits bcf PORTA,0 dtoutsub5 btfsc PORTA,1 goto dtoutsub5 bsf PORTA,0 return ; ;data in from CPU to READBF ; ; dtinsub movf PORTB,w andlw 0f movwf datawk bcf PORTA,2 dtinsub1 btfss PORTA,3 goto dtinsub1 bsf PORTA,2 dtinsub2 btfsc PORTA,3 goto dtinsub2 movf PORTB,w bcf PORTA,2 movwf datawkh4 rlncf datawkh4 rlncf datawkh4 rlncf datawkh4 rlncf datawkh4,w andlw 0f0 iorwf datawk,w dtinsub3 btfss PORTA,3 goto dtinsub3 bsf PORTA,2 return |