找回密码
 立即注册

QQ登录

只需一步,快速开始

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

求解决PIC18F4520为什么不能读出MPU6050陀螺仪的数据

[复制链接]
跳转到指定楼层
楼主
ID:169653 发表于 2017-9-11 15:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
100黑币
  1. #include <p18cxxx.h>    /*18F系列单片机头文件*/
  2. #include "k18.h"        /*开发板头文件*/
  3. #include "REG.h"
  4. #define uchar    unsigned char
  5. #define uint     unsigned int
  6. #define ulong    unsigned long
  7. #define ushort   unsigned short  
  8. #define IIC_SCL  PORTCbits.RC5
  9. #define IIC_SDA  PORTCbits.RC4
  10. #define READ_SDA PORTCbits.RC4  //输入SDA
  11. #define IIC_SDA_TRIS TRISCbits.TRISC3
  12. #define SDA_IN()   1
  13. #define SDA_OUT()  0
  14. float   Angle[3];        //陀螺仪角度        
  15. float   a[3];            //陀螺仪加速度
  16. float   w[3];            //陀螺仪角速度
  17. float   h[3];                           
  18. uchar   chrTemp[22];
  19. ushort  data[3];
  20. void PIC18F_High_isr(void);  /*中断服务函数声明*/
  21. void PIC18F_Low_isr(void);

  22. #pragma code high_vector_section=0x8

  23. void high_vector (void)
  24. {
  25.         _asm goto PIC18F_High_isr _endasm   /*通过一条跳转指令(汇编指令),跳转到中断服务函数(中断服务程序)处*/
  26. }
  27. #pragma code low_vector_section=0x18
  28. void low_vector (void)
  29. {
  30.         _asm goto PIC18F_Low_isr _endasm
  31. }
  32. #pragma code

  33. #pragma interrupt PIC18F_High_isr
  34. void PIC18F_High_isr (void)
  35. {   
  36.         PIR1bits.RCIF=0;

  37. }
  38. #pragma interruptlow PIC18F_Low_isr

  39. void PIC18F_Low_isr (void)
  40. {

  41. }
  42. void Delay_us(uchar n)
  43. {
  44.     uint j,k;
  45.     for(j=0;j<n;j++)         
  46.       for(k=1;k>0;k--);
  47. }
  48. void Delay_ms(uint n)
  49. {
  50.     uint j,k;
  51.     for(j=0;j<n;j++)
  52.       for(k=730;k>0;k--);
  53. }
  54. void IIC_Init(void)
  55. {                        
  56.         
  57.         SDA_OUT();     //sda线输出
  58.         IIC_SDA=1;                    
  59.         IIC_SCL=1;
  60. }
  61. /**************************实现函数********************************************
  62. *函数原型:                void IIC_Start(void)
  63. *功  能:                产生IIC起始信号
  64. *******************************************************************************/
  65. void IIC_Start(void)
  66. {
  67.         SDA_OUT();     //sda线输出
  68.         IIC_SDA=1;                    
  69.         IIC_SCL=1;        
  70.         Delay_us(5);
  71.          IIC_SDA=0;//START:when CLK is high,DATA change form high to low         
  72.         Delay_us(5);
  73.         IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
  74. }

  75. /**************************实现函数********************************************
  76. *函数原型:                void IIC_Stop(void)
  77. *功  能:            //产生IIC停止信号
  78. *******************************************************************************/         
  79. void IIC_Stop(void)
  80. {
  81.         SDA_OUT();//sda线输出
  82.         IIC_SCL=0;
  83.         IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
  84.          
  85.         Delay_us(5);
  86.         IIC_SCL=1;
  87.         IIC_SDA=1;//发送I2C总线结束信号
  88.         
  89.         Delay_us(5);                                                                  
  90. }

  91. /**************************实现函数********************************************
  92. *函数原型:                u8 IIC_Wait_Ack(void)
  93. *功  能:            等待应答信号到来
  94. //返回值:1,接收应答失败
  95. //        0,接收应答成功
  96. *******************************************************************************/
  97. uchar IIC_Wait_Ack(void)
  98. {
  99.         uchar  ucErrTime=0;
  100.         SDA_IN();      //SDA设置为输入  
  101.         IIC_SDA=1;
  102.         Delay_us(5);         
  103.         while(READ_SDA)
  104.         {
  105.                 ucErrTime++;
  106.                 if(ucErrTime>50)
  107.                 {
  108.                         IIC_Stop();
  109.                         return 1;
  110.                 }
  111.                 Delay_us(5);
  112.         }  
  113.             IIC_SCL=1;
  114.             Delay_us(5);
  115.             IIC_SCL=0;//时钟输出0  
  116.             return 0;  
  117. }

  118. /**************************实现函数********************************************
  119. *函数原型:                void IIC_Ack(void)
  120. *功  能:            产生ACK应答
  121. *******************************************************************************/
  122. void IIC_Ack(void)
  123. {
  124.         IIC_SCL=0;
  125.         SDA_OUT();
  126.         IIC_SDA=0;
  127.         Delay_us(5);
  128.         IIC_SCL=1;
  129.         Delay_us(5);
  130.         IIC_SCL=0;
  131. }
  132.         
  133. /**************************实现函数********************************************
  134. *函数原型:                void IIC_NAck(void)
  135. *功  能:            产生NACK应答
  136. *******************************************************************************/            
  137. void IIC_NAck(void)
  138. {
  139.         IIC_SCL=0;
  140.         SDA_OUT();
  141.         IIC_SDA=1;
  142.         
  143.         Delay_us(5);
  144.         IIC_SCL=1;
  145.         Delay_us(5);
  146.         IIC_SCL=0;
  147. }                                                                              

  148. /**************************实现函数********************************************
  149. *函数原型:                void IIC_Send_Byte(u8 txd)
  150. *功  能:            IIC发送一个字节
  151. *******************************************************************************/                  
  152. void IIC_Send_Byte(uint txd)
  153. {                        
  154.     uint t;
  155.         SDA_OUT();            
  156.     IIC_SCL=0;//拉低时钟开始数据传输
  157.     for(t=0;t<8;t++)
  158.     {              
  159.         IIC_SDA=(txd&0x80)>>7;
  160.         txd<<=1;           
  161.                         
  162.                 Delay_us(5);   
  163.                 IIC_SCL=1;
  164.                 Delay_us(5);
  165.                 IIC_SCL=0;        
  166.                 Delay_us(5);
  167.     }         
  168. }         

  169. /**************************实现函数********************************************
  170. *函数原型:                u8 IIC_Read_Byte(unsigned char ack)
  171. *功  能:            //读1个字节,ack=1时,发送ACK,ack=0,发送nACK
  172. *******************************************************************************/  
  173. uchar  IIC_Read_Byte(uchar ack)
  174. {
  175.         uchar i,receive=0;
  176.         SDA_IN();//SDA设置为输入
  177.     for(i=0;i<8;i++ )
  178.         {
  179.         IIC_SCL=0;

  180.                 Delay_us(5);
  181.                 IIC_SCL=1;
  182.         receive<<=1;
  183.         if(READ_SDA)receive++;   
  184.                
  185.                 Delay_us(5);
  186.     }                                         
  187.     if (ack)
  188.         IIC_Ack(); //发送ACK
  189.     else
  190.         IIC_NAck();//发送nACK  
  191.     return receive;
  192. }

  193. /**************************实现函数********************************************
  194. *函数原型:                u8 IICreadBytes(u8 dev, u8 reg, u8 length, u8 *data)
  195. *功  能:            读取指定设备 指定寄存器的 length个值
  196. 输入        dev  目标设备地址
  197.                 reg          寄存器地址
  198.                 length 要读的字节数
  199.                 *data  读出的数据将要存放的指针
  200. 返回   读出来的字节数量
  201. *******************************************************************************/
  202. ulong IICreadBytes(uchar dev, uchar reg, ulong length, ulong  *data)
  203. {
  204.     uint count = 0;
  205.         
  206.         IIC_Start();
  207.         IIC_Send_Byte(dev<<1);           //发送写命令
  208.         IIC_Wait_Ack();
  209.         IIC_Send_Byte(reg);   //发送地址
  210.     IIC_Wait_Ack();         
  211.         IIC_Start();
  212.         IIC_Send_Byte((dev<<1)+1);  //进入接收模式        
  213.         IIC_Wait_Ack();        
  214.     for(count=0;count<length;count++)
  215.             {                 
  216.                  if(count!=length-1)data[count]=IIC_Read_Byte(1);  //带ACK的读数据
  217.                  else  data[count]=IIC_Read_Byte(0);         //最后一个字节NACK
  218.             }
  219.     IIC_Stop();//产生一个停止条件
  220.     return count;
  221. }

  222. /**************************实现函数********************************************
  223. *函数原型:                u8 IICwriteBytes(u8 dev, u8 reg, u8 length, u8 *data)
  224. *功  能:            将多个字节写入指定设备 指定寄存器
  225. 输入        dev     目标设备地址
  226.                 reg            寄存器地址
  227.                 length  要写的字节数
  228.                 *data   将要写的数据的首地址
  229. 返回   返回是否成功
  230. *******************************************************************************/
  231. ulong IICwriteBytes(uchar dev, uchar reg, ulong length, ulong  *data)
  232. {

  233.          uint count = 0;
  234.         IIC_Start();
  235.         IIC_Send_Byte(dev<<1);           //发送写命令
  236.         IIC_Wait_Ack();
  237.         IIC_Send_Byte(reg);   //发送地址
  238.         IIC_Wait_Ack();         
  239.         for(count=0;count<length;count++)
  240.       {
  241.                 IIC_Send_Byte(data[count]);
  242.                 IIC_Wait_Ack();
  243.       }
  244.         IIC_Stop();//产生一个停止条件

  245.     return 1; //status == 0;
  246.         
  247. }
  248. void ShortToChar(short sData,unsigned char cData[])
  249. {
  250.         cData[0]=sData&0xff;
  251.         cData[1]=sData>>8;
  252. }
  253. short CharToShort(unsigned char cData[])
  254. {
  255.         return ((short)cData[1]<<8)|cData[0];
  256. }
  257. void main(void)
  258. {        
  259.         k18_init();           /*K18开发板初始化*/
  260.         IIC_Init();        
  261.         RCSTAbits.SPEN = 1;   /*使能串口(将RX和TX引脚配置为串口引脚)*/
  262.         TXSTAbits.SYNC = 0;   /*异步模式*/
  263.         SPBRG = 0x47;         /*波特率寄存器置值,设置波特率38400*/
  264.         TXSTAbits.BRGH=1;  /*速度模式:高速*/
  265.         RCSTAbits.CREN=1;  /*接收使能*/
  266.         TXSTAbits.TXEN=1;  /*发送使能*/               
  267.         IPR1bits.RCIP=1;      /*设定串口接收中断为高优先级,本句也可以省略,复位后默认为高优先级*/
  268.         PIE1bits.RCIE=1;      /*串口接收中断允许*/
  269.         INTCONbits.PEIE=1;    /*外设中断允许*/
  270.         INTCONbits.GIE=1;     /*开总中断*/        
  271.         while(1)
  272.         {   
  273.                 Delay_ms(100);
  274.                 IICreadBytes(0x55, AX, 24,&chrTemp[0]);
  275.                
  276.                 //a[0] = (float)CharToShort(&chrTemp[0])/32768*16;
  277.                 //a[1] = (float)CharToShort(&chrTemp[2])/32768*16;
  278.         //        a[2] = (float)CharToShort(&chrTemp[4])/32768*16;
  279.         //        w[0] = (float)CharToShort(&chrTemp[6])/32768*2000;
  280.         //        w[1] = (float)CharToShort(&chrTemp[8])/32768*2000;
  281.         //        w[2] = (float)CharToShort(&chrTemp[10])/32768*2000;
  282.         //        h[0] = CharToShort(&chrTemp[12]);
  283.         //        h[1] = CharToShort(&chrTemp[14]);
  284.         //        h[2] = CharToShort(&chrTemp[16]);
  285.                 Angle[0] = (float)CharToShort(&chrTemp[18])/32768*180;
  286.             Angle[1] = (float)CharToShort(&chrTemp[20])/32768*180;
  287.                 Angle[2] = (float)CharToShort(&chrTemp[22])/32768*180;
  288.                

  289.         /*        IICreadBytes(0x51, AX, 24,&chrTemp[0]);
  290.                 a[0] = (float)CharToShort(&chrTemp[0])/32768*16;
  291.                 a[1] = (float)CharToShort(&chrTemp[2])/32768*16;
  292.                 a[2] = (float)CharToShort(&chrTemp[4])/32768*16;
  293.                 w[0] = (float)CharToShort(&chrTemp[6])/32768*2000;
  294.                 w[1] = (float)CharToShort(&chrTemp[8])/32768*2000;
  295.                 w[2] = (float)CharToShort(&chrTemp[10])/32768*2000;
  296.                 h[0] = CharToShort(&chrTemp[12]);
  297.                 h[1] = CharToShort(&chrTemp[14]);
  298.                 h[2] = CharToShort(&chrTemp[16]);
  299.                 Angle[0] = (float)CharToShort(&chrTemp[18])/32768*180;
  300.                 Angle[1] = (float)CharToShort(&chrTemp[20])/32768*180;
  301.                 Angle[2] = (float)CharToShort(&chrTemp[22])/32768*180;
  302.         */
  303.                  // uint i;
  304.                   //data[0]=MPU6050_I2C_ReadByte(GXH);
  305.                  // a[1]=data[1]/32768*16;
  306.                   //a[2]=data[2]/32768*16;
  307.                   //a[3]=data[3]/32768*16;
  308.               //if((data[0]=0x51)|(data[0]=0x53)|(data[0]=0x50))  //读取MPU6050的地址
  309.          //{
  310.                    //  for(i=0;i<3;i++)
  311.                    //  data[1]=(GXH<<8|GXL)/32768*180;
  312.                    //  data[2]=(GYH<<8|GYL)/32768*180;
  313.                     // data[3]=(GZH<<8|GZL)/32768*180;
  314.                    //  TXREG=data[0];
  315.                   
  316.                
  317.                //}
  318.                 /*a[0] = (float)CharToShort(&chrTemp[0])/32768*16;
  319.                 a[1] = (float)CharToShort(&chrTemp[2])/32768*16;
  320.                        a[2] = (float)CharToShort(&chrTemp[4])/32768*16;
  321.                     w[0] = (float)CharToShort(&chrTemp[6])/32768*2000;
  322.                      w[1] = (float)CharToShort(&chrTemp[8])/32768*2000;
  323.                     w[2] = (float)CharToShort(&chrTemp[10])/32768*2000;
  324.                     h[0] = CharToShort(&chrTemp[12]);
  325.                     h[1] = CharToShort(&chrTemp[14]);
  326.                     h[2] = CharToShort(&chrTemp[16]);               
  327.                     Angle[0] = (float)CharToShort(&chrTemp[18])/32768*180;
  328.                     Angle[1] = (float)CharToShort(&chrTemp[20])/32768*180;
  329.                     Angle[2] = (float)CharToShort(&chrTemp[22])/32768*180;*/              
  330.         }
  331. }


复制代码


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

使用道具 举报

沙发
ID:123289 发表于 2017-9-11 18:48 | 只看该作者
一定是你自己不会写程序
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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