搜索
bottom↓
回复: 2

关于飞思卡尔IIC的问题

[复制链接]

出0入0汤圆

发表于 2013-3-15 21:12:11 | 显示全部楼层 |阅读模式
各位大神,最近小弟正在调硬件IIC总线,一直都很头疼,现在求救于各位大大,先贴出程序!
  /*The slave address of the MPU-60X0 is b110100X which is 7 bits lengths.the address of the devices  should be b1101000(0xD0)(pin AD0 is logic low),by then,the writing address is 0xD0 and the reading address is 0xD1 */
/*the interface is as follows,SCLJ7 SDAJ6 */

#include <hidef.h>      /* common defines and macros */
#include "derivative.h"      /* derivative-specific definitions */

#define SlaveAddress 0xD0

//****************************************
// ¶¨òåMPU6050Äú2¿μØÖ·
//****************************************
#define        SMPLRT_DIV                0x19        //íóÂYòÇ2éÑùÂ꣬μäDíÖμ£o0x07(125Hz)
#define        CONFIG                          0x1A        //μíí¨ÂË2¨ÆμÂ꣬μäDíÖμ£o0x06(5Hz)
#define        GYRO_CONFIG                0x1B        //íóÂYòÇ×Լ켰2aá¿·¶Î§£¬μäDíÖμ£o0x18(2»×Լ죬2000deg/s)
#define        ACCEL_CONFIG        0x1C        //¼óËù¼Æ×Լ졢2aá¿·¶Î§¼°¸ßí¨ÂË2¨ÆμÂ꣬μäDíÖμ£o0x01(2»×Լ죬2G£¬5Hz)
#define        ACCEL_XOUT_H        0x3B
#define        ACCEL_XOUT_L        0x3C
#define        ACCEL_YOUT_H        0x3D
#define        ACCEL_YOUT_L        0x3E
#define        ACCEL_ZOUT_H        0x3F
#define        ACCEL_ZOUT_L        0x40
#define        TEMP_OUT_H                0x41
#define        TEMP_OUT_L                0x42
#define        GYRO_XOUT_H                0x43
#define        GYRO_XOUT_L                0x44        
#define        GYRO_YOUT_H                0x45
#define        GYRO_YOUT_L                0x46
#define        GYRO_ZOUT_H                0x47
#define        GYRO_ZOUT_L                0x48
#define        PWR_MGMT_1                0x6B        //μçÔ′1üàí£¬μäDíÖμ£o0x00(Õy3£ÆôóÃ)
#define        WHO_AM_I                        0x75        //IICμØÖ·¼Ä′æÆ÷(ĬèÏêyÖμ0x68£¬Ö»¶á)



struct Mpu_data{
sWord Accel_X;
sWord Accel_Y;
sWord Accel_Z;
sWord Temp;
sWord Gyro_X;
sWord Gyro_Y;
sWord Gyro_Z;
}mpu_data;      


struct IMU{
  float a_x;
  float a_y;
  float a_z;
  float gyro_x;
  float gyro_y;
  float gyro_z;
}Imu_data;

void delay(word time)
{

       word i=0,j=0;
      while(time--)
        {
         for(i=0;i<25;i++)
          for(j=0;j<1200;j++)
           asm("nop");
       }
}


/*************************************************************/
/*                      3õê¼»ˉËøÏà»·                         */
/*************************************************************/
void PLL_init(void)
{
    CLKSEL=0X00;                                //disengage PLL to system
    PLLCTL_PLLON=1;                        //turn on PLL
    SYNR =0xc0 | 0x07;                        
    REFDV=0x80 | 0x01;
    POSTDIV=0x00;       //pllclock=2*osc*(1+SYNR)/(1+REFDV)=128MHz;
    _asm(nop);          //BUS CLOCK=64M
    _asm(nop);
    while(!(CRGFLG_LOCK==1));          //when pll is steady ,then use it;
    CLKSEL_PLLSEL =1;                        //engage PLL to system;
    asm NOP;
    asm NOP;
    while(!(CRGFLG&0x08)); //PLLCLK is Locked already
    CLKSEL |= 0x80;        //set PLLCLK as sysclk
}


//-----I2C 3õê¼»ˉ3ìDò --------//
void I2C_Bus_init(void)
{
     IIC0_IBFD=0x65; //this choose f(I2C)=100K,sda hold=1.53125us,scl hold start=4.9375us,scl hold stop=5.13125us
     IIC0_IBAD=0xF4; //choose slave address of the chip,ensure that this is not the address of MPU6050
     IIC0_IBCR|=0x80;//enable I2C system
     IIC0_IBCR|=0x30;//disable I2C interrupt,choose Slave mode,Tx mode,then it generates a P signal
    IIC0_IBSR_IBAL=1;//set the bus to be idle
}


void I2C_Single_Write(uchar REG_Address,uchar REG_data){
  IIC0_IBCR=0xB0;//master mode ,Tx mode ,then it generates a S signal
  //while(!IIC0_IBSR_IBB);
  IIC0_IBDR=SlaveAddress;// send AD+W
   while(IIC0_IBSR_RXAK);//wait ACK
  IIC0_IBDR=REG_Address; //send RA
   while(IIC0_IBSR_RXAK);//wait ACK
  IIC0_IBDR=REG_data;   //send DATA
  while(IIC0_IBSR_RXAK);//wait ACK
  IIC0_IBCR=0x80;
}

//**************************************
//′óI2Cé豸¶áè¡ò»¸ö×Ö½úêy¾Y
//**************************************
byte I2C_Single_Read(byte REG_Address)
{
  byte REG_data;
  IIC0_IBCR=0xB0;//master mode ,Tx mode ,then it generates a S signal
  IIC0_IBDR=SlaveAddress;// send AD+W

    //while(IIC0_IBSR_RXAK);//wait ACK
  IIC0_IBDR=REG_Address; //send RA

    while(IIC0_IBSR_RXAK);//wait ACK

  IIC0_IBCR_RSTA=1;//send Repeat_S signal
  IIC0_IBDR=SlaveAddress+1;// send AD+R
   IIC0_IBCR_TX_RX=0;// turn to receive
    //  IIC0_IBCR_TXAK=1;

    while(IIC0_IBSR_RXAK);//wait ACK
  //IIC0_IBCR_RSTA=0;//close Repeat_S signal

  REG_data=IIC0_IBDR;
    while(!IIC0_IBSR_IBIF);
    IIC0_IBSR_IBIF=1;
  IIC0_IBCR=0x80;      //send P
  while(IIC0_IBSR_IBB);
  REG_data=IIC0_IBDR;  //when the data is read,then the bus turn to busy,the IBSR is 0x36,so the NACK has not been sent
        return REG_data;
}

//**************************************
//′óI2Cé豸¶áè¡N¸ö×Ö½úêy¾Y
//**************************************
/*void Burst_ReadI2C(byte REG_Address)
{
  byte i;
  byte* add;
   add=(byte*)&(mpu_data.Accel_X);
  I2C_Start();   //Æeê¼DÅoÅ,S
  I2C_Send(0xD0);  //·¢Ëíé豸μØÖ·+D′DÅoÅ,AD+W
  I2C_Wait_Ack();  //μè′yé豸ó|′eDÅoÅ,ACK
  I2C_Send(REG_Address);  //·¢Ëí′æ′¢μ¥ÔaμØÖ·£¬′ó0¿aê¼,RA
  I2C_Wait_Ack();//ACK
  I2C_Start();//S
  I2C_Send(0xD1);  //·¢Ëíé豸μØÖ·+¶áDÅoÅ,AD+R
  I2C_Wait_Ack();//ACK
  *add=I2C_Receive();  //¶á3ö¼Ä′æÆ÷êy¾Y,DATA
   for(i=0;i<13;i++)
   {
    I2C_Send_Ack();
    *(add+i+1)=I2C_Receive();  //¶á3ö¼Ä′æÆ÷êy¾Y,DATA
   }
  I2C_Send_Nack();        //·¢Ëí·Çó|′eDÅoÅ,NACK
  I2C_Stop();             //í£Ö1DÅoÅ,P
}
     */

void InitMPU6050(void)
{
        I2C_Single_Write(PWR_MGMT_1, 0x00);        //½a3yDYÃß×′ì¬
  I2C_Single_Write(SMPLRT_DIV, 0x07);
        I2C_Single_Write(CONFIG, 0x06);
//        I2C_Single_Write(GYRO_CONFIG, 0x18);
//        I2C_Single_Write(ACCEL_CONFIG, 0x01);
}

byte a;

void main(void) {
  /* put your own code here */
  DisableInterrupts;
  PLL_init();
  DDRB=0xFF;
  PORTB=0xff;
  I2C_Bus_init();
  InitMPU6050();
  PORTB=0x00;
  EnableInterrupts;
  for(;;) {
    I2C_Single_Write(GYRO_CONFIG, 0x18);
          I2C_Single_Write(ACCEL_CONFIG, 0x01);
  //         a=I2C_Single_Read(ACCEL_XOUT_L);
          PORTB=~PORTB;
    delay(20);
    _FEED_COP(); /* feeds the dog */
  } /* loop forever */
  /* please make sure that you never leave main */
}
部分内容已更改,现在说下情况:
   数据线、时钟线没反应,示波器上也没波形,遇到很奇怪的现象,就是我把SCL和SDA换过后程序依然可以运行,我现在有点确定我的I2C时钟没发出去,不知道肿么办了,希望大神来帮帮小弟,小弟万分感激!
小弟用的芯片是自己焊的,用的是龙丘4.1版本的MC9S12XS128MAL的板子,焊的芯片是MC9S12XET256MAL,内带I2C模块,今天下午试了下,PWM没问题!用软件模拟也没问题,关键就是这个硬件I2C模块问题,真心纠结!

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2013-5-12 22:36:52 | 显示全部楼层
这个地方你不常来吧。我在别的网站看见你的问题已经解决了,请问什么问题?

出0入0汤圆

 楼主| 发表于 2013-6-2 09:46:51 | 显示全部楼层
jiang887786 发表于 2013-5-12 22:36
这个地方你不常来吧。我在别的网站看见你的问题已经解决了,请问什么问题? ...

我的问题是那个总线总是提示在忙,后来改成先清下总线标志位,然后再等待它空闲就好了~!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-6-3 19:21

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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