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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 8702|回復: 11
收起左側

ADXL345傾角傳感器的51單片機源程序

  [復制鏈接]
ID:247060 發表于 2018-4-12 22:12 | 顯示全部樓層 |閱讀模式
這是自己做的一個小程序,用到了STC12C5160S2這塊單片機芯片做控制,實現ADXL345傾角傳感器模塊測量角度

單片機源程序如下:
  1. /********************************************************************
  2. * 文件名  :GY-29 ADXL345 測角度,角度值顯示
  3. * 創建人  :飛翔的貓
  4. * 描述    : 該文件實現了用GY-29 ADXL345角度的采集,并在數碼管上顯示出來。
  5.                         使用單片機STC89C51
  6. *晶振          :11.0592M
  7. *顯示     :LCD1602
  8. *編譯環境 :Keil uVision4
  9. ****************************************/
  10. #include  <REG51.H>       
  11. #include  <math.h>    //Keil library  
  12. #include  <stdio.h>   //Keil library       
  13. #include  <INTRINS.H>
  14. #define   uchar unsigned char
  15. #define   uint unsigned int       

  16. //這個一定要根據自己接的引腳來改,否則不出數據
  17. sbit          SCL=P2^0;      //IIC時鐘引腳定義
  18. sbit           SDA=P2^1;      //IIC數據引腳定義

  19. #define   DataPort P0    //LCD1602數據端口
  20. sbit      LCM_RS=P2^4;   //LCD1602命令端口               
  21. sbit      LCM_RW=P2^5;   //LCD1602命令端口               
  22. sbit      LCM_EN=P2^7;   //LCD1602命令端口

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

  27. BYTE BUF[8];                         //接收數據緩存區             
  28. uchar ge,shi,bai,qian,wan;           //顯示變量
  29. int  dis_data;                       //變量
  30. int  data_xyz[3];



  31. void delay(unsigned int k);
  32. void InitLcd();                      //初始化lcd1602
  33. void Init_ADXL345(void);             //初始化ADXL345

  34. void WriteDataLCM(uchar dataW);
  35. void WriteCommandLCM(uchar CMD,uchar Attribc);
  36. void DisplayOneChar(uchar X,uchar Y,uchar DData);
  37. void conversion(uint temp_data);

  38. void  Single_Write_ADXL345(uchar REG_Address,uchar REG_data);   //單個寫入數據
  39. uchar Single_Read_ADXL345(uchar REG_Address);                   //單個讀取內部寄存器數據
  40. void Mutiple_Read_ADXL345(void);     
  41. void clear(void);                               //連續的讀取內部寄存器數據
  42. //------------------------------------
  43. void Delay5us();
  44. void Delay5ms();
  45. void ADXL345_Start();
  46. void ADXL345_Stop();
  47. void ADXL345_SendACK(bit ack);
  48. bit  ADXL345_RecvACK();
  49. void ADXL345_SendByte(BYTE dat);
  50. BYTE ADXL345_RecvByte();
  51. void ADXL345_ReadPage();
  52. void ADXL345_WritePage();
  53. //-----------------------------------

  54. //*********************************************************
  55. void conversion(uint temp_data)  
  56. {  
  57.     wan=temp_data/10000+0x30 ;
  58.     temp_data=temp_data%10000;   //取余運算
  59.         qian=temp_data/1000+0x30 ;
  60.     temp_data=temp_data%1000;    //取余運算
  61.     bai=temp_data/100+0x30   ;
  62.     temp_data=temp_data%100;     //取余運算
  63.     shi=temp_data/10+0x30    ;
  64.     temp_data=temp_data%10;      //取余運算
  65.     ge=temp_data+0x30;        
  66. }

  67. /*******************************/
  68. void delay(unsigned int k)       
  69. {                                               
  70. unsigned int i,j;                               
  71. for(i=0;i<k;i++)
  72. {                       
  73. for(j=0;j<121;j++)                       
  74. {;}}                                               
  75. }
  76. /*******************************/
  77. void WaitForEnable(void)       
  78. {                                       
  79. DataPort=0xff;               
  80. LCM_RS=0;LCM_RW=1;_nop_();
  81. LCM_EN=1;_nop_();_nop_();
  82. while(DataPort&0x80);       
  83. LCM_EN=0;                               
  84. }                                       
  85. /*******************************/
  86. void WriteCommandLCM(uchar CMD,uchar Attribc)
  87. {                                       
  88. if(Attribc)WaitForEnable();       
  89. LCM_RS=0;LCM_RW=0;_nop_();
  90. DataPort=CMD;_nop_();       
  91. LCM_EN=1;_nop_();_nop_();LCM_EN=0;
  92. }                                       
  93. /*******************************/
  94. void WriteDataLCM(uchar dataW)
  95. {                                       
  96. WaitForEnable();               
  97. LCM_RS=1;LCM_RW=0;_nop_();
  98. DataPort=dataW;_nop_();       
  99. LCM_EN=1;_nop_();_nop_();LCM_EN=0;
  100. }               
  101. /***********************************/
  102. void InitLcd()                        //液晶顯示器的設置       
  103. {                       
  104. WriteCommandLCM(0x38,1);       
  105. WriteCommandLCM(0x08,1);       
  106. WriteCommandLCM(0x01,1);       
  107. WriteCommandLCM(0x06,1);       
  108. WriteCommandLCM(0x0c,1);
  109. }                       
  110. /***********************************/
  111. void DisplayOneChar(uchar X,uchar Y,uchar DData)
  112. {                                               
  113. Y&=1;                                               
  114. X&=15;                                               
  115. if(Y)X|=0x40;                                       
  116. X|=0x80;                       
  117. WriteCommandLCM(X,0);               
  118. WriteDataLCM(DData);               
  119. }                                               

  120. /**************************************
  121. 延時5微秒(STC90C52RC@12M)
  122. 不同的工作環境,需要調整此函數,注意時鐘過快時需要修改
  123. 當改用1T的MCU時,請調整此延時函數
  124. **************************************/
  125. void Delay5us()
  126. {
  127.     _nop_();_nop_();_nop_();_nop_();
  128.     _nop_();_nop_();_nop_();_nop_();
  129.         _nop_();_nop_();_nop_();_nop_();
  130. }

  131. /**************************************
  132. 延時5毫秒(STC90C52RC@12M)
  133. 不同的工作環境,需要調整此函數
  134. 當改用1T的MCU時,請調整此延時函數
  135. **************************************/
  136. void Delay5ms()
  137. {
  138.     WORD n = 560;

  139.     while (n--);
  140. }

  141. /**************************************
  142. 起始信號
  143. **************************************/
  144. void ADXL345_Start()
  145. {
  146.     SDA = 1;                    //拉高數據線
  147.     SCL = 1;                    //拉高時鐘線
  148.     Delay5us();                 //延時
  149.     SDA = 0;                    //產生下降沿
  150.     Delay5us();                 //延時
  151.     SCL = 0;                    //拉低時鐘線
  152. }

  153. /**************************************
  154. 停止信號
  155. **************************************/
  156. void ADXL345_Stop()
  157. {
  158.     SDA = 0;                    //拉低數據線
  159.     SCL = 1;                    //拉高時鐘線
  160.     Delay5us();                 //延時
  161.     SDA = 1;                    //產生上升沿
  162.     Delay5us();                 //延時
  163. }

  164. /**************************************
  165. 發送應答信號
  166. 入口參數:ack (0:ACK 1:NAK)
  167. **************************************/
  168. void ADXL345_SendACK(bit ack)
  169. {
  170.     SDA = ack;                  //寫應答信號
  171.     SCL = 1;                    //拉高時鐘線
  172.     Delay5us();                 //延時
  173.     SCL = 0;                    //拉低時鐘線
  174.     Delay5us();                 //延時
  175. }

  176. /**************************************
  177. 接收應答信號
  178. **************************************/
  179. bit ADXL345_RecvACK()
  180. {
  181.     SCL = 1;                    //拉高時鐘線
  182.     Delay5us();                 //延時
  183.     CY = SDA;                   //讀應答信號
  184.     SCL = 0;                    //拉低時鐘線
  185.     Delay5us();                 //延時

  186.     return CY;
  187. }

  188. /**************************************
  189. 向IIC總線發送一個字節數據
  190. **************************************/
  191. void ADXL345_SendByte(BYTE dat)
  192. {
  193.     BYTE i;

  194.     for (i=0; i<8; i++)         //8位計數器
  195.     {
  196.         dat <<= 1;              //移出數據的最高位
  197.         SDA = CY;               //送數據口
  198.         SCL = 1;                //拉高時鐘線
  199.         Delay5us();             //延時
  200.         SCL = 0;                //拉低時鐘線
  201.         Delay5us();             //延時
  202.     }
  203.     ADXL345_RecvACK();
  204. }

  205. /**************************************
  206. 從IIC總線接收一個字節數據
  207. **************************************/
  208. BYTE ADXL345_RecvByte()
  209. {
  210.     BYTE i;
  211.     BYTE dat = 0;

  212.     SDA = 1;                    //使能內部上拉,準備讀取數據,
  213.     for (i=0; i<8; i++)         //8位計數器
  214.     {
  215.         dat <<= 1;
  216.         SCL = 1;                //拉高時鐘線
  217.         Delay5us();             //延時
  218.         dat |= SDA;             //讀數據               
  219.         SCL = 0;                //拉低時鐘線
  220.         Delay5us();             //延時
  221.     }
  222.     return dat;
  223. }

  224. //******單字節寫入*******************************************

  225. void Single_Write_ADXL345(uchar REG_Address,uchar REG_data)
  226. {
  227.     ADXL345_Start();                  //起始信號
  228.     ADXL345_SendByte(SlaveAddress);   //發送設備地址+寫信號
  229.     ADXL345_SendByte(REG_Address);    //內部寄存器地址,請參考中文pdf22頁
  230.     ADXL345_SendByte(REG_data);       //內部寄存器數據,請參考中文pdf22頁
  231.     ADXL345_Stop();                   //發送停止信號
  232. }

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

  276. void clear(void)
  277. {   uchar i;
  278.     ADXL345_Start();  
  279.                                 //起始信號
  280.     ADXL345_SendByte(SlaveAddress);           //發送設備地址+寫信號
  281.     ADXL345_SendByte(0x32);                   //發送存儲單元地址,從0x32開始       
  282.     ADXL345_Start();                          //起始信號
  283.     ADXL345_SendByte(SlaveAddress+1);         //發送設備地址+讀信號
  284.          for (i=0; i<6; i++)                      //連續讀取6個地址數據,存儲中BUF
  285.     {
  286.         //BUF[i] = ADXL345_RecvByte();          //BUF[0]存儲0x32地址中的數據
  287.                 BUF[i]=i;
  288.         if (i == 5)
  289.         {
  290.            ADXL345_SendACK(1);                //最后一個數據需要回NOACK
  291.         }
  292.         else
  293.         {
  294.            ADXL345_SendACK(0);                //回應ACK
  295.        }
  296.    }
  297.     ADXL345_Stop();                          //停止信號
  298.     Delay5ms();
  299. }
  300. //*****************************************************************

  301. //初始化ADXL345,根據需要請參考pdf進行修改************************
  302. void Init_ADXL345()
  303. {
  304.    Single_Write_ADXL345(0x31,0x0B);   //測量范圍,正負16g,13位模式
  305.    Single_Write_ADXL345(0x2C,0x08);   //速率設定為12.5 參考pdf13頁
  306.    Single_Write_ADXL345(0x2D,0x08);   //選擇電源模式   參考pdf24頁
  307.    Single_Write_ADXL345(0x2E,0x80);   //使能 DATA_READY 中斷
  308.    Single_Write_ADXL345(0x1E,0x00);   //X 偏移量 根據測試傳感器的狀態寫入pdf29頁
  309.    Single_Write_ADXL345(0x1F,0x00);   //Y 偏移量 根據測試傳感器的狀態寫入pdf29頁
  310.    Single_Write_ADXL345(0x20,0x05);   //Z 偏移量 根據測試傳感器的狀態寫入pdf29頁
  311. }
  312. //***********************************************************************
  313. //顯示x軸
  314. void display_x()
  315. {   float temp;
  316.     dis_data=(BUF[1]<<8)+BUF[0];  //合成數據   
  317.         if(dis_data<0){
  318.         dis_data=-dis_data;
  319.     DisplayOneChar(2,0,'-');      //顯示正負符號位
  320.         }
  321.         else DisplayOneChar(2,0,' '); //顯示空格

  322.     temp=(float)dis_data*3.9;  //計算數據和顯示,查考ADXL345快速入門第4頁
  323.     conversion(temp);          //轉換出顯示需要的數據
  324.         DisplayOneChar(0,0,'X');   //第0行,第0列 顯示X
  325.     DisplayOneChar(1,0,':');
  326.     DisplayOneChar(3,0,qian);
  327.         DisplayOneChar(4,0,'.');
  328.     DisplayOneChar(5,0,bai);
  329.     DisplayOneChar(6,0,shi);
  330.         DisplayOneChar(7,0,'g');
  331. }

  332. //***********************************************************************
  333. //顯示y軸
  334. void display_y()
  335. {     float temp;
  336.     dis_data=(BUF[3]<<8)+BUF[2];  //合成數據   
  337.         if(dis_data<0){
  338.         dis_data=-dis_data;
  339.     DisplayOneChar(2,1,'-');      //顯示正負符號位
  340.         }
  341.         else DisplayOneChar(2,1,' '); //顯示空格

  342.     temp=(float)dis_data*3.9;  //計算數據和顯示,查考ADXL345快速入門第4頁
  343.     conversion(temp);          //轉換出顯示需要的數據
  344.         DisplayOneChar(0,1,'Y');   //第1行,第0列 顯示y
  345.     DisplayOneChar(1,1,':');
  346.     DisplayOneChar(3,1,qian);
  347.         DisplayOneChar(4,1,'.');
  348.     DisplayOneChar(5,1,bai);
  349.     DisplayOneChar(6,1,shi);  
  350.         DisplayOneChar(7,1,'g');  
  351. }

  352. //***********************************************************************
  353. //顯示z軸
  354. void display_z()
  355. {      float temp;
  356.     dis_data=(BUF[5]<<8)+BUF[4];    //合成數據   
  357.         if(dis_data<0){
  358.         dis_data=-dis_data;
  359.     DisplayOneChar(10,1,'-');       //顯示負符號位
  360.         }
  361.         else DisplayOneChar(10,1,' ');  //顯示空格

  362.     temp=(float)dis_data*3.9;  //計算數據和顯示,查考ADXL345快速入門第4頁
  363.     conversion(temp);          //轉換出顯示需要的數據
  364.         DisplayOneChar(10,0,'Z');  //第0行,第10列 顯示Z
  365.     DisplayOneChar(11,0,':');
  366.     DisplayOneChar(11,1,qian);
  367.         DisplayOneChar(12,1,'.');
  368.     DisplayOneChar(13,1,bai);
  369.     DisplayOneChar(14,1,shi);
  370.         DisplayOneChar(15,1,'g');  
  371. }



  372. //串口通訊函數  自己加的程序段,將ADXL的角度值寫到串口中
  373. void uart_initial_with_interrupt(void);
  374. void uart_adxl(void);
  375. int uart_i;
  376. void uart_initial_with_interrupt(void)
  377. {   
  378.         //TOMD 定時器工作模式寄存器
  379.         //TCON 中斷控制寄存器:定時器中斷和外部中斷
  380.         //IE   中斷允許控制寄存器

  381.         TMOD=0x20;           //設置定時器工作模式,定時器1工作在模式2,8位自動重裝

  382.         TH1=0xfd;           //定時器1設置,產生9600波特率,開啟定時器1
  383.         TL1=0xfd;
  384.         TR1=1;

  385.         SM0=0;
  386.         SM1=1;
  387.         REN=1;

  388.         EA=1;  //允許總中斷
  389.         ES=1;  //允許串口中斷       
  390. }
  391. void  uart_adxl(void) interrupt 4
  392. {
  393.         uchar ch;
  394.         if(RI)
  395.         {
  396.                 ch='a';               
  397.         }

  398. }
  399. int Roll_int,Pitch_int;
  400. uchar Roll_int_high,Roll_int_low;
  401. uchar Pitch_int_high,Pitch_int_low;
  402. //*********************************************************
  403. //******主程序********
  404. //*********************************************************
  405. void main()
  406. {         int d;
  407.           uchar devid;
  408.         float Roll,Pitch,Q,T,K;

  409.         //打開串口中斷
  410.         uart_initial_with_interrupt();
  411.                        
  412.         Init_ADXL345();                 //初始化ADXL345
  413.         devid=Single_Read_ADXL345(0X00);//讀出的數據為0XE5,表示正確
  414.        
  415.     while(1)                         //循環
  416.     {
  417.             
  418.                 //測試串口工作情況
  419.                 for(uart_i=0;uart_i<2;uart_i++)
  420.                 {
  421.                          SBUF=0;
  422.                         while(!TI);
  423.                         TI=0;
  424.                         delay(500);
  425.                 }


  426.                 Init_ADXL345();                     //初始化ADXL345
  427.        //連續讀出數據,存儲在BUF       
  428.                 Mutiple_Read_ADXL345();
  429.                 data_xyz[0]=(BUF[1]<<8)|BUF[0];  //合成數據    【改動】將+ 改成了 |
  430.                 data_xyz[1]=(BUF[3]<<8)|BUF[2];  //合成數據   
  431.                 data_xyz[2]=(BUF[5]<<8)|BUF[4];  //合成數據  
  432.                
  433.                  
  434.                 //測試是否有數據改變
  435.                 for(d=0;d<3;d++){
  436.                 SBUF=data_xyz[d];
  437.                 while(!TI);
  438. ……………………

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

所有資料51hei提供下載:
ADXL345-angle.rar (44.98 KB, 下載次數: 134)
回復

使用道具 舉報

ID:327783 發表于 2019-3-15 20:25 | 顯示全部樓層
能修改一下控制LED閃爍嗎 不要顯示!
回復

使用道具 舉報

ID:371527 發表于 2019-4-3 09:18 | 顯示全部樓層
結合飛行器做個項目
回復

使用道具 舉報

ID:503819 發表于 2019-4-3 09:40 | 顯示全部樓層
學到了學到了
回復

使用道具 舉報

ID:508101 發表于 2019-4-9 18:02 | 顯示全部樓層
高手老師,能不能做個傾角傳感器采集角度后,通過GSM通信傳輸到手機上,十分感謝
回復

使用道具 舉報

ID:683253 發表于 2020-1-7 22:10 | 顯示全部樓層
好難啊,一臉懵
回復

使用道具 舉報

ID:658700 發表于 2020-2-10 19:25 | 顯示全部樓層
大佬,想問一下CY是什么,如果是個變量也沒見定義呀
回復

使用道具 舉報

ID:658700 發表于 2020-2-10 19:30 | 顯示全部樓層
感覺是個形參,但是在函數內部還是沒有定義
回復

使用道具 舉報

ID:730148 發表于 2020-5-18 20:32 | 顯示全部樓層
樓主,有沒有電路圖呀,PROTEUS仿真
回復

使用道具 舉報

ID:989951 發表于 2021-12-9 10:55 | 顯示全部樓層
剛發現51為數不多的關于傾角傳感器應用的帖子
回復

使用道具 舉報

ID:704640 發表于 2022-6-26 09:32 | 顯示全部樓層
每天來學學,讓自己老了能做點東西哄哄孫兒
回復

使用道具 舉報

ID:99242 發表于 2025-3-13 16:09 來自手機 | 顯示全部樓層
零度怎么樣
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久久亚洲欧美日韩精品专区 | 国产黄色大片在线观看 | 欧美电影免费观看高清 | 免费一级黄色电影 | 亚洲国产精品自拍 | 精品国产不卡一区二区三区 | 欧美一级在线免费观看 | 日韩精品在线免费 | 久久久久久久久久久久久九 | 天天久 | 综合二区 | 国产偷录视频叫床高潮对白 | 国产成人精品一区二区三区四区 | 国产网站在线播放 | 性生生活大片免费看视频 | 国产91网站在线观看 | 久久国产精品一区二区 | 91视频导航 | 午夜视频免费 | 爱爱视频网 | 91手机精品视频 | 欧美精品一二三区 | 午夜久久久久久久久久一区二区 | 亚洲狠狠| 欧美激情久久久 | 久久久久久国产一区二区三区 | 免费在线观看黄色av | 欧美伊人久久久久久久久影院 | 91在线精品一区二区 | 日本精品一区 | 精品一区二区久久久久久久网站 | 日韩成人在线一区 | 国产免费一区二区三区 | 久久久久国产一区二区三区四区 | 国产在线观看一区二区 | 欧美在线一区二区三区四区 | 国产精品一二区 | 男女爱爱网站 | 九九热精品在线 | 久久婷婷av| 欧美亚洲国产日韩 |