如何在STM32F334K8T6上通过I2C传输修复代码? 不起作用

问题描述

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

我研究了文档并提出了一些代码(由于我对理解寄存器感兴趣,所以我不使用HAL)。

#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;
  }
}

总线频率APB1 = 24MHz(必须运行计时器)。

I2C频率100kHz,主模式。

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

  1. 0x03-设置扩展器I / O配置模式
  2. 0x0-使所有引脚输出
  3. 0x01-切换到输出模式
  4. 0xa8-启用扩展器输出之一。

我也看了 F0系列的官方代码片段,那里有一个类似的I2C示例,但是没有从主机发送的详细过程。

您能帮我找到错误吗?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...