打印
[STM32H7]

H750 硬件I2C1

[复制链接]
641|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
qioby|  楼主 | 2021-6-8 09:37 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
使用硬件的I2C感觉要比模拟的好用,速度还快。使用64MHz的HSI,

//   IIC_add=IIC_24C02_ADD;  //器件地址

void I2C1_INIT(void)
{
    RCC_CR |= 1; //HSION
    RCC_D2CCIP2R |=Bit1_13;  // HSI->I2C  64MHz
    RCC_APB1LENR |= Bit1_21; //I2C1EN
    __NOP();
    RCC_APB1LRSTR |= Bit1_21; //RST
    __NOP();
    RCC_APB1LRSTR &= Bit0_21;
   
    RCC_AHB4ENR |= Bit1_1; //GPIOB
    GPIOB_MODER &=0xFFFF0FFF;
    GPIOB_MODER |=0x0000A000;
    GPIOB_OTYPER |=Bit1_7 ;
    GPIOB_OSPEEDR |= 0x0000F000;
    GPIOB_PUPDR &=0xFFFF0FFF;
    GPIOB_PUPDR |=0x00005000; //上拉
    GPIOB_AFRL  |=0x44000000; //AF4 I2C
   
     IIC_add=IIC_SD3078_ADD;  //器件地址
    I2C1_CR1 = 0;
    I2C1_TIMINGR = 0x00602173;  //速率 100KHz=0x10707DBC / 400KHz=0x00602173 / 1MHz=0x00300B29  
    I2C1_TIMOUTR =0x00;
    I2C1_CR2 = 0;
    I2C1_ICR = 0x3F38;  //清ISR
    I2C1_OAR1 = 0;
    I2C1_OAR2 = 0;
}

HAL_StatusTypeDef I2C_tx(uint8_t iic_ad, uint8_t *IIC_p, uint8_t IIC_n) //起始地址 + RAM地址+ 数量
{
    uint32_t Regset;
   
    I2C1->ICR = 0x3F38; //清ISR
    I2C1->CR1 = 1;
    Regset=IIC_n+1; //add+data
    Regset<<=16;    //NBYTES
    Regset|=Bit1_25; //AutoEnd
    //Regset &=Bit0_12; //7addres
    //Regset &=Bit0_11; //7addres
    Regset &= Bit0_10; //W0  R1
    Regset |= IIC_add; //起始地址
    I2C1->CR2 = Regset;
    I2C1->CR2 |=Bit1_13; //START
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    Regset=0x0000FFFF;
    while((I2C1->CR2 &Bit1_13)==Bit1_13)
    { //等待发送起始地址START=0
        Regset--;
        if(Regset==0) return HAL_ERROR;
    }
    I2C1->TXDR=iic_ad;
    while(IIC_n--)
    {
        Regset=0x0000FFFF;
        while((I2C1->ISR&1)==0)
        {
            Regset--;
            if(Regset==0) return HAL_ERROR;
        }
      I2C1->TXDR=*(IIC_p++);
    }   
    Regset=0x0000FFFF;
    while((I2C1->ISR&1)==0)
    { //发送最后数据
        Regset--;
        if(Regset==0) return HAL_ERROR;
    }
    I2C1->CR2 |= Bit1_14;  //STOP
    Regset=0x0000FFFF;
    while((I2C1->ISR&Bit1_15)==Bit1_15)
    { //等待结束
        Regset--;
        if(Regset==0) return HAL_ERROR;
    }
    I2C1->CR1 = 0;
    return HAL_OK;
}

HAL_StatusTypeDef I2C_rx(uint8_t iic_ad, uint8_t *IIC_p,uint8_t IIC_n)
{
    uint32_t Regset;
   
    if(I2C_tx(iic_ad, IIC_p, 1)!=HAL_OK ) return HAL_ERROR ;
   
    //IIC_add = IIC_SD3078_ADD;
    //I2C1->CR1 = 0;
    I2C1->ICR = 0x3F38; //清ISR
    I2C1->CR1 = 1;
    I2C1->CR2 = 0;
    Regset=IIC_n;
    Regset<<=16;   //NBYTES
    Regset|=Bit1_25; //AutoEnd
    //Regset &=Bit0_12; //7addres
    //Regset &=Bit0_11; //7addres
    Regset |= Bit1_10; //R1
    Regset |= IIC_add; //从地址
    I2C1->CR2 = Regset;
    I2C1->CR2 |=Bit1_13; //START
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    Regset=0x0000FFFF;
    while((I2C1->CR2 &Bit1_13)==Bit1_13)
    { //等待发送从地址 START=0
        Regset--;
        if(Regset==0) return HAL_ERROR;
    }
  while(IIC_n--)
    {
        Regset=0x0000FFFF;
        while((I2C1->ISR&Bit1_2)==0)
        {  //接收为空
            Regset--;
          if(Regset==0) return HAL_ERROR;
        }
      *(IIC_p++)=I2C1->RXDR;
    }
    I2C1->CR2 |= Bit1_14;  //STOP   
    Regset=0x0000FFFF;
    while((I2C1->ISR&Bit1_15)==Bit1_15)
    {  //等待结束
        Regset--;
        if(Regset==0) return HAL_ERROR;
    }
    I2C1->CR1 = 0;
    return HAL_OK;
}




使用特权

评论回复
沙发
可怜的小弗朗士| | 2021-6-10 15:57 | 只看该作者
硬件的I2C肯定是优于软件模拟的,但是很多人在使用硬件的时候都会出现各种问题

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

6

主题

44

帖子

0

粉丝