楽天市場
[無料でホームページを作成] [通報・削除依頼]

続PIC10F322 ソフトシリアル一考察

続PIC10F322 ソフトシリアル一考察

PIC10F322では下図のようにピン割り当てが行われており、入力専用のRA3を除くRA0~RA2に多くの機能が割り当てられています。

img_20130422-094807.jpg


PIC10F322は少ピンですので、入力専用のRA3も出力として使用できれば、プログラム設計の自由度は大幅に向上します。

この一例として前のページではLED点灯の方法を示しました。



このページでは次に入力ポートを通信出力として使う方法について考察します。

入力ポートのみでソフトシリアルインターフェイスを構成する方法

壱.追加するハードウエア
実験の結果、トランジスタの反転回路2段が確実なようです。
ブートローダに適用した回路図を以下に示します。
この回路を使用する場合JMP_TXのジャンパはショートしてはいけません。

img_20130422-094849.jpg

弐.ソフトウエアの変更ポイント
基本的な変更として送信サブルーチンに以下の処置が必要です。

(1)OPTION_REGレジスタのビット7をLowにしてポートのプルアップを有効にする。
(2)WPUAレジスタをPORTAレジスタのように使用しビット操作する。

以下のプログラムは入力ポートのみで構成したブートローダーで、赤文字の部分が従来からの変更点です。ブートローダーとしての動作を確認しています。

注意.OPTION_REGレジスタの操作を送信サブルーチンの外で行うと信号レベルが変化して正常に作動しません。




<ソースプログラム>

radix DEC
LIST P=PIC10F322
xtal EQU 8000000 ; you may also want to change: _HS_OSC _XT_OSC
baud EQU 9600 ; standard TinyBld baud rates: 115200 or 19200
; The above 3 lines can be changed and buid a bootloader for the desired frequency (and PIC type)

;********************************************************************
; Tiny Bootloader 10F322 Size=100words
; claudiu.chiculita@ugal.ro
; http://www.etc.ugal.ro/cchiculita/software/picbootloader.htm
;********************************************************************
#include "../icdpictypes.inc" ;takes care of: #include "p16fxxxA.inc", max_flash, IdTypePIC
; #include "../spbrgselect.inc"
; #include "../bankswitch.inc"

#define first_address max_flash-100 ; 100 word in size

__CONFIG _FOSC_INTOSC & _BOREN_OFF & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _LVP_OFF & _LPBOR_OFF & _BORV_HI & _WRT_OFF

#define TX 2 ;RS-232C データ出力用ポート
#define RX 3 ;RS-232C データ入力用ポート
#define Direct_TX ;RS-232C直結方式、コメントアウトで反転方式
#define Direct_RX ;RS-232C直結方式、コメントアウトで反転方式

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;注意)
; TXとして選択可能なPORTAのビットは、0,1,2,3のいずれか
; RXとして選択可能なPORTAのビットは、0,1,2,3のいずれか
;
; 直結方式とは、抵抗やレベル変換ICを用いてシリアルポートとPICを接続する方法
; 反転方式とは、MAX232を使用した場合のように専用のレベル変換ICを用いてシリアルポートとPICを接続する方法
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; errorlevel 1, -305 ; suppress warning msg that takes f as default

cblock 0x40
buffer:32
endc

cblock 0x7D
crc ;0x7D
rs ;0x7E
rxd ;0x7F
endc

;btime equ 53h ;9600bps 10MHz 時のウエイトタイム
btime equ 42h ;9600bps 8MHz 時のウエイトタイム
;btime equ 1fh ;9600bps 4MHz 時のウエイトタイム
;btime equ 28h ;19200bps 10MHz 時のウエイトタイム
;btime equ 0eh ;19200bps 4MHz 時のウエイトタイム

User_Program equ 0x0001 ;ブートローダーの出口

SendL macro car
movlw car
call rs1tx
endm

;0000000000000000000000000 RESET 00000000000000000000000000

org 0x0000
goto IntrareBootloader
;view with TabSize=4

;&&&&&&&&&&&&&&&&&&&&&&& START &&&&&&&&&&&&&&&&&
;---------------------- Bootloader ----------------------
;
;PC_flash: C1h AddrH AddrL nr ...(DataLo DataHi)... crc
;PIC_response: id K K

org first_address
; nop
; nop
; nop
; nop

org first_address+4
IntrareBootloader
;init int clock & serial port
clrf ANSELA ;digital I/O
comf T2CON,F ;TMR2=ON,PRE=1:64,POST=1:16
; bcf TRISA,TX ;TXポートをセット
;wait for computer
call Receive
sublw 0xC1 ;Expect C1
skpz
goto way_to_exit
SendL IdTypePIC ;PIC type
; SendL IdSoftVer ;firmware ver x

MainLoop
SendL 'K'
mainl
clrf crc ;clear checksum
call Receive ;get PMADRH
movwf PMADRH
call Receive ;get PMADRL
movwf PMADRL

call Receive ;get count
movlw buffer ;FSR=Buffer_Top
movwf FSR
rcvoct
call Receive ;get data
movwf INDF
incf FSR,f
btfss FSR,5 ;FSR=Buffer_Top+0x20=0x60?
goto rcvoct

call Receive ;get checksum
skpz
goto ziieroare

call wr_e ;erase operation
;write
bcf FSR,5 ;FSR=0x60-0x20=0x40=Buffer_Top
writeloop ;write 2 bytes = 1 instruction
movf INDF,w ;L
incf FSR,f
movwf PMDATL
movf INDF,w ;H
incf FSR,f
movwf PMDATH
call wr_w ;write operation
incf PMADRL,f ;does not cross zones
btfss FSR,5 ;FSR=Buffer_Top+0x20=0x60?
goto writeloop
goto MainLoop

ziieroare
SendL 'N'
goto mainl
Receive
clrf TMR2
bcf PIR1,TMR2IF
rptc
#ifdef Direct_RX
btfss PORTA,RX
#else
btfsc PORTA,RX
#endif
goto loop ;STARTビットが未検出ならループ
r1rx11
call bwait2 ;1/2ビット分待つ
movlw B'10000000' ;rxd=B'10000000'
movwf rxd
r1rx12
call bwait ;1ビット分待つ
bcf STATUS,C ;
#ifdef Direct_RX
btfss PORTA,RX
#else
btfsc PORTA,RX
#endif
bsf STATUS,C ;
rrf rxd,f ;Carry=0->0->0->0->0->0->0->1
btfss STATUS,C ;Carry=1 ?
goto r1rx12 ;Carry=0ならループ
call bwait2 ;1/2ビット分待つ
call bwait ;1ビット分待つ(STOPビット)
movf rxd,W ;W=rxd
addwf crc,f ;compute checksum
return
loop
btfss PIR1,TMR2IF
goto rptc
way_to_exit
goto User_Program ;timeout:exit in all other cases

;*************************************************************
;
; フラッシュデータメモリー操作サブルーチン
;
; wr_e :PMADRで指定したアドレスを含む16ワード境界のデータブロック
; (16ワード)を消去する。
; 例.PMADRH:PMADRL=0x0137のとき、0x0130~0x013Fを消去
;
; wr_w :PMADRで指定したアドレスのデータを書き込む。
; 書き込むデータはPMDATに予めセットしておく。
;
; ********************************************************************

wr_e
bsf PMCON1,FREE
wr_w
bsf PMCON1,WREN
movlw 0x55
movwf PMCON2
movlw 0xaa
movwf PMCON2
bsf PMCON1,WR ;WR=1
nop
nop
clrf PMCON1 ;CFGS=0 LWLO=0 FREE=0 WREN=0
ret00
return

; ********************************************************************
;
; RS-232C 1文字送信
;
; 送信文字を W にセットして呼ぶ
;
; ********************************************************************

rs1tx movwf rxd ;rxd=W
bcf OPTION_REG,7
#ifdef Direct_TX
; bsf PORTA,TX ;スタートビット:TX=1
bsf WPUA,TX

call bwait ;1ビット分待つ
bsf STATUS,C ;Carry=1
r1tx11 rrf rxd,f ;Bit Output
btfss STATUS,C ;
; bsf PORTA,TX ;
bsf WPUA,TX

btfsc STATUS,C ;
; bcf PORTA,TX ;
bcf WPUA,TX

call bwait ;1ビット分待つ
bcf STATUS,C ;Carry=0
decfsz rxd,W ;8ビット送信したか?
goto r1tx11 ;
; bcf PORTA,TX ;ストップビット:TX=0
bcf WPUA,TX

#else
; bcf PORTA,TX ;スタートビット:TX=0
bcf WPUA,TX

call bwait ;1ビット分待つ
bsf STATUS,C ;Carry=1
r1tx11 rrf rxd,f ;Bit Output
btfss STATUS,C ;
; bcf PORTA,TX ;
bcf WPUA,TX

btfsc STATUS,C ;
; bsf PORTA,TX ;
bsf WPUA,TX

call bwait ;1ビット分待つ
bcf STATUS,C ;Carry=0
decfsz rxd,W ;8ビット送信したか?
goto r1tx11 ;
; bsf PORTA,TX ;ストップビット:TX=1
bsf WPUA,TX

#endif
bwait ;1ビットのウエイトを作る
call bwait2 ;1 us total:1+49+49=99 us

bwait2 ;1/2ビットのウエイトを作る
movlw btime/2-2 ;0.5 us
movwf rs ;0.5 us
decfsz rs,f ;0.5 us
goto $-1 ;1 us
goto ret00 ;1 us total:0.5+0.5+(0.5+1)*(33-2)-0.5+1+1=49 us

; ********************************************************************
; After reset
; Do not expect the memory to be zero,
; Do not expect registers to be initialised like in catalog.

end
   






























.