久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 14559|回復: 15
收起左側

ADXL345測傾斜角(程序)

  [復制鏈接]
ID:219529 發表于 2017-7-26 20:09 | 顯示全部樓層 |閱讀模式
ADXL345測傾斜角

單片機源程序如下:

  1. #include  <REG51.H>       
  2. #include  <math.h>    //Keil library  
  3. #include  <stdio.h>   //Keil library       
  4. #include  <INTRINS.H>

  5. #define   uchar unsigned char
  6. #define   uint unsigned int       
  7. #define   DataPort P0    //LCD1602數據端口

  8. sfr TUXR=0x8E;
  9. sfr CMOD=0xD9;
  10. sfr CCON=0xD8;
  11. sfr CL=0xE9;
  12. sfr CH=0xF9;
  13. sfr CCAPM0=0xDA;
  14. sfr CCAPM1=0xDB;
  15. sfr CCAP0L=0xEA;
  16. sfr CCAP0H=0xFA;
  17. sfr CCAP1L=0xEB;
  18. sfr CCAP1H=0xFB;
  19. sbit CR=CCON^6;


  20. sbit          SCL=P2^0;      //IIC時鐘引腳定義
  21. sbit           SDA=P2^1;      //IIC數據引腳定義
  22. sbit  p22=P2^2;
  23. sbit  p31=P3^1;
  24. sbit  p33=P3^3;
  25. sbit      LCM_RS=P2^6;   //LCD1602命令端口               
  26. sbit      LCM_RW=P2^5;   //LCD1602命令端口               
  27. sbit      LCM_EN=P2^7;   //LCD1602命令端口

  28. #define        SlaveAddress   0xA6        //定義器件在IIC總線中的從地址,根據ALT  ADDRESS地址引腳不同修改
  29.                             //ALT  ADDRESS引腳接地時地址為0xA6,接電源時地址為0x3A
  30. typedef unsigned char  BYTE;
  31. typedef unsigned short WORD;

  32. BYTE BUF[8];                         //接收數據緩存區             
  33. uchar ge,shi,bai,qian,wan;           //顯示變量  個十百千萬
  34. int  dis_data;                       //變量
  35. float jd;
  36. uint PWMH;
  37. void InitLcd();                      //初始化lcd1602
  38. void Init_ADXL345(void);             //初始化ADXL345

  39. void WriteDataLCM(uchar dataW);                // LCD1602相關函數
  40. void WriteCommandLCM(uchar CMD,uchar Attribc); //
  41. void DisplayOneChar(uchar X,uchar Y,uchar DData); //
  42. void conversion(uint temp_data);        //數據處理

  43. void  Single_Write_ADXL345(uchar REG_Address,uchar REG_data);   //單個寫入數據
  44. uchar Single_Read_ADXL345(uchar REG_Address);                   //單個讀取內部寄存器數據
  45. void  Multiple_Read_ADXL345();                                  //連續的讀取內部寄存器數據
  46. //------------------------------------
  47. void Delay5us();
  48. void Delay5ms();
  49. void ADXL345_Start();       //與iic有關函數
  50. void ADXL345_Stop();
  51. void ADXL345_SendACK(bit ack); //傳送應答
  52. bit  ADXL345_RecvACK();                   //接收應答
  53. void ADXL345_SendByte(BYTE dat);
  54. BYTE ADXL345_RecvByte();
  55. void ADXL345_ReadPage();
  56. void ADXL345_WritePage();

  57. /*******************************/
  58. void WaitForEnable(void)          
  59. {                                       
  60.         DataPort=0xff;               
  61.         LCM_RS=0;
  62.         LCM_RW=1;
  63.         _nop_(); _nop_();
  64.         LCM_EN=1;
  65.         _nop_();_nop_(); _nop_();_nop_();
  66.         while(DataPort&0x80);       
  67.         LCM_EN=0;                               
  68. }                                       
  69. /*******************************/
  70. void WriteCommandLCM(uchar CMD,uchar Attribc)
  71. {                                       
  72.         if(Attribc)
  73.         WaitForEnable();       
  74.         LCM_RS=0;
  75.         LCM_RW=0;
  76.         _nop_();_nop_();
  77.         DataPort=CMD;
  78.         _nop_();_nop_();       
  79.         LCM_EN=1;
  80.         nop_();_nop_();nop_();_nop_();
  81.         LCM_EN=0;
  82. }                                       
  83. /*******************************/
  84. void WriteDataLCM(uchar dataW)
  85. {                                       
  86.         WaitForEnable();               
  87.         LCM_RS=1;LCM_RW=0;
  88.         _nop_();_nop_();
  89.         DataPort=dataW;_nop_();       
  90.         LCM_EN=1;
  91.         _nop_();_nop_();_nop_();_nop_();
  92.          LCM_EN=0;
  93. }               
  94. /***********************************/
  95. void InitLcd()                               
  96. {                       
  97.         WriteCommandLCM(0x38,1);       
  98.         WriteCommandLCM(0x08,1);       
  99.         WriteCommandLCM(0x01,1);       
  100.         WriteCommandLCM(0x06,1);
  101.         WriteCommandLCM(0x0c,1);
  102. }                       
  103. /***********************************/
  104. void DisplayOneChar(uchar X,uchar Y,uchar DData) //X,Y為字符坐標
  105. {                                               
  106.         Y&=0x01;                                               
  107.         X&=0x0f;                                               
  108.         if(Y)
  109.         X|=0x40;   //8+4=c
  110.                                                
  111.         X|=0x80;                       
  112.         WriteCommandLCM(X,1);               
  113.         WriteDataLCM(DData);               
  114. }                                               


  115. void Delay5us()                //@12.000MHz
  116. {
  117.         unsigned char i;

  118.         i = 12;
  119.         while (--i);
  120. }


  121. void Delay5ms()                //@12.000MHz
  122. {
  123.         unsigned char i, j;

  124.         _nop_();
  125.         _nop_();
  126.         i = 59;
  127.         j = 89;
  128.         do
  129.         {
  130.                 while (--j);
  131.         } while (--i);
  132. }


  133. /**************************************
  134. 起始信號
  135. **************************************/
  136. void ADXL345_Start()
  137. {
  138.     SDA = 1;                    //拉高數據線
  139.     SCL = 1;                    //拉高時鐘線
  140.     Delay5us();                 //延時
  141.     SDA = 0;                    //產生下降沿
  142.     Delay5us();                 //延時
  143.     SCL = 0;                    //拉低時鐘線
  144. }

  145. /**************************************
  146. 停止信號
  147. **************************************/
  148. void ADXL345_Stop()
  149. {
  150.     SDA = 0;                    //拉低數據線
  151.     SCL = 1;                    //拉高時鐘線
  152.     Delay5us();                 //延時
  153.     SDA = 1;                    //產生上升沿
  154.     Delay5us();                 //延時
  155. }

  156. /**************************************
  157. 發送應答信號
  158. 入口參數:ack (0:ACK 1:NAK)
  159. **************************************/
  160. void ADXL345_SendACK(bit ack)
  161. {
  162.     SDA = ack;                  //寫應答信號
  163.     SCL = 1;                    //拉高時鐘線
  164.     Delay5us();                 //延時
  165.     SCL = 0;                    //拉低時鐘線
  166.     Delay5us();                 //延時
  167. }

  168. /**************************************
  169. 接收應答信號
  170. **************************************/
  171. bit ADXL345_RecvACK()
  172. {
  173.     SCL = 1;                    //拉高時鐘線
  174.     Delay5us();                 //延時
  175.     CY = SDA;                   //讀應答信號
  176.     SCL = 0;                    //拉低時鐘線
  177.     Delay5us();                 //延時

  178.     return CY;
  179. }

  180. /**************************************
  181. 向IIC總線發送一個字節數據
  182. **************************************/
  183. void ADXL345_SendByte(BYTE dat)
  184. {
  185.     BYTE i;

  186.     for (i=0; i<8; i++)         //8位計數器
  187.     {
  188.         dat <<= 1;              //移出數據的最高位
  189.         SDA = CY;               //送數據口
  190.         SCL = 1;                //拉高時鐘線
  191.         Delay5us();             //延時
  192.         SCL = 0;                //拉低時鐘線
  193.         Delay5us();             //延時
  194.     }
  195.     ADXL345_RecvACK();
  196. }

  197. /**************************************
  198. 從IIC總線接收一個字節數據
  199. **************************************/
  200. BYTE ADXL345_RecvByte()
  201. {
  202.     BYTE i;
  203.     BYTE dat = 0;
  204.     SDA = 1;                    //使能內部上拉,準備讀取數據,
  205.     for (i=0; i<8; i++)         //8位計數器
  206.     {
  207.         dat <<= 1;
  208.         SCL = 1;                //拉高時鐘線
  209.         Delay5us();             //延時
  210.         dat |= SDA;             //讀數據               
  211.         SCL = 0;                //拉低時鐘線
  212.         Delay5us();             //延時
  213.     }
  214.     return dat;
  215. }

  216. //******單字節寫入*******************************************
  217. //用于ADXL345初始化
  218. void Single_Write_ADXL345(uchar REG_Address,uchar REG_data)
  219. {
  220.     ADXL345_Start();                  //起始信號
  221.     ADXL345_SendByte(SlaveAddress);   //發送設備地址+寫信號
  222.     ADXL345_SendByte(REG_Address);  //內部寄存器地址,請參考中文pdf22頁
  223.     ADXL345_SendByte(REG_data);    //內部寄存器數據,請參考中文pdf22頁
  224.                                        //相當于 向相應的地址寫入命令字
  225.     ADXL345_Stop();                 //發送停止信號
  226. }

  227. //********單字節讀取*****************************************
  228. uchar Single_Read_ADXL345(uchar REG_Address)
  229. {   
  230.     uchar REG_data;
  231.     ADXL345_Start();                          //起始信號
  232.     ADXL345_SendByte(SlaveAddress);           //發送設備地址+寫信號,//0xA6寫入
  233.     ADXL345_SendByte(REG_Address);            //發送存儲單元地址,從0開始       
  234.     ADXL345_Start();                          //起始信號
  235.     ADXL345_SendByte(SlaveAddress+1);         //發送設備地址+讀信號,//0xA7讀取
  236.     REG_data=ADXL345_RecvByte();              //讀出寄存器數據
  237.         ADXL345_SendACK(1);   
  238.         ADXL345_Stop();                           //停止信號
  239.     return REG_data;
  240. }
  241. //*********************************************************
  242. //
  243. //連續讀出ADXL345內部加速度數據,地址范圍0x32~0x37
  244. //
  245. //*********************************************************
  246. void Multiple_read_ADXL345(void)
  247. {   
  248.     uchar i;
  249.     ADXL345_Start();                          //起始信號
  250.     ADXL345_SendByte(SlaveAddress);           //發送設備地址+寫信號
  251.     ADXL345_SendByte(0x32);                   //發送存儲單元地址,從0x32開始       
  252.     ADXL345_Start();                          //起始信號
  253.     ADXL345_SendByte(SlaveAddress+1);         //發送設備地址+讀信號
  254.          for (i=0; i<6; i++)                      //連續讀取6個地址數據,存儲中BUF
  255.     {
  256.         BUF[i] = ADXL345_RecvByte();          //BUF[0]存儲0x32地址中的數據
  257.         if (i == 5)
  258.         {
  259.            ADXL345_SendACK(1);                //最后一個數據需要回NOACK
  260.         }
  261.         else
  262.         {
  263.           ADXL345_SendACK(0);                //回應ACK
  264.        }
  265.    }
  266.     ADXL345_Stop();                          //停止信號
  267.     Delay5ms();
  268. }

  269. //*****************************************************************

  270. //初始化ADXL345,根據需要請參考pdf進行修改************************
  271. void Init_ADXL345()
  272. {
  273.    Single_Write_ADXL345(0x31,0x0B);   //測量范圍,正負16g,13位模式
  274.    Single_Write_ADXL345(0x2C,0x08);   //速率設定為12.5 參考pdf13頁
  275.    Single_Write_ADXL345(0x2D,0x08);   //選擇電源模式   參考pdf24頁
  276.    Single_Write_ADXL345(0x2E,0x80);   //使能 DATA_READY 中斷
  277.    Single_Write_ADXL345(0x1E,0x00);   //X 偏移量 根據測試傳感器的狀態寫入,pdf29頁//自己調試,得出偏移量
  278.    Single_Write_ADXL345(0x1F,0x00);   //Y 偏移量 根據測試傳感器的狀態寫入,pdf29頁
  279.    Single_Write_ADXL345(0x20,0x05);   //Z 偏移量 根據測試傳感器的狀態寫入,pdf29頁
  280. }

  281. //*********************************************************
  282. void conversion(uint temp_data)  
  283. {  
  284.     wan=temp_data/10000+0x30 ;              //0x30='0'
  285.     temp_data=temp_data%10000;   //取余運算
  286.         qian=temp_data/1000+0x30 ;
  287.     temp_data=temp_data%1000;    //取余運算
  288.     bai=temp_data/100+0x30   ;
  289.     temp_data=temp_data%100;     //取余運算
  290.     shi=temp_data/10+0x30    ;
  291.     temp_data=temp_data%10;      //取余運算
  292.     ge=temp_data+0x30;       
  293. }

  294. //顯示x軸傾斜角,即x軸與垂線所成角度
  295. void display_jd_x()
  296. {   
  297.     bit bj=0;//標記
  298.     int  dis_data_x,dis_data_z;  //x,y軸加速度的原始數據,用補碼形式表示
  299.     float mg_x,mg_z;           //角度,加速度
  300.     dis_data_x=(BUF[1]<<8)+BUF[0];  //合成數據   
  301.         dis_data_z=(BUF[5]<<8)+BUF[4];  //合成數據

  302.         if((dis_data_x<=0)&&(dis_data_z>0))          //第二象限
  303.         {
  304.             dis_data_x=-dis_data_x;
  305.                 DisplayOneChar(8,0,' ');
  306.         bj=1;
  307.         }
  308.         else if((dis_data_z<0)&&(dis_data_x>=0))         //第四象限
  309.         {
  310.             dis_data_z=-dis_data_z;
  311.         DisplayOneChar(8,0,'-');  //顯示正負符號位
  312.         }
  313.         else if((dis_data_z<=0)&&(dis_data_x<0))           //第三象限
  314.         {
  315.             bj=1;
  316.             dis_data_z=-dis_data_z;
  317.                 dis_data_x=-dis_data_x;
  318.         DisplayOneChar(8,0,'-');  //顯示正負符號位
  319.         }
  320.         else if((dis_data_z>=0)&&(dis_data_x>0))
  321.          DisplayOneChar(8,0,' ');                //第一象限

  322.     mg_x=(float)dis_data_x*3.9;  //計算數據和顯示,查看ADXL345快速入門第4頁,1LSB=3.9mg(毫g)
  323.         mg_z=(float)dis_data_z*3.9;         //強制類型轉換,dis_data_z的類型和值不會發生改變

  324.         jd=atan2(mg_z,mg_x)*(180/3.14159);
  325.         if(bj==1)jd=180-jd;       
  326.           //jd=jd*10;  消除小數點,便于轉換數據和顯示
  327.     conversion(jd*10);      //轉換出顯示需要的數據                                        //
  328.         DisplayOneChar(6,0,'X');
  329.         DisplayOneChar(7,0,':');   
  330.         DisplayOneChar(9,0,qian);
  331.     DisplayOneChar(10,0,bai);        
  332.     DisplayOneChar(11,0,shi);
  333.     DisplayOneChar(12,0,'.');
  334.         DisplayOneChar(13,0,ge);
  335.         DisplayOneChar(14,0,0xdf);            //顯示 °
  336.         DisplayOneChar(15,0,' ');
  337. }

  338. void PCAinit()        //PCA模塊初始化
  339. {
  340.      CCON=0;
  341.          CL=0;
  342.          CH=0;
  343.          CMOD=0x00;        //sysclk/12
  344.          CCAPM0=0x42;//8位PWM,無中斷
  345.          CR=1;
  346.          CCAP0H=CCAP0L=256-240;
  347. }
  348. void init_t0()         //定時器0初始化
  349. {
  350.     TUXR&=0x7f;         //12T
  351.         TMOD=0x01;
  352.         TH0=(65536-50000)/256;
  353.         TL0=(65536-50000)%256;
  354.         TR0=1;
  355.         EA=1;
  356.         ET0=1;
  357. }

  358. //*********************************************************
  359. //******主程序********
  360. //*********************************************************
  361. void main()
  362. {        
  363.         char H;       
  364.         InitLcd();               //液晶初始化ADXL345
  365.         Delay5ms();
  366.         Init_ADXL345();                 //初始化ADXL345
  367.         PCAinit();
  368.         init_t0();
  369.         H=CCAP0H;

  370.         while(1)
  371.         {                                                                         
  372.                 if(p33==0)
  373.                 {         
  374.                      Delay5ms();
  375.                      if(p33==0)
  376.                      {
  377.                           H=H+5;
  378.                               if(H>255)H=255;
  379.                               CCAP0H=H;
  380.                               CCAP0L=H;
  381.                               while(p33==0);
  382.                       }
  383.             }
  384.                 if(p31==0)
  385.                 {         
  386.                      Delay5ms();
  387.                      if(p31==0)
  388.                          {
  389.                             H=H-5;
  390.                                 if(H<0)H=0;
  391. ……………………

  392. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼

所有資料51hei提供下載:
ADXL345測傾斜角.zip (69.11 KB, 下載次數: 351)


評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

ID:198407 發表于 2017-8-1 20:10 | 顯示全部樓層
謝謝 大神解答
回復

使用道具 舉報

ID:91469 發表于 2017-12-21 15:47 來自手機 | 顯示全部樓層
感謝分享!!!
回復

使用道具 舉報

ID:288884 發表于 2018-4-23 21:05 來自手機 | 顯示全部樓層
非常感謝大神的程序,Y軸的怎么寫麻煩大神指導下?
回復

使用道具 舉報

ID:289063 發表于 2018-8-17 11:33 | 顯示全部樓層
感謝樓主感謝感謝
回復

使用道具 舉報

ID:385261 發表于 2018-8-22 15:31 | 顯示全部樓層

感謝樓主分享
回復

使用道具 舉報

ID:55184 發表于 2018-11-21 11:00 | 顯示全部樓層
學習一下
回復

使用道具 舉報

ID:55184 發表于 2018-11-21 11:03 | 顯示全部樓層
代碼寫得好亂,不好分析。
回復

使用道具 舉報

ID:482211 發表于 2019-2-28 16:34 | 顯示全部樓層
感謝大神分享。
回復

使用道具 舉報

ID:501479 發表于 2019-3-30 23:17 | 顯示全部樓層
感謝!!
回復

使用道具 舉報

ID:521766 發表于 2019-4-26 22:32 | 顯示全部樓層
好的,后面的程序。
回復

使用道具 舉報

ID:568916 發表于 2019-7-6 12:00 | 顯示全部樓層
sbit  p22=P2^2;
sbit  p31=P3^1;
sbit  p33=P3^3;這連接的是什么
回復

使用道具 舉報

ID:804262 發表于 2020-7-28 14:48 | 顯示全部樓層
不錯,有用的數據
回復

使用道具 舉報

ID:820214 發表于 2020-11-16 21:49 | 顯示全部樓層
有接法嗎
回復

使用道具 舉報

ID:847444 發表于 2020-11-22 20:23 | 顯示全部樓層
感謝分享,最近正在研究這個
回復

使用道具 舉報

ID:72231 發表于 2021-9-11 17:13 | 顯示全部樓層
精度如何?
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 日本三级播放 | 色婷婷综合久久久中字幕精品久久 | 国产成人精品久久二区二区 | 亚洲色图综合 | 天天射美女| 在线观看av网站永久 | 天天干夜夜拍 | 日韩高清在线观看 | 国产色网站| 久久精品a级毛片 | 国产乱码精品1区2区3区 | 久99久视频| 国产h视频 | 国产亚洲精品精品国产亚洲综合 | 男女视频免费 | 美国一级片在线观看 | 久久爱综合 | 亚洲男人网| 日韩欧美国产电影 | 91麻豆精品国产91久久久更新资源速度超快 | 在线免费观看黄a | 国产一区www| 超碰97在线免费 | 日韩视频91| 成人三级网址 | 先锋资源网 | jlzzjlzz国产精品久久 | 欧美中文字幕一区二区三区亚洲 | 在线日韩欧美 | 日韩在线观看中文字幕 | 欧美日韩国产精品一区 | 欧美日韩国产一区二区三区 | 黄色毛片网站在线观看 | 午夜精品一区二区三区免费视频 | 久久最新| 欧美一区二区三区精品免费 | 国产一区二区三区欧美 | 搞av.com| 在线播放中文字幕 | 久久精品一级 | 欧美一区免费在线观看 |