OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4606|回复: 6

关于STM32F103VET6读取ADXL345问题

[复制链接]

2

主题

6

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2015-4-30
在线时间
0 小时
发表于 2015-4-30 17:41:37 | 显示全部楼层 |阅读模式
5金钱
最近做一个项目用ADXL345芯片测量加速度,然后进行速度和位移的求解,加速度芯片是从网上买的模块,用的模拟I2C通信,程序是按照原子哥的代码写的,可是不知道为啥,当模块平放在桌子上时,读取Z轴的加速度,总会出现一些波动较大的点,完全超过芯片手册上写的零飘,求用过模拟I2C的大神们指点下,谢谢了!
[mw_shl_code=c,true]void I2C_init(void) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = I2C_SCL|I2C_SDA; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOB,&GPIO_InitStructure); //I2C_SCL_H; //I2C_SDA_H; } void I2C_SDA_OUT(void) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin =I2C_SDA; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOB,&GPIO_InitStructure); } void I2C_SDA_IN(void) { GPIO_InitTypeDef GPIO_InitStructureA; GPIO_InitStructureA.GPIO_Pin =I2C_SDA; GPIO_InitStructureA.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIO_I2C, &GPIO_InitStructureA); } void I2C_START(void) { I2C_SDA_OUT(); I2C_SCL_H; I2C_SDA_H; delay_us(4); //6 I2C_SDA_L; delay_us(4); //6 I2C_SCL_L; } void I2C_STOP(void) { I2C_SDA_OUT(); I2C_SCL_L; I2C_SDA_L; delay_us(4); I2C_SCL_H; delay_us(4); //6 I2C_SDA_H; delay_us(4); //6 } void I2C_ACK(void) { I2C_SCL_L; I2C_SDA_OUT(); I2C_SDA_L; delay_us(2); //2 I2C_SCL_H; delay_us(2); //5 I2C_SCL_L; } void I2C_NACK(void) { I2C_SCL_L; I2C_SDA_OUT(); I2C_SDA_H; delay_us(2); //2 I2C_SCL_H; delay_us(2); //5 I2C_SCL_L; } u8 I2C_Wait_ACK(void) { u8 temp=0; I2C_SDA_IN(); I2C_SDA_H; delay_us(1); //1 I2C_SCL_H; delay_us(1); //1 while(GPIO_ReadInputDataBit(GPIO_I2C,I2C_SDA)) { temp++; if(temp>250) { I2C_STOP(); return 1; //返回值1 接收应答失败 } } I2C_SCL_L; return 0; } void I2C_Send_BYTE(u8 txd) { u8 i=0; I2C_SDA_OUT(); I2C_SCL_L;//拉低时钟初始 for(i=0;i<8;i++) { if((txd&0x80)>0) I2C_SDA_H; else I2C_SDA_L; txd<<=1; delay_us(2); I2C_SCL_H; delay_us(2); //2 I2C_SCL_L; delay_us(2); //2 } } u8 I2C_Read_BYTE(u8 ack) { u8 i=0; u8 receive; I2C_SDA_IN(); for(i=0;i<8;i++) { I2C_SCL_L; delay_us(2); //5 I2C_SCL_H; receive<<=1; if(GPIO_ReadInputDataBit(GPIO_I2C,I2C_SDA)) receive++; delay_us(1); //5 } if(ack==0) I2C_NACK(); else I2C_ACK(); return receive; }[/mw_shl_code]
上面是I2C的代码





[mw_shl_code=c,true]u8 ADXL345_ReadOneByte(u8 addr) { u8 temp=0; I2C_START(); I2C_Send_BYTE(0xA6); I2C_Wait_ACK(); I2C_Send_BYTE(addr); I2C_Wait_ACK(); I2C_START(); I2C_Send_BYTE(0xA7); I2C_Wait_ACK(); temp = I2C_Read_BYTE(0); I2C_STOP(); return temp; } void ADXL345_WriteOneByte(u8 addr,u8 data) { I2C_START(); I2C_Send_BYTE(0xA6); if(I2C_Wait_ACK()==0) { I2C_Send_BYTE(addr); if(I2C_Wait_ACK()==0) I2C_Send_BYTE(data); } I2C_STOP(); delay_ms(10); } u8 ADXL345_init(void) { if(ADXL345_ReadOneByte(0x00)==0xE5) { ADXL345_WriteOneByte(0x2D,0x00); //设置芯片为待机模式 ADXL345_WriteOneByte(0x2C,0x0D); //带宽1600hz 输出速率3200hz ADXL345_WriteOneByte(0x31,0x29); //低电平中断输出,10位全分辨率,输出数据右对齐,4g量程 ADXL345_WriteOneByte(0x2E,0x00); //中断不使能 ADXL345_WriteOneByte(0x1E,0x00); //X,Y,Z偏移 ADXL345_WriteOneByte(0x1F,0x00); ADXL345_WriteOneByte(0x20,0x00); ADXL345_WriteOneByte(0x2D,0x08); //测量模式 return 0; } return 1; } void ADXL345_Read_XYZ(short *x,short *y,short *z) { u8 BUF[2]; u8 i; I2C_START(); I2C_Send_BYTE(0xA6); //发送写器件指令 I2C_Wait_ACK(); I2C_Send_BYTE(0x36); //发送寄存器地址(数据缓存的起始地址为0X32) I2C_Wait_ACK(); //delay_us(2); I2C_START(); //重新启动 I2C_Send_BYTE(0xA7); //发送读器件指令 I2C_Wait_ACK(); for(i=0;i<2;i++) { if(i==1) BUF = I2C_Read_BYTE(0); else BUF = I2C_Read_BYTE(1); } I2C_STOP(); //*x=(short)(((u16)BUF[1]<<8)+BUF[0]); //*y=(short)(((u16)BUF[3]<<8)+BUF[2]); *z=(short)(((u16)BUF[1]<<8)+BUF[0]); }[/mw_shl_code]

求各位帮帮忙了非常感谢!

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-4-30 22:59:22 | 显示全部楼层
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

2

主题

6

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2015-4-30
在线时间
0 小时
 楼主| 发表于 2015-5-4 10:29:51 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
没有加自动校准函数,一定需要加吗?
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-5-5 00:19:43 | 显示全部楼层
回复【3楼】孤独的菜鸟:
---------------------------------
必须的
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

2

主题

6

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2015-4-30
在线时间
0 小时
 楼主| 发表于 2015-5-8 14:25:27 | 显示全部楼层
回复【4楼】正点原子:
---------------------------------
自校准就是利用前面测试的100个数据做平均值,然后加入到偏移寄存器里是吗? 那是不是数越多越精确
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-5-8 23:11:40 | 显示全部楼层
回复【5楼】孤独的菜鸟:
---------------------------------
这个,也没必要吧,太多了时间就浪费了。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

2

主题

6

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2015-4-30
在线时间
0 小时
 楼主| 发表于 2015-5-13 09:27:26 | 显示全部楼层
回复【6楼】正点原子:
---------------------------------
我的测量分为2部分,前一段一直测量1ms/一次  存最近的1000个数据,然后当产生突变的时候测量3000个数据 用最近的1000个数据进行计算平均值补偿,可是测试了几次发现那3000个数据进过补偿以后得到的在1006左右 这样是正常的吗?不是应该在980左右吗
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-22 22:05

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表