I2C初始化

一、管脚初始化
由于STM32的硬件初始化比较复杂,这里我们采用软件初始化,选用端口PB6,PB7,以匿名的I2C初始化程序为例

/***************I2C GPIO定义******************/
#define ANO_GPIO_I2C    GPIOB
#define I2C_Pin_SCL     GPIO_Pin_6
#define I2C_Pin_SDA     GPIO_Pin_7
#define ANO_RCC_I2C     RCC_APB2Periph_GPIOB
/*********************************************/

#define SCL_H         ANO_GPIO_I2C->BSRR = I2C_Pin_SCL
#define SCL_L         ANO_GPIO_I2C->BRR  = I2C_Pin_SCL
#define SDA_H         ANO_GPIO_I2C->BSRR = I2C_Pin_SDA
#define SDA_L         ANO_GPIO_I2C->BRR  = I2C_Pin_SDA
#define SCL_read      ANO_GPIO_I2C->IDR  & I2C_Pin_SCL
#define SDA_read      ANO_GPIO_I2C->IDR  & I2C_Pin_SDA
void I2c_Soft_delay()
{ 
    __NOP();
    __NOP();
    __NOP();
    __NOP();
}
void I2c_Soft_Init()
{
  GPIO_InitTypeDef  GPIO_InitStructure; 
  RCC_APB2PeriphClockCmd(ANO_RCC_I2C , ENABLE );
  GPIO_InitStructure.GPIO_Pin =  I2C_Pin_SCL;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;  
  GPIO_Init(ANO_GPIO_I2C, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin =  I2C_Pin_SDA;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
  GPIO_Init(ANO_GPIO_I2C, &GPIO_InitStructure);     
}
//以下是驱动MPU6050所需要的
int I2c_Soft_Start()
{
    SDA_H;
    SCL_H;
    I2c_Soft_delay();
    if(!SDA_read)return 0;  //SDA线为低电平则总线忙,退出
    SDA_L;
    I2c_Soft_delay();
    if(SDA_read) return 0;  //SDA线为高电平则总线出错,退出
    SDA_L;
    I2c_Soft_delay();
    return 1;   

}
void I2c_Soft_Stop()
{
    SCL_L;
    I2c_Soft_delay();
    SDA_L;
    I2c_Soft_delay();
    SCL_H;
    I2c_Soft_delay();
    SDA_H;
    I2c_Soft_delay();
}
void I2c_Soft_Ask()
{
    SCL_L;
    I2c_Soft_delay();
    SDA_L;
    I2c_Soft_delay();
    SCL_H;
    I2c_Soft_delay();
    SCL_L;
    I2c_Soft_delay();
}
void I2c_Soft_NoAsk()
{
    SCL_L;
    I2c_Soft_delay();
    SDA_H;
    I2c_Soft_delay();
    SCL_H;
    I2c_Soft_delay();
    SCL_L;
    I2c_Soft_delay();
}
int I2c_Soft_WaitAsk(void)   //返回为:=1有ASK,=0无ASK
{
  u8 ErrTime = 0;
    SCL_L;
    I2c_Soft_delay();
    SDA_H;          
    I2c_Soft_delay();
    SCL_H;
    I2c_Soft_delay();
    if(SDA_read)
    {
        ErrTime++;
        if(ErrTime>200)
        {
            I2c_Soft_Stop();
            return 1;
        }
    }
    SCL_L;
    I2c_Soft_delay();
    return 0;
}
void I2c_Soft_SendByte(u8 SendByte) //数据从高位到低位//
{
    u8 i=8;
    while(i--)
    {
        SCL_L;
        I2c_Soft_delay();
      if(SendByte&0x80)
        SDA_H;  
      else 
        SDA_L;   
        SendByte<<=1;
        I2c_Soft_delay();
                SCL_H;
                I2c_Soft_delay();
    }
    SCL_L;
} 
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
u8 I2c_Soft_ReadByte(u8 ask)  //数据从高位到低位//
{ 
    u8 i=8;
    u8 ReceiveByte=0;

    SDA_H;              
    while(i--)
    {
      ReceiveByte<<=1;      
      SCL_L;
      I2c_Soft_delay();
            SCL_H;
      I2c_Soft_delay(); 
      if(SDA_read)
      {
        ReceiveByte|=0x01;
      }
    }
    SCL_L;

    if (ask)
        I2c_Soft_Ask();
    else
        I2c_Soft_NoAsk();  
    return ReceiveByte;
} 
// IIC写一个字节数据
u8 IIC_Write_1Byte(u8 SlaveAddress,u8 REG_Address,u8 REG_data)
{
    I2c_Soft_Start();
    I2c_Soft_SendByte(SlaveAddress<<1);   
    if(I2c_Soft_WaitAsk())
    {
        I2c_Soft_Stop();
        return 1;
    }
    I2c_Soft_SendByte(REG_Address);       
    I2c_Soft_WaitAsk(); 
    I2c_Soft_SendByte(REG_data);
    I2c_Soft_WaitAsk();   
    I2c_Soft_Stop(); 
    return 0;
}
// IIC读1字节数据
u8 IIC_Read_1Byte(u8 SlaveAddress,u8 REG_Address,u8 *REG_data)
{           
    I2c_Soft_Start();
    I2c_Soft_SendByte(SlaveAddress<<1); 
    if(I2c_Soft_WaitAsk())
    {
        I2c_Soft_Stop();
        return 1;
    }
    I2c_Soft_SendByte(REG_Address);     
    I2c_Soft_WaitAsk();
    I2c_Soft_Start();
    I2c_Soft_SendByte(SlaveAddress<<1 | 0x01);
    I2c_Soft_WaitAsk();
    *REG_data= I2c_Soft_ReadByte(0);
    I2c_Soft_Stop();
    return 0;
}   
// IIC写n字节数据
u8 IIC_Write_nByte(u8 SlaveAddress, u8 REG_Address, u8 len, u8 *buf)
{   
    I2c_Soft_Start();
    I2c_Soft_SendByte(SlaveAddress<<1); 
    if(I2c_Soft_WaitAsk())
    {
        I2c_Soft_Stop();
        return 1;
    }
    I2c_Soft_SendByte(REG_Address); 
    I2c_Soft_WaitAsk();
    while(len--) 
    {
        I2c_Soft_SendByte(*buf++); 
        I2c_Soft_WaitAsk();
    }
    I2c_Soft_Stop();
    return 0;
}
u8 mpu_test;
// IIC读n字节数据
u8 IIC_Read_nByte(u8 SlaveAddress, u8 REG_Address, u8 len, u8 *buf)
{   
    mpu_test = I2c_Soft_Start();
    I2c_Soft_SendByte(SlaveAddress<<1); 
    if(I2c_Soft_WaitAsk())
    {
        I2c_Soft_Stop();
        return 1;
    }
    I2c_Soft_SendByte(REG_Address); 
    I2c_Soft_WaitAsk();

    I2c_Soft_Start();
    I2c_Soft_SendByte(SlaveAddress<<1 | 0x01); 
    I2c_Soft_WaitAsk();
    while(len) 
    {
        if(len == 1)
        {
            *buf = I2c_Soft_ReadByte(0);
        }
        else
        {
            *buf = I2c_Soft_ReadByte(1);
        }
        buf++;
        len--;
    }
    I2c_Soft_Stop();
    return 0;
}
  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于DSP28335芯片的I2C初始化,你可以按照以下步骤进行操作: 1. 配置GPIO引脚:首先,选择适当的GPIO引脚作为I2C的SDA(数据线)和SCL(时钟线)。将这些引脚配置为I2C功能。 2. 配置I2C模块:通过配置I2C控制寄存器和时钟分频寄存器来设置I2C模块。你可以设置I2C的主从模式、时钟频率、传输模式等。 3. 编写初始化代码:根据你的需求,编写初始化代码来配置I2C模块。这些代码可能会使用到DSP28335的寄存器和相关函数。 以下是一个简单的示例代码,用于初始化DSP28335的I2C模块: ```c #include "DSP2833x_Device.h" #include "DSP2833x_Examples.h" void I2C_Init(void) { // 配置GPIO引脚为I2C功能 GpioCtrlRegs.GPAMUX1.bit.GPIO28 = 1; // SDA GpioCtrlRegs.GPAMUX1.bit.GPIO29 = 1; // SCL // 配置I2C控制寄存器和时钟分频寄存器 I2caRegs.I2CMDR.bit.IRS = 0; // I2C模块处于复位状态 I2caRegs.I2CPSC.all = 19; // 时钟分频,根据需要设置 I2caRegs.I2CCLKL = 10; // SCL时钟低电平时间,根据需要设置 I2caRegs.I2CCLKH = 5; // SCL时钟高电平时间,根据需要设置 I2caRegs.I2CMDR.bit.IRS = 1; // 释放I2C模块复位状态 // 其他配置,根据需要设置 // 完成初始化 } ``` 请注意,以上代码仅为示例,具体的配置参数需要根据你的实际需求进行调整。同时,你还需要根据DSP28335的技术手册和相关资料,了解I2C模块的寄存器和功能,以便正确地进行初始化和使用。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值