広告
*12F629や12F675でシリアル通信 [#nf3a00b3]
12F629や12F675のようにシリアル通信の機能「USART」が無い場合は自力でタイミングなどを設定する必要がある。
RS232Cの場合、ただ通信するだけなら送信、受信の2本線があれば良く、GNDと合わせても3本線で通信ができるので簡単。~
そして通信する双方の通信速度、データビット長、パリティー、ストップビット長を合わせてあげれば通信できる。
*必要な部品 [#ke3cf556]
コンデンサや抵抗以外には
-12F629や12F675
-RS232C用のレベル変換IC
--秋月電子などに売っている「ADM3202」シリーズなど
-D-subコネクタ
--秋月電子などに売っている
*回路 [#b24a01ea]
シリアル通信用の簡単な回路は以下の図の通り、RS232C用のレベル変換ICとして「ADM3202」を使っている。~
12F629、12F675どちらも同じ回路で大丈夫
#ref(12F675_serial.png)
プリントパターンは以下の通り
#ref(12F675_serial_pcb.png)
印刷用
#ref(12F675_serial_pcb.pdf.tgz)
*アセンブラソース [#ad562154]
以下のソースは12F675用。12F629用にするためには先頭の2行を変える。~
内部クロックだとあまり精度が良くないためタイミングを作る待ちルーチンはチップごとに調整が必要。
**送信 [#z5c7841f]
「[[PICと温度計モジュールを利用した、温度計測装置の作成:http://scw.asahi-u.ac.jp/~sanozemi/Sakuhin/pic02/PIC02.html]]」のソースを改造した物。~
「Test」という文字を送り続ける。~
データビット長8bit、パリティーなし、ストップビット長1bitです。~
通信速度が早くなってくるとタイミングを合わせるのが大変になってくる。
; Test RS-232C
; GPIO 5 = TXD
; GPIO 3 = RXD
list p=12f675 ;12F629のときはここを変える
include p12f675.inc ;12F629のときはここを変える
__CONFIG _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT
__IDLOCS H'0100'
CBLOCK H'20'
CNT1
CNT3
BUF
ENDC
;ポートを定義
#DEFINE TX232 GPIO,5 ;GPIOレジスタの第5ビットを送信用にする
#DEFINE RX232 GPIO,3 ;GPIOレジスタの第3ビットを受信用にする
;----Initial setting
L1:
BCF STATUS,RP0 ;Bank 0
CLRF GPIO ;Init GPIO
MOVLW 07h ;
MOVWF CMCON ;digital IO
BSF STATUS,RP0 ;Bank 1
CLRF ANSEL ;Digital I/O
MOVLW B'00011111' ;ポート4を出力、ポート0,1,2,3,4を入力に設定します。3 is read
MOVWF TRISIO ;
BCF STATUS,RP0 ;Bank 0
BSF TX232 ;データを送信しないときは常に1を送出していなければならないので、GPIOレジスタの第5ビットを1にします。
;----SEND DATA
L2:
MOVLW A'T'
CALL SEND232C
MOVLW A'e'
CALL SEND232C
MOVLW A's'
CALL SEND232C
MOVLW A't'
CALL SEND232C
MOVLW 0x0a ;Send LF
CALL SEND232C
GOTO L2
;--------RS232--------
;参考サイト
;http://scw.asahi-u.ac.jp/~sanozemi/Sakuhin/pic02/PIC02.html
SEND232C: ;Wレジスターより、送出すべき文字をBUFに受け取ります。続いて、スタートビットとして、とにかく、0を送出します。その後待ちます。
MOVWF BUF ;W -> BUF
MOVLW D'8'
MOVWF CNT3
BCF TX232 ;0を送出
CALL W232
L9:
;データを、下位ビットから順に8ビット送出します。
BTFSS BUF,0 ;BUFの0ビット目が1なら次をスキップ
BCF TX232 ;0を送出
BTFSC BUF,0 ;BUFの0ビット目が0なら次をスキップ
BSF TX232 ;1を送出
CALL W232 ;Wait
RRF BUF,F ;シフト
DECFSZ CNT3,F
GOTO L9
BSF TX232 ;最後に、ストップビットとして、1を送出します。
CALL W232
RETURN
;---wait 10us
W10
MOVLW D'2'
MOVWF CNT1
WL10
DECFSZ CNT1,F
GOTO WL10
RETURN
;------------Wait------------
;19200bps=52us
;38400bps=26us
;57600bps=17us
;4MHz clock=> 1us/cycle
;細かに調整するためにループを使わないでやってみる。
;個体差があるのでそれぞれのチップで調整が必要
W232: ;38400bps用 NOPx14
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
RETURN
;19200bpsなら以下のループでも大丈夫
;W232:
; MOVLW D'14' ;19200bps
; MOVWF CNT1
;WWL:
; DECFSZ CNT1,F
; GOTO WWL
END ;プログラムの最後
**送信、受信 [#bbd19d0c]
受信も含めたもの。一文字ずつループバックする。通信速度は38400bps、データビット長8bit、パリティーなし、ストップビット長1bitです。~
受信部の元にさせて頂いたサイトを失念してしまいました。すみません。~
通信速度が速くなってくると、処理する時間が少なくなってしまうためできるだけステップ数が少なくなるようにする必要があります。~
もし不都合なら、通信速度を落とすか、内部クロックを使わずに外部発振子を使うようにします。
list p=12f675 ;12F629のときはここを変える
include p12f675.inc ;12F629のときはここを変える
__CONFIG _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT
__IDLOCS H'0100'
CBLOCK H'20'
CNT1
CNT3
BUF
BITCNT
RXDATA
ENDC
;ポートを定義
#DEFINE TX232 GPIO,5 ;GPIOレジスタの第5ビットを送信用にする
#DEFINE RX232 GPIO,3 ;GPIOレジスタの第3ビットを受信用にする
;----Initial setting
L1:
BCF STATUS,RP0 ;Bank 0
CLRF GPIO ;Init GPIO
MOVLW 07h ;
MOVWF CMCON ;digital IO
BSF STATUS,RP0 ;Bank 1
CLRF ANSEL ;Digital I/O
MOVLW B'00011111' ;ポート4を出力、ポート0,1,2,3,4を入力に設定します。3 is read
MOVWF TRISIO ;
BCF STATUS,RP0 ;Bank 0
BSF TX232 ;データを送信しないときは常に1を送出していなければならないので、GPIOレジスタの第5ビットを1にします。
;----SEND DATA
L2:
MOVLW A'T'
CALL SEND232C
MOVLW A'e'
CALL SEND232C
MOVLW A's'
CALL SEND232C
MOVLW A't'
CALL SEND232C
MOVLW A'>'
CALL SEND232C
;----GET Command DATA
CALL RXSTART
;----Send recived Command
MOVF RXDATA,W
CALL SEND232C
GOTO L2
;----Recive Command DATA
RXSTART:
MOVLW D'8' ;Count set
MOVWF BITCNT
CLRF RXDATA ;Clear RXDATA
BTFSC RX232 ;IF RX232 is Clear
GOTO RXSTART
CALL W10 ;Wait 10us
BTFSC RX232 ;IF RX232 is Clear
GOTO RXSTART
RXLOOP:
CALL W232 ;wait
BCF STATUS,C ;ビット0セット
BTFSC RX232 ;受信ビット0か1か
BSF STATUS,C ;1 の時1にセット
RRF RXDATA,F ;RXDATAに1ビット書き込み
DECFSZ BITCNT,F
GOTO RXLOOP
RETURN
;--------RS232--------
;参考サイト
;http://scw.asahi-u.ac.jp/~sanozemi/Sakuhin/pic02/PIC02.html
SEND232C: ;Wレジスターより、送出すべき文字をBUFに受け取ります。続いて、スタートビットとして、とにかく、0を送出します。その後待ちます。
MOVWF BUF ;W -> BUF
MOVLW D'8'
MOVWF CNT3
BCF TX232 ;0を送出
CALL W232
L9:
;データを、下位ビットから順に8ビット送出します。
BTFSS BUF,0 ;BUFの0ビット目が1なら次をスキップ
BCF TX232 ;0を送出
BTFSC BUF,0 ;BUFの0ビット目が0なら次をスキップ
BSF TX232 ;1を送出
CALL W232 ;Wait
RRF BUF,F ;シフト
DECFSZ CNT3,F
GOTO L9
BSF TX232 ;最後に、ストップビットとして、1を送出します。
CALL W232
RETURN
;---wait 10us
W10
MOVLW D'3' ;要調整
MOVWF CNT1
WL10
DECFSZ CNT1,F
GOTO WL10
RETURN
;------------Wait------------
;19200bps=52us
;38400bps=26us
;57600bps=17us
;4MHz clock=> 1us/cycle
;細かに調整するためにループを使わないでやってみる。
;個体差があるのでそれぞれのチップで調整が必要
W232: ;38400bps用 NOPx14
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
RETURN
;19200bpsなら以下のループでも大丈夫
;W232:
; MOVLW D'14' ;19200bps
; MOVWF CNT1
;WWL:
; DECFSZ CNT1,F
; GOTO WWL
END ;プログラムの最後
広告 |