基于51单片机的电子罗盘数字指南针HCM8553原理图程序设计

文件仅供参考:
链接:https://pan.baidu.com/s/1JAGteF7odF1i1nV3uoCIhQ
提取码:rkou

硬件设计

方案:
数字电子罗盘3大模块分别是:传感器模块、数据采集模块和MCU模块。需要硬件有: 磁阻传感器、 双轴加速度传感器、AD转换器以及单片机的磁阻式电子罗盘。硬件总体框图如下:
在这里插入图片描述
采用三轴磁阻传感器进行地球磁场矢量测量,双轴加速传感器可以传感地球重力场中测量载体的姿态,然后通过姿态坐标变换将磁阻传感器得到载体坐标的测量信号变换到地平坐标系。其磁阻式传感器HMC5883包含输出为3路的差分模拟电压值,差分值大约为几毫伏,信号经过传感器内置的ASIC放大器把信号进行放大,再进行模数转换器进行放大和模数转换;再由有单片机处理数字信号,经由处理后得到航向角由显示屏来显示;复位电路用于恢复磁阻传感器在强磁干扰后的灵敏度;电源模块分别为复位电路和信号处理电路供电。

原理图:
在这里插入图片描述

程序设计

方案:
系统软件除了完成初始化、信号采集、信号调理、A/D转换,再到单片机中进行信号处理分析,然后判断能否输出。其框图如下所示:
在这里插入图片描述
单片机对传感器失调、温度漂移等干扰造成的误差进行调整。失调和温度漂移会在传感器敏感信号上面叠加一个直流偏置电路,单片机通过将传感器在置位和复位情况下得到的信号进行分析,算出平均值。就可以得到由于失调和漂移造成的直流偏置信号,在方向角计算前对该偏置信号进行补偿即可消除其影响。再判断能否输出,如果不能输出,则再采集一次;能输出则把数据送到显示屏显示。

//***************************************
// HMC5883 IIC测试程序
// 使用单片机STC89C51 
// 晶振:11.0592M
// 显示:LCD1602

//****************************************
#include  <REG51.H>	
#include  <math.h>    //Keil library  
#include  <stdio.h>   //Keil library	
#include  <INTRINS.H>

#define   uchar unsigned char
#define   uint unsigned int	
//使用的端口,请按照以下接线
#define   DataPort P0	//LCD1602数据端口
sbit	SCL=P3^4;      //IIC时钟引脚定义
sbit	SDA=P3^5;      //IIC数据引脚定义
sbit    LCM_RS=P2^5;   //LCD1602命令端口		
sbit    LCM_RW=P2^6;   //LCD1602命令端口		
sbit    LCM_EN=P2^7;   //LCD1602命令端口 

#define	SlaveAddress   0x3C	  //定义器件在IIC总线中的从地址
typedef unsigned char BYTE;
typedef unsigned short WORD;

BYTE BUF[8];                         //接收数据缓存区      	
uchar ge,shi,bai,qian,wan;           //显示变量
int  dis_data;                       //变量
double angle;
WORD Dushu;
void delay(unsigned int k);
 
void Init_HMC5883(void);            //初始化5883
 
void conversion(uint temp_data);

void  Single_Write_HMC5883(uchar REG_Address,uchar REG_data);   //单个写入数据
uchar Single_Read_HMC5883(uchar REG_Address);                   //单个读取内部寄存器数据
void  Multiple_Read_HMC5883();                                  //连续的读取内部寄存器数据
//以下是模拟iic使用函数-------------
void Delay5us();
void Delay5ms();
void HMC5883_Start();
void HMC5883_Stop();
void HMC5883_SendACK(bit ack);
bit  HMC5883_RecvACK();
void HMC5883_SendByte(BYTE dat);
BYTE HMC5883_RecvByte();
void HMC5883_ReadPage();
void HMC5883_WritePage();
//-----------------------------------
 #include  <lcd1602.H>	
//*********************************************************
void conversion(uint temp_data)  
{  
    wan=temp_data/10000+0x30 ;
    temp_data=temp_data%10000;   //取余运算
	qian=temp_data/1000 ;
    temp_data=temp_data%1000;    //取余运算
    bai=temp_data/100 ;
    temp_data=temp_data%100;     //取余运算
    shi=temp_data/10  ;
    temp_data=temp_data%10;      //取余运算
    ge=temp_data+0x30; 	
	Dushu= qian*1000+bai*100+shi*10;
}

/*******************************/
void delay(unsigned int k)	
{						
unsigned int i,j;				
for(i=0;i<k;i++)
{			
for(j=0;j<121;j++)			
{;}}						
}
 
 						

/**************************************
延时5微秒(STC90C52RC@12M)
不同的工作环境,需要调整此函数,注意时钟过快时需要修改
当改用1T的MCU时,请调整此延时函数
**************************************/
void Delay5us()
{
             _nop_();_nop_();_nop_();_nop_();
             _nop_();_nop_();_nop_();_nop_();
	_nop_();_nop_();_nop_();_nop_();
	_nop_();_nop_();_nop_();_nop_();
              _nop_();_nop_();_nop_();_nop_();
	_nop_();_nop_();_nop_();_nop_();
	_nop_();_nop_();_nop_();_nop_();
             _nop_();_nop_();_nop_();_nop_();

}

/**************************************
延时5毫秒(STC90C52RC@12M)
不同的工作环境,需要调整此函数
当改用1T的MCU时,请调整此延时函数
**************************************/
void Delay5ms()
{
    WORD n = 560;

    while (n--);
}

/**************************************
起始信号
**************************************/
void HMC5883_Start()
{
    SDA = 1;                    //拉高数据线
    SCL = 1;                    //拉高时钟线
    Delay5us();                 //延时
    SDA = 0;                    //产生下降沿
    Delay5us();                 //延时
    SCL = 0;                    //拉低时钟线
}

/**************************************
停止信号
**************************************/
void HMC5883_Stop()
{
    SDA = 0;                    //拉低数据线
    SCL = 1;                    //拉高时钟线
    Delay5us();                 //延时
    SDA = 1;                    //产生上升沿
    Delay5us();                 //延时
}

/**************************************
发送应答信号
入口参数:ack (0:ACK 1:NAK)
**************************************/
void HMC5883_SendACK(bit ack)
{
    SDA = ack;                  //写应答信号
    SCL = 1;                    //拉高时钟线
    Delay5us();                 //延时
    SCL = 0;                    //拉低时钟线
    Delay5us();                 //延时
}

/**************************************
接收应答信号
**************************************/
bit HMC5883_RecvACK()
{
    SCL = 1;                    //拉高时钟线
    Delay5us();                 //延时
    CY = SDA;                   //读应答信号
    SCL = 0;                    //拉低时钟线
    Delay5us();                 //延时

    return CY;
}

/**************************************
向IIC总线发送一个字节数据
**************************************/
void HMC5883_SendByte(BYTE dat)
{
    BYTE i;

    for (i=0; i<8; i++)         //8位计数器
    {
        dat <<= 1;              //移出数据的最高位
        SDA = CY;               //送数据口
        SCL = 1;                //拉高时钟线
        Delay5us();             //延时
        SCL = 0;                //拉低时钟线
        Delay5us();             //延时
    }
    HMC5883_RecvACK();
}

/**************************************
从IIC总线接收一个字节数据
**************************************/
BYTE HMC5883_RecvByte()
{
    BYTE i;
    BYTE dat = 0;

    SDA = 1;                    //使能内部上拉,准备读取数据,
    for (i=0; i<8; i++)         //8位计数器
    {
        dat <<= 1;
        SCL = 1;                //拉高时钟线
        Delay5us();             //延时
        dat |= SDA;             //读数据               
        SCL = 0;                //拉低时钟线
        Delay5us();             //延时
    }
    return dat;
}

//***************************************************

void Single_Write_HMC5883(uchar REG_Address,uchar REG_data)
{
    HMC5883_Start();                  //起始信号
    HMC5883_SendByte(SlaveAddress);   //发送设备地址+写信号
    HMC5883_SendByte(REG_Address);    //内部寄存器地址,请参考中文pdf 
    HMC5883_SendByte(REG_data);       //内部寄存器数据,请参考中文pdf
    HMC5883_Stop();                   //发送停止信号
}

.

.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值