;　　　　　　プログラム名　　　AMS.asm
;
;muRata製の圧電振動ジャイロを使用した角速度センサー ENC-03J を組み込んだ
;共立電子産業製の圧電振動ジャイロ基板 SK-GYRO から出力される直流電圧を読み出し、
;ＲＳ－２３２Ｃ経由でパソコンにそのデータを送信するプログラムである。
;
;Ａ／Ｄ変換値が精密なほど結構なので、１０ビットのＡＤ変換器を有する
;PIC16C873 を用いることにした。
;都合がよいことに、この素子にはＲＳ－２３２Ｃ専用端子もある。
;
;開発開始　２０００年６月７日　　　　　　　　　　金野
;
;
;パソコン側からの開始指令で本装置は動作を開始し、;
;　　開始指令として、１バイトの”１”の数値がシリアルポートに入力する
;
;パソコン側からの停止指令で動作を一時停止する。　この部分は未だできていない
;　　停止指令として、１バイトの”２”の数値がシリアルポートに入力する
;
;
;******************************************************************************************
;
     LIST P=PIC16F873               ;使用するプロセッサの種類を指定する
     #INCLUDE "P16F873.INC"         ;上記のプロセッサ用インクルードファイルを呼び出し、結合する

;PIC本体の初期設定
     __CONFIG  _WDT_OFF & _XT_OSC & _BODEN_OFF & _LVP_OFF
                               ;ウオッチドックタイマーはオフ
                               ;発信はクリスタル方式
                               ;ブラウンアウトはオンにし、規定電圧以下ではリセットがかかる
                               ;低電圧プログラミングはオフ
;*********************************
;使用する変数の定義
   CBLOCK h'0020'
      low8bit   ;ＡＤ変換値の低位８ビットが入る
      hig2bit   ;ＡＤ変換値の高位２ビットが入る８ビット変数。上位６ビットは０
      temp0     ;カウンター用変数
      temp1     ;カウンター用変数
      recdata   ;受信した１データの入る変数

   ENDC

;*********************************
;使用端子に名称を定義する
  #define   Ledmonitor  PORTC,2  ;ＲＣ２端子に名称を与える

;*********************************
;使用する定数の定義
timecon0  equ   50           ;時間間隔設定用定数その０
timecon1  equ   54           ;時間間隔設定用定数その１
com_start equ   b'00110001'  ;”１”のアスキーコード。スタート指令として使用する
com_stop  equ   b'00110010'  ;”２”のアスキーコード。ストップ指令として使用する

;*******************************************************************************************

      org      0               ;
      goto     start           ;

;*********************************
;割込処理
;　ＲＸ端子にデータが届くと割込が発生する。ここではそのデータを取り込み、処理をし、
;　測定データの送信処理に行くようにする
;
      org      4               ;
handler
      bcf     INTCON,GIE     ;割込がかかったので、以後の割込を禁止する。
   ;ＲＸポートからデータを取り込む処理を書く
      movf    RCREG,0        ;受信したデータが納められているレジスタの内容を
      movwf   recdata        ;Ｗレジスタに取り込み、recdata に入れる
;      movwf   PORTB          ;モニター出力
;      bsf     Ledmonitor
;loop1 nop                    ;エンドレスループ
;      goto loop1

      bcf    RCSTA,CREN      ;クリアしておいた方がよい
   ;受信したデータの内容で処理を分岐させる
      ;スタート記号”１”の時、測定を開始し、データの連続送信に移る
      movlw  com_start     ;受信データの識別を行う
      subwf  recdata,0     ;recdata-com_start を計算する
      btfsc  STATUS,Z      ;結果がゼロの時にのみ、Ｚ＝１となる。その時recdata=com_start
      goto   startwait1    ;なので、測定を開始し、データの連続送信の処理に行く。    
                           ;recdata<>com_start の時は、次の識別を行う

      ;”２”の時、測定を中止し、初期状態に戻らせる

        bsf   Ledmonitor   ; 
loop4   nop
        goto  loop4        ;コード比較が失敗したときには、エンドレスとしておく
;       return

;*********************************
;スタート
start

  ;割込条件を設定する。電源オン後、待機状態としておき、ＲＳ／２３２Ｃポートに信号が入った
  ;時に割込を起こし、それにより、こちらからのデータの送信を開始する
  ;（１）ＲＸポートに信号が入ったら、このプログラムを実行させる。それまでは待機状態とする
     ;全体として割込を受け付ける状態とする
     ;ＲＳ－２３２Ｃ割込はペリフェラル割込である
      movlw   b'11000000'   ;INTCON=(GIE,PEIE,T0IE,INTE,RBIE,T0IF,INTF,RBIF)
      movwf   INTCON        ;  GIE  全ての割込    　　　　　=1　許可　=0　不可
                            ; PEIE　全てのペリフェラル割込　=1　許可　=0  不可

;*********************************
    ;各ポート初期設定
    ;　ポートＡ　ＲＡ０のみアナログ入力ＡＮ０として使用、他は未使用
    ;　ポートＢ　ＲＢ０～ＲＢ７を出力端子と設定。１０ビットＤＡの下位８ビットを出力　
    ;　ポートＣ　ＲＣ０とＲＣ１は出力端子と設定。１０ビットＤＡの上位２ビットを出力　 
    ;　　　　　　ＲＣ２は出力端子として使用し、モニター用ＬＥＤをドライブする
    ;　　　　　　ＲＣ６はＲＳ－２３２の出力端子ＴＸとして使用する
    ;　　　　　　ＲＣ７はＲＳ－２３２の入力端子ＲＸとして使用する　

      bcf     STATUS,RP0   ;
      bcf     STATUS,RP1   ;この２つで、バンク０を選定
      clrf    PORTA        ;
      clrf    PORTB        ;
      clrf    PORTC        ;

      bsf     STATUS,RP0   ;バンク１に移す
      movlw   b'00000011'  ;ポートＡのＲＡ０のみアナログ入力ＡＮ０、
      movwf   TRISA        ;　　　　　ＲＡ１はデジタル入力端子、残りは出力端子にしておく
      movlw   b'00000000'  ;
      movwf   TRISB        ;ポートＢは全て出力端子
      movlw   b'10000000'  ;
      movwf   TRISC        ;ポートＣはＲＣ７（ＲＸ　入力）以外は出力端子としておく
      bcf     STATUS,RP0   ;バンク０に戻す 
   ;
    ;ＲＡ０／ＡＮ０端子のアナログ入力端子としての設定
      bsf     STATUS,RP0   ;バンク１に移る
      movlw   b'10001110'  ;b7=1  １０ビットＡＤ変換結果の収まる ADRESH の高位６ビットを０とする
                           ;　　　１０ビットデータを２バイトに右揃えする　
      movwf   ADCON1       ;b3-b0 で
                           ;ＲＡ０のみアナログ入力端子、他の端子はデジタル端子、
                           ;参照正電圧は電源電圧、参照負電圧は電源アース電位、と設定。
      bcf     STATUS,RP0   ;バンク０に戻しておく
    ;ＡＤ変換器の初期設定
                           ;ADCON0=(ADCS1,ADCS0,CHS2,CHS1,CHS0,GO/DONE,-,ADON)
      bsf     ADCON0,ADCS1 ;  (ADCS1,ADCS0)=(1,0)　クロック１０ＭＨｚのとき使用できる組み合わせ。
      bcf     ADCON0,ADCS0 ;   この２つで、ＡＤ変換クロックを基準クロックの３２分の１とする
      bcf     ADCON0,CHS2  ;  (CHS2,CHS1,CHS0)=(0,0,0) で、ＲＡ０／ＡＮ０端子の入力電圧をＡＤ変換する
      bcf     ADCON0,CHS1  ;  GO/DONE  ADON=1 の時、=1 ならば、ＡＤ変換中、 =0 ならば、変換中ではない
      bcf     ADCON0,CHS0  ;           ＡＤ変換が完了すると、このビットは自動的に０となる
                           ;  ADON     =1 の時、ＡＤ変換器をオンとする、 =0 の時、ＡＤ変換器をオフする
                           ;従って、以降でＡＤ変換を行うには　ADON=1 とし、GO/DONE が０になるまで待機
                           ;させ、GO/DONE が０になったら、ADRESL とADRESHからデータを読み出せばよい。 

    ;ＲＣ６／ＴＸ、ＲＣ７／ＲＸ端子のＲＳ－２３２端子としての設定
    ;まづ、通信は、データ８ビットの非同期通信方式とし、常時送受信可能としておく
      bsf     STATUS,RP0   ;バンク１に移る
                           ;TXSTA=(CSRC,TX9,TXEN,SYNC,-,BRGH,TRMT,TX9D)
                           ;  CSRC   クロック源選択ビット。非同期通信では気にする必要がない
      bcf     TXSTA,TX9    ;  TX9 =1 ９ビットデータ送信 =0 ８ビットデータ送信
      bsf     TXSTA,TXEN   ;  TXEN=1 送信可能           =0 送信不可
      bcf     TXSTA,BRGH   ;  BRGH   非同期通信でのボーレート程度の設定 =1 高速 = 低速

      movlw   7            ;クロックが１０ＭＨｚの時、BRGH=0 として、１０進数の７を SPBRG に代入すると
      movwf   SPBRG        ;ボーレートは１９２００となる。
      bcf     TXSTA,SYNC   ;非同期モードを選択
      bsf     PIE1,RCIE    ;受信割込を可とする
      bcf     STATUS,RP0   ;バンク０に戻しておく
      bsf     RCSTA,SPEN   ;端子をシリアルポートとして設定
      bsf     RCSTA,CREN   ; 受信を可とする
  
;**********************************
;各ポートの設定が終わったら、ＲＳ－２３２Ｃポートにスタートデータ”１”が送られてくるまで待機させる
recwait  nop                ;エンドレスループ。シリアルポートにデータが届くまで待機状態とし、
         goto    recwait    ;データが届いたらループを抜け出し、割込処理に移る

;測定実行　当面の課題
;　　　　　　定時間毎にアナログ入力をサンプリングし、それを１０ビットＤＡモニター出力する。
;　　　　　　これをエンドレスで繰り返させる　 

startwait1  ;パソコンからスタート信号を受信したときに実行する

         bsf     ADCON0,ADON     ;ＡＤ変換器をオンとする
repeat
         bsf     Ledmonitor      ;モニターＬＥＤ点灯
                                 ;注意　この端子は送信データの高位バイトの第３ビットと兼用になっている。
                                 ;      高位バイトの第３ビットは常に０なので、高位バイトが送信された
                                 ;　　　ＬＥＤは消灯する。
         call    wait

         bsf     ADCON0,GO       ;ＡＤ変換を開始させる
adloop   btfsc   ADCON0,GO       ;GO/DONE が０になるまで待機
         goto    adloop          ;ＡＤ変換が完了すると０となる

         movf    ADRESH,0        ;ＡＤ変換結果の高位２ビットを
         movwf   hig2bit         ;hig2bit に代入し、保存
         movwf   PORTC           ;Ｒ－２Ｒ式ＤＡ変換器に高位２ビットのデータを送出

         bsf     STATUS,RP0      ;バンク１に移る
         movf    ADRESL,0        ;ＡＤ変換結果の低位８ビットを
         bcf     STATUS,RP0      ;
         movwf   low8bit         ;low8bit に代入し、保存
         movwf   PORTB           ;Ｒ－２Ｒ式ＤＡ変換器に低位８ビットのデータを送出

   ;ＲＳ－２３２Ｃ送信
   ;  最初に高位バイト、続いて低位バイトを順次送信する
         movf    hig2bit,0       ;高位２ビットのデータをＷに取り込み、
         movwf   TXREG           ;送信用レジスタに入れる
         bsf     STATUS,RP0      ;バンク１に移る
         bsf     TXSTA,TXEN      ;送信を可とする
         bcf     STATUS,RP0
RSwait1  btfss   PIR1,TXIF       ;TXSTA が空になるまで待機。１データの転送完了待ち
         goto    RSwait1         ;空になると、TXIF=1 となる

         call    wait

         movf    low8bit,0       ;低位８ビットのデータをＷに取り込み、
         movwf   TXREG           ;
         bsf     STATUS,RP0      ;
         bsf     TXSTA,TXEN      ;
         bcf     STATUS,RP0      ;
RSwait2  btfss   PIR1,TXIF       ;
         goto    RSwait2         ;       
         

         bcf     Ledmonitor      ;モニターＬＥＤ消灯
         call    wait

         goto    repeat

;**********************************************
;サンプリング時間の設定　　当初は、約１0.0ｍ秒ごとに、サンプリングさせることにする
wait
         movlw   timecon0        ;定数値を取り込む
         movwf   temp0           ;temp0 に定数timecon0 の値を代入
         movlw   timecon1        ;
         movwf   temp1           ;
delay0   decfsz  temp1,1         ;
         goto    delay0
         movlw   timecon1
         movwf   temp1
         decfsz  temp0,1         ;temp0 をー１する
         goto    delay0 

         return

      end

;******************************************************************************************





