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