STM32F207 I2C 测试失败

2024-01-08

我正在使用 STM32F207 微控制器在 STM3220G-EVAL 板上学习嵌入式开发。我尝试通过连接同一芯片上的两个 I2C2 和 I2C3 模块并发送/接收字符来测试 I2C 接口。这是我当前编写的代码(使用 mdk-arm 5):

#include <stm32f2xx.h>

volatile uint8_t data = 'a', recv = 'x';

void i2c_init(void);

void I2C2_EV_IRQHandler(void)
{
    volatile uint16_t stat, dummy;
    stat = I2C2->SR1;
    switch(stat)
    {
        // SB set; read SR1 and write slave address in DR to clear
        case 0x01:
            dummy = I2C2->SR1;
            // Send address of slave
            I2C2->DR = (0x08 << 1);
            break;
        // ADDR set; read SR1 and SR2 to clear
        case 0x02:
            dummy = I2C2->SR1;
            dummy = I2C2->SR2;
            break;
        // TxE set; write to DR to clear
        case 0x80:
            I2C2->DR = data;
            break;
        // TxE and BTF set; generate stop condition to clear
        case 0x84:
            // Generate stop
            I2C2->CR1 |= (1 << 9);
            break;
    }
}

void I2C3_EV_IRQHandler(void)
{
    volatile uint16_t stat, dummy;
    stat = I2C3->SR1;
    switch(stat)
    {
        // ADDR set; read SR1 and SR2 to clear
        case 0x02:
            dummy = I2C3->SR1;
            dummy = I2C3->SR2;
            break;
        // STOPF set; read SR1 and write CR1 to clear
        case 0x10:
            dummy = I2C3->SR1;
            I2C3->CR1 &= ~(1 << 0);
            break;
        // RxNE set; read DR to clear
        case 0x40:
            recv = I2C3->DR;
            break;
    }
}

int main()
{
    i2c_init();
    // Generate START condition
    I2C2->CR1 |= (1 << 8);
    while(1)
    {
        if(!(I2C2->OAR1 & (1 << 14)))
            I2C2->OAR1 |= (1 << 14);
        if(!(I2C3->OAR1 & (1 << 14)))
            I2C3->OAR1 |= (1 << 14);
        if(recv != 'x')
            break;
    }
    return 0;
}

void i2c_init(void)
{
    // Enable GPIOA, GPIOC, GPIOF, I2C2 and I2C3 peripherals
    RCC->AHB1ENR |= (1 << 0);
    RCC->AHB1ENR |= (1 << 2);
    RCC->AHB1ENR |= (1 << 5);
    RCC->APB1ENR |= (1 << 22);
    RCC->APB1ENR |= (1 << 23);
    // Set GPIO mode to AF
    GPIOA->MODER |= (1 << 17);
    GPIOC->MODER |= (1 << 19);
    GPIOF->MODER |= (1 << 1);
    GPIOF->MODER |= (1 << 3);
    // Set GPIO type to OD
    GPIOA->OTYPER |= (1 << 8);
    GPIOC->OTYPER |= (1 << 9);
    GPIOF->OTYPER |= (1 << 0);
    GPIOF->OTYPER |= (1 << 1);
    // Set GPIO speed to 50MHz
    GPIOA->OSPEEDR |= (1 << 17);
    GPIOC->OSPEEDR |= (1 << 19);
    GPIOF->OSPEEDR |= (1 << 1);
    GPIOF->OSPEEDR |= (1 << 3);
    // Link to AFs
    GPIOA->AFR[1] |= (1 << 2);
    GPIOC->AFR[1] |= (1 << 6);
    GPIOF->AFR[0] |= (1 << 2);
    GPIOF->AFR[0] |= (1 << 6);
    // Reset clocks
    I2C2->CR2 = 0x00;
    I2C3->CR2 = 0x00;
    I2C2->CCR = 0x00;
    I2C3->CCR = 0x00;
    // Enable interrupts
    I2C2->CR2 |= (1 << 9);
    I2C2->CR2 |= (1 << 10);
    I2C3->CR2 |= (1 << 9);
    I2C3->CR2 |= (1 << 10);
    NVIC_EnableIRQ(I2C2_EV_IRQn);
    NVIC_EnableIRQ(I2C3_EV_IRQn);
    // Must set bit 14 in OAR1 to 1
    I2C2->OAR1 |= (1 << 14);
    I2C3->OAR1 |= (1 << 14);
    // Set addresses
    I2C2->OAR1 = (0x04 << 1);
    I2C3->OAR1 = (0x08 << 1);
    // Set peripheral clock frequency
    I2C2->CR2 |= 0x08;
    I2C3->CR2 |= 0x08;
    I2C2->CCR |= 0x28;
    I2C3->CCR |= 0x28;
    I2C2->TRISE = 0x09;
    I2C3->TRISE = 0x09;
    // Enable ACK
    I2C2->CR1 |= (1 << 10);
    I2C3->CR1 |= (1 << 10);
    // Enable I2C peripherals
    I2C2->CR1 |= (1 << 0);
    I2C3->CR1 |= (1 << 0);
}

我面临的问题是:

  1. 执行永远不会进入中断处理程序(由 断点)
  2. 即使我在 CR1 中设置了 START 位,主机(I2C2)的 SR1 中的 SB 位也从未设置
  3. SDA 线为高电平,但 SCL 线被拉低

我在 SDA 上使用 13K 上拉电阻,在 SCL 上使用 10K 上拉电阻。使用的引脚号为 PF0、PF1(I2C2 SDA、SCL)和 PA8、PC9(I2C3 SCL、SDA)。 使用内部或外部上拉电阻会导致 SR2 寄存器显示总线忙。 另外我还没有在 RTE_Device.h 中启用 I2C2 和 I2C3。它似乎只是提供了方便的 typedef。 (EDIT :尝试启用这些,但没有帮助)

有人能帮我解决这个问题吗?我似乎走进了死胡同。

(EDIT :在板上设置一些跳线后,主事件处理程序将被成功调用。但仍然存在一些问题。现在正在设置确认失败位,并且不会调用从属处理程序。已验证总线线路在空闲时为高电平。)


很抱歉迟到了,但我已经通过使用 ST 提供的 STM32 CPAL 库成功解决了这个问题。我通过读取加速度计中的“WHO_AM_I”寄存器,使用板载加速度计测试了该库。其代码是:

#include "cpal_i2c.h"

int main()
{
    // Configuration
    CPAL_TransferTypeDef RxStruct;
    uint8_t RxBuf;
    RxStruct.pbBuffer = &RxBuf;
    RxStruct.wAddr1 = 0x39;
    // Initialization
    CPAL_I2C_StructInit(&I2C1_DevStructure);
    I2C1_DevStructure.CPAL_Mode = CPAL_MODE_MASTER;
    I2C1_DevStructure.CPAL_ProgModel = CPAL_PROGMODEL_DMA;
    I2C1_DevStructure.pCPAL_I2C_Struct->I2C_ClockSpeed = 100000;
    I2C1_DevStructure.pCPAL_TransferRx = &RxStruct;
    I2C1_DevStructure.pCPAL_TransferTx = pNULL;
    CPAL_I2C_Init(&I2C1_DevStructure);
    // Communication
    RxStruct.wNumData = 1;
    RxStruct.wAddr2 = 0x0F;
    if(CPAL_I2C_Read(&I2C1_DevStructure) != CPAL_PASS)
    {
        // Error
    }
    while(I2C1_DevStructure.CPAL_State != CPAL_STATE_READY);
    while(1);
    return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32F207 I2C 测试失败 的相关文章

随机推荐

  • 声明与类型不兼容

    头文件 ifndef H bankAccount define H bankAccount class bankAccount public string getAcctOwnersName const int getAcctNum con
  • AVCaptureSession 旋转 |视频传输时的方向

    我正在开发视频流应用程序 其中我需要捕获前置摄像头视频帧并编码然后传输到另一端 典型的流程是这样的 AVCaptureSession gt AVCaptureDeviceInput gt AVCaptureVideoDataOutput g
  • 如何取消或处置 WebBrowser 元素的当前导航

    我正在开发一个 C NET Framework 4 0 应用程序 它按顺序访问一些页面 有时我必须移至下一页而不等待上一页完成工作 如何取消之前的导航过程WebBrowser元素 WebBrowser元素使用 Internet Explor
  • 模拟器设备框架未显示

    我第一次在 MacBook 上安装 Android Studio 我按如下方式安装了第一个模拟器 但是当我打开设备时 我看不到设备框架 我需要做什么才能看到设备周围的框架 我使用的是 M2 MacBook 创建模拟器 没有设备框架的模拟器
  • 初始化使指针来自整数而不进行强制转换 - C

    很抱歉 如果这篇文章显得无知 但我对 C 还很陌生 所以我对它没有很好的理解 现在我正在尝试找出指针 我编写了这段代码来测试是否可以更改更改函数中 b 的值 并通过传入指针将其带回主函数 不返回 但是 我收到一条错误消息 Initializ
  • Docker 挂载发生在入口点执行之前或之后

    我正在构建一个 Docker 映像来运行基于 Spring Boot 的应用程序 我希望用户能够通过将包含 application properties 的文件夹安装到容器中来提供运行时属性文件 这是我的 Dockerfile FROM j
  • Mysql:重复键更新所有值?

    有没有简单的方法可以更新重复键后的所有值 例如 INSERT INTO published books SELECT FROM books WHERE book id book id ON DUPLICATE KEY UPDATE ever
  • 从超类访问 __DATA__

    我有一个名为 Response 的超类 package Response use strict use warnings use HTML Template sub response my class request return requ
  • 并行运行测试会导致 java 堆内存不足。

    并行运行测试会导致 java 堆内存不足 但是当我不并行运行它们时 不存在内存问题 这是错误 java lang OutOfMemoryError Java 堆空间 在 java util Arrays copyOf Arrays java
  • 使用 NGINX 添加 AWS 公共证书

    我正在使用 EC2 并使用 NGINX 由 PuTTY 提供 我选择了AWS 公共证书因此我明白要使用HTTPS我也需要配置 NGINX 我找到了一些关于它的教程 但是他们到处都添加了ssl certificate and ssl cert
  • 如何在 UICollectionViewController 中提供 GetSizeForItem 实现?

    UICollectionViewDelegateFlowLayout http developer apple com library ios documentation UIKit Reference UICollectionViewDe
  • 如何在渲染方法之外使用未声明的反应?

    我在我的项目中使用 usated 库 在渲染方法中 我使用set像这样 render return
  • WebGL 和 Tessellation 库?

    在 C C 中 OpenGL 有一个很好的库 用于将复杂的多边形形状细分为三角形条和扇形 该库是 GLUtesselator 是否有任何库具有与 WebGL HTML 等效的功能 GLUtesselator 已由 Google 地图的 Br
  • Git diff:忽略以单词开头的行

    据我所知here https stackoverflow com questions 53450186 git diff show only changes not matching a pattern 我们可以告诉git diff忽略以
  • 在弹出窗口中显示用户控件

    I have a button and another control placed in a usercontrol I want to pop out the control below the button to the topp o
  • 强制 C# 应用程序编译为 x64 而不是 AnyCpu

    我一直在尝试使用 C 2010 Express 在 C 应用程序中引用本机 x64 dll 我有一个从 2008 年项目转换而来的演示项目 其属性中有配置和平台选项 但我创建的新项目没有 下拉菜单根本不存在 事实上我什至无法从 调试 切换到
  • 当在 bean 内部调用该方法时,Spring AOP 不起作用

    我的应用程序中编码了几个方面 除以下内容外 所有其他内容均有效 服务接口 package com enbiso proj estudo system service public interface MessageService Messa
  • 捕获异常但使用 Sidekiq 重试

    默认情况下 sidekiq 将重试任何引发异常的作业 没事儿 但是 我希望能够捕获该异常 以便我的异常处理程序不会收到通知 然后重试该作业 我如何在反应中实现这一点 所以我的代码如下所示 def perform rescue ExcClas
  • 发送固定长度的 TCP 帧

    我需要使用 TCP 通过具有固定非标准 MTU 例如 1560 的子网发送一些数据 如果帧的长度小于 MTU 则通过该子网传输的所有以太网帧都应手动填充 0 所以 数据大小应该是 1560 sizeof IP 标头 sizeof TCP 标
  • STM32F207 I2C 测试失败

    我正在使用 STM32F207 微控制器在 STM3220G EVAL 板上学习嵌入式开发 我尝试通过连接同一芯片上的两个 I2C2 和 I2C3 模块并发送 接收字符来测试 I2C 接口 这是我当前编写的代码 使用 mdk arm 5 i