基于51单片机操控的HMC5883L电子指南针
时间:10-02
整理:3721RD
点击:
/*无敌呆呆猫 2016年10月9日凌晨2:00 编写完成 留此纪念 */
#include<reg51.h>
#include <math.h>
#include<LCD1602.h>
#include<IIC.h>
//对数据类型不是很明白 很努力了就写成这样 不知道对不对。
unsigned int xa,xb,ya,yb,za,zb;
signed int x,y,z;
unsigned int ok;
double angle; //LCD1602字库
unsigned char temp[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};
void main()
{
EA=1;
EX0=1;
IT0=1;
//先把需要固定显示在1602上的几个字母预先写在固定位置上
init_LCD1602();
write_date('X');
write_com(0x80+0x07);
write_date('Y');
write_com(0x80+0x40);
write_date('Z');
write_com(0x80+0x47);
write_date('F');
//下面这些是5883的一些初始矫正 反正没看明白说明书
//上说的意思 只是照葫芦画瓢乱写了点
delay1(5);
init_IIC();
start();
write_byte(0x3c);
write_byte(0x00);
write_byte(0x01);
stop();
start();
write_byte(0x3c);
write_byte(0x02);
write_byte(0x01);
stop();
delay1(20);
start();
write_byte(0x3c);
write_byte(0x00);
write_byte(0x10);
stop();
start();
write_byte(0x3c);
write_byte(0x02);
write_byte(0x00);
stop();
delay1(110);
while(1)
{ //合并3组数据的高低8位
x=xa<<8|xb;
y=ya<<8|yb;
z=za<<8|zb;
//计算角度的死公式
angle= atan2((double)y,(double)x) * (180 / 3.14159265) + 180;
ok=angle*10;
//在1602的相对位置显示方位角度
write_com(0x80+0x48);
write_date(temp[ok/1000]);
write_date(temp[ok%1000/100]);
write_date(temp[ok%1000%100/10]);
write_date('.');
write_date(temp[ok%1000%100%10]);
write_date(0Xdf);//度符号的右上角小圆圈
//x轴在1602上相应位置的数值显示
write_com(0x80+0x01);
if(x>0){write_date(0x2b);}
else { write_date(0x2d);
x=-x;
}
write_date(temp[x/1000]);
write_date(temp[x%1000/100]);
write_date(temp[x%1000%100/10]);
write_date(temp[x%1000%100%10]);
//y轴在1602上相应位置的数值显示
write_com(0x80+0x08);
if(y>0){write_date(0x2b);}
else { write_date(0x2d);
y=-y;
}
write_date(temp[y/1000]);
write_date(temp[y%1000/100]);
write_date(temp[y%1000%100/10]);
write_date(temp[y%1000%100%10]);
//z轴在1602上相应位置的数值显示
write_com(0x80+0x41);
if(z>0){write_date(0x2b);}
else { write_date(0x2d);
z=-z;
}
write_date(temp[z/1000]);
write_date(temp[z%1000/100]);
write_date(temp[z%1000%100/10]);
write_date(temp[z%1000%100%10]);
EA=1;
//该死的z轴暂时还不明白怎么用。
//防止1602还没完成数据显示的时候又再次进入中断反复读取数据
while(EA);
}
}
void my5883(void) interrupt 0 using 1
{ //中断中用IIC功能取出xyz的3组高低8位数据
start();
write_byte(0x3c);
write_byte(0x03);
start();
write_byte(0x3d);
xa=read_byte();
respons_0();
xb=read_byte();
respons_0();
ya=read_byte();
respons_0();
yb=read_byte();
respons_0();
za=read_byte();
respons_0();
zb=read_byte();
respons_1();
stop();
EA=0; //防止1602还没完成数据显示的时候又再次进入中断反复读取数据
}
#include<reg51.h>
#include <math.h>
#include<LCD1602.h>
#include<IIC.h>
//对数据类型不是很明白 很努力了就写成这样 不知道对不对。
unsigned int xa,xb,ya,yb,za,zb;
signed int x,y,z;
unsigned int ok;
double angle; //LCD1602字库
unsigned char temp[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};
void main()
{
EA=1;
EX0=1;
IT0=1;
//先把需要固定显示在1602上的几个字母预先写在固定位置上
init_LCD1602();
write_date('X');
write_com(0x80+0x07);
write_date('Y');
write_com(0x80+0x40);
write_date('Z');
write_com(0x80+0x47);
write_date('F');
//下面这些是5883的一些初始矫正 反正没看明白说明书
//上说的意思 只是照葫芦画瓢乱写了点
delay1(5);
init_IIC();
start();
write_byte(0x3c);
write_byte(0x00);
write_byte(0x01);
stop();
start();
write_byte(0x3c);
write_byte(0x02);
write_byte(0x01);
stop();
delay1(20);
start();
write_byte(0x3c);
write_byte(0x00);
write_byte(0x10);
stop();
start();
write_byte(0x3c);
write_byte(0x02);
write_byte(0x00);
stop();
delay1(110);
while(1)
{ //合并3组数据的高低8位
x=xa<<8|xb;
y=ya<<8|yb;
z=za<<8|zb;
//计算角度的死公式
angle= atan2((double)y,(double)x) * (180 / 3.14159265) + 180;
ok=angle*10;
//在1602的相对位置显示方位角度
write_com(0x80+0x48);
write_date(temp[ok/1000]);
write_date(temp[ok%1000/100]);
write_date(temp[ok%1000%100/10]);
write_date('.');
write_date(temp[ok%1000%100%10]);
write_date(0Xdf);//度符号的右上角小圆圈
//x轴在1602上相应位置的数值显示
write_com(0x80+0x01);
if(x>0){write_date(0x2b);}
else { write_date(0x2d);
x=-x;
}
write_date(temp[x/1000]);
write_date(temp[x%1000/100]);
write_date(temp[x%1000%100/10]);
write_date(temp[x%1000%100%10]);
//y轴在1602上相应位置的数值显示
write_com(0x80+0x08);
if(y>0){write_date(0x2b);}
else { write_date(0x2d);
y=-y;
}
write_date(temp[y/1000]);
write_date(temp[y%1000/100]);
write_date(temp[y%1000%100/10]);
write_date(temp[y%1000%100%10]);
//z轴在1602上相应位置的数值显示
write_com(0x80+0x41);
if(z>0){write_date(0x2b);}
else { write_date(0x2d);
z=-z;
}
write_date(temp[z/1000]);
write_date(temp[z%1000/100]);
write_date(temp[z%1000%100/10]);
write_date(temp[z%1000%100%10]);
EA=1;
//该死的z轴暂时还不明白怎么用。
//防止1602还没完成数据显示的时候又再次进入中断反复读取数据
while(EA);
}
}
void my5883(void) interrupt 0 using 1
{ //中断中用IIC功能取出xyz的3组高低8位数据
start();
write_byte(0x3c);
write_byte(0x03);
start();
write_byte(0x3d);
xa=read_byte();
respons_0();
xb=read_byte();
respons_0();
ya=read_byte();
respons_0();
yb=read_byte();
respons_0();
za=read_byte();
respons_0();
zb=read_byte();
respons_1();
stop();
EA=0; //防止1602还没完成数据显示的时候又再次进入中断反复读取数据
}