1、/*/ HMC5883 IIC 测试程序/ 使用单片机 STC89C51 / 晶振:11.0592M/ 显示:串口/ 编译环境 Keil uVision5/2015/7/26/*#include #include #include #include #define uchar unsigned char#define uint unsigned int/*IIC 定义*/sbit SCL=P12; /IIC 时钟引脚定义sbit SDA=P13; /IIC 数据引脚定义typedef unsigned short WORD;/*IIC 定义*/*磁力计定义*/#define SlaveAddr
2、ess 0x3C /定义器件在 IIC 总线中的从地址(0x3c 是写入的地址。7bit 地址是 0x1E)/*磁力计定义*/*串口定义*/unsigned char Bufer=“hello n“;typedef unsigned char BYTE;BYTE BUF6; /接收数据缓存区 uchar ge,shi,bai,qian,wan; /显示变量/*串口定义*/*函数声明*/延时void delay(unsigned int k);/串口void UART_init(void);void UART_send_byte(unsigned char dat);void UART_send
3、_string(unsigned char *bufer);/转换void conversion(uint temp_data);/磁力计void Init_HMC5883(void); /初始化 5883/IICvoid Single_Write_HMC5883(uchar REG_Address,uchar REG_data); /单个写入数据uchar Single_Read_HMC5883(uchar REG_Address); /单个读取内部寄存器数据void Multiple_Read_HMC5883(); /连续的读取内部寄存器数据void Delay5us();void Del
4、ay5ms();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();/*函数声明*/*函数定义*/UART 初始化 波特率:9600void UART_init(void)SCON = 0x50; / 10 位 uart,允许串行接受TMOD = 0x20
5、; / 定时器 1 工作在方式 2(自动重装)TH1 = 0xFD;TL1 = 0xFD;TR1 = 1;/UART 发送一字节void UART_send_byte(unsigned char dat)SBUF = dat;while (TI = 0);TI = 0;/UART 发送字符串void UART_send_string(unsigned char *bufer)while (*bufer != 0)UART_send_byte(*bufer+);/延时函数 void delay(unsigned int k)unsigned int i,j;for(i=0;ik;i+)for(j
6、=0;j121;j+);/转换函数void conversion(uint temp_data) wan=temp_data/10000+0x30 ;temp_data=temp_data%10000; /取余运算qian=temp_data/1000+0x30 ;temp_data=temp_data%1000; /取余运算bai=temp_data/100+0x30 ;temp_data=temp_data%100; /取余运算shi=temp_data/10+0x30 ;temp_data=temp_data%10; /取余运算ge=temp_data+0x30; /自测 HMC5883
7、 void Init_HMC5883()Single_Write_HMC5883(0x00,0x71);/Write CRA (00) send 0x3C 0x00 0x70 (8-average, 15 Hz default, normal measurement)Single_Write_HMC5883(0x01,0xA0);/Write CRB (01) send 0x3C 0x01 0xA0 (Gain=5, or any other desired gain)Single_Write_HMC5883(0x02,0x01);/Write Mode(02) send 0x3C 0x02
8、0x00 (Continuous-measurement mode)/离开自测 HMC5883 void leave_HMC5883()Single_Write_HMC5883(0x00,0xF0);/Write CRA (00) send 0x3C 0x00 0x70 (8-average, 15 Hz default, normal measurement)Single_Write_HMC5883(0x01,0xA0);/Write CRB (01) send 0x3C 0x01 0xA0 (Gain=5, or any other desired gain)Single_Write_HM
9、C5883(0x02,0x00);/Write Mode(02) send 0x3C 0x02 0x00 (Continuous-measurement mode)/*延时 5 微秒(STC90C52RC12M)不同的工作环境,需要调整此函数,注意时钟过快时需要修改当改用 1T 的 MCU 时,请调整此延时函数*/void Delay5us()_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_()
10、;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();/* 延时 5 毫秒 (STC90C52RC12M)不同的工作环境,需要调整此函数当改用 1T 的 MCU 时,请调整此延时函数*/void Delay5ms()WORD n = 560;while (n-);/ 起始信号void HMC5883_Start()SDA = 1; /拉高数据线SCL = 1; /拉高时钟线Delay5us()
11、; /延时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 HMC5
12、883_RecvACK()SCL = 1; /拉高时钟线Delay5us(); /延时CY = SDA; /读应答信号SCL = 0; /拉低时钟线Delay5us(); /延时return CY;/向 IIC 总线发送一个字节数据void HMC5883_SendByte(BYTE dat)BYTE i;for (i=0; i8; i+) /8 位计数器dat = 1; /移出数据的最高位SDA = CY; /送数据口SCL = 1; /拉高时钟线Delay5us(); /延时SCL = 0; /拉低时钟线Delay5us(); /延时HMC5883_RecvACK();/从 IIC 总线接
13、收一个字节数据BYTE HMC5883_RecvByte()BYTE i;BYTE dat = 0;SDA = 1; /使能内部上拉, 准备读取数据,for (i=0; i8; 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_Sen
14、dByte(SlaveAddress); /发送设备地址+写信号HMC5883_SendByte(REG_Address); /内部寄存器地址,请参考中文 pdf HMC5883_SendByte(REG_data); /内部寄存器数据,请参考中文 pdfHMC5883_Stop(); /发送停止信号/单字节读取内部寄存器uchar Single_Read_HMC5883(uchar REG_Address) uchar REG_data;HMC5883_Start(); /起始信号HMC5883_SendByte(SlaveAddress); /发送设备地址+写信号HMC5883_SendB
15、yte(REG_Address); /发送存储单元地址,从 0 开始HMC5883_Start(); /起始信号HMC5883_SendByte(SlaveAddress+1); /发送设备地址+读信号REG_data=HMC5883_RecvByte(); /读出寄存器数据HMC5883_SendACK(1); HMC5883_Stop(); /停止信号return REG_data; /连续读出 HMC5883 内部角度数据void Multiple_read_HMC5883(void) uchar i;HMC5883_Start(); /起始信号HMC5883_SendByte(Slav
16、eAddress); /发送设备地址+写信号HMC5883_SendByte(0x03); /发送存储单元地址,从 0x3 开始HMC5883_Start(); /起始信号HMC5883_SendByte(SlaveAddress+1); /发送设备地址+读信号for (i=0; i6; i+) /连续读取 6 个地址数据,存储中 BUFBUFi = HMC5883_RecvByte(); /BUF0存储数据if (i = 5)HMC5883_SendACK(1); /最后一个数据需要回 NOACKelseHMC5883_SendACK(0); /回应 ACKHMC5883_Stop(); /
17、停止信号Delay5ms();/*主程序*/void main() unsigned int i;int x,y,z;double angle;delay(500);UART_init();Init_HMC5883();delay(600);BUF0 = Single_Read_HMC5883(0x03);BUF1 = Single_Read_HMC5883(0x04);BUF2 = Single_Read_HMC5883(0x05);BUF3 = Single_Read_HMC5883(0x06);BUF4 = Single_Read_HMC5883(0x07);BUF5 = Single_
18、Read_HMC5883(0x08);x=BUF0 8 | BUF1; /Combine MSB and LSB of X Data output registerz=BUF2 8 | BUF3; /Combine MSB and LSB of Z Data output registery=BUF4 8 | BUF5; /Combine MSB and LSB of Y Data output registerangle= atan2(double)y,(double)x) * (180 / 3.14159265) + 180; / angle in degreesangle*=10;con
19、version(angle); /计算数据和显示Bufer0=(“qian=“,qian); Bufer1=(“bai=“,bai); Bufer2=(“shi=“,shi); Bufer3=(.); Bufer4=(“ge=“,ge); Bufer5=(,); UART_send_string(Bufer);for (i=0;i10000;i+); /延时 UART_send_string(Bufer);for (i=0;i10000;i+); /延时 UART_send_string(Bufer);for (i=0;i10000;i+); /延时 UART_send_string(Bufe
20、r);for (i=0;i10000;i+); /延时 UART_send_string(Bufer);for (i=0;i10000;i+); /延时 UART_send_string(Bufer);leave_HMC5883();while(1) Multiple_Read_HMC5883();/连续读出数据,存储在 BUF 中x=BUF0 8 | BUF1; /Combine MSB and LSB of X Data output registerz=BUF2 8 | BUF3; /Combine MSB and LSB of Z Data output registery=BUF4
21、8 | BUF5; /Combine MSB and LSB of Y Data output registerangle= atan2(double)y,(double)x) * (180 / 3.14159265) + 180; / angle in degreesangle*=10;conversion(angle); /计算数据和显示Bufer0=(“qian=“,qian); Bufer1=(“bai=“,bai); Bufer2=(“shi=“,shi); Bufer3=(.); Bufer4=(“ge=“,ge); Bufer5=(,); UART_send_string(Bufer);for (i=0;i10000;i+); /延时 /*主程序*/