打印
[开发资料]

基于芯源CW32F030 MCU的I2C通信与应用

[复制链接]
473|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Clyde011|  楼主 | 2024-10-10 08:22 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

芯源微的CW32F030是一款基于Arm Cortex-M0内核的32位低功耗MCU,具备高性能和丰富的外设功能,广泛应用于物联网、智能家居、工业控制等领域。CW32F030支持包括I2C、SPI、UART等多种通信接口,其中I2C接口由于其简单、节省引脚的特性,广泛用于与传感器、存储器等外围设备的通信。本文将介绍如何使用CW32F030 MCU实现I2C通信,并通过代码示例展示如何与外部I2C设备进行数据交互。

1. 硬件准备
  • CW32F030开发板
  • I2C外设(如EEPROM、温度传感器等)
  • 若干杜邦线

2. 开发环境
  • Keil MDK5
  • CW32F030库文件和相关驱动

3. I2C通信原理I2C(Inter-Integrated Circuit)是一种用于短距离通信的串行总线,由飞利浦公司发明。它通过SDA(数据线)和SCL(时钟线)两根线进行数据传输,支持多个主从设备的通信。
I2C的主要特点:
  • 双向通信:同一条数据线可用于发送和接收数据。
  • 多主多从架构:支持多个主设备和从设备。
  • 简单的硬件设计:只需要两根信号线,节省了引脚资源。

4. I2C通信配置在CW32F030中,通过配置I2C控制寄存器来实现对I2C外设的控制,主要包括以下步骤:
  • 初始化I2C模块:配置I2C时钟、地址模式等参数。
  • 开始通信:生成I2C起始信号。
  • 发送数据:将数据写入I2C数据寄存器。
  • 停止通信:发送停止信号,结束数据传输。

5. 实例代码:I2C读写EEPROM下面的代码展示了如何使用CW32F030 MCU通过I2C接口与EEPROM进行通信,完成数据的读写操作。
#include "cw32f030_i2c.h"  // 包含I2C驱动库

#define EEPROM_ADDRESS 0x50  // EEPROM设备地址
#define I2C_SPEED 100000     // I2C速度:100kHz

// 初始化I2C
void I2C_Init(void) {
    I2C_InitTypeDef I2C_InitStruct;
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);  // 使能I2C时钟
    I2C_InitStruct.I2C_ClockSpeed = I2C_SPEED;            // 设置I2C速度
    I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;               // 设置为I2C模式
    I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;       // 设置占空比
    I2C_InitStruct.I2C_OwnAddress1 = 0x00;                // 主设备地址
    I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;              // 使能应答
    I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;  // 7位地址
    I2C_Init(I2C1, &I2C_InitStruct);                      // 初始化I2C
    I2C_Cmd(I2C1, ENABLE);                                // 启用I2C
}

// I2C写入数据
void I2C_WriteByte(uint8_t devAddr, uint8_t memAddr, uint8_t data) {
    I2C_GenerateSTART(I2C1, ENABLE);                     // 生成起始信号
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));  // 等待起始条件
    I2C_Send7bitAddress(I2C1, devAddr, I2C_Direction_Transmitter); // 发送设备地址
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));  // 确认从机地址应答
    I2C_SendData(I2C1, memAddr);                         // 发送EEPROM内存地址
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));  // 确认内存地址应答
    I2C_SendData(I2C1, data);                            // 发送数据
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));  // 确认数据发送
    I2C_GenerateSTOP(I2C1, ENABLE);                      // 生成停止信号
}

// I2C读取数据
uint8_t I2C_ReadByte(uint8_t devAddr, uint8_t memAddr) {
    uint8_t data;
    I2C_GenerateSTART(I2C1, ENABLE);                     // 生成起始信号
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));  // 等待起始条件
    I2C_Send7bitAddress(I2C1, devAddr, I2C_Direction_Transmitter); // 发送设备地址
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));  // 确认从机地址应答
    I2C_SendData(I2C1, memAddr);                         // 发送EEPROM内存地址
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));  // 确认内存地址应答
    I2C_GenerateSTART(I2C1, ENABLE);                     // 重新生成起始信号
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));  // 等待起始条件
    I2C_Send7bitAddress(I2C1, devAddr, I2C_Direction_Receiver);    // 发送设备地址,设置为接收模式
    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));  // 确认应答
    data = I2C_ReceiveData(I2C1);                        // 接收数据
    I2C_GenerateSTOP(I2C1, ENABLE);                      // 生成停止信号
    return data;
}

// 主函数
int main(void) {
    uint8_t readData;

    I2C_Init();  // 初始化I2C
    I2C_WriteByte(EEPROM_ADDRESS, 0x00, 0x5A);  // 向EEPROM写入数据
    readData = I2C_ReadByte(EEPROM_ADDRESS, 0x00);  // 从EEPROM读取数据
   
    while (1) {
        // 循环读取数据或进行其他操作
    }
}

6. 代码解析
  • I2C_Init函数初始化I2C外设,配置时钟、模式和地址,并启用I2C。
  • I2C_WriteByte函数用于向EEPROM的特定地址写入数据。通过I2C起始信号开始通信,发送设备地址、内存地址以及数据,最后生成停止信号。
  • I2C_ReadByte函数用于从EEPROM的特定地址读取数据,过程类似于写入数据,但设置为接收模式,并读取数据后生成停止信号。
  • 主函数调用I2C的初始化函数,并演示了向EEPROM写入和读取数据的过程。

7. 实际应用I2C通信常用于读取传感器数据、存储器的读写等场景。在CW32F030中,I2C控制器具有良好的兼容性和稳定性,能够轻松与市面上的I2C设备进行通信。通过本示例代码,开发者可以快速上手使用CW32F030的I2C功能,完成与外设的连接和数据交互。

8. 常见问题
  • 波特率设置错误:不同I2C设备对波特率有要求,通常使用100kHz或400kHz。
  • 引脚配置错误:I2C的SDA和SCL引脚需要正确连接,注意上拉电阻的配置。
  • 从设备未应答:可能是设备地址错误或设备未上电,需检查设备的连接情况。

9. 结论通过本篇文章的讲解与代码示例,大家可以轻松实现CW32F030 MCU的I2C通信功能。I2C作为嵌入式系统中重要的通信接口,广泛应用于与外部传感器、存储器等设备的连接与数据交换。掌握I2C的使用不仅有助于提升开发效率,也为解决更多复杂的系统问题提供了基础。


使用特权

评论回复
沙发
公羊子丹| | 2024-10-10 08:23 | 只看该作者
这个I2C代码太实用了,终于搞明白了和EEPROM通信!

使用特权

评论回复
板凳
周半梅| | 2024-10-10 08:23 | 只看该作者
正好手上有个CW32F030的板子,按照这个例子调试了一下,成功了!

使用特权

评论回复
地板
帛灿灿| | 2024-10-10 08:23 | 只看该作者
请问有没有写大容量EEPROM的例子?

使用特权

评论回复
5
童雨竹| | 2024-10-10 08:24 | 只看该作者
哇!I2C原来这么简单,以前一直以为很复杂。

使用特权

评论回复
6
Wordsworth| | 2024-10-10 08:24 | 只看该作者
这个EEPROM写读的代码很棒,能不能分享一个用I2C读取传感器数据的?

使用特权

评论回复
7
万图| | 2024-10-10 08:24 | 只看该作者
大佬,这个波特率调成400kHz怎么改?100kHz好像有点慢。

使用特权

评论回复
8
Bblythe| | 2024-10-10 08:24 | 只看该作者
我之前I2C总是读不出数据,看了这个才发现是地址搞错了。

使用特权

评论回复
9
Pulitzer| | 2024-10-10 08:25 | 只看该作者
代码写得太好了,刚好用来读写外接存储器。

使用特权

评论回复
10
Uriah| | 2024-10-10 08:25 | 只看该作者
有没有人知道怎么用这个MCU连接OLED显示屏的?

使用特权

评论回复
11
CW32TechSupport| | 2024-10-10 10:00 | 只看该作者
Uriah 发表于 2024-10-10 08:25
有没有人知道怎么用这个MCU连接OLED显示屏的?

请参考如下链接:
https://bbs.21ic.com/icview-3244752-1-1.html
【CW32F030CxTx StartKit测评】3.硬件I2C驱动OLED

使用特权

评论回复
12
szt1993| | 2024-10-12 10:38 | 只看该作者
非常不错的IIC案例分享

使用特权

评论回复
13
szt1993| | 2024-10-12 10:40 | 只看该作者
CW32TechSupport 发表于 2024-10-10 10:00
请参考如下链接:
https://bbs.21ic.com/icview-3244752-1-1.html
【CW32F030CxTx StartKit测评】3.硬件I ...

感谢分享,学习一下

使用特权

评论回复
14
星辰大海不退缩| | 2024-10-12 11:19 | 只看该作者
非常好的案例研究一下

使用特权

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

本版积分规则

32

主题

3440

帖子

0

粉丝