ソース
//compass module HM55B
//
#include <16f88.h>
#fuses INTRC_IO,NOWDT,NOLVP,NOMCLR,NOBROWNOUT
#use delay(CLOCK = 4000000)
#use fast_io(B)
#define CLK PIN_B2
#define CSB PIN_B3
#define DOUT PIN_B4
#define DIN PIN_B1
#define negbits 0xf800
void reset();
void start();
void sendCmnd(int cmd);
int checkBusy();
void readxy(signed long *dx,signed long *dy);
int read4();
signed long read11();
signed long dx,dy,val2;
int i;
int val;
void main()
{
set_tris_b(0xF1);
set_tris_a(0xF0);
delay_ms(50);//電源の立ち上がりを待つ
reset();//リセット
while(1){
start();//計測開始
while(!checkBusy()){}//計測完了を待つ
dx=0;dy=0;
readxy(&dx,&dy);//dx,dyに計測値を取得
output_low(PIN_A1);
output_low(PIN_A0);
if(dx<2 && dx>-2) output_high(PIN_A1);//Xの値が小さいとき
if(dy<2 && dy>-2) output_high(PIN_A0);//Yの値が小さいとき
delay_ms(500);//休止
output_low(PIN_A2);
delay_ms(500);
}
}
void reset()
{
output_low(CSB);//モジュールを選択
sendCmnd(0x0);//リセットコマンドを送る
output_high(CSB); //モジュールを選択を解除
}
void start()
{
output_low(CSB);
sendCmnd(0x8);//測定開始コマンドを送る
output_high(CSB);
}
int checkBusy()
{
output_low(CSB);
sendCmnd(0xC);//読み取りコマンドを送る
val=read4(); //フラグを読む
output_high(CSB);
if(val==0xc) output_high(PIN_A2);//測定完了チェック
else output_low(PIN_A2);
return (val==0xc);//測定完了したらtrueを返す
}
int read4()
{
//フラグを読む
val=0;
for(i=0;i<4;i++){
output_high(CLK);
output_low(CLK);
//
if(input(DOUT)) bit_set(val,3-i);//上位ビットが先頭
}
return val;
}
void readxy(signed long *dx,signed long *dy)
{
//X,Y のデータを取得
output_low(CSB);
sendCmnd(0xC);
val=read4();
*dx = read11();//Xデータを読む
*dy = read11();//Yデータを読む
//負の数なら、16bitの補数にする
if(bit_test(*dx,10)) *dx |= negbits;
if(bit_test(*dy,10)) *dy |= negbits;
output_high(CSB);
return;
}
//12ビットデータを読む
signed long read11()
{
//クロックを送り、11ビットのデータを読む
val2=0;
for(i=0;i<11;i++){
output_high(CLK);
output_low(CLK);
//上位ビットからくる???
if(input(DOUT)) bit_set(val2,10-i);
}
return val2;
}
void sendCmnd(int cmnd)
{
//クロックに同期してコマンドを送る
for(i=0;i<4;i++){
output_high(CLK);
output_bit(DIN,bit_test(cmnd,3-i));
output_low(CLK);
}
}