10807|8

2856

帖子

260

TA的资源

五彩晶圆(高级)

楼主
 

【TI首届低功耗设计大赛】三轴加速度演示 [复制链接]

本帖最后由 ltbytyn 于 2014-11-17 23:18 编辑

硬件部分:MSP430FR5969 Launchpad+430BOOST-SHARP96+ADXL345
ADXL345数字三轴重力加速度芯片,支持I2C\SPI两种接口,本设计中采用I2C接口。MSP430FR5969事实上是有硬件I2C接口,但是与430BOOST-SHARP96连接后,I2C接口(P1.6/P1.7)被占用。只有P2.5\P2.6\P3.0可做他用,这三个脚均不支持硬件I2C,故使用IO模拟I2C。
I2C硬件连接
P2.6   <——————>  SDA
P2.5   <——————>  SCL
P3.0预留
  1. #define I2C_DIR  P2DIR
  2. #define I2C_OUT  P2OUT
  3. #define I2C_IN   P2IN
  4. #define I2C_SCL  0x20     //SCL P2.5
  5. #define I2C_SDA  0x40     //SDA P2.6

  6. #define SDA_HIGH     I2C_OUT |= I2C_SDA//SDA_HIGH
  7. #define SDA_LOW      I2C_OUT &= ~I2C_SDA//SDA_LOW
  8. #define SCL_HIGH     I2C_OUT |= I2C_SCL//SCL_HIGH
  9. #define SCL_LOW      I2C_OUT &= ~I2C_SCL//SCL_LOW

  10. #define SET_SDA_IN   I2C_DIR &= ~I2C_SDA  //SET SDA IN
  11. #define SET_SDA_OUT  I2C_DIR |= I2C_SDA   //SET SDA OUT

  12. #define SDA_IN ( I2C_IN & I2C_SDA)  //READ SDA DATA

  13. #define        SlaveAddress   0xA6          //定义器件在IIC总线中的从地址,根据ALT  ADDRESS地址引脚不同修改
  14.                               //ALT  ADDRESS引脚接地时地址为0xA6,接电源时地址为0x3A
复制代码
  1. /**************************************
  2. 起始信号
  3. **************************************/
  4. void ADXL345_Start(void)
  5. {
  6.     SET_SDA_OUT;
  7.     SDA_HIGH;                    //拉高数据线
  8.     SCL_HIGH;                    //拉高时钟线
  9.     Delay5us();                 //延时
  10.     SDA_LOW;                    //产生下降沿
  11.     Delay5us();                 //延时
  12.     SCL_LOW;                    //拉低时钟线
  13. }

  14. /**************************************
  15. 停止信号
  16. **************************************/
  17. void ADXL345_Stop(void)
  18. {
  19.     SET_SDA_OUT;
  20.     SDA_LOW;                    //拉低数据线
  21.     SCL_HIGH;                    //拉高时钟线
  22.     Delay5us();                 //延时
  23.     SDA_HIGH;                    //产生上升沿
  24.     Delay5us();                 //延时
  25. }

  26. /**************************************
  27. 发送应答信号
  28. 入口参数:ack (0:ACK 1:NAK)
  29. **************************************/
  30. void ADXL345_SendACK(uchar ack)
  31. {
  32.     SET_SDA_OUT;
  33.     if(ack)
  34.       SDA_HIGH;                //写NACK应答信号
  35.     else
  36.       SDA_LOW;                 //写ACK应答信号
  37.     SCL_HIGH;                    //拉高时钟线
  38.     Delay5us();                 //延时
  39.     SCL_LOW;                    //拉低时钟线
  40.     Delay5us();                 //延时
  41. }

  42. /**************************************
  43. 接收应答信号
  44. **************************************/
  45. uchar ADXL345_RecvACK(void)
  46. {
  47.     unsigned char ack;
  48.     SCL_HIGH;                    //拉高时钟线
  49.     SET_SDA_IN;
  50.     Delay5us();                 //延时
  51.     ack = SDA_IN;                   //读应答信号
  52.     SCL_LOW;                    //拉低时钟线
  53.     Delay5us();                 //延时

  54.     return ack;
  55. }

  56. /**************************************
  57. 向IIC总线发送一个字节数据
  58. **************************************/
  59. void ADXL345_Senduchar(uchar dat)
  60. {
  61.     uchar i,m;
  62.     SET_SDA_OUT;
  63.     for (i=8; i!=0; i--)         //8位计数器
  64.     {
  65.         m=dat&0x80;           //移出数据的最高位
  66.         if(m==0x80)
  67.             SDA_HIGH;
  68.         else
  69.             SDA_LOW;
  70.         SCL_HIGH;                //拉高时钟线
  71.         Delay5us();             //延时
  72.         SCL_LOW;                //拉低时钟线
  73.         dat=dat<<1;
  74.         Delay5us();             //延时
  75.     }
  76.     ADXL345_RecvACK();
  77. }

  78. /**************************************
  79. 从IIC总线接收一个字节数据
  80. **************************************/
  81. uchar ADXL345_Recvuchar(void)
  82. {
  83.     uchar i;
  84.     uchar dat = 0;
  85.     uchar m;
  86.     SDA_HIGH;                    //使能内部上拉,准备读取数据,
  87.     SET_SDA_IN;
  88.     for (i=8; i!=0; i--)         //8位计数器
  89.     {
  90.         dat <<= 1;
  91.         SCL_HIGH;                //拉高时钟线
  92.         SET_SDA_IN;
  93.         m = SDA_IN;
  94.         if(m == I2C_SDA)
  95.             dat = dat|0x01;
  96.         Delay5us();             //延时
  97.         SCL_LOW;                //拉低时钟线
  98.         Delay5us();             //延时
  99.     }
  100.     return dat;
  101. }

  102. //******单字节写入*******************************************

  103. void Single_Write_ADXL345(uchar REG_Address,uchar REG_data)
  104. {
  105.     ADXL345_Start();                  //起始信号
  106.     ADXL345_Senduchar(SlaveAddress);   //发送设备地址+写信号
  107.     ADXL345_Senduchar(REG_Address);    //内部寄存器地址,请参考中文pdf22页
  108.     ADXL345_Senduchar(REG_data);       //内部寄存器数据,请参考中文pdf22页
  109.     ADXL345_Stop();                   //发送停止信号
  110. }

  111. //********单字节读取*****************************************
  112. uchar Single_Read_ADXL345(uchar REG_Address)
  113. {  uchar REG_data;
  114.     ADXL345_Start();                          //起始信号
  115.     ADXL345_Senduchar(SlaveAddress);           //发送设备地址+写信号
  116.     ADXL345_Senduchar(REG_Address);                   //发送存储单元地址,从0开始
  117.     ADXL345_Start();                          //起始信号
  118.     ADXL345_Senduchar(SlaveAddress+1);         //发送设备地址+读信号
  119.     REG_data=ADXL345_Recvuchar();              //读出寄存器数据
  120.         ADXL345_SendACK(1);
  121.         ADXL345_Stop();                           //停止信号
  122.     return REG_data;
  123. }
  124. //*********************************************************
  125. //
  126. //连续读出ADXL345内部加速度数据,地址范围0x32~0x37
  127. //
  128. //*********************************************************
  129. void Multiple_Read_ADXL345(void)
  130. {
  131.         uchar i;
  132.     ADXL345_Start();                          //起始信号
  133.     ADXL345_Senduchar(SlaveAddress);           //发送设备地址+写信号
  134.     ADXL345_Senduchar(0x32);                   //发送存储单元地址,从0x32开始
  135.     ADXL345_Start();                          //起始信号
  136.     ADXL345_Senduchar(SlaveAddress+1);         //发送设备地址+读信号
  137.          for (i=0; i<6; i++)                      //连续读取6个地址数据,存储中BUF
  138.     {
  139.         BUF[i] = ADXL345_Recvuchar();          //BUF[0]存储0x32地址中的数据
  140.         if (i == 5)
  141.         {
  142.            ADXL345_SendACK(1);                //最后一个数据需要回NOACK
  143.         }
  144.         else
  145.         {
  146.           ADXL345_SendACK(0);                //回应ACK
  147.         }
  148.    }
  149.     ADXL345_Stop();                          //停止信号
  150.         for(i=0;i<3;i++)
  151.         {
  152.                 Result =  ((BUF[i*2+1]<<8) + BUF[i*2]);
  153.                 //if(Result<0)
  154.                 //  Result = -Result;
  155.                 buffer[cnt][i] = (float)Result*3.9;
  156.         }
  157.         cnt++;
  158.         if(cnt>99)
  159.           cnt = 0;
  160. //        read_i2c_flag = 0;
  161.     Delay5ms();
  162. }


  163. //*****************************************************************

  164. //初始化ADXL345,根据需要请参考pdf进行修改************************
  165. void Init_ADXL345(void)
  166. {
  167.    Single_Write_ADXL345(0x31,0x0B);   //测量范围,正负16g,13位模式
  168.    Single_Write_ADXL345(0x2C,0x08);   //速率设定为12.5 参考pdf13页
  169.    Single_Write_ADXL345(0x2D,0x08);   //选择电源模式   参考pdf24页
  170.    Single_Write_ADXL345(0x2E,0x80);   //使能 DATA_READY 中断
  171.    Single_Write_ADXL345(0x1E,0x00);   //X 偏移量 根据测试传感器的状态写入pdf29页
  172.    Single_Write_ADXL345(0x1F,0x00);   //Y 偏移量 根据测试传感器的状态写入pdf29页
  173.    Single_Write_ADXL345(0x20,0x05);   //Z 偏移量 根据测试传感器的状态写入pdf29页
  174. }
复制代码

演示视频(先沿X轴方向改变,随后沿Y轴方向改变,最后改变Z轴):

ADXL345快速入门AN-1077_cn.pdf (347.33 KB, 下载次数: 27)
ADXL345中文PDF.pdf (874.7 KB, 下载次数: 31)
本例实现读取三轴加速度数据及显示,未考虑低功耗的应用。430玩的就是低功耗。一切与低功耗无关的430设计都是失败的设计。所以针对目前的程序,后续会对其进行低功耗优化。


最新回复

@ltbytyn 终于用找到程序中的错误,结果让我很不淡定,我只修改了大哥接收应答信号函数,调换SCL_HIGH;  SET_SDA_IN;即先设置为输入,(即使有SDA变化,也不会被从机采集到)就搞定了。各种蛋疼啊。 我把逻辑分析仪得到的错误数据共享出来, [attach]179660[/attach]   详情 回复 发表于 2014-11-23 02:39

赞赏

1

查看全部赞赏

 
点赞 关注(2)

回复
举报

2056

帖子

0

TA的资源

五彩晶圆(初级)

沙发
 
谢谢楼主分享
 
 

回复

2144

帖子

3

TA的资源

五彩晶圆(中级)

板凳
 
这屏幕相当不错
 
个人签名电工
 
 

回复

2856

帖子

260

TA的资源

五彩晶圆(高级)

4
 
屏小,显示效果确实不错的。
 
 
 

回复

106

帖子

0

TA的资源

一粒金砂(中级)

5
 
楼主,借用你的IIC, MSP430G2553驱动MPU6050,可是读取的数据全是0XFF,https://bbs.eeworld.com.cn/thread-451208-1-1.html

点评

注意延时  详情 回复 发表于 2014-11-18 14:24
 
 
 

回复

2856

帖子

260

TA的资源

五彩晶圆(高级)

6
 
王项电子 发表于 2014-11-18 14:02
楼主,借用你的IIC, MSP430G2553驱动MPU6050,可是读取的数据全是0XFF,https://bbs.eeworld.com.cn/thread-4 ...

注意延时                                                         

点评

@ltbytyn[/backcolor] 终于用找到程序中的错误,结果让我很不淡定,我只修改了大哥接收应答信号函数,调换SCL_HIGH; SET_SDA_IN;即先设置为输入,(即使有SDA变化,也不会被从机采集到)就搞定了。各种蛋疼啊。 我  详情 回复 发表于 2014-11-23 02:39
 
 
 

回复

5979

帖子

8

TA的资源

版主

7
 
写的很详细,如果能加上图片就更好了
 
个人签名生活就是油盐酱醋再加一点糖,快活就是一天到晚乐呵呵的忙
===================================
做一个简单的人,踏实而务实,不沉溺幻想,不庸人自扰
 
 

回复

3414

帖子

0

TA的资源

纯净的硅(高级)

8
 
液晶真不错
 
个人签名

So TM what......?

 

 

回复

106

帖子

0

TA的资源

一粒金砂(中级)

9
 

@ltbytyn 终于用找到程序中的错误,结果让我很不淡定,我只修改了大哥接收应答信号函数,调换SCL_HIGH;  SET_SDA_IN;即先设置为输入,(即使有SDA变化,也不会被从机采集到)就搞定了。各种蛋疼啊。
我把逻辑分析仪得到的错误数据共享出来,
错误模拟iic.rar (1.23 MB, 下载次数: 3)

 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表