美新加速度传感器角度传感器I2C总线
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
MXC6202xGHMN 是低成本、双轴加速度计,芯片具有混合信号处理功能和集成式IIC总线,允许该设备直接连接到微处理器。
可以同时测量动态加速度(如振动)和静态加速度(如重力)。
分辨率优于1mg(g为重力加速度),量程±2g。
它输出即为数字量,所以省去了模数转换所需的硬件和时间,数字量输出方式为IIC总线。
总的来说使用该传感器可以电路硬件简化。
MXC6202各引脚定义如图:
从美新提供的说明书来看芯片外围电路也很简单,主要包括2.7-3.6V的供电部分,IIC总线的上拉电阻和电源去噪部分。
电源去噪可使用0.1uF的电容,IIC上拉电阻10kΩ即可。
供电部分可使用1N4728a稳压管,测量显示串联电阻
为20-50Ω时稳压管端电压为3V左右。
应用电路如图:
MXC6202xx说明书数据通信部分的简单翻译
并没有完全依照原文翻译,中间加入了一些内容,部分专业术语很可能用错了,将就一下吧。
下文中主机指IIC通信主设备(以51单片机为例,型号为
STC89C54RD+),从机即IIC从设备指美新加速度计,型号为MXC62020G。
数据通信示例:
第一周期:主机发出START指令,然后发送从机地址[0010xxx]包含写信号(第8时钟脉冲,SDA保持低电平,其实就是发送信号0010xxx0)。
[xxx](地址位)已由工厂编程决定,一共有8种不同的可用地址。
([xxx]从芯片的型号标识C6202xx 中前一个x可以看出,具体见附图1。
我手中的芯片为C62020G,对应[xxx]是[000])第二周期:主机接收到应答信号(芯片在第9个时钟脉冲期间保持SDA为低电平)后,主机发送[00000000]作为被写入数据的地址。
从机应当在结束时发出应答信号(从机在第9个时钟脉冲期间保持SDA为低电平,以下提到的应答信号非特殊说明均为此种含义)。
注意:因为美新的此种芯片只有一个可被写入的内部寄存器,使用者应当只声明[00000000]作为写入地址。
第三周期:主机向从机写入代码[xxxxxxx0]作为唤醒信号,从机应答,使用STOP 指令结束写入过程。
等待75ms以便从机从低能耗模式回到正常模式,等待时间由从机型号决定,一般来说,低功耗产品需要比较长的唤醒时间。
第四周期:主机发送START指令,然后发送从机地址包含写信号(参照第一周期)。
从机发出应答信号作为结尾。
第五周期:主机向从机写代码[00000000]作为内部寄存器被读取的开始地址,从这个地址开始的读取可以作为操作验证并用于确认写入指令是成功的。
注意:开始地址原则上可以是5个地址中的一个(这五个地址见附图2)。
例如使用者可以从地址[00000001]开始读取,该地址是X方向数据的高8位。
从机应答。
另,因为
第六周期发送地址信号是[0010xxx1],与先前的[0010xxx0]不同,主机需要再发送一次START指令(原文中没有提到这一点)。
第六周期:主机发送从机地址包含读信号(第8时钟脉冲,SDA保持高电平,其实就是发送信号0010xxx1)。
从机应答(从机在第9时钟脉冲时保持SDA为低电平)。
第七周期:主机控制时钟脉冲,内部寄存器第一个地址上的数据出现在SDA线上,如果在第五周期(原文中为step 7,怀疑是打错了)写入的代码是[00000000],出现的应该是内部控制寄存器数据,从机应答。
第八周期:主机继续控制时钟脉冲,内部寄存器的下一字节数据出现在SDA线上(X方向数据的高8位),内部寄存器指针会自动移向下一字节。
主机应答。
第九周期:X方向的低8位。
主机应答。
如果内部控制寄存器的TEON位已被设为1,则上面两个周期出现的应当是TOUT(温度)的高8位和低8位。
第十周期:Y方向数据的高8位。
主机应答。
第十一周期:Y方向数据的低8位。
主机发送非应答信号(主机在一个时钟脉冲期间保持SDA为高电平)后发出STOP 指令以结束通信。
注意:如果主机继续控制时钟脉冲,内部寄存器指针将到达第6和第7的位置,which always have [00000000](这个看不懂)。
第7个位置之后,指针将回到0位置
注意:主机通过写入内部控制寄存器数据使从机进入低能耗模式。
原文:
EXAMPLE OF DATA COMMUNICATION
First cycle: START followed by a calling to slave address [0010xxx] to WRITE (8th SCL, SDA keep low). [xxx] Is determined by factory programming, a total of 8 different addresses are available.
Second cycle: After an acknowledge signal is received by the master device (Memsic device pulls SDA line low during 9th SCL pulse), master device sends “[00000000]” as the target address to be written into. Memsic device
should acknowledge at the end (9th SCL pulse). Note: since Memsic device has only one internal register that can be written into, user should always indicate “[00000000]” as the write address.
Third cycle: Master device writes to internal Memsic device memory code “[xxxxxxx0]” as a wake-up call. The Memsic device should send acknowledge signal. A STOP command indicates the end of write operation. A 75msS (typical) wait period should be given to Memsic device to return from a power-down mode. The delay value depends on the type of Memsic device. Generally speaking, low power products tend to have longer startup time. Fourth cycle: Master device sends a START command followed by calling Memsic device address with a WRITE (8th SCL, SDA keep low). An “acknowledge”should be sent by Memsic device at the end.
Fifth cycle: Master device writes to Memsic device a “[00000000]” as the starting address for which internal memory is to be read. Since “[00000000]” is the address of internal control register, reading from this address can serve as a verification of operation and to confirm the write command has been successful. Note: the starting address in principle can be any of the 5 addresses. For example, user can start read from address [0000001], which is X channel MSB.
Sixth cycle: Master device calls Memsic device address with a READ (8th SCL cycle SDA line high). Memsic device should acknowledge at the end. Seventh cycle: Master device cycles SCL line, first addressed memory data appears on SDA line. If in step 7, “[00000000]” was sent, internal control register datashould appear (in the following steps, this case is assumed). Master device should send acknowledge at the end.
Eighth cycle: Master device continues cycle SCL line, next byte of internal memory should appear on SDA line (MSB of X channel). The internal memory address pointer automatically moves to the next byte. Master acknowledges. Ninth cycle: LSB of X channel. In the case that TOEN bit of internal register was set to “1”, the MSB and LSB of TOUT (temperature) should appear in last two steps.
Tenth cycle: MSB of Y channel.
Eleventh cycle: LSB of Y channel.
Master ends communications by sending NO acknowledge and followed by a STOP command. Note: if mater device continues to cycle SCL line, the memory pointer will go to sixth and seventh positions, which always have “[00000000]”. After seventh position, pointer will go to zero again. Optional: Master powers down Memsic device by writing into internalcontrol register. (See step 1 through 4 for WRITE operation)
美新MXC6202加速度计数据的读取和显示 C程序
2010-06-16 20:45
#include<reg52.h>
#include<math.h> //需要用到求绝对值函数#define uchar unsigned char
#define uint unsigned int
float xg,yg;
uchar str0[]={"X-X:"};
uchar str1[]={"Y-Y:"};
uchar s[]={"0123"};
sbitsda=P2^1;
sbitscl=P2^0;
sbitlcdrs=P2^4;
sbitlcden=P2^6;
sbitlcdrw=P2^5;
sbitleden=P3^7;
/***************************************************************/ /***********定义两个延时函数,一个微妙级,一个毫秒级************/ void delay()
{ ; ; }
void delayms(uint z)
{
uinti,j;
for(i=z;i>0;i--)
for(j=115;j>0;j--);
}
/***************************************************************/ /***********LCD的写指令,写数据,定点插入及初始化***************/ void lcd_write_com(uchar com)
{
delayms(5);
lcdrs=0;
P0=com;
lcden=1;
delay();
lcden=0;
}
void lcd_write_data(uchar date)
{
delayms(5);
lcdrs=1;
P0=date;
lcden=1;
delay();
lcden=0;
}
void lcd_row_column_vector_len(ucharrow,ucharcolumn,uchar
*vector,ucharlen)
{
ucharposition,cnt;
position=128+row*64+column;
lcd_write_com(position);
for(cnt=0;cnt<len;cnt++)
{
lcd_write_data(*vector);
vector++;
}
}
void LCD_init()
{
leden=1;
P0=0x00;
delay();
leden=0; /*我使用的是DY_mini80型学习板,这四步程序是为了关闭数码管的显示功能*/
lcden=0;
lcdrw=0;
lcd_write_com(0x38);
lcd_write_com(0x0c);
lcd_write_com(0x06);
lcd_write_com(0x01);
lcd_row_column_vector_len(0,0,str0,4);
lcd_row_column_vector_len(1,0,str1,4);
}
void start()
{
sda=1;
delay();
scl=1;
delay();
sda=0;
delay();
scl=0;
delay();
}
void stop()
{
sda=0;
delay();
scl=1;
delay();
sda=1;
delay();
}
void ack()
{
uchar i;
scl=1;
delay();
while((sda==1)&&(i<25))i++;
scl=0;
delay();
}
void write_byte(uchar date)
{
uchari,temp;
temp=date;
for(i=0;i<8;i++)
{
temp=temp<<1;
scl=0;
delay();
sda=CY;
delay();
scl=1;
delay();
scl=0;
}
scl=0;
delay();
sda=1;
delay();
}
ucharread_byte()
{
uchari,k;
scl=0;
delay();
sda=1;
delay();
for(i=0;i<8;i++)
{
scl=1;
delay();
k=(k<<1)|sda;
scl=0;
delay();
}
return k;
}
void acknowledge(uchar a) /*主机应答程序 acknowledge(0)为应答,acknowledge(1)为非应答*/
{
if(a==0)
sda=0;
else
sda=1;
delay();
scl=1;
delay();
scl=0;
delay();
}
void MXC_init()
{
start(); /*对应数据通信示例的第一至第三周期*/ write_byte(0x20);
ack();
write_byte(0x00);
ack();
write_byte(0xf0);
ack();
stop();
delayms(75);
}
/***************************************************************/
/*********获取4个字节的数据*************************************/ void receive5bytes()
{
uchar i;
start();
write_byte(0x20); //对应数据通信示例的第四周期
ack();
write_byte(0x01); //第五周期
ack();
start();
write_byte(0x21); //第六周期
ack();
for(i=0;i<3;i++) //第八至十周期(第七周期省略)
{
s[i]=read_byte();
acknowledge(0);
}
s[3]=read_byte(); //第十一周期acknowledge(1);
stop();
}
void II2()
{
uint x=0,y=0;
ucharsx[6],sy[6],abs_xg,abs_yg;
receive5bytes();
x=s[0]*256+s[1]; //
xg=x/512.0-4; /*数据的处理,C6202量程为-2g至+2g,G型号分辨率512counts/g,0g对应x值是
2048,有点矛盾*/
abs_xg=(unsigned char)abs((xg*100));
if(x<2048)
sx[0]='-';
else
sx[0]='+';
sx[1]=(unsigned char)abs(xg)+'0';
sx[2]='.';
sx[3]=(unsigned char)abs(xg*10)%10+'0';
sx[4]=(unsigned char)abs(xg*100)%10+'0';
sx[5]='g';
y=s[2]*256+s[3];
yg=y/512.0-4;
abs_yg=(unsigned char)abs((yg*100));
if(y<2048)
sy[0]='-';
else
sy[0]='+';
sy[1]=(unsigned char)abs(yg)+'0';
sy[2]='.';
sy[3]=(unsigned char)abs(yg*10)%10+'0';
sy[4]=(unsigned char)abs(yg*100)%10+'0';
sy[5]='g';
lcd_row_column_vector_len(0,4,sx,6);
lcd_row_column_vector_len(1,4,sy,6);
}
void main()
{
LCD_init(); //初始化LCD
MXC_init(); /*加速度计的唤醒(在此程序中因为传感器一直处于正常模式,所以没有这一步也可以)*/
while(1)
II2();
}。