模拟IIC


IIC相对而言硬件设计较为简单,两线总线可以直接挂载很多芯片,但通信受干扰,容易进入“死锁”状态,需要软件处理。SPI相对而言需要的硬线更多,但不存在出现“死锁”的问题,另外通信速率也更高。

死锁: 是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。

那么为什么会产生死锁呢?
1.因为系统资源不足。
2.进程运行推进的顺序不合适。    
3.资源分配不当。

产生死锁的四个必要条件:

互斥条件(Mutual exclusion):资源不能被共享,只能由一个进程使用。
请求与保持条件(Hold and wait):已经得到资源的进程可以再次申请新的资源。
非剥夺条件(No pre-emption):已经分配的资源不能从相应的进程中被强制地剥夺。
循环等待条件(Circular wait):系统中若干进程组成环路,该环路中每个进程都在等待相邻进程正占用的资源。


#ifndef __USER_IIC_
#define __USER_IIC_

#include "pca10040.h"
#include "nrf_gpio.h"
#include "nrf_delay.h"

//ERROR
#define ERROR_CODE_TRUE 0
#define ERROR_CODE_FALSE 1
#define ERROR_CODE_WRITE_ADDR 10
#define ERROR_CODE_WRITE_DATA        20
#define ERROR_CODE_READ_ADDR        30
#define ERROR_CODE_READ_DATA        40
#define ERROR_CODE_START_BIT        50
#define ERROR_CODE_APROCESS 60
#define ERROR_CODE_DENY 70

#define I2C_DELAY nrf_delay_us(13) // 5uS delay setting
#define I2C_DELAY_LONG nrf_delay_us(130)  // 10uS delay setting

#define SCL1 6
#define SDA1 7
//设置IO方向
#define SDA_OUT1()  nrf_gpio_cfg_output(SDA1)
#define SDA_IN1()   nrf_gpio_cfg_input(SDA1,NRF_GPIO_PIN_PULLUP)
//设置IO电平

#define I2C_SCL_HIGH1   nrf_gpio_pin_set(SCL1)   //SCL = 1
#define I2C_SCL_LOW1    nrf_gpio_pin_clear(SCL1) //SCL = 0
#define I2C_SDA1        1    //SDA  
#define READ_SDA1          nrf_gpio_pin_read(SDA1)  //read SDA
#define I2C_SDA_HIGH1   nrf_gpio_pin_set(SDA1)   //SDA
#define I2C_SDA_LOW1    nrf_gpio_pin_clear(SDA1) //SDA

void IIC_IO_Init1(void);
void _i2c_start1(void);
void _i2c_stop1(void);
unsigned char _i2c_write_byte1(unsigned char data);
unsigned char _i2c_read_byte1(unsigned char ack);
void _i2c_ack_send1(void);
void _i2c_nack_send1(void);
unsigned char _i2c_ack_detect1(void);

#endif


void IIC_IO_Init1(void)
{
nrf_gpio_cfg_output(SDA1);
nrf_gpio_cfg_output(SCL1);

I2C_SDA_HIGH1;
I2C_SCL_HIGH1;
}
void _i2c_start1(void)
{
    SDA_OUT1();
    I2C_SDA_HIGH1;
    I2C_SCL_HIGH1;
    I2C_DELAY;
    I2C_SDA_LOW1;
    I2C_DELAY;
    I2C_SCL_LOW1;
    I2C_DELAY;
}

void _i2c_stop1(void)
{
    SDA_OUT1();
    I2C_SCL_LOW1;
    I2C_SDA_LOW1;
    I2C_DELAY;
    I2C_SCL_HIGH1;
    I2C_DELAY;
    I2C_SDA_HIGH1;
    I2C_DELAY_LONG;
}
void _i2c_ack_send1(void)//??ACK??
{
    SDA_OUT1();
    I2C_SCL_LOW1;
    I2C_SDA_LOW1;
    I2C_DELAY;
    I2C_SCL_HIGH1;
    I2C_DELAY;
    I2C_SCL_LOW1;
    I2C_DELAY;
}

void _i2c_nack_send1(void)
{
    SDA_OUT1();
    I2C_SCL_LOW1;
    I2C_SDA_HIGH1;
    I2C_DELAY;
    I2C_SCL_HIGH1;
    I2C_SCL_LOW1;
    I2C_DELAY;
}
unsigned char _i2c_ack_detect1(void)
{
    unsigned char ucErrTime=0;
    SDA_IN1(); // SDA Input Mode
    I2C_SDA_HIGH1;
    I2C_SCL_HIGH1;
    I2C_DELAY;
    while(READ_SDA1==I2C_SDA1)
    {
        ucErrTime++;
        if(ucErrTime>250)
        {
            SDA_OUT1();        
            return ERROR_CODE_FALSE; // false
        }        
    }

    I2C_SCL_LOW1;
    I2C_DELAY;
    return ERROR_CODE_TRUE;

unsigned char _i2c_write_byte1(unsigned char data)
{
    unsigned char i ;  
    SDA_OUT1(); 
    I2C_SCL_LOW1;    
    for(i = 0; i< 8; i++)
    {
        if( (data & 0x80) == 0x80) I2C_SDA_HIGH1;
        else I2C_SDA_LOW1;
        data <<=1;
        I2C_DELAY;
        I2C_SCL_HIGH1;
        I2C_DELAY;
        I2C_SCL_LOW1;
        I2C_DELAY;
    }
    if(_i2c_ack_detect1()) 
    {
        return ERROR_CODE_FALSE;
    }
    return ERROR_CODE_TRUE;
}

unsigned char _i2c_read_byte1(unsigned char ack)//ack=1 send ACK,ack=0 send NACK
{
    unsigned char i=0, data=0;
    SDA_IN1();
    I2C_SDA_HIGH1;
    for(i = 0; i< 8; i++)
    {
        data <<= 1;  
        I2C_SCL_LOW1;
        I2C_DELAY;
        I2C_SCL_HIGH1;
        I2C_DELAY;      
        if (READ_SDA1==I2C_SDA1) data |= 0x01;  
        I2C_DELAY;     
    } 
    if (!ack) _i2c_nack_send1();
    else _i2c_ack_send1();
    return data;
}



//MPU6050

struct MPU6050_ACCEL1 MPU6050_ACCEL_OUT1;

unsigned char MPU_X050_Write_Byte1(unsigned char SlaveAddress,unsigned char REG_Address,unsigned char REG_data)
{
    _i2c_start1();
    if(_i2c_write_byte1(SlaveAddress))  
    {
        _i2c_stop1();
        return ERROR_CODE_WRITE_ADDR;    
    }   
    if(_i2c_write_byte1(REG_Address))
    {
        _i2c_stop1();
        return ERROR_CODE_WRITE_ADDR;      
    }
    if(_i2c_write_byte1(REG_data))
    {
        _i2c_stop1();
        return ERROR_CODE_WRITE_ADDR;     
    }   
    _i2c_stop1(); 
    I2C_DELAY_LONG;

    return ERROR_CODE_TRUE;      
}


unsigned char MPU_X050_Read_Byte1(unsigned char SlaveAddress,unsigned char REG_Address)
{
    unsigned char REG_data; 
    _i2c_start1();   
    if(_i2c_write_byte1(SlaveAddress))
    {
        _i2c_stop1();
        return 0;     
    }
    if(_i2c_write_byte1(REG_Address))
    {
        _i2c_stop1();
        return 0;      
    }   
    _i2c_start1();
    if(_i2c_write_byte1(SlaveAddress+1))
    {
        _i2c_stop1();
        return 0;     
    }
    REG_data = _i2c_read_byte1(0);
    _i2c_stop1();
    I2C_DELAY_LONG;
    return REG_data;    
}



unsigned char MPU_Write_Len1(unsigned char SlaveAddress,unsigned char REG_Address,unsigned char len,unsigned char *buf)
{
    unsigned char i; 
    _i2c_start1(); 
    if(_i2c_write_byte1(SlaveAddress))
    {
        _i2c_stop1();
        return ERROR_CODE_WRITE_ADDR;     
    }
    if(_i2c_write_byte1(REG_Address))
    {
        _i2c_stop1();
        return ERROR_CODE_WRITE_ADDR;      
    }
    for(i=0;i<len;i++)
    {
        if(_i2c_write_byte1(buf[i]))
        {
            _i2c_stop1();
            return ERROR_CODE_WRITE_ADDR;      
        }
    }    
    _i2c_stop1();
    return 0;
}


unsigned char MPU_Read_Len1(unsigned char SlaveAddress,unsigned char REG_Address,unsigned char len,unsigned char *buf)
{

    _i2c_start1(); 
    if(_i2c_write_byte1(SlaveAddress))
    {
        _i2c_stop1();
        return ERROR_CODE_READ_ADDR;     
    }    
    if(_i2c_write_byte1(REG_Address))
    {
        _i2c_stop1();
        return ERROR_CODE_READ_ADDR;      
    }    
    _i2c_start1();
    if(_i2c_write_byte1(SlaveAddress+1))
    {
        _i2c_stop1();
        return ERROR_CODE_READ_ADDR;     
    } 
    while(len)
    {
        if(len==1)*buf=_i2c_read_byte1(0);
        else *buf=_i2c_read_byte1(1);

        len--;
        buf++; 
    }   
    _i2c_stop1();
    return 0;
}
unsigned char MPU0605_Init1(void)
{
    unsigned char res;
    nrf_delay_ms(100);
    IIC_IO_Init1();
    nrf_delay_ms(100);
    MPU_X050_Write_Byte1(MPU6050_Addr,PWR_MGMT_1,0X80);
    nrf_delay_ms(100);
    MPU_X050_Write_Byte1(MPU6050_Addr,PWR_MGMT_1, 0x00);
    MPU_X050_Write_Byte1(MPU6050_Addr,SMPLRT_DIV, 7);
    MPU_X050_Write_Byte1(MPU6050_Addr,CONFIG, 0x06);
    MPU_X050_Write_Byte1(MPU6050_Addr,GYRO_CONFIG, 0x18);
    MPU_X050_Write_Byte1(MPU6050_Addr,ACCEL_CONFIG, 0x00);


    MPU_X050_Write_Byte1(MPU6050_Addr,MPU_INT_EN_REG,0X00);
    MPU_X050_Write_Byte1(MPU6050_Addr,MPU_USER_CTRL_REG,0X00);
    MPU_X050_Write_Byte1(MPU6050_Addr,MPU_FIFO_EN_REG,0X00);
    nrf_delay_ms(50);
    res=MPU_X050_Read_Byte1(MPU6050_Addr,WHO_AM_I);
    printf("\r\nWHO = %x", res);
    if(res==0x68)
    {
        MPU_X050_Write_Byte1(MPU6050_Addr,PWR_MGMT_1, 0x03);
        MPU_X050_Write_Byte1(MPU6050_Addr,PWR_MGMT_2, 0x00);
    }
    else
            return 1;
    return 0;

}
unsigned char MPU_Get_Accelerometer1(void)
{
    unsigned char buf[6],res;  
    res=MPU_Read_Len1(MPU6050_Addr,ACCEL_XOUT_H,6,buf);
    if(res==0)
    {
        MPU6050_ACCEL_OUT1.ACCEL_xOUT=((int)buf[0]<<8)|buf[1];  
        MPU6050_ACCEL_OUT1.ACCEL_yOUT=((int)buf[2]<<8)|buf[3];  
        MPU6050_ACCEL_OUT1.ACCEL_zOUT=((int)buf[4]<<8)|buf[5];
    }
    return res;    
}


void test_MPU60501(void)
{
#if(user_printf==jiaodu)
float Accel_x;
float Accel_y;
float Accel_z;
MPU_Get_Accelerometer1();
  Accel_x = MPU6050_ACCEL_OUT1.ACCEL_xOUT;
  Accel_y = MPU6050_ACCEL_OUT1.ACCEL_yOUT;
  Accel_z = MPU6050_ACCEL_OUT1.ACCEL_zOUT;
  if(Accel_x>=0x8000)
  {
     Accel_x = -(65536-Accel_x);
  }
  if(Accel_y>=0x8000)
  {
     Accel_y = -(65536-Accel_y);
  }
  if(Accel_z>=0x8000)
  {
     Accel_z = -(65536 - Accel_z);
  } 
  Accel_x=(int)((Accel_x/16384.0f)*1000);
  Accel_y=(int)((Accel_y/16384.0f)*1000);
  Accel_z=(int)((Accel_z/16384.0f)*1000);


  printf("X1 %d ",(int)Accel_x);
  printf("Y1 %d ",(int)Accel_y);
  printf("Z1 %d ",(int)Accel_z);
#else
MPU_Get_Accelerometer1();
//  printf("X1 %d ",MPU6050_ACCEL_OUT1.ACCEL_xOUT);
//  printf("Y1 %d ",MPU6050_ACCEL_OUT1.ACCEL_yOUT);
//  printf("Z1 %d ",MPU6050_ACCEL_OUT1.ACCEL_zOUT);
#endif
}









  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值