当前位置: 首页 > article >正文

RP2040 C SDK I2C外设使用

RP2040 C SDK I2C外设使用


  • 📌相关篇《RP2040 VSCode C/C++开发环境快速部署》
  • 📍I2C API 外设:https://www.raspberrypi.com/documentation/pico-sdk/hardware.html#group_hardware_i2c
  • 🔧驱动I2C ssd1306 屏幕需要使用到的库: https://github.com/daschr/pico-ssd1306

RP2040有2 个硬件 I2C 控制器。

📗利用I2C扫描I2C设备地址

/*
  CMSIS-DAP烧录命令:openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c  "adapter speed 5000"-c "program RP2040_I2C_SCAN.elf verify reset exit"

 jlink命令: openocd -f interface/jlink.cfg -f target/rp2040.cfg  -c  "adapter speed 2000" -c  "program RP2040_I2C_SCAN.elf verify reset exit"
 */
#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/binary_info.h"
#include "hardware/i2c.h"

// 板载LED连接的GPIO引脚
#define LED_PIN 25
// I2C defines
// This example will use I2C0 on GPIO4 (SDA) and GPIO5 (SCL) running at 400KHz.
// Pins can be changed, see the GPIO function select table in the datasheet for information on GPIO assignments
#define I2C_PORT i2c0
#define I2C_SDA_PIN 4
#define I2C_SCL_PIN 5

void i2c_setup() {
    // I2C Initialisation. Using it at 400Khz.
    i2c_init(I2C_PORT, 400 * 1000);
    gpio_set_function(I2C_SDA_PIN, GPIO_FUNC_I2C);
    gpio_set_function(I2C_SCL_PIN, GPIO_FUNC_I2C);
    gpio_pull_up(I2C_SDA_PIN);//开启内部上拉
    gpio_pull_up(I2C_SCL_PIN);
    // Make the I2C pins available to picotool
    bi_decl(bi_2pins_with_func(I2C_SDA_PIN, I2C_SCL_PIN, GPIO_FUNC_I2C));
}

void scan_i2c_addresses() {
    for (uint8_t addr = 0x03; addr <= 0x7f; addr++) {
        uint8_t data = 0x00;
        int result = i2c_write_blocking(I2C_PORT, addr, &data, 1, false);
        if (result == 1) {
            printf("I2C device found at address 0x%02X\n", addr);
        }
    }
}

int main()
{
    stdio_init_all();
    // 设置LED_PIN为输出模式
    gpio_init(LED_PIN);
    gpio_set_dir(LED_PIN, GPIO_OUT);

    // 初始化I2C
    i2c_setup();
    scan_i2c_addresses();

    while (1) {
        tight_loop_contents();
        // 翻转LED状态
        gpio_put(LED_PIN,!gpio_get(LED_PIN));
        // 等待0.5秒
        sleep_ms(3500);
        scan_i2c_addresses();
    }

    return 0;
}

📘SSD1306 oled屏幕驱动显示

配合上面的库实现,很容易点亮屏幕。

  • 调用库需要在项目的CMakeLists.txt中添加对应的源文件。推荐拷贝到项目文件夹内,这样就免去路径。
add_executable(RP2040_I2C_SSD1306 RP2040_I2C_SSD1306.c
                                  ssd1306.c

)
  • 测试demo
/*
  CMSIS-DAP烧录命令:openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c  "adapter speed 5000"-c "program RP2040_I2C_SSD1306.elf verify reset exit"

 jlink命令: openocd -f interface/jlink.cfg -f target/rp2040.cfg  -c  "adapter speed 2000" -c  "program RP2040_I2C_SSD1306.elf verify reset exit"
 */
#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/binary_info.h"
#include "hardware/i2c.h"

#include "ssd1306.h" // Include the SSD1306 library
#include "acme_5_outlines_font.h"
// I2C defines
// This example will use I2C0 on GPIO8 (SDA) and GPIO9 (SCL) running at 400KHz.
// Pins can be changed, see the GPIO function select table in the datasheet for information on GPIO assignments
#define I2C_PORT i2c0
#define I2C_SDA_PIN 4
#define I2C_SCL_PIN 5

const uint8_t num_chars_per_disp[]={7,7,7,5};
//const uint8_t *fonts[4]= {acme_font, bubblesstandard_font, crackers_font, BMSPA_font};
//const uint8_t *fonts[1]= {font_8x5};
// 板载LED连接的GPIO引脚
#define LED_PIN 25
#define SLEEPTIME 25

/**
 * @brief 初始化I2C接口
 *
 * 该函数用于初始化I2C接口,设置I2C的时钟频率为400KHz,
 * 并将I2C的SDA和SCL引脚设置为I2C功能,同时启用上拉电阻。
 *
 * @param 无
 * @return 无
 */
void i2c_setup() {
    
    // 初始化I2C接口,设置I2C的时钟频率为400KHz
    i2c_init(I2C_PORT, 400 * 1000);

    // 将I2C的SDA引脚设置为I2C功能
    gpio_set_function(I2C_SDA_PIN, GPIO_FUNC_I2C);

    // 将I2C的SCL引脚设置为I2C功能
    gpio_set_function(I2C_SCL_PIN, GPIO_FUNC_I2C);

    // 启用I2C的SDA引脚的上拉电阻
    gpio_pull_up(I2C_SDA_PIN);

    // 启用I2C的SCL引脚的上拉电阻
    gpio_pull_up(I2C_SCL_PIN);
    // Make the I2C pins available to picotool
    bi_decl(bi_2pins_with_func(I2C_SDA_PIN, I2C_SCL_PIN, GPIO_FUNC_I2C));//需要包含binary_info.h头文件
}

void animation(void) {
    const char *words[]= {"SSD1306", "DISPLAY", "DRIVER"};

    ssd1306_t disp;
    disp.external_vcc=false;
    ssd1306_init(&disp, 128, 64, 0x3C, i2c0);
    ssd1306_clear(&disp);

    printf("ANIMATION!\n");

    char buf[8];

    for(;;) {
        for(int y=0; y<31; ++y) {
            ssd1306_draw_line(&disp, 0, y, 127, y);
            ssd1306_show(&disp);
            sleep_ms(SLEEPTIME);
            ssd1306_clear(&disp);
        }

        for(int y=0, i=1; y>=0; y+=i) {
            ssd1306_draw_line(&disp, 0, 31-y, 127, 31+y);
            ssd1306_draw_line(&disp, 0, 31+y, 127, 31-y);
            ssd1306_show(&disp);
            sleep_ms(SLEEPTIME);
            ssd1306_clear(&disp);
            if(y==32) i=-1;
        }

        for(int i=0; i<sizeof(words)/sizeof(char *); ++i) {
            ssd1306_draw_string(&disp, 8, 24, 2, words[i]);
            ssd1306_show(&disp);
            sleep_ms(800);
            ssd1306_clear(&disp);
        }

        for(int y=31; y<63; ++y) {
            ssd1306_draw_line(&disp, 0, y, 127, y);
            ssd1306_show(&disp);
            sleep_ms(SLEEPTIME);
            ssd1306_clear(&disp);
        }



              //  ssd1306_draw_string_with_font(&disp, 8, 24, 2, font_8x5, buf);
        ssd1306_draw_string_with_font(&disp, 8, 24, 2, acme_font, (char*)"Hello!");
        ssd1306_draw_string(&disp, 8, 0, 1, "Perseverance51");
                ssd1306_show(&disp);
                sleep_ms(800);
                ssd1306_clear(&disp);

            gpio_put(LED_PIN,!gpio_get(LED_PIN));
        sleep_ms(2000);
    }
}

int main()
{
    stdio_init_all();
    gpio_init(LED_PIN);
    gpio_set_dir(LED_PIN, GPIO_OUT);
    i2c_setup();
while (1) {
 //       tight_loop_contents()
       animation();
    }
    return 0;
}

📒利用I2C读写AT24C02数据操作

  • AT24C02是一个只有256字节的存储器。
/*
  CMSIS-DAP烧录命令:openocd -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c  "adapter speed 5000"-c "program RP2040_I2C_AT24C02.elf verify reset exit"

 jlink命令: openocd -f interface/jlink.cfg -f target/rp2040.cfg  -c  "adapter speed 2000" -c  "program RP2040_I2C_AT24C02.elf verify reset exit"
 */
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/i2c.h"
#include "pico/binary_info.h"

// 板载LED连接的GPIO引脚
#define LED_PIN 25
// I2C defines
// This example will use I2C0 on GPIO4 (SDA) and GPIO5 (SCL) running at 400KHz.
// Pins can be changed, see the GPIO function select table in the datasheet for information on GPIO assignments
#define I2C_PORT i2c0
#define I2C_SDA_PIN 4
#define I2C_SCL_PIN 5

#define AT24C02_ADDR 0x50   // AT24C02的地址

void i2c_setup() {
    // I2C Initialisation. Using it at 100Khz.
    i2c_init(I2C_PORT, 100 * 1000);
    gpio_set_function(I2C_SDA_PIN, GPIO_FUNC_I2C);
    gpio_set_function(I2C_SCL_PIN, GPIO_FUNC_I2C);
    gpio_pull_up(I2C_SDA_PIN);//开启内部上拉
    gpio_pull_up(I2C_SCL_PIN);
    // Make the I2C pins available to picotool
    bi_decl(bi_2pins_with_func(I2C_SDA_PIN, I2C_SCL_PIN, GPIO_FUNC_I2C));
}

void scan_i2c_addresses() {
    for (uint8_t addr = 0x03; addr <= 0x7f; addr++) {
        uint8_t data = 0x00;
        int result = i2c_write_blocking(I2C_PORT, addr, &data, 1, false);
        if (result == 1) {
            printf("I2C device found at address 0x%02X\n", addr);
        }
    }
}


// 向AT24C02写入一个字节
void at24c02_write_byte(uint8_t addr, uint8_t data) {
    uint8_t buffer[2];
    buffer[0] = addr;
    buffer[1] = data;
    i2c_write_blocking(I2C_PORT, AT24C02_ADDR, buffer, 2, false);
    sleep_ms(5); // AT24C02写入需要一定时间,这里简单延时等待
}

// 从AT24C02读取一个字节
uint8_t at24c02_read_byte(uint8_t addr) {

    i2c_write_blocking(I2C_PORT, AT24C02_ADDR, &addr,1, true);
    uint8_t data;
    i2c_read_blocking(I2C_PORT, AT24C02_ADDR, &data, 1, false);
    return data;
}

// 从AT24C02读取指定长度的数据
void at24c02_read(uint8_t addr, uint8_t *data, size_t length) {

    i2c_write_blocking(I2C_PORT, AT24C02_ADDR, &addr, 1, true);
    i2c_read_blocking(I2C_PORT, AT24C02_ADDR, data, length, false);
}

int main()
{
    uint8_t EP_data[35];
    stdio_init_all();
    i2c_setup();
    gpio_init(LED_PIN);
    gpio_set_dir(LED_PIN, GPIO_OUT);
     scan_i2c_addresses();
     at24c02_write_byte(255, 'A');

     while (1) {
        // tight_loop_contents();
        // 翻转LED状态
        gpio_put(LED_PIN,!gpio_get(LED_PIN));
        // 读取AT24C02的状态
        uint8_t data = at24c02_read_byte(255);
        printf("AT24C02 Address 255 data: %c\n", data);
        at24c02_read(0, EP_data, 35);
        printf("EP_data: %s\n", EP_data);

        sleep_ms(1000);

    }
  //  puts("Hello, world!");

    return 0;
}

在这里插入图片描述


http://www.kler.cn/a/460907.html

相关文章:

  • leetcode 173.二叉搜索树迭代器栈绝妙思路
  • JS基础 -- 数组 (对象 / 数组 / 类数组 / 对象数组)的遍历
  • Echarts+vue电商平台数据可视化——webSocket改造项目
  • 基于SpringBoot和OAuth2,实现通过Github授权登录应用
  • SQL-leetcode-197. 上升的温度
  • springboot523基于Spring Boot的大学校园生活信息平台的设计与实现(论文+源码)_kaic
  • Docker容器镜像制作
  • 正则表达式介绍和python中的简单使用
  • 大中厂面试经验分享:如何使用消息队列(MQ)解决系统问题
  • 科技风杂志科技风杂志社科技风编辑部2024年第36期目录
  • 【优选算法】有效三角形的个数
  • SpringBoot集成ECDH密钥交换
  • Linux C/C++编程-网络程序架构与套接字类型
  • 【Java 新特性】深入浅出 Java Lambda 表达式
  • vim里搜索关键字
  • 【Windows】Windows系统查看目录中子目录占用空间大小
  • YK人工智能(二)——万字长文了解深度学习环境配置
  • grep如何打印行数
  • C++线程池的使用
  • 智能商业分析 Quick BI
  • Spring Security 3.0.2.3版本
  • 为什么需要设置 `NCCL_P2P_DISABLE=1` 和 `NCCL_IB_DISABLE=1`?
  • 4G报警器WT2003H-16S低功耗语音芯片方案开发-实时音频上传
  • 国产低代码框架zdppy开发笔记001 zdppy_api快速入门
  • 《鸿蒙HarmonyOS应用开发从入门到精通(第2版)》学习笔记——HarmonyOS架构介绍
  • 力扣-数据结构-8【算法学习day.79】