6回答

0收藏

基于机智云的ADXL345的快速开发

机智云GoKit 机智云GoKit 3196 人阅读 | 6 人回复 | 2015-11-14

最近在做加速度相关的东东,一致过来让大家看看。
首先是关于ADXL345的代码,有两个文件,adxl345.cadxl345.h,这里使用了IIC模拟IIC通信的方式,使用引出脚A0A5中的任意引脚。

首先是选择模拟IIC通信的引脚,这里选择了A0A1左右通信引脚,其中A1引脚作为SDAA0作为SCL。这里有两种方式,一种是在添加文件中直接定义引脚,另一种是使用sa_gpio.c文件中的引脚初始化函数进行定义。
在代码中给出了这两种方式。用到的是sa_gpio.c中的引脚初始化函数。
  1. void start()
  2. {
  3.   SCL_OUT;
  4.   SDA_OUT;
  5.   SDA_H;
  6.   SCL_H;
  7.   Delay_us(2);
  8.   SDA_L;
  9.   Delay_us(2);
  10.   SCL_L;
  11. }

  12. void stop(void)
  13. {
  14.   SCL_OUT;
  15.   SDA_OUT;
  16.   SDA_L;
  17.   SCL_H;
  18.   Delay_us(2);
  19.   SDA_H;
  20.   Delay_us(2);
  21.   SCL_L;
  22. }

  23. void mack(void)
  24. {
  25.   SDA_OUT;
  26.   SCL_OUT;
  27.   SDA_L;
  28.   SCL_H;
  29.   Delay_us(2);
  30.   SCL_L;
  31.   SDA_H;
  32. }

  33. void mnack(void)
  34. {
  35.   SDA_OUT;
  36.   SCL_OUT;
  37.   SDA_H;
  38.   Delay_us(2);
  39.   SCL_H;
  40.   Delay_us(2);
  41.   SCL_L;
  42.   SDA_L;
  43. }

  44. void cack()
  45. {
  46.   SDA_IN;
  47.   SCL_OUT;
  48.   SCL_L;
  49.   Delay_us(2);
  50.   SCL_H;
  51.   err=0;
  52.   if(SDA_DATE)err=1;
  53.   SCL_L;
  54.   SDA_OUT;
  55. }

  56. void write1byte(uchar byte1)
  57. {
  58.   unsigned char i=8;
  59.   SDA_OUT;
  60.   SCL_OUT;
  61.   while(i--)
  62.   {
  63.     Delay_us(4);
  64.     if(byte1 & 0x80)
  65.     {SDA_H;}
  66.     else
  67.     {SDA_L;}
  68.     Delay_us(2);
  69.     SCL_H;
  70.     Delay_us(2);
  71.     SCL_L;
  72.     byte1<<=1;
  73.   }
  74. }

  75. uchar read1byte(void)
  76. {
  77.   unsigned char i;
  78.   unsigned char ddata=0;
  79.   signed    char temp;
  80.   SCL_OUT;
  81.   SDA_IN;
  82.   for(i=0;i<8;i++)
  83.   {
  84.     ddata<<=1;
  85.     Delay_us(4);
  86.     SCL_H;
  87.     temp=SDA_DATE;
  88.     if(temp) ddata++;
  89.     Delay_us(4);
  90.     SCL_L;
  91.   }
  92.   return ddata;
  93. }

  94. void Single_Write_ADXL345(uchar REG_Address,uchar REG_data)
  95. {
  96.   start();
  97.   write1byte(SlaveAddress);
  98.   cack();
  99.   write1byte(REG_Address);
  100.   cack();
  101.   write1byte(REG_data);
  102.   cack();
  103.   stop();
  104. }

  105. uchar Single_Read_ADXL345(uchar REG_Address)
  106. {
  107.   uchar REG_data;
  108.   start();
  109.   write1byte(SlaveAddress);
  110.   cack();
  111.   write1byte(REG_Address);
  112.   cack();
  113.   start();
  114.   write1byte(SlaveAddress+1);
  115.   cack();
  116.   REG_data=read1byte();
  117.   mnack();
  118.   stop();
  119.   return REG_data;
  120. }

  121. void Multiple_read_ADXL345(void)
  122. {
  123.   uchar i;
  124.   start();
  125.   write1byte(SlaveAddress);
  126.   cack();
  127.   write1byte(0x32);
  128.   cack();
  129.   start();
  130.   write1byte(SlaveAddress+1);
  131.   cack();
  132.   for (i=0; i<6; i++)
  133.   {
  134.     BUF[i] = read1byte();
  135.     if (i == 5)
  136.     {
  137.       mnack();
  138.     }
  139.     else
  140.     {
  141.       mack();
  142.     }
  143.   }
  144.   stop();
  145.   Delay_us(100);
  146. }

  147. void Init_ADXL345()
  148. {
  149.   RCC->APB2ENR|=1<<3;
  150.   Single_Write_ADXL345(0x31,0x0B);
  151.   Single_Write_ADXL345(0x2C,0x08);
  152.   Single_Write_ADXL345(0x2D,0x08);
  153.   Single_Write_ADXL345(0x2E,0x80);
  154.   Single_Write_ADXL345(0x1E,0x00);
  155.   Single_Write_ADXL345(0x1F,0x00);
  156.   Single_Write_ADXL345(0x20,0x05);
  157. }

  158. int Hecheng_data()
  159. {
  160.   int sum,a,b,c;
  161.   Multiple_read_ADXL345();
  162.   
  163.   data_xyz[0]=(BUF[1]<<8)+BUF[0];
  164.   data_xyz[1]=(BUF[3]<<8)+BUF[2];  
  165.   data_xyz[2]=(BUF[5]<<8)+BUF[4];

  166.         kaifang( data_xyz[0]*data_xyz[0]+data_xyz[1]*data_xyz[1]+data_xyz[2]*data_xyz[2]);
  167.   return sum;   
  168. }

  169. float kaifang( float number )
  170. {
  171.     long i;
  172.     float x2, y;
  173.     const float threehalfs = 1.5F;
复制代码
main函数中只需要增加adxl的初始化函数。
  1. int main(void)
  2. {
  3.         SystemInit();
  4.         UARTx_Init();
  5.         Printf_SystemRccClocks();
  6.         RTC_Init();
  7.         Hal_Init();
  8.         McuStatusInit();
  9.         Init_ADXL345();
  10.         Delay_Init(8);
  11.         while(1)
  12.         {
  13.                 MessageHandle();
  14.                 KEY_Handle();               
  15.                 IR_Handle();
  16.                 DHT11_Read_Data(&Device_ReadStruct.Temperature, &Device_ReadStruct.Humidity);
  17.                 ReportDevStatusHandle();
  18.                 Hecheng_data();
  19.         }
  20. }
复制代码
其中在adxl.c中增加了一个很有用的快速开方算法。这个在网上无意中找到的开方算法可以快速的实现开方运算,比math中自带的开方算法要快很多。有兴趣的同学可以看看这个链接对应的介绍。非常给力哦,计算速度超快。
http://blog.sina.com.cn/s/blog_6cd2030b01018fp8.html


分享到:
回复

使用道具 举报

回答|共 6 个

倒序浏览

沙发

shaoziyang

发表于 2015-11-15 09:49:39 | 只看该作者

快速开方运算是什么原理?
板凳

liujincai

发表于 2015-11-16 10:14:27 | 只看该作者

同问,快速开方运算是什么原理?
地板

rui199009

发表于 2015-11-29 21:35:05 | 只看该作者

抱歉哈,具体原理我也不明了。根据我发的链接的博主查到的资料,应该是国外某个游戏软件工程师写的,具体是为了解决游戏引擎中的问题,这个代码可以以非常快速完成开方运算,但是输出的却是倒数,我在代码中已经再次倒数了一下,所以输出的是接近开方的值。国外一个教授也仔细研究过这个算法,最后用穷举法找到了一个比原本算法中的固定的值更好的一个固定的值。


这里附上代码:
5#

rui199009

发表于 2015-11-29 21:37:57 | 只看该作者

想深入研究的同学,可以看我帖子中的那个链接哦。
6#

lcr12

发表于 2015-11-29 22:01:55 | 只看该作者

浮点运算不错
您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条