文档库 最新最全的文档下载
当前位置:文档库 › HMC5883程序AVR单片机

HMC5883程序AVR单片机

HMC5883程序AVR单片机
HMC5883程序AVR单片机

//========基于A Tmega8的HMC5883L测试程序============= //** 模块:3-轴数字罗盘

//** 用途:测磁场强度

//** 协议:IIC 详细读写协议,请参考相关资料

#include

#include

#include

#include

typedef unsigned char uchar;

typedef unsigned int uint;

/*LCD引脚定义*/

#define CS_set PORTD |=BIT(6)

#define CS_clr PORTD &=~BIT(6)

#define SID_set PORTD |=BIT(7)

#define SID_clr PORTD &=~BIT(7)

#define CLK_set PORTB |=BIT(0)

#define CLK_clr PORTB &=~BIT(0)

/*IIC端口定义*/

#define SCL_set PORTC |=(1<<5)

#define SCL_clr PORTC &=~(1<<5)

#define SDA_set PORTC |=(1<<4)

#define SDA_clr PORTC &=~(1<<4)

#define SDA_in DDRC &=~(1<<4)

#define SDA_out DDRC |=(1<<4)

#define SlaveAddress 0x3c //定义器件在IIC总线中的从地址uchar Rec_Data[6];

/*延时函数*/

void Delay(uint t)

{

while(t--)

{}

}

/*LCD12232端口初始化*/

void PORT_Init(void)

{ //LCD端口设置为输出,且为高电平DDRD |=(1<<6)|(1<<7);

DDRB |=(1<<0);

PORTD |=(1<<6)|(1<<7);

PORTB |=(1<<0);

DDRC |=(1<<5);//SCL设置为输出

}

/*LCD12232写数据*/

void Send_DATA(uchar Data,uchar O_Z) {

uchar i,Order;

CS_clr;

switch(O_Z)

{

case 0 : Order=0xf8;break;//写指令

case 1 : Order=0xfa;break;//写数据

default : break;

}

CLK_clr;

CS_set;

for(i=0;i<8;i++)

{

if(Order&0x80)

SID_set;

else

SID_clr;

CLK_clr;

CLK_set;

Order<<=1;

}

Order=Data;

Order &=0xf0;

for(i=0;i<8;i++)

{

if(Order&0x80)

SID_set;

else

SID_clr;

CLK_clr;

CLK_set;

Order<<=1;

}

Order=Data;

Order<<=4;

for(i=0;i<8;i++)

{

if(Order&0x80)

SID_set;

else

SID_clr;

CLK_clr;

CLK_set;

Order<<=1;

}

CS_clr;

Delay(20);

}

/*显示一字符串*/

void Dis_str(uchar Addr,uchar *str)

{

Send_DATA(Addr,0);

Delay(30);

while(*str!='\0')

{

Send_DATA(*str,1);

str++;

Delay(20);

}

}

/*LCD12232初始化*/

void Init_LCD(void)

{

Delay(20000);

Send_DATA(0x06,0);

Delay(200);

Send_DATA(0x02,0);

Delay(200);

Send_DATA(0x0c,0);

Delay(200);

Send_DATA(0x80,0);

Delay(200);

Send_DATA(0x30,0);

Delay(200);

Send_DATA(0x01,0);

Delay(5000);

}

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

** HMC5883L程序部分

*******************************************/ /*起始信号*/

void IIC_Start(void)

{

SDA_out;

SDA_set;

SCL_set;

Delay(35);

SDA_clr;

Delay(35);

SCL_clr;

}

/*停止信号*/

void IIC_Stop(void)

{

SDA_out;

SDA_clr;

SCL_set;

Delay(35);

SDA_set;

Delay(35);

}

/*接收应答信号*/

uchar IIC_RecAck(void)

{

uchar A;

SDA_in;

SCL_set;

Delay(35);

if(PINC & (1<<4))

A=1;

else

A=0;

SCL_clr;

Delay(35);

return A ? 1:0;

}

/*向IIC总线发送一个字节数据*/

void HMC5883_Send_Byte(uchar Dat)

{

uchar i;

SDA_out;

for(i=0;i<8;i++)

{

if(Dat & 0x80)

SDA_set;

else

SDA_clr;

SCL_set;

Delay(35);

SCL_clr;

Delay(35);

Dat<<=1;

}

IIC_RecAck();

}

/*从IIC总线接收一个字节数据*/

uchar HMC5883_Rec_Byte(void)

{

uchar i,Dat=0;

SDA_in;

SDA_set;

for(i=0;i<8;i++)

{

Dat<<=1;

SCL_set;

Delay(35);

if(PINC & (1<<4))

Dat |=0x01;

SCL_clr;

Delay(35);

}

return Dat;

}

/*单字节写HMC5833*/

void Single_Write_HMC5883(uchar Address,uchar Dat) {

IIC_Start();

HMC5883_Send_Byte(SlaveAddress);

HMC5883_Send_Byte(Address);

HMC5883_Send_Byte(Dat);

IIC_Stop();

}

/*单字节读HMC5833*/

/*uchar Single_Read_HMC5883(uchar Addr)

{

uchar Value;

IIC_Start();

HMC5883_Send_Byte(SlaveAddress);

HMC5883_Send_Byte(Addr);

IIC_Start();

HMC5883_Send_Byte(SlaveAddress+1);

V alue=HMC5883_Rec_Byte();

IIC_SendAck(1);

IIC_Stop();

return Value;

}*/

//初始化HMC5883,根据需要请参考pdf进行修改****

void HMC5883_Init(void)

{

Single_Write_HMC5883(0x02,0x00);

}

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

**主函数

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

void main(void)

{

uchar N;

int X,Y,Z;

double Angle;

uint Acr;

Delay(60000);

PORT_Init();

Init_LCD();

//Dis_str(0x80,"HMC5883L");

HMC5883_Init();//HMC5883初始化

do

{

Multiple_Read_HMC5883();//连续读出数据,存储在Rec_Data[]中

X=Rec_Data[0]<<8 | Rec_Data[1];//Combine MSB and LSB of X Data output register

Z=Rec_Data[2]<<8 | Rec_Data[3];//Combine MSB and LSB of Z Data output register

Y=Rec_Data[4]<<8 | Rec_Data[5];//Combine MSB and LSB of Y Data output register

Angle= atan2((double)Y,(double)X)*(180/3.14159265)+180;//单位:角度(0~360)

Angle*=10;

Acr=(uint)Angle;

Send_DATA(0x82,0);

Send_DATA(0x20,1);

Send_DATA(Acr%10000/1000+0x30,1);

Send_DATA(Acr%1000/100+0x30,1);

Send_DATA(Acr%100/10+0x30,1);

//Send_DATA('.',1);

//Send_DATA(Acr%10+0x30,1);

Send_DATA(0xa1,1);

Send_DATA(0xe3,1);

if((Acr>=0 && Acr<=300) || (Acr>=3300))

Dis_str(0x92,"【东】");

if(Acr>=600 && Acr<=1200)

Dis_str(0x92,"【南】");

if(Acr>=1500 && Acr<=2100)

Dis_str(0x92,"【西】");

if(Acr>=2400 && Acr<=3000)

Dis_str(0x92,"【北】");

for(N=12;N>0;N--)

Delay(50000);

}

while(1);

}

相关文档