用msp430fr4133控制hmc5883l

2019-03-24 08:43发布

求大神帮助,我用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) ;
{

}
}

此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
6条回答
nickzhong
2019-03-25 08:10
michael_llh 发表于 2016-4-9 13:40
如果是软件模拟的话和硬件没有太大关系,只要你的IO口可以正常实现输出高和输出低就可以了。

现在程序改动之后只能固定显示45度

一周热门 更多>

相关问题

    相关文章