找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 3702|回復(fù): 4
打印 上一主題 下一主題
收起左側(cè)

單片機(jī)+ADXL345傳感器的LCD1602角度顯示功能程序設(shè)計(jì)

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:517871 發(fā)表于 2019-5-10 10:14 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
單片機(jī)源程序如下:
  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數(shù)據(jù)端口
  8. sbit          SCL=P1^2;      //IIC時(shí)鐘引腳定義
  9. sbit           SDA=P1^3;      //IIC數(shù)據(jù)引腳定義
  10. sbit      LCM_RS=P1^0;   //LCD1602命令端口               
  11. sbit      LCM_RW=P1^1;   //LCD1602命令端口               
  12. sbit      LCM_EN=P2^5;   //LCD1602命令端口

  13. #define        SlaveAddress   0xA6          //定義器件在IIC總線中的從地址,根據(jù)ALT  ADDRESS地址引腳不同修改
  14.                               //ALT  ADDRESS引腳接地時(shí)地址為0xA6,接電源時(shí)地址為0x3A
  15. typedef unsigned char  BYTE;
  16. typedef unsigned short WORD;

  17. BYTE BUF[8];                         //接收數(shù)據(jù)緩存區(qū)             
  18. uchar ge,shi,bai,qian,wan;           //顯示變量
  19. int  dis_data;                       //變量
  20. int  data_xyz[3];


  21. void delay(unsigned int k);
  22. void InitLcd();                      //初始化lcd1602
  23. void Init_ADXL345(void);             //初始化ADXL345

  24. void WriteDataLCM(uchar dataW);
  25. void WriteCommandLCM(uchar CMD,uchar Attribc);
  26. void DisplayOneChar(uchar X,uchar Y,uchar DData);
  27. void conversion(uint temp_data);

  28. void  Single_Write_ADXL345(uchar REG_Address,uchar REG_data);   //單個(gè)寫入數(shù)據(jù)
  29. uchar Single_Read_ADXL345(uchar REG_Address);                   //單個(gè)讀取內(nèi)部寄存器數(shù)據(jù)
  30. void  Multiple_Read_ADXL345();                                  //連續(xù)的讀取內(nèi)部寄存器數(shù)據(jù)
  31. //------------------------------------
  32. void Delay5us();
  33. void Delay5ms();
  34. void ADXL345_Start();
  35. void ADXL345_Stop();
  36. void ADXL345_SendACK(bit ack);
  37. bit  ADXL345_RecvACK();
  38. void ADXL345_SendByte(BYTE dat);
  39. BYTE ADXL345_RecvByte();
  40. void ADXL345_ReadPage();
  41. void ADXL345_WritePage();
  42. //-----------------------------------

  43. //*********************************************************
  44. void conversion(uint temp_data)  
  45. {  
  46.     wan=temp_data/10000+0x30 ;
  47.     temp_data=temp_data%10000;   //取余運(yùn)算
  48.         qian=temp_data/1000+0x30 ;
  49.     temp_data=temp_data%1000;    //取余運(yùn)算
  50.     bai=temp_data/100+0x30   ;
  51.     temp_data=temp_data%100;     //取余運(yùn)算
  52.     shi=temp_data/10+0x30    ;
  53.     temp_data=temp_data%10;      //取余運(yùn)算
  54.     ge=temp_data+0x30;        
  55. }

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

  109. /**************************************
  110. 延時(shí)5微秒(STC90C52RC@12M)
  111. 不同的工作環(huán)境,需要調(diào)整此函數(shù),注意時(shí)鐘過快時(shí)需要修改
  112. 當(dāng)改用1T的MCU時(shí),請(qǐng)調(diào)整此延時(shí)函數(shù)
  113. **************************************/
  114. void Delay5us()
  115. {
  116.     _nop_();_nop_();_nop_();_nop_();
  117.     _nop_();_nop_();_nop_();_nop_();
  118.         _nop_();_nop_();_nop_();_nop_();
  119. }

  120. /**************************************
  121. 延時(shí)5毫秒(STC90C52RC@12M)
  122. 不同的工作環(huán)境,需要調(diào)整此函數(shù)
  123. 當(dāng)改用1T的MCU時(shí),請(qǐng)調(diào)整此延時(shí)函數(shù)
  124. **************************************/
  125. void Delay5ms()
  126. {
  127.     WORD n = 560;

  128.     while (n--);
  129. }

  130. /**************************************
  131. 起始信號(hào)
  132. **************************************/
  133. void ADXL345_Start()
  134. {
  135.     SDA = 1;                    //拉高數(shù)據(jù)線
  136.     SCL = 1;                    //拉高時(shí)鐘線
  137.     Delay5us();                 //延時(shí)
  138.     SDA = 0;                    //產(chǎn)生下降沿
  139.     Delay5us();                 //延時(shí)
  140.     SCL = 0;                    //拉低時(shí)鐘線
  141. }

  142. /**************************************
  143. 停止信號(hào)
  144. **************************************/
  145. void ADXL345_Stop()
  146. {
  147.     SDA = 0;                    //拉低數(shù)據(jù)線
  148.     SCL = 1;                    //拉高時(shí)鐘線
  149.     Delay5us();                 //延時(shí)
  150.     SDA = 1;                    //產(chǎn)生上升沿
  151.     Delay5us();                 //延時(shí)
  152. }

  153. /**************************************
  154. 發(fā)送應(yīng)答信號(hào)
  155. 入口參數(shù):ack (0:ACK 1:NAK)
  156. **************************************/
  157. void ADXL345_SendACK(bit ack)
  158. {
  159.     SDA = ack;                  //寫應(yīng)答信號(hào)
  160.     SCL = 1;                    //拉高時(shí)鐘線
  161.     Delay5us();                 //延時(shí)
  162.     SCL = 0;                    //拉低時(shí)鐘線
  163.     Delay5us();                 //延時(shí)
  164. }

  165. /**************************************
  166. 接收應(yīng)答信號(hào)
  167. **************************************/
  168. bit ADXL345_RecvACK()
  169. {
  170.     SCL = 1;                    //拉高時(shí)鐘線
  171.     Delay5us();                 //延時(shí)
  172.     CY = SDA;                   //讀應(yīng)答信號(hào)
  173.     SCL = 0;                    //拉低時(shí)鐘線
  174.     Delay5us();                 //延時(shí)

  175.     return CY;
  176. }

  177. /**************************************
  178. 向IIC總線發(fā)送一個(gè)字節(jié)數(shù)據(jù)
  179. **************************************/
  180. void ADXL345_SendByte(BYTE dat)
  181. {
  182.     BYTE i;

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

  194. /**************************************
  195. 從IIC總線接收一個(gè)字節(jié)數(shù)據(jù)
  196. **************************************/
  197. BYTE ADXL345_RecvByte()
  198. {
  199.     BYTE i;
  200.     BYTE dat = 0;

  201.     SDA = 1;                    //使能內(nèi)部上拉,準(zhǔn)備讀取數(shù)據(jù),
  202.     for (i=0; i<8; i++)         //8位計(jì)數(shù)器
  203.     {
  204.         dat <<= 1;
  205.         SCL = 1;                //拉高時(shí)鐘線
  206.         Delay5us();             //延時(shí)
  207.         dat |= SDA;             //讀數(shù)據(jù)               
  208.         SCL = 0;                //拉低時(shí)鐘線
  209.         Delay5us();             //延時(shí)
  210.     }
  211.     return dat;
  212. }

  213. //******單字節(jié)寫入*******************************************

  214. void Single_Write_ADXL345(uchar REG_Address,uchar REG_data)
  215. {
  216.     ADXL345_Start();                  //起始信號(hào)
  217.     ADXL345_SendByte(SlaveAddress);   //發(fā)送設(shè)備地址+寫信號(hào)
  218.     ADXL345_SendByte(REG_Address);    //內(nèi)部寄存器地址,請(qǐng)參考中文pdf22頁
  219.     ADXL345_SendByte(REG_data);       //內(nèi)部寄存器數(shù)據(jù),請(qǐng)參考中文pdf22頁
  220.     ADXL345_Stop();                   //發(fā)送停止信號(hào)
  221. }

  222. //********單字節(jié)讀取*****************************************
  223. uchar Single_Read_ADXL345(uchar REG_Address)
  224. {  uchar REG_data;
  225.     ADXL345_Start();                          //起始信號(hào)
  226.     ADXL345_SendByte(SlaveAddress);           //發(fā)送設(shè)備地址+寫信號(hào)
  227.     ADXL345_SendByte(REG_Address);                   //發(fā)送存儲(chǔ)單元地址,從0開始       
  228.     ADXL345_Start();                          //起始信號(hào)
  229.     ADXL345_SendByte(SlaveAddress+1);         //發(fā)送設(shè)備地址+讀信號(hào)
  230.     REG_data=ADXL345_RecvByte();              //讀出寄存器數(shù)據(jù)
  231.         ADXL345_SendACK(1);   
  232.         ADXL345_Stop();                           //停止信號(hào)
  233.     return REG_data;
  234. }
  235. //*********************************************************
  236. //
  237. //連續(xù)讀出ADXL345內(nèi)部加速度數(shù)據(jù),地址范圍0x32~0x37
  238. //
  239. //*********************************************************
  240. void Multiple_read_ADXL345(void)
  241. {   uchar i;
  242.     ADXL345_Start();                          //起始信號(hào)
  243.     ADXL345_SendByte(SlaveAddress);           //發(fā)送設(shè)備地址+寫信號(hào)
  244.     ADXL345_SendByte(0x32);                   //發(fā)送存儲(chǔ)單元地址,從0x32開始       
  245.     ADXL345_Start();                          //起始信號(hào)
  246.     ADXL345_SendByte(SlaveAddress+1);         //發(fā)送設(shè)備地址+讀信號(hào)
  247.          for (i=0; i<6; i++)                      //連續(xù)讀取6個(gè)地址數(shù)據(jù),存儲(chǔ)中BUF
  248.     {
  249.         BUF[i] = ADXL345_RecvByte();          //BUF[0]存儲(chǔ)0x32地址中的數(shù)據(jù)
  250.         if (i == 5)
  251.         {
  252.            ADXL345_SendACK(1);                //最后一個(gè)數(shù)據(jù)需要回NOACK
  253.         }
  254.         else
  255.         {
  256.           ADXL345_SendACK(0);                //回應(yīng)ACK
  257.        }
  258.    }
  259.     ADXL345_Stop();                          //停止信號(hào)
  260.     Delay5ms();
  261. }


  262. //*****************************************************************

  263. //初始化ADXL345,根據(jù)需要請(qǐng)參考pdf進(jìn)行修改************************
  264. void Init_ADXL345()
  265. {
  266.    Single_Write_ADXL345(0x31,0x0B);   //測(cè)量范圍,正負(fù)16g,13位模式
  267.    Single_Write_ADXL345(0x2C,0x08);   //速率設(shè)定為12.5 參考pdf13頁
  268.    Single_Write_ADXL345(0x2D,0x08);   //選擇電源模式   參考pdf24頁
  269.    Single_Write_ADXL345(0x2E,0x80);   //使能 DATA_READY 中斷
  270.    Single_Write_ADXL345(0x1E,0x00);   //X 偏移量 根據(jù)測(cè)試傳感器的狀態(tài)寫入pdf29頁
  271.    Single_Write_ADXL345(0x1F,0x00);   //Y 偏移量 根據(jù)測(cè)試傳感器的狀態(tài)寫入pdf29頁
  272.    Single_Write_ADXL345(0x20,0x05);   //Z 偏移量 根據(jù)測(cè)試傳感器的狀態(tài)寫入pdf29頁
  273. }
  274. //***********************************************************************
  275. //顯示x軸
  276. void display_x()
  277. {   float temp;
  278.     dis_data=(BUF[1]<<8)+BUF[0];  //合成數(shù)據(jù)   
  279.         if(dis_data<0){
  280.         dis_data=-dis_data;
  281.     DisplayOneChar(2,0,'-');      //顯示正負(fù)符號(hào)位
  282.         }
  283.         else DisplayOneChar(2,0,' '); //顯示空格

  284.     temp=(float)dis_data*3.9;  //計(jì)算數(shù)據(jù)和顯示,查考ADXL345快速入門第4頁
  285.     conversion(temp);          //轉(zhuǎn)換出顯示需要的數(shù)據(jù)
  286.         DisplayOneChar(0,0,'X');   //第0行,第0列 顯示X
  287.     DisplayOneChar(1,0,':');
  288.     DisplayOneChar(3,0,qian);
  289.         DisplayOneChar(4,0,'.');
  290.     DisplayOneChar(5,0,bai);
  291.     DisplayOneChar(6,0,shi);
  292.         DisplayOneChar(7,0,'g');
  293. }

  294. //***********************************************************************
  295. //顯示y軸
  296. void display_y()
  297. {     float temp;
  298.     dis_data=(BUF[3]<<8)+BUF[2];  //合成數(shù)據(jù)   
  299.         if(dis_data<0){
  300.         dis_data=-dis_data;
  301.     DisplayOneChar(2,1,'-');      //顯示正負(fù)符號(hào)位
  302.         }
  303.         else DisplayOneChar(2,1,' '); //顯示空格

  304.     temp=(float)dis_data*3.9;  //計(jì)算數(shù)據(jù)和顯示,查考ADXL345快速入門第4頁
  305.     conversion(temp);          //轉(zhuǎn)換出顯示需要的數(shù)據(jù)
  306.         DisplayOneChar(0,1,'Y');   //第1行,第0列 顯示y
  307.     DisplayOneChar(1,1,':');
  308.     DisplayOneChar(3,1,qian);
  309.         DisplayOneChar(4,1,'.');
  310.     DisplayOneChar(5,1,bai);
  311.     DisplayOneChar(6,1,shi);  
  312.         DisplayOneChar(7,1,'g');  
  313. }

  314. //***********************************************************************
  315. //顯示z軸
  316. void display_z()
  317. {      float temp;
  318.     dis_data=(BUF[5]<<8)+BUF[4];    //合成數(shù)據(jù)   
  319.         if(dis_data<0){
  320.         dis_data=-dis_data;
  321.     DisplayOneChar(10,1,'-');       //顯示負(fù)符號(hào)位
  322.         }
  323.         else DisplayOneChar(10,1,' ');  //顯示空格

  324.     temp=(float)dis_data*3.9;  //計(jì)算數(shù)據(jù)和顯示,查考ADXL345快速入門第4頁
  325.     conversion(temp);          //轉(zhuǎn)換出顯示需要的數(shù)據(jù)
  326.         /*
  327.         DisplayOneChar(10,0,'Z');  //第0行,第10列 顯示Z
  328.     DisplayOneChar(11,0,':');
  329.     DisplayOneChar(11,1,qian);
  330.         DisplayOneChar(12,1,'.');
  331.     DisplayOneChar(13,1,bai);
  332.     DisplayOneChar(14,1,shi);
  333.         DisplayOneChar(15,1,'g');  
  334.         */
  335. }


  336. //*********************************************************
  337. //******主程序********
  338. //*********************************************************
  339. void main()
  340. {

  341.   uchar devid;
  342.   float Roll,Pitch,Q,T,K;

  343.   delay(500);                           //上電延時(shí)               
  344.   InitLcd();                      //液晶初始化ADXL345
  345.   Init_ADXL345();                 //初始化ADXL345
  346.   devid=Single_Read_ADXL345(0X00);//讀出的數(shù)據(jù)為0XE5,表示正確
  347.   while(1)                         //循環(huán)
  348.   {
  349.     Init_ADXL345();                     //初始化ADXL345
  350.     Multiple_Read_ADXL345();       //連續(xù)讀出數(shù)據(jù),存儲(chǔ)在BUF中

  351. data_xyz[0]=(BUF[1]<<8)+BUF[0];  //合成數(shù)據(jù)   
  352. data_xyz[1]=(BUF[3]<<8)+BUF[2];  //合成數(shù)據(jù)   
  353. data_xyz[2]=(BUF[5]<<8)+BUF[4];  //合成數(shù)據(jù)   

  354. //分別是加速度X,Y,Z的原始數(shù)據(jù),10位的
  355. Q=(float)data_xyz[0]*3.9;
  356. T=(float)data_xyz[1]*3.9;
  357. K=(float)data_xyz[2]*3.9;
  358. Q=-Q;
  359. Roll=(float)(((atan2(K,Q)*180)/3.14159265));    //X軸角度值
  360. Pitch=(float)(((atan2(K,T)*180)/3.14159265));  //Y軸角度值

  361.     DisplayOneChar(0,0,'A');
  362.         DisplayOneChar(1,0,'n');
  363.         DisplayOneChar(2,0,'g');
  364.         DisplayOneChar(3,0,'l');
  365.         DisplayOneChar(4,0,'e');
  366.          
  367.         DisplayOneChar(10,0,'O');  
  368.         DisplayOneChar(11,0,'f');
  369.         DisplayOneChar(12,0,'f');  
  370.         DisplayOneChar(13,0,'s');
  371.         DisplayOneChar(14,0,'e');  
  372.         DisplayOneChar(15,0,'t');


  373.     conversion(Roll);          //轉(zhuǎn)換出顯示需要的數(shù)據(jù)X軸
  374.     DisplayOneChar(0,1,'X');
  375.         DisplayOneChar(1,1,':');
  376.     DisplayOneChar(2,1,bai);
  377.     DisplayOneChar(3,1,shi);
  378.         DisplayOneChar(4,1,ge);
  379.         DisplayOneChar(5,1,0xdf);  
  380.          
  381.         conversion(Pitch);          //轉(zhuǎn)換出顯示需要的數(shù)據(jù)Y軸
  382.     DisplayOneChar(10,1,'Y');
  383.         DisplayOneChar(11,1,':');
  384.     DisplayOneChar(12,1,bai);
  385.     DisplayOneChar(13,1,shi);
  386.         DisplayOneChar(14,1,ge);  
  387.         DisplayOneChar(15,1,0xdf);  
  388.     delay(200);                    //延時(shí)            
  389.   }
  390. }
復(fù)制代碼

所有資料51hei提供下載:
基于ADXL345傳感器的LCD1602角度顯示功能設(shè)計(jì).zip (48.23 KB, 下載次數(shù): 57)


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:1 發(fā)表于 2019-5-10 18:33 | 只看該作者
本帖需要重新編輯補(bǔ)全電路原理圖,源碼,詳細(xì)說明與圖片即可獲得100+黑幣(帖子下方有編輯按鈕)
回復(fù)

使用道具 舉報(bào)

板凳
ID:897819 發(fā)表于 2021-3-28 23:34 來自手機(jī) | 只看該作者
admin 發(fā)表于 2019-5-10 18:33
本帖需要重新編輯補(bǔ)全電路原理圖,源碼,詳細(xì)說明與圖片即可獲得100+黑幣(帖子下方有編輯按鈕)

你好,現(xiàn)在有原理圖了嗎?
回復(fù)

使用道具 舉報(bào)

地板
ID:815431 發(fā)表于 2021-3-30 14:53 | 只看該作者
求原理圖
回復(fù)

使用道具 舉報(bào)

5#
ID:958362 發(fā)表于 2021-8-3 12:24 | 只看該作者
IN接口都用不到的嗎
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表