小试牛刀之nios2中采用SPI和I2C总线操作ADXL345经验总结
ADXL345是ADI公司推出的三轴(x,y,z)iMEMS数字加速度计(digital accelerometer),具有在16G下高分辨率(13Bit)测量能力,同时具备16Bit数字输出。ADXL345 适用于静态倾角测量以及动态加速度测量,高达4mg/LSB的灵敏度允许测量小于1度的倾角。
该传感器还具备单击 /双击探测,自由落体探测,并允许用户设置一个加速度阀值,当加速度值超过设定阀值后可以产生一个信号输出。所有这些功能都可以映射到2个中断上。内置的32级FIFO缓存可以极大的缓解处理器的压力。
特点:
2.0 - 3.6VDC供电电压
超低功耗: 40uA的测量模式, 0.1uA在standby@2.5V
单击/双击检测
自由落体检测
用户阀值设定
SPI和I2C接口
ADXL345以+2.5V的电源电压工作时的消耗电流控制为标准25μ~130μA。该产品可比与3轴惯性传感器节约80%的耗电量。主要面向手机、便携式游戏机、游戏机控制器以及PND等。还支持硬盘的跌落检测等。
可检测的加速度范围为±2/4/8/16G。集成了FIFO(First-in, First-out)型存储器,最多可存储32组3轴数据。耐冲击性为1万G。输出接口备有I2C和SPI。数据输出速度为0.1~3.2kHz。
电源电压(Vs)为+2.0~3.6V,接口部分为+1.8V~Vs。工作温度范围为-40~+85℃。封装采用14端子的LFCSP。
1.ADXL345 SPI-4线模式的硬件连接电路
SPI-4线模式是adxl345默认的操作总线,无需配置即可用。,详见datasheet page25 DATA_FORMAT寄存器。
2.关于ADXL345的PI总线协议与标准的SPI协议的一些差异(标准的SPI协议可以参考http://baike.baidu.com/view/245026.htm?fr=ala0_1这里不做详细介绍)
标准的SPI总线时序中,每个字节之间的操作是断开的,即片选线SS_n和串行时钟线SCLK正在传输该字节时有效,其余时刻保持无效状态(即SS_n=1,SCLK=1)如下图:
ADXL345 datasheet中要求clock polarity (CPOL) = 1 and clock phase (CPHA) = 1,这可以在SOPC中选择SPI IP核作为nios2外设构建系统时,用GUI的方式方便的设置,其SPI操作的时序如下图:
从图中可以看到:SPI总线对ADXL345内部寄存器的读写操作都是以字节为单位进行的(这是由ADXL345内部30个可操作寄存器均为字节寄存器所决定的),然而每两个字节数据/地址之间CS_n和SCLK一直需要保持有效。
由以上分析,在采用Altera提供的nios2 SPI API函数alt_avalon_spi_command()访问ADXL345时,其最后一个参数 alt_u32 flags必须置为ALT_AVALON_SPI_COMMAMD_MERGE,该标志的意思是“把多个SPI访问命令/数据合并到一起”,若置为0,则是标准的SPI时序,每次访问后自动释放CS_n和SCLK。
3.读取ADXL345内部寄存器的顺序
先读取地址0x00的DEVID,device ID寄存器,正确之后再进行其他寄存器的操作。只要该器件具有唯一的ID号,首先读取器件ID寄存器并判断正确就应该是必要和首要的。如果读出ID正确了,至少可以证明我们操作时序正确了。O(∩_∩)O~,个人总结而已。当然,你如果看过linux下面外设的驱动程序,这样的操作时非常常见的,也就算是一种默认的规范吧!
4.ADXL345的SPI协议的第一字节
Bit7
|
Bit6
|
Bit5
|
Bit4
|
Bit3
|
Bit2
|
Bit1
|
Bit0
|
R/W
|
MB
|
A5
|
A4
|
A3
|
A2
|
A1
|
A0
|
说明:bit7:1—读,0—写;
Bit6:1—多字节读写;0—单字节操作;
Bit5~bit0:ADXL345内部寄存器地址A5~A0;
1.ADXL345 I2C通信模式的硬件连接电路
这里需要注意:a. cs_n必须上拉至VDD以启动I2C总线模式
b.SDA和SCL需上拉电阻,(2.2KΩ-400Kbitps,10KΩ—100kbitps)
c.SDA为双向通信端口,故在FPGA的IO配置时,需将其配置为inout类型,在SOPC中SDA信号线需设置为bidirectional(tri-state)ports。
d.ALT_ADDRESS的接法对应的ADXL345的设备从地址不一样,具体为:
若ALT_ADDRESS = 1,ADXL345_slave_addr=0x1D;
相应的I2C第一字节:read——0x3B,write——0x3A
若ALT_ADDRESS = 0,ADXL345_slave_addr=0x53;
相应的I2C第一字节:read——0xA7,write——0xA6
2.I2C时序操作要点
对ADXL345的I2C总线访问,只要严格按照NXP的i2c总线规范进行即可,可以采用nios2外挂I2C总线IP的方式实现,亦可以采用nios2 GPIO软件模拟的方式实现。
这里总结一下,初学者使用I2C总线是容易犯的错误:
如上,在用I2C总线协议访问ADXL345(其他所有的I2C器件也一样),无论是读操作还是写操作,I2C总线的SDA信号线上送出的第一字节都必须是SLAVE ADDRESS + WRITE,这一点切记不能搞错。我之前就是因为没有注意这一点,而在读ADXL345内部寄存器时,第一字节送成SLAVE ADDRESS + READ了,一直不出来数据,很是郁闷了半天。O(∩_∩)O~呵呵,最后改正确后,数据立马就出现了!!!!
凡是牵涉到时序的外设(比如常见的i2c,spi,lin,can总线器件)调试,时序都是第一位的,顺序不正确,命令送不起,数据配置不了,信息也读不出来。一般在我们会借助示波器,逻辑分析仪来判断硬件电路连接的通断。
但是,逻辑分析仪价格昂贵,不易获得。好在FPGA里面提供了嵌入式的逻辑分析仪——QuartusII中为signaltap II,ISE里面为chipscope。我们可以免费使用它们,设置好触发条件,观察FPGA板子上实时运行的信号状态和顺序,何乐而不为呢!
另外,我们也可以把手中的FPGA板子用作免费的逻辑分析仪来用!方法很简单,就是用Quartus II做一个简单的FPGA工程,引出一定数量的IO口,并用将所有的IO口信号配置为Signaltap II的输入捕捉,并根据所要观察的信号和顺序设置好触发条件,采样时钟以及采样深度,保存并连同Quartus工程一起整体编译下载sof文件运行即可。实时准确,配置灵活,百试不爽呀!
以上是我最近工作和学习的一些总结,在这里写出来与大家分享,希望能够对大家有所帮助!
同样,个人己见,不当之处难免,还望大牛赐教!
你们的反馈是对我博客的最大支持!
联系QQ:718059156
长期博客网址:http://huxiongwei.spaces.eepw.com.cn/
胡恩伟·重庆
重庆大学A区一舍426
2010年9月11日
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。