找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3010|回复: 4
打印 上一主题 下一主题
收起左侧

单片机+ADXL345传感器的LCD1602角度显示功能程序设计

[复制链接]
跳转到指定楼层
楼主
ID:517871 发表于 2019-5-10 10:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
单片机源程序如下:
  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. sbit          SCL=P1^2;      //IIC时钟引脚定义
  9. sbit           SDA=P1^3;      //IIC数据引脚定义
  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总线中的从地址,根据ALT  ADDRESS地址引脚不同修改
  14.                               //ALT  ADDRESS引脚接地时地址为0xA6,接电源时地址为0x3A
  15. typedef unsigned char  BYTE;
  16. typedef unsigned short WORD;

  17. BYTE BUF[8];                         //接收数据缓存区             
  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);   //单个写入数据
  29. uchar Single_Read_ADXL345(uchar REG_Address);                   //单个读取内部寄存器数据
  30. void  Multiple_Read_ADXL345();                                  //连续的读取内部寄存器数据
  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;   //取余运算
  48.         qian=temp_data/1000+0x30 ;
  49.     temp_data=temp_data%1000;    //取余运算
  50.     bai=temp_data/100+0x30   ;
  51.     temp_data=temp_data%100;     //取余运算
  52.     shi=temp_data/10+0x30    ;
  53.     temp_data=temp_data%10;      //取余运算
  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()                        //液晶显示器的设置       
  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. 延时5微秒(STC90C52RC@12M)
  111. 不同的工作环境,需要调整此函数,注意时钟过快时需要修改
  112. 当改用1T的MCU时,请调整此延时函数
  113. **************************************/
  114. void Delay5us()
  115. {
  116.     _nop_();_nop_();_nop_();_nop_();
  117.     _nop_();_nop_();_nop_();_nop_();
  118.         _nop_();_nop_();_nop_();_nop_();
  119. }

  120. /**************************************
  121. 延时5毫秒(STC90C52RC@12M)
  122. 不同的工作环境,需要调整此函数
  123. 当改用1T的MCU时,请调整此延时函数
  124. **************************************/
  125. void Delay5ms()
  126. {
  127.     WORD n = 560;

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

  130. /**************************************
  131. 起始信号
  132. **************************************/
  133. void ADXL345_Start()
  134. {
  135.     SDA = 1;                    //拉高数据线
  136.     SCL = 1;                    //拉高时钟线
  137.     Delay5us();                 //延时
  138.     SDA = 0;                    //产生下降沿
  139.     Delay5us();                 //延时
  140.     SCL = 0;                    //拉低时钟线
  141. }

  142. /**************************************
  143. 停止信号
  144. **************************************/
  145. void ADXL345_Stop()
  146. {
  147.     SDA = 0;                    //拉低数据线
  148.     SCL = 1;                    //拉高时钟线
  149.     Delay5us();                 //延时
  150.     SDA = 1;                    //产生上升沿
  151.     Delay5us();                 //延时
  152. }

  153. /**************************************
  154. 发送应答信号
  155. 入口参数:ack (0:ACK 1:NAK)
  156. **************************************/
  157. void ADXL345_SendACK(bit ack)
  158. {
  159.     SDA = ack;                  //写应答信号
  160.     SCL = 1;                    //拉高时钟线
  161.     Delay5us();                 //延时
  162.     SCL = 0;                    //拉低时钟线
  163.     Delay5us();                 //延时
  164. }

  165. /**************************************
  166. 接收应答信号
  167. **************************************/
  168. bit ADXL345_RecvACK()
  169. {
  170.     SCL = 1;                    //拉高时钟线
  171.     Delay5us();                 //延时
  172.     CY = SDA;                   //读应答信号
  173.     SCL = 0;                    //拉低时钟线
  174.     Delay5us();                 //延时

  175.     return CY;
  176. }

  177. /**************************************
  178. 向IIC总线发送一个字节数据
  179. **************************************/
  180. void ADXL345_SendByte(BYTE dat)
  181. {
  182.     BYTE i;

  183.     for (i=0; i<8; i++)         //8位计数器
  184.     {
  185.         dat <<= 1;              //移出数据的最高位
  186.         SDA = CY;               //送数据口
  187.         SCL = 1;                //拉高时钟线
  188.         Delay5us();             //延时
  189.         SCL = 0;                //拉低时钟线
  190.         Delay5us();             //延时
  191.     }
  192.     ADXL345_RecvACK();
  193. }

  194. /**************************************
  195. 从IIC总线接收一个字节数据
  196. **************************************/
  197. BYTE ADXL345_RecvByte()
  198. {
  199.     BYTE i;
  200.     BYTE dat = 0;

  201.     SDA = 1;                    //使能内部上拉,准备读取数据,
  202.     for (i=0; i<8; i++)         //8位计数器
  203.     {
  204.         dat <<= 1;
  205.         SCL = 1;                //拉高时钟线
  206.         Delay5us();             //延时
  207.         dat |= SDA;             //读数据               
  208.         SCL = 0;                //拉低时钟线
  209.         Delay5us();             //延时
  210.     }
  211.     return dat;
  212. }

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

  214. void Single_Write_ADXL345(uchar REG_Address,uchar REG_data)
  215. {
  216.     ADXL345_Start();                  //起始信号
  217.     ADXL345_SendByte(SlaveAddress);   //发送设备地址+写信号
  218.     ADXL345_SendByte(REG_Address);    //内部寄存器地址,请参考中文pdf22页
  219.     ADXL345_SendByte(REG_data);       //内部寄存器数据,请参考中文pdf22页
  220.     ADXL345_Stop();                   //发送停止信号
  221. }

  222. //********单字节读取*****************************************
  223. uchar Single_Read_ADXL345(uchar REG_Address)
  224. {  uchar REG_data;
  225.     ADXL345_Start();                          //起始信号
  226.     ADXL345_SendByte(SlaveAddress);           //发送设备地址+写信号
  227.     ADXL345_SendByte(REG_Address);                   //发送存储单元地址,从0开始       
  228.     ADXL345_Start();                          //起始信号
  229.     ADXL345_SendByte(SlaveAddress+1);         //发送设备地址+读信号
  230.     REG_data=ADXL345_RecvByte();              //读出寄存器数据
  231.         ADXL345_SendACK(1);   
  232.         ADXL345_Stop();                           //停止信号
  233.     return REG_data;
  234. }
  235. //*********************************************************
  236. //
  237. //连续读出ADXL345内部加速度数据,地址范围0x32~0x37
  238. //
  239. //*********************************************************
  240. void Multiple_read_ADXL345(void)
  241. {   uchar i;
  242.     ADXL345_Start();                          //起始信号
  243.     ADXL345_SendByte(SlaveAddress);           //发送设备地址+写信号
  244.     ADXL345_SendByte(0x32);                   //发送存储单元地址,从0x32开始       
  245.     ADXL345_Start();                          //起始信号
  246.     ADXL345_SendByte(SlaveAddress+1);         //发送设备地址+读信号
  247.          for (i=0; i<6; i++)                      //连续读取6个地址数据,存储中BUF
  248.     {
  249.         BUF[i] = ADXL345_RecvByte();          //BUF[0]存储0x32地址中的数据
  250.         if (i == 5)
  251.         {
  252.            ADXL345_SendACK(1);                //最后一个数据需要回NOACK
  253.         }
  254.         else
  255.         {
  256.           ADXL345_SendACK(0);                //回应ACK
  257.        }
  258.    }
  259.     ADXL345_Stop();                          //停止信号
  260.     Delay5ms();
  261. }


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

  263. //初始化ADXL345,根据需要请参考pdf进行修改************************
  264. void Init_ADXL345()
  265. {
  266.    Single_Write_ADXL345(0x31,0x0B);   //测量范围,正负16g,13位模式
  267.    Single_Write_ADXL345(0x2C,0x08);   //速率设定为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 偏移量 根据测试传感器的状态写入pdf29页
  271.    Single_Write_ADXL345(0x1F,0x00);   //Y 偏移量 根据测试传感器的状态写入pdf29页
  272.    Single_Write_ADXL345(0x20,0x05);   //Z 偏移量 根据测试传感器的状态写入pdf29页
  273. }
  274. //***********************************************************************
  275. //显示x轴
  276. void display_x()
  277. {   float temp;
  278.     dis_data=(BUF[1]<<8)+BUF[0];  //合成数据   
  279.         if(dis_data<0){
  280.         dis_data=-dis_data;
  281.     DisplayOneChar(2,0,'-');      //显示正负符号位
  282.         }
  283.         else DisplayOneChar(2,0,' '); //显示空格

  284.     temp=(float)dis_data*3.9;  //计算数据和显示,查考ADXL345快速入门第4页
  285.     conversion(temp);          //转换出显示需要的数据
  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];  //合成数据   
  299.         if(dis_data<0){
  300.         dis_data=-dis_data;
  301.     DisplayOneChar(2,1,'-');      //显示正负符号位
  302.         }
  303.         else DisplayOneChar(2,1,' '); //显示空格

  304.     temp=(float)dis_data*3.9;  //计算数据和显示,查考ADXL345快速入门第4页
  305.     conversion(temp);          //转换出显示需要的数据
  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];    //合成数据   
  319.         if(dis_data<0){
  320.         dis_data=-dis_data;
  321.     DisplayOneChar(10,1,'-');       //显示负符号位
  322.         }
  323.         else DisplayOneChar(10,1,' ');  //显示空格

  324.     temp=(float)dis_data*3.9;  //计算数据和显示,查考ADXL345快速入门第4页
  325.     conversion(temp);          //转换出显示需要的数据
  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);                           //上电延时               
  344.   InitLcd();                      //液晶初始化ADXL345
  345.   Init_ADXL345();                 //初始化ADXL345
  346.   devid=Single_Read_ADXL345(0X00);//读出的数据为0XE5,表示正确
  347.   while(1)                         //循环
  348.   {
  349.     Init_ADXL345();                     //初始化ADXL345
  350.     Multiple_Read_ADXL345();       //连续读出数据,存储在BUF中

  351. data_xyz[0]=(BUF[1]<<8)+BUF[0];  //合成数据   
  352. data_xyz[1]=(BUF[3]<<8)+BUF[2];  //合成数据   
  353. data_xyz[2]=(BUF[5]<<8)+BUF[4];  //合成数据   

  354. //分别是加速度X,Y,Z的原始数据,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);          //转换出显示需要的数据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);          //转换出显示需要的数据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);                    //延时            
  389.   }
  390. }
复制代码

所有资料51hei提供下载:
基于ADXL345传感器的LCD1602角度显示功能设计.zip (48.23 KB, 下载次数: 56)


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1 发表于 2019-5-10 18:33 | 只看该作者
本帖需要重新编辑补全电路原理图,源码,详细说明与图片即可获得100+黑币(帖子下方有编辑按钮)
回复

使用道具 举报

板凳
ID:897819 发表于 2021-3-28 23:34 来自手机 | 只看该作者
admin 发表于 2019-5-10 18:33
本帖需要重新编辑补全电路原理图,源码,详细说明与图片即可获得100+黑币(帖子下方有编辑按钮)

你好,现在有原理图了吗?
回复

使用道具 举报

地板
ID:815431 发表于 2021-3-30 14:53 | 只看该作者
求原理图
回复

使用道具 举报

5#
ID:958362 发表于 2021-8-3 12:24 | 只看该作者
IN接口都用不到的吗
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表