;　　　　　　プログラム名　　　Grad_xy
;
;ＡＮＡＬＯＧ　ＤＥＶＩＣＥＳ社製の２軸加速度センサＡＤＸＬ２０２を利用して
;計測される加速度値をＲＳ－２３２Ｃ経由でパソコンにそのデータを送信する
;プログラムである。
;ＡＤＸＬ２０２は加速度センサというより、傾斜センサと呼んだ方がよい。
;
;本システムの概要
;　　本センサを持ったハード部で、その傾斜角度を関知し、パソコンにそのデータを送信する。
;　　パソコン画面上に、その傾斜度に比例した位置にスポットを描写し続ける。
;　　傾斜が変化すれば、それに従ってスポットも移動する。
;
;なを、母プログラムは角速度センサーのアセンブラプログラムである。
;
;
;Ａ／Ｄ変換値が精密なほど結構なので、１０ビットのＡＤ変換器を有する
;ＰＩＣ１６Ｆ８７３ を用いることにした。
;都合がよいことに、この素子にはＲＳ－２３２Ｃ専用端子もある。
;
;開発開始　２００１年３月１３日　　　　　　　　　　金野
;　　Ｘ軸加速度値、Ｙ軸加速度値を交互に計測し、送信させる。
;
;パソコン側からの開始指令で本装置は動作を開始し、;
;　　開始指令として、１バイトの”１”の数値がシリアルポートに入力する
;
;パソコン側からの停止指令で動作を一時停止する。　
;　　停止指令として、１バイトの”２”の数値がシリアルポートに入力する
;
;一定時間間隔（５０ｍ秒毎とする）に、ＡＮ０、ＡＮ１、ＡＮ０，ＡＮ１、・・・の順でサンプリングし、
;送信する。エンドレスである。
;
;******************************************************************************************
;
     LIST P=PIC16F873               ;使用するプロセッサの種類を指定する
     #INCLUDE "P16F873.INC"         ;上記のプロセッサ用インクルードファイルを呼び出し、結合する

;PIC本体の初期設定
     __CONFIG  _WDT_OFF & _XT_OSC & _BODEN_OFF & _LVP_OFF
                               ;ウオッチドックタイマーはオフ
                               ;発信はクリスタル方式
                               ;ブラウンアウトはオンにし、規定電圧以下ではリセットがかかる
                               ;低電圧プログラミングはオフ
;*********************************
;使用する変数の定義
   CBLOCK h'0020'
      low8bit   ;ＡＤ変換値の低位８ビットが入る
      hig2bit   ;ＡＤ変換値の高位２ビットが入る８ビット変数。上位６ビットは０
      temp0     ;カウンター用変数
      temp1     ;カウンター用変数
      temp3     ;カウンター用変数
      recdata   ;受信した１データの入る変数

   ENDC

;*********************************
;使用端子に名称を定義する
  #define   Ledmonitor  PORTC,2  ;ＲＣ２端子に名称を与える

;*********************************
;使用する定数の定義
timecon0  equ   250  ;50     ;時間間隔設定用定数その０  50 の時、１０ｍ秒
timecon1  equ   54           ;時間間隔設定用定数その１
com_start equ   b'00110001'  ;”１”のアスキーコード。スタート指令として使用する
com_stop  equ   b'00110010'  ;”２”のアスキーコード。ストップ指令として使用する

;*******************************************************************************************

         org      0               ;
         goto     start           ;

;*********************************
;割込処理
;　ＲＸ端子にデータが届くと割込が発生する。ここではそのデータを取り込み、処理をし、
;　測定データの送信処理に行くようにする
;
         org      4               ;
handler
   ;ＲＸポートからデータを取り込む処理を書く
         movf    RCREG,0        ;受信したデータが納められているレジスタの内容を
         movwf   recdata        ;Ｗレジスタに取り込み、recdata に入れる

   ;受信したデータの内容で処理を分岐させる
      ;スタート記号”１”の時、測定を開始し、データの連続送信に移る
         movlw  com_start     ;受信データの識別を行う
         subwf  recdata,0     ;recdata-com_start を計算する
         btfsc  STATUS,Z      ;結果がゼロの時にのみ、Ｚ＝１となる。その時recdata=com_start
         goto   startwait1    ;なので、測定を開始し、データの連続送信の処理に行く。    
                              ;recdata<>com_start の時は、次の識別を行う
      ;”２”の時、測定を中止し、初期状態に戻らせる
         movlw  com_stop      ;受信データの識別を行う
         subwf  recdata,0     ;recdata-com_stop を計算する
         btfsc  STATUS,Z      ;結果がゼロの時にのみ、Ｚ＝１となる。その時recdata=com_stop
         goto   start         ;なので、測定を終了し、初期状態に戻らせる。    

         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'00001111'  ;ポートＡのＲＡ０，ＲＡ１，ＲＡ２，ＲＡ３を入力端子に指定
      movwf   TRISA        ;　　　　　　　　　　　　　　　　　　残りは出力端子にしておく
      movlw   b'00000000'  ;
      movwf   TRISB        ;ポートＢは全て出力端子
      movlw   b'10000000'  ;
      movwf   TRISC        ;ポートＣはＲＣ７（ＲＸ　入力）以外は出力端子としておく
      bcf     STATUS,RP0   ;バンク０に戻す 
   ;
    ;ＡＮ０、ＡＮ１端子のアナログ入力端子、Ｖｒｅｆ－、Ｖｒｅｆ＋としての設定
      bsf     STATUS,RP0   ;バンク１に移る
      movlw   b'10001101'  ;b7=1  １０ビットＡＤ変換結果の収まる ADRESH の高位６ビットを０とする
                           ;　　　１０ビットデータを２バイトに右揃えする　
                           ;b3=1,b2=1,b1=0,b0=1で アナログ入力端子ＡＮ０、ＡＮ１を使用可、
      movwf   ADCON1       ;Vref+,Vref- の参照電圧を使用可とする
                           ;
      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,0or1) で、ＡＮ０ or ＡＮ１端子の入力電圧をＡＤ変換する
      bcf     ADCON0,CHS1  ;  GO/DONE  ADON=1 の時、=1 ならば、ＡＤ変換中、 =0 ならば、変換中ではない
                           ;           ＡＤ変換が完了すると、このビットは自動的に０となる
                           ;  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 高速 = 低速
      bcf     TXSTA,SYNC   ;非同期モードを選択
      movlw   7            ;クロックが１０ＭＨｚの時、BRGH=0 として、１０進数の７を SPBRG に代入すると
      movwf   SPBRG        ;ボーレートは１９２００となる。
      bsf     PIE1,RCIE    ;受信割込を可とする
      bcf     STATUS,RP0   ;バンク０に戻しておく

      bsf     RCSTA,SPEN   ;端子をシリアルポートとして設定
      bsf     RCSTA,CREN   ;連続受信を可とする
  
;**********************************
;各ポートの設定が終わったら、ＲＳ－２３２Ｃポートにスタートデータ”１”が送られてくるまで待機させる
recwait  nop                ;エンドレスループ。シリアルポートにデータが届くまで待機状態とし、
         goto    recwait    ;データが届いたらループを抜け出し、割込処理に移る

;測定実行　当面の課題
;　　　　　　定時間毎にアナログ入力をサンプリングし、それを１０ビットＤＡモニター出力する。
;　　　　　　これをエンドレスで繰り返させる　 

startwait1  ;パソコンからスタート信号を受信したときに実行する  
      ;パソコン側のＲＤ－２３２Ｃが能動になるまで待機させる。若干時間を稼ぐ。約１秒
         movlw  60
         bsf    Ledmonitor       ;その間モニターＬＥＤを連続点灯する。
         movwf  temp3
st_wait  call    wait            ;
         decfsz temp3,1          ; 
         goto   st_wait          ;

         bsf     INTCON,GIE      ;割り込みが発生すると、このビットは０となり、
                                 ;割り込み処理が実行される。その後、再割り込みを許可するためには
                                 ;このビットを１としなければならないので。
         bsf     ADCON0,ADON     ;ＡＤ変換器をオンとする
repeat
         bsf     Ledmonitor      ;モニターＬＥＤ点灯
                                 ;注意　この端子は送信データの高位バイトの第３ビットと兼用になっている。
                                 ;      高位バイトの第３ビットは常に０なので、高位バイトが送信された
                                 ;　　　ＬＥＤは消灯する。
         bcf     ADCON0,CHS0     ;ＡＮ０端子を指定
         call    wait            ;チャンネル選択確定まで待機
         bsf     ADCON0,GO       ;ＡＤ変換を開始させる
adloop0  btfsc   ADCON0,GO       ;GO/DONE が０になるまで待機
         goto    adloop0         ;ＡＤ変換が完了すると０となる
         call    trans_exe       ;送信のルーチンを実行する
                                 ;Ｘ軸加速度値の出力

         bsf     Ledmonitor      ;
         bsf     ADCON0,CHS0     ;ＡＮ１端子を指定
         call    wait            ;
         bsf     ADCON0,GO       ;ＡＤ変換を開始させる
adloop1  btfsc   ADCON0,GO       ;GO/DONE が０になるまで待機
         goto    adloop1         ;ＡＤ変換が完了すると０となる
         call    trans_exe       ;送信のルーチンを実行する
                                 ;Ｙ軸加速度値の出力

         goto    repeat          ;

;**********************************************
;ＲＳ－２３２Ｃ送信  最初に高位バイト、続いて低位バイトを順次送信する
trans_exe
         movf    ADRESH,0        ;ＡＤ変換結果の高位２ビットを
         movwf   hig2bit         ;hig2bit に代入し、保存
         bsf     STATUS,RP0      ;バンク１に移る
         movf    ADRESL,0        ;ＡＤ変換結果の低位８ビットを
         bcf     STATUS,RP0      ;
         movwf   low8bit         ;low8bit に代入する

         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

         return

;**********************************************
;サンプリング時間の設定　　５０ｍ秒毎、（当初は、約１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

;******************************************************************************************





