Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何修复STM32F334K8T6上I2C传输的代码?(不起作用)_Stm32_I2c_Stm32f3 - Fatal编程技术网

如何修复STM32F334K8T6上I2C传输的代码?(不起作用)

如何修复STM32F334K8T6上I2C传输的代码?(不起作用),stm32,i2c,stm32f3,Stm32,I2c,Stm32f3,几天来,我一直在研究使用I2C控制多个I/O扩展器的操作 我研究了文档并提出了一些代码(我不与HAL合作,因为我对理解寄存器感兴趣) #包括“main.h” #包括“stdio.h” //功能 /***时钟和计时器部分***/ //系统时钟设置 int systemClockInit(){ //开始时钟序列 /* 1-运行HSE+等待准备就绪 2-配置PLL 3-EN PLL+等待就绪 4-设置闪存等待周期 5套母线分压器 6-切换到PLL模式 7-禁用HSI(可选) */ //身体 int w

几天来,我一直在研究使用I2C控制多个I/O扩展器的操作

我研究了文档并提出了一些代码(我不与HAL合作,因为我对理解寄存器感兴趣)

#包括“main.h”
#包括“stdio.h”
//功能
/***时钟和计时器部分***/
//系统时钟设置
int systemClockInit(){
//开始时钟序列
/*
1-运行HSE+等待准备就绪
2-配置PLL
3-EN PLL+等待就绪
4-设置闪存等待周期
5套母线分压器
6-切换到PLL模式
7-禁用HSI(可选)
*/
//身体
int waitCounter=0;
//&-位“和”->1&1=1或=0(比较位)
//运行HSE时钟(HSEON-16位)
//1打开16位上的1
RCC->CR |=(1 CR和(1 0x1000){
//清孔钻头
//(替换1-0/0-1位和-清除16位,保存其他)
RCC->CR&=~(1 CFGR |)=(0x1 CR&=~(1 CR&=~(1)设置零等待周期
闪存->ACR |=(0x00 CFGR |=(0x00 AFR[0]|=(0x04 OSpeder&=~GPIO_OSpeder_OSpeder6;//AF(PB6)
GPIOB->ospeder&=~GPIO\u ospeder\u ospeder7;//AF(PB7)
RCC->APB1ENR |=RCC_APB1ENR_I2C1EN;//EN i2c时钟
//I2C总线设置
//RCC->APB1RSTR |=(1 CR1 |=(0 CR1 |=(1计时r |=0x00506682;//I2C计时(0x2000090E)
I2C1->CR1 |=(1 CR1 |=(1 CR1 |=(1 ISR&15);//在总线不忙时等待
I2C1->CR2 |=(0x4 CR2 |=(1 CR2 |=(0x20 CR2 |=(1 ISR&1)和字节计数器){
I2C1->TXDR=0x03;//发送字节#1
字节计数器++;
返回;
}
否则如果((I2C1->ISR&1)和字节计数器==1){
I2C1->TXDR=0x0;//发送字节#2
字节计数器++;
返回;
}
否则如果((I2C1->ISR&1)和字节计数器==3){
I2C1->TXDR=0x01;//发送字节#3
字节计数器++;
返回;
}
否则如果((I2C1->ISR&1)和字节计数器==4){
I2C1->TXDR=0xf8;//发送字节#4
字节计数器++;
返回;
}
}
总线频率APB1=24MHz(计时器必须运行)

I2C频率100kHz,主模式

我只想向地址为0x20的设备发送4个字节

  • 0x03-设置扩展器I/O配置模式
  • 0x0-使所有管脚输出
  • 0x01-切换到输出模式
  • 0xa8-启用一个扩展器输出
  • 我也看了 F0系列的官方代码片段,其中有一个类似的I2C示例,但没有从主机传输的详细过程


    您能帮我找到错误吗?

    不要使用幻数。没有人会分析此类代码。至少使用带有人类可读定义的CMSIS标题。
    #include "main.h"
    #include "stdio.h"
    
    // Functions
    /*** Clock and timers sections ***/
    // System clock settings
    int systemClockInit() {
    
    
      // Start clock sequence
      /*
       1 - RUN HSE + WAIT ready
       2 - Configure PLL
       3 - EN PLL + WAIT ready
       4 - Set flash wait cycles
       5 - Set bus divider
       6 - Switch to PLL mode
       7 - Disable HSI (Optional)
      */
    
      // Body
      int waitCounter = 0;
      // & - bit "AND" -> 1 & 1 = 1 or = 0 (Compare bits)
    
      // Run HSE clock (HSEON - 16bit)
      // 1 << 16 -> turn on 1 on 16 bit
      RCC->CR |= (1 << 16);
    
      // HSEREADY wait
      for(waitCounter = 0; ; waitCounter++) {
        if(RCC->CR & (1 << 17)) { break; } // If HSE success enabled
        if(waitCounter > 0x1000) {
          // Clear HSEON bit
          // (Replace 1 - 0 / 0 - 1, bit and - clear 16 bit, save other)
          RCC->CR &= ~(1 << 16);
          return 1;
        }
      }
    
      // Configure PLL
      // 24mHz (x3)
      RCC->CFGR |= (0x1 << 18) // PLL x3 (0x1 = 0001), 18 - start PLLMULL sector
                | (0x01 << 16); // Enable PLL src on HSE clock
    
      // Enable PLL
      RCC->CR |= (1 << 24); // 24 bit - PLLON
      // PLL enable WAIT
      for(waitCounter = 0; ; waitCounter++) {
        if(RCC->CR & (1 << 25)) { break; } // If PLL success enabled
        if(waitCounter > 0x1000) {
          RCC->CR &= ~(1 << 16); // Disable HSE
          RCC->CR &= ~(1 << 24); // Disable PLL
          return 2;
        }
      }
    
      // Set flash wait counter and bus divider
      // Core frequency = 24mHz -> set zero wait cycles
      FLASH->ACR |= (0x00 << 0); // 0x00 = 000, 0 latency position sector
    
      // Set bus dividers
      RCC->CFGR |= (0x00 << 11) // PPRE2 divider disabled (000)
                // For < 36mHz
                | (0x00 << 8) // APB1 divider disabled (000)
    
      // Wait reconnect to PLL
      RCC->CFGR |= (0x02 << 0);
    
      while((RCC->CFGR & 0x08) != (0x02 << 2)) {} // 0x08 - RCC_CFGR_SWS_MSK (00001100). 0x02 - 00000010 - PLL selected sysclk, 2 - SWS bits position
    
      // Disabled HSI clock
      RCC->CR &= ~(1 << 0); // Disabled HSI
    
      // Return 0 (Success)
      return 0;
    }
    
    void I2C_Init(void);
    void I2C_Start(void);
    void I2C_WriteData(void);
    
    
    // Main function
    int main(void)
    {
      // System Clock init
      systemClockInit();
      //printf("State: %d", state);
    
      RCC->AHBENR |= (1 << 17) | (1 << 18); // PORTA and PORTB clock enabled
    
      // Configure ms timer
      #define coreFrequency 24000000 // 72mHz core frequency
      SysTick_Config(coreFrequency / 1000);
    
    
      I2C_Init();
      I2C_Start();
    
      // Loop
      while (1)
      {
          I2C_WriteData();
      }
    }
    
    
    
    void I2C_Init(void) {
      RCC->AHBENR  |= RCC_AHBENR_GPIOBEN; // PORT B clock EN
    
      // I2C pins settings
      GPIOB->OTYPER  |= GPIO_OTYPER_OT_6 | GPIO_OTYPER_OT_7; // Open-Drain PB6, PB7
      GPIOB->AFR[0]  |= (0x04 << 16); // AF4 (PORTB)
      GPIOB->OSPEEDR &= ~GPIO_OSPEEDER_OSPEEDR6; // AF (PB6)
      GPIOB->OSPEEDR &= ~GPIO_OSPEEDER_OSPEEDR7; // AF (PB7)
    
      RCC->APB1ENR |= RCC_APB1ENR_I2C1EN; // EN i2c clock
    
      // I2C bus settings
      //RCC->APB1RSTR  |= (1 << 21);  // I2C reset
      I2C1->CR1      |= (0 << 0);   // I2C peripheral disabled
      I2C1->CR1      |= (1 << 12);  // I2C analog filter disabled
      I2C1->TIMINGR  |= 0x00506682; // I2C timing (0x2000090E)
      I2C1->CR1      |= (1 << 17);  // Clock stretching disabled
      I2C1->CR1      |= (1 << 1);   // Enable TXIS interrupt
      I2C1->CR1      |= (1 << 0);   // I2C peripheral enabled
    }
    
    void I2C_Start(void) {
      while(I2C1->ISR & 15);    // wait untin bus not busy
      I2C1->CR2 |= (0x4 << 16); // 4 bytes (NBYTE)
      I2C1->CR2 |= (1 << 25);   // AUTOEND EN
      I2C1->CR2 |= (0x20 << 0); // Slave address
      I2C1->CR2 |= (1 << 13);   // Set START
    }
    
    void I2C_WriteData(void) {
      static int byteCounter = 0;
      if((I2C1->ISR & 1) && !byteCounter) {
        I2C1->TXDR = 0x03; // send byte #1
        byteCounter++;
        return;
      }
      else if((I2C1->ISR & 1) && byteCounter == 1) {
        I2C1->TXDR = 0x0; // send byte #2
        byteCounter++;
        return;
      }
      else if((I2C1->ISR & 1) && byteCounter == 3) {
        I2C1->TXDR = 0x01; // send byte #3
        byteCounter++;
        return;
      }
      else if((I2C1->ISR & 1) && byteCounter == 4) {
        I2C1->TXDR = 0xf8; // send byte #4
        byteCounter++;
        return;
      }
    }