微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 基于51单片机操控的HMC5883L电子指南针

基于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还没完成数据显示的时候又再次进入中断反复读取数据
                                      
}


Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top