求大神帮助,我用msp430fr4133控制hmc5883l,但是无法成功显示读数。
读数一直是角度转换方程部分的整数。请问这是什么原因导致的。
除此之外,在使用msp430的时候需要对主机寄存器设置才能使用I2C传输功能吗?还是对主机寄存器设置只是在硬件I2C的时候才做的。
本人新手,麻烦大神们说的详细点。
下面是代码
#include <msp430.h>
#include <driverlib.h>
#include "hal_LCD.h"
#include <stdlib.h>
#include <math.h>
typedef unsigned char uchar;
typedef unsigned int uint;
#define HMC5883L_DIR P8DIR
#define HMC5883L_IN P2IN
#define HMC5883L_OUT P2OUT
#define SCL BIT2 //define cloclk pin
#define SDA BIT3 //define data pin
#define SCL_H (HMC5883L_DIR|=SCL,HMC5883L_OUT|=SCL)
#define SCL_L (HMC5883L_DIR|=SCL,HMC5883L_OUT&=~SCL)
#define SDA_H (HMC5883L_DIR|=SDA,HMC5883L_OUT|=SDA)
#define SDA_L (HMC5883L_DIR|=SDA,HMC5883L_OUT&=~SDA)
#define SDA_in P8DIR&=~BIT3
#define SlaveAddress 0x3C //define SlaveAddress
uchar Rec_Data[6];
unsigned short int x,y,z;
double Angle;
uint Acr;
unsigned int A=1;
int delay=1;
unsigned char number=0;
unsigned char a,b,c,d,e;
unsigned int headingN=305;
/*delay function*/
void Delay(uint t)
{
while(t--);
}
/*start signal*/
void IIC_Start(void)
{
SDA_H;
SCL_H;
Delay(50);
SDA_L;
Delay(50);
SCL_L;
}
/*stop signal*/
void IIC_Stop(void)
{
SDA_L;
SCL_H;
Delay(50);
SDA_H;
Delay(50);
}
/*send response signal*/
void IIC_SendAck(char Ack)
{
if(Ack) //ack (0:ACK 1:NO ACK)
SDA_H;
else SDA_L;
SCL_H;
Delay(50);
SCL_L;
Delay(50);
}
/*recive reponse signal*/
char IIC_RecAck(void)
{
char CY;
HMC5883L_DIR&=~SDA;
SCL_H;
Delay(50);
if(HMC5883L_DIR&SDA)
CY=1;
else CY=0;
SCL_L;
Delay(50);
return CY;
}
/*send one byte data from IIC*/
uchar HMC5883_Send_Byte(uchar Dat)
{
uchar i;
for(i=0;i<8;i++)
{
if(Dat&BIT7)
SDA_H;
else SDA_L;
SCL_H;
Delay(50);
SCL_L;
Delay(50);
Dat<<=1;
}
IIC_RecAck();
return Dat;
}
/*recive one byte data from IIC*/
uchar HMC5883_Rec_Byte(void)
{
uchar i,Dat=0;
SDA_H;
HMC5883L_DIR&=~SDA;
for(i=0;i<8;i++)
{
Dat<<=1;
SCL_H;
Delay(50);
if((HMC5883L_IN&SDA)==SDA)
Dat|=BIT0;
SCL_L;
Delay(50);
}
return Dat;
}
/*single byte write HMC5883L*/
void Single_Write_HMC5883(uchar Address,uchar Dat)
{
IIC_Start();
HMC5883_Send_Byte(SlaveAddress);
HMC5883_Send_Byte(Address);
HMC5883_Send_Byte(Dat);
IIC_Stop();
}
/*single byte read HMC5883*/
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);
Value=HMC5883_Rec_Byte();
IIC_SendAck(1);
IIC_Stop();
return Value;
}
/*multiple byte read HMC5883*/
void Multiple_Read_HMC5883(void)
{
uchar i;// read data of angle in HMC5883,address from 0x3 to 0x5
IIC_Start();
HMC5883_Send_Byte(SlaveAddress);
HMC5883_Send_Byte(0x03);// send address of svae unit , from 0x03
IIC_Start();
HMC5883_Send_Byte(SlaveAddress+1);
for(i=0;i<6;i++)// read data from six registers, and save them in Rec_Data
{
Rec_Data[i]=HMC5883_Rec_Byte();
if(i==5)
IIC_SendAck(1);// final data return to NOACK
else
IIC_SendAck(0);//
}
IIC_Stop();
Delay(100);
}
//initialize HMC5883
void HMC5883_Init(void)
{
Single_Write_HMC5883(0x00,0x60);
Single_Write_HMC5883(0x02,0x00);
//HMC5883_Send_Byte(0x00);
}
/* get angle*/
/* o degree to the south*/
void get_angle()
{
Multiple_Read_HMC5883();//read data,save in Rec_Data[]
x=Rec_Data[0]<<8 | Rec_Data[1];//Combine MSB and LSB of X Data output register
z=Rec_Data[4]<<8 | Rec_Data[5];//Combine MSB and LSB of Z Data output register
y=Rec_Data[2]<<8 | Rec_Data[3];//Combine MSB and LSB of Y Data output register
Angle=atan2((double)y,(double)x)*(180/3.141592654)+180;//unit:degree(0~360)
Acr=(uint)Angle;
//Angle*=10;
Delay(50000);
}
int main(void)
{
//Default MCLK = 1MHz
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
PMM_unlockLPM5();
// Disable the GPIO power-on default high-impedance mode
// to activate previously configured port settings
Init_LCD();
displayScrollText("ELECTRONIC COMPASS");
HMC5883_Init();//HMC5883 initialize
get_angle();//unit:degree(0~360)
a=Acr/100;
b=Acr/10%10;
c=Acr%10;
//d=Angle/1000%10;
//e=Angle/10000%10;
showChar('N', pos1);
showChar(a+48,pos2);
showChar(b+48,pos3);
showChar(c+48,pos4);
//showChar(d+48,pos5);
//showChar(e+48,pos6);
while(1) ;
{
}
} |