Function: PIC16F648A Tiny Monitor Processor: PIC16F648A at 20 MHz using external HS oscillator Hardware: http://www.geocities.jp/jk1brk/misc/pic/pic16f648a.pdf Filename: PicMonV6.asm Author: jk1brk Website: http://www.geocities.jp/jk1brk/ Credit: Notes: USARTによる RS232 PIC16F648A 20MHz@ 115200,8,N,1 DIP-SW 2,6,8-ON Ref. Doc.: http://ww1.microchip.com/downloads/en/appnotes/00547c.pdf Last Upadte: '0701222 File required:monmacro.inc Remarks: Copyright 2004 Tsurumi Keiichi このファイルを 'include' する時は末尾の end を削除してファイル名の拡張子を.incに 変更する PIC16F84と比較して EEROM関連のSFR レジスタの番地が異なっています BANK0 BANK1 EEDATA:9AH EEADR:9BH コマンド SRAM 読み / 書き Mwwww SRAM 0x0000~0x007f, 0x0080~0x00ff 0x0100~0x017f, 0x0180~0x01ff EEPROM 読み / 書き Ewwww EEPROM 0x0000~0x00cf(0x2100 ~0x21cf) サブルーチン実行 Gwwww SRAM ダンプ Dwwww,bb wwww=16 ビットアドレス bb= サイズ (8 ビット ) LIST P=16F648A, ST=OFF, R=DEC, F=INHX8M, N=130 Use the PIC16F648A and decimal system INCLUDE P16F648A.INC Include header file ERRORLEVEL -207,-302,-306 suppress message 207, 302, 306 from list file CONFIG _CP_OFF & _DATA_CP_OFF & _LVP_OFF & _BOREN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC #include <MonMacro.inc> Macroの定義 #define BANK0 #define BANK1 #define READY BCF STATUS, RP0 BSF STATUS, RP0 RXREG,0 #define ClkFreq 20000000 input clock frequency = 20 MHz #define X 115200 9600bps up to 115200bps #define baud(x) ((10*ClkFreq/(16*X))+5)/10-1 非同期 / 高速 prog_add equ 0x150 テストプログラム開始アドレス レジスタ ファイル : ワークエリア org 0x0070 レジスタ退避 wtemp res 1 W レジスタ退避 ( テストプログラム実行後の値 ) 0x70 statustemp res 1 Status レジスタ退避 ( テストプログラム実行後の値 ) 0x71 pclathtemp res 1 0x73 fsrtemp res 1 FSR レジスタ退避 ( テストプログラム実行後の値 ) 0x74 ch res 1 送信受信データ (8 ビット ) hexh res 1 16 進入出力ハイバイト 0x76 hexl res 1,, ローバイト 0x77 datatemp res 1 バイトデータ一時保管 bcnt res 1 バイト カウント ccnt res 1 コラム カウント WorkRamEnd res 0 Program Start! org 0x00 CLRF STATUS CLRF FSR GOTO INITIALIZE ISR not in use org 0x04 goto IntSvc 割込みサービス org 0x05 INITIALIZE 1
BANK1 MOVLW b'00000111' PIC16F648A独自 MOVWF CMCON コンパレータ OFF BCF INTCON,PEIE 周辺割り込み OFF PIC16F648A独自 MOVLW B'00000010' RB2/TX, RB1/RX PIC16F648A独自 MOVWF TRISB MOVLW B'00000000' PORTA Output MOVWF TRISA BANK0 MOVLW B'00000100' TX初期化 MOVWF PORTB Initialization Asynchronous Transmitter/Receiver ============================================================== BANK1 MOVLW baud(x) ((10*ClkFreq/(16*X))+5)/10-1 非同期 / 高速 MOVWF SPBRG MOVLW B'00100100' TX9 = 8ビット送信 TXEN = 送信許可 BRGH = 非同期 / 高速 MOVWF TXSTA 送信レジスタの初期設定 BANK0 MOVLW B'10010000' SPEN = シリアルポート許可 RX9 = 8ビット受信 CREN = 連続受信許可 MOVWF RCSTA 受信レジスタの初期設定 INT_UART_ERR MOVF RCREG,W ダミーリード MOVF RCSTA,W ANDLW B'00000110' BTFSS STATUS, Z GOTO INT_UART_ERR ============================================================== MOVLW B'00000000' 周辺機能の割り込みフラグビットクリア MOVWF PIR1 clrf clrf clrf statustemp pclathtemp fsrtemp ターゲットプログラム call Init ターゲットプログラムの初期化 モニタ コマンド待ち call receive 1バイト受信 ( ch= 受信データ ) 1バイト送信 RS232C 送信サブルーチン transmit BCF INTCON,GIE グローバル割込み禁止 MOVF ch,w BTFSS PIR1,TXIF GOTO $-1 MOVWF TXREG MOVWF ch BSF INTCON,GIE グローバル割込み許可 RETURN RS232C 受信サブルーチン receive BTFSS PIR1,RCIF GOTO $-1 BCF INTCON,GIE グローバル割込み禁止 MOVF RCREG,W MOVWF ch BCF PIR1,RCIF BSF INTCON,GIE グローバル割込み許可 RETURN モニタ コマンド待ち Mprompt call sendscr CR movlw '*' 2
call toupper movlw 'M' jnz Mnlpm1 goto MnMcmd 'M' ならば SRAMの読み書き Mnlpm1 movlw 'E' jnz Mnlpm2 goto MnEcmd 'E' ならば EEPROMの読み書き Mnlpm2 movlw 'G' jnz Mnlpm3 goto MnGcmd 'G' ならばサブルーチンを実行 Mnlpm3 movlw 'D' jnz Mprompt goto MnDcmd 'D' ならばメモリダンプ コマンド 'M' SRAM 読み書き スペースで変更 'Enter' で次のアドレス ' /' で前のアドレス MnMcmd call get4hex 4桁アドレス値の入力 call receive movlw 0dh 'Enter' が打たれたら実行 jnz Mprompt MnM01 call sendscr CR送信 MnM02 call send4hex アドレスの表示 16進 4桁 hexh/hexl movlw 0x20 スペース movwf FSR movf INDF,W call send2hex メモリ内容の表示 16進二桁 movlw 0dh jz MnMnx 'Enter' なら次のアドレス movlw '/' jz MnMpr '/' なら前のアドレス movlw 20h jz MnMwr スペースなら変更 内容の変更 MnMwr call get2hex 16進二桁を入力 movwf INDF MnMnx incf hexl,f アドレスをインクリメント MnMbk call sendscr goto MnM02 アドレスをデクリメント MnMpr decf hexl,f goto MnMbk コマンド 'E' EEPROMの読書き スペースで変更 'Enter' で次のアドレス ' /' で前のアドレス MnEcmd call get4hex hexh/hexlへ 4桁アドレス値の入力 call receive movlw 0dh jz MnE01 MnE01 call sendscr MnE02 call send4hex アドレスの表示 movlw 0x20 スペース call rdeedt 3
call send2hex EEPROM内容の表示 16進二桁 movlw 0dh jz MnEnx 'Enter' なら次のアドレス movlw '/' jz MnEpr '/' なら前のアドレス movlw 20h jz MnEwr スペースなら変更 MnEnx incf hexl,f アドレスをインクリメント MnEbk call sendscr goto MnE02 MnEpr decf hexl,f アドレスをデクリメント goto MnEbk EEPROM 内容の変更 for PIC16F6xxA MnEwr call get2hex 16進二桁を入力 call enabee 書き込み許可 BANK1 ページ 1 movwf EEADR BANK0 ページ 0 call wreedt 書込み call disee 書込み禁止 goto MnEnx EEPROM 一バイト リード (7 サイクル ) for PIC16F6xxA アドレスを Wレジスタに入れてコール リードデータは Wレジスタ rdeedt BANK1 ページ 1 movwf EEADR bsf EECON1,RD movf EEDATA,W BANK0 ページ 0 EEPROM 一バイト ライト for PIC16F6xxA コール時 : アドレスを EEADR, データを Wレジスタにセット 前もって enabeeを実行 終了後は diseeを実行しておく wreedt BANK1 ページ 1 movwf EEDATA movlw 0x55 movwf EECON2 movlw 0xaa movwf EECON2 bsf EECON1,WR ewrend btfsc EECON1,WR 書込み終了待ち goto ewrend bcf EECON1,EEIF BABK0 ページ 0 EEPROM 書き込み許可 enabee BANK1 ページ 1 bsf EECON1,WREN 書き込みを許可 BANK0 ページ 0 EEPROM 書込み禁止 disee BANK1 ページ 1 bcf EECON1,WREN 書込みを禁止 BANK0 ページ 0 コマンド 'G' サブルーチンを実行 MnGcmd call get4hex 16進四桁を入力 hexh, hexlに保管 movlw 0dh 'Enter' が打たれたら実行 jnz Mprompt 4
MnG01 clrf STATUS Bank 0を選択 movf fsrtemp,0 FSRレジスタを復帰 movwf FSR C:\Program Files\Microchip\PIC mechatro\picmonv6.asm call gotarget 次のアドレスを push ターケ ットアドレスへシ ャンフ サブルーチンからの復帰で次行からが実行される movwf wtemp Wレジスタ保存 movf STATUS,0 Statusレジスタをリード clrf STATUS Bank 0を選択 movwf statustemp Statusレジスタを保存 movf FSR,0 FSRレジスタをリード movwf fsrtemp FSRレジスタを保存 モニタ コマンド待ち ターゲットアドレスへジャンプ gotarget movf hexh,0 PCLATHにアドレス上位バイトをセット movwf PCLATH movf statustemp,0 Statusレジスタ復帰 Zは影響受ける movwf STATUS movf hexl,0 ターケ ットアドレス下位ハ イトを Wレジスタへ movwf PCL Wレシズタを pclに移動してターケ ットシ ャンフ コマンド 'D' SRAM ダンプ 'Dwwww,bb' wwww=16 ビットアドレス bb= バイト数 MnDcmd call get4hex helh/hexlへ 4桁アドレス値の入力 movlw '0' subwf ch,w ch - W btfsc STATUS,C skip if minus call get2hex datatempへ二桁のバイト数を入力 バイト カウント bcntへ移動 movwf bcnt MnDS02 movlw.8 コラムカウンタを 8 movwf ccnt call sendscr call send4hex アドレスの表示 MnDS01 movlw 0x20 スペース movwf FSR movf INDF,W call send2hex メモリ内容の表示 (16 進二桁 ) incf hexl,f djnz bcnt,mndscnt バイト カウントが 0ならば終了 MnDScnt djnz ccnt,mnds01 goto MnDS02 Other Subroutines 16 進二桁の入力 エコーバック付 get2hex 上位桁を一文字入力 get2hx1 call toupper 大文字に変換 call hextobin 上位桁 16進文字 ->2進 movf ch,w swapf datatemp,f rdatatempの上 4ヒ ットに 16進上位桁を保管 下位桁を一文字入力 call toupper call hextobin 下位桁 16進文字 ->2進 movf ch,w iorwf datatemp,f hexh, hexlへ 16進四桁の入力 get4hex call get2hex movwf hexh call get2hex movwf hexl 5
キャリッジリターン ラインフィードを送出 sendscr movlw 0x0d movlw 0x0a goto transmit C:\Program Files\Microchip\PIC mechatro\picmonv6.asm insecho call receive エコーバック付一文字受信 goto transmit hexh/hexlを 16進四桁で送出 send4hex movf hexh,w call send2hex 16 進二桁送出 send2hex swapf ch,f movlw 0x0f andwf ch,f call hexs1 movlw 0x0f andwf ch,f hexs1 movlw.9 ^ 0xff addwf ch,w btfsc STATUS,C goto abv9 hexs12 movlw 0x30 addwf ch,f abv9 movlw.7 addwf ch,f goto hexs12 小文字 -> 大文字変換 toupper movlw 'a' subwf ch,w ch - W btfss STATUS,C skip if plus or equal goto toup1 movlw 'a' - 'A' subwf ch,f toup1 chの 16進文字を二進数に変換 hextobin movlw '9' ^ 0xff addwf ch,w btfsc STATUS,C goto hextob2 hextob1 movlw '0' subwf ch,f hextob2 movlw.7 subwf ch,f goto hextob1 テストプログラム org prog_add テストプログラムの開始アドレス Test1 movlw.10 movwf bcnt Test2 movlw.10 addwf bcnt,f call sendscr movf 0x30,W SRAM 30H のASCII コードを TX tstlp djnz bcnt,tstlp movf 0x31,W SRAM 31Hのデータを Wに持ってリターン 6
initialize eeprom locations ORG 0x2100 DE "C","o","p","y","r","i","g","h","t"," " DE "b","y"," " DE "J","K","1","B","R","K" end 7