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

无锡新吴区住房建设和交通局网站WordPress phpspider

无锡新吴区住房建设和交通局网站,WordPress phpspider,芜湖网站建设优化,比较好的网站建设品牌设计本文一开始讲述了解决方案,后面是我做的笔记,用来讲述我的发现流程和探究的 Pico I2C 代码结构。 前提知识 首先要说明一点:Pico 有两个 I2C,也就是两套 SDA 和 SCL。这点你可以在针脚图中名字看出,比如下图的 Pin 4…

本文一开始讲述了解决方案,后面是我做的笔记,用来讲述我的发现流程和探究的 Pico I2C 代码结构。

前提知识

首先要说明一点:Pico 有两个 I2C,也就是两套 SDA 和 SCL。这点你可以在针脚图中名字看出,比如下图的 Pin 4 和 Pin 5是 I2C1 的,而默认的 Pin 6 和 Pin 7 是 I2C0 的。

请添加图片描述

默认情况下是只开启了第一个 I2C,也就是只有 I2C0 的针脚是可以使用的。如果这种情况下,你哪怕修改了针脚,但不是 I2C0 的,也是不会正常运行的。

如何选择哪个I2C控制器,以及SDA和SCL针脚

在设置之前声明三个变量或宏来方便开发。建议使用宏,这比较符合树莓派的开发风格:

#define I2C				i2c0
#define I2C_SDA_PIN 	4
#define I2C_SCL_PIN 	5

如果宏扩展出错,那么就使用变量。

然后初始化 I2C 的时候来设置使用哪个 I2C 控制器,以及哪个SDA和SCL针脚。下面是设置根据上面的设置,这里使用的是第一个 I2C 控制器,SDA 使用的是 GP4,SCL 使用的是 GP5,频率为1000000

i2c_init(I2C, 1000000);
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);

由于有两个 I2C 控制器,那么可以同时使用两套SDASCL针脚,但是要注意必须是I2C0I2C1的针脚,不能是同一个控制器的。

发现历程(选读)

这部分不一定要看。这里记录一下我是怎么知道是这样处理的,顺道了解了一下代码结构和信息传递的流程,万一以后需要就不用花时间翻来翻去了。

第一次尝试

首先分析一下:要定义针脚就要知道针脚这个值是如何被利用的,这样就可以知道如何传递处理这个值了。

一般是在初始化的时候设置使用哪个I2C控制器以及SDA和SCL针脚,代码一般如下:

i2c_init(i2c_default, CLK);
gpio_set_function(PICO_DEFAULT_I2C_SDA_PIN, GPIO_FUNC_I2C);
gpio_set_function(PICO_DEFAULT_I2C_SCL_PIN, GPIO_FUNC_I2C);
gpio_pull_up(PICO_DEFAULT_I2C_SDA_PIN);
gpio_pull_up(PICO_DEFAULT_I2C_SCL_PIN);

研究《用C/C++修改I2C默认的SDA和SCL针脚》的时候,我知道了默认针脚是在pico.h中配置的的,相关值有三个:PICO_DEFAULT_I2CPICO_DEFAULT_I2C_SDA_PINPICO_DEFAULT_I2C_SCL_PIN,那么只要追溯这三个值就行。

但是这样不好找,引用太多了。所以我就尝试了从另一方面先入手:I2C 是通过i2c_init()函数初始化的,如下:

i2c_init(i2c_default, SSD1306_I2C_CLK);

我需要的只有第一个参数i2c_default,因为这个参数传递了一些信息,第二个参数uint baudrate是传递速率的,和针脚无关。

那么i2c_init()函数的内容是什么呢?知道这个才能知道i2c_default的类型是什么结构,以及内部进行了什么处理。

i2c_init()函数声明在pico-sdk/src/rp2_common/hardware_i2c/i2c.c中,函数参数列表如下:

uint i2c_init(i2c_inst_t *i2c, uint baudrate) {i2c_reset(i2c);i2c_unreset(i2c);i2c->restart_on_next = false;i2c->hw->enable = 0;...// Re-sets i2c->hw->enable upon returning:return i2c_set_baudrate(i2c, baudrate);
}

那这个i2c_inst_t是个什么数据类型呢?我就继续找它。

pico-sdk/src/rp2_common/hardware_i2c/include/hardware/i2c.h的第 52 行可以看到它是i2c_inst结构体的重命名:

typedef struct i2c_inst i2c_inst_t;

那继续找结构体i2c_inst,这个结构体就在同一个文件里的第 135 行:

struct i2c_inst {i2c_hw_t *hw;bool restart_on_next;
};

终点还是第一个变量i2c_hw_t *hw,因为只有它可能会传递针脚的值,那就继续找i2c_hw_t是什么数据类型。

这个数据类型的声明在pico-sdk/src/rp2040/hardware_structs/include/hardware/structs/i2c.h中。换句话说,这个文件就是为i2c_hw_t结构体所准备的:

请添加图片描述

这个结构体存储了很多 I2C 的信息,但还是没找到针脚的信息,那么我就回到一开始在进行寻找。

第二次尝试

最开始我是寻找了i2c_init()的第一个参数的类型i2c_inst_t,收获不大。但是它的值我还没寻找,所以这次从参数值出发i2c_default,这个值是哪定义的呢?

在刚才发现i2c_inst_t声明和定义的pico-sdk/src/rp2_common/hardware_i2c/include/hardware/i2c.h头文件中发现了需要的东西(第 76 行):

#ifdef PICO_DEFAULT_I2C_INSTANCE
#define i2c_default PICO_DEFAULT_I2C_INSTANCE
#endif

这个PICO_DEFAULT_I2C_INSTANCE是什么呢?往上一瞅就能看到:

#if !defined(PICO_DEFAULT_I2C_INSTANCE) && defined(PICO_DEFAULT_I2C)
#define PICO_DEFAULT_I2C_INSTANCE (__CONCAT(i2c,PICO_DEFAULT_I2C))
#endif

在这里终于看到一个需要的值:PICO_DEFAULT_I2C,前文可知这个默认为0

这里的(__CONCAT(i2c,PICO_DEFAULT_I2C))是将i2cPICO_DEFAULT_I2C的值连接起来了,默认情况下也就是i2c0也就是说,参数i2c_default就是i2c0

这个技巧很不错,但是有些编译器用不了,比如我用 Clang x86_64-apple-darwin21.6.0 就无法扩展PICO_DEFAULT_I2C

再深入一些

但是这里的i2c0是什么呢?这是个什么类型的数据呢?

请添加图片描述

还是在pico-sdk/src/rp2_common/hardware_i2c/include/hardware/i2c.h头文件中(如上图)有这样一段:

#define i2c0 (&i2c0_inst) ///< Identifier for I2C HW Block 0
#define i2c1 (&i2c1_inst) ///< Identifier for I2C HW Block 1

可以看到i2c0i2c0_inst的地址,注释说这是I2C HW Block 0的标识符。从上面的

extern i2c_inst_t i2c0_inst;
extern i2c_inst_t i2c1_inst;

可以看到i2c0_insti2c1_inst是外部变量,类型是i2c_inst_t,这个类型之前我看到了定义的结构体:

struct i2c_inst {i2c_hw_t *hw;bool restart_on_next;
};

那这个i2c0_inst是在哪声明的?

这部分在pico-sdk/src/rp2_common/hardware_i2c/i2c.c中声明的:

i2c_inst_t i2c0_inst = {i2c0_hw, false};
i2c_inst_t i2c1_inst = {i2c1_hw, false};

这个i2c0_hw又是啥呢?在哪定义的呢?

这是在pico-sdk/src/rp2040/hardware_structs/include/hardware/structs/i2c.h中:

#define i2c0_hw ((i2c_hw_t *)I2C0_BASE)
#define i2c1_hw ((i2c_hw_t *)I2C1_BASE)

i2c0_hw表示((i2c_hw_t *)I2C0_BASE),意思是I2C0_BASE是个指向i2c_hw_t的指针,它的内容在pico-sdk/src/rp2040/hardware_regs/include/hardware/regs/addressmap.h中:

#define I2C0_BASE _u(0x40044000)
#define I2C1_BASE _u(0x40048000)

也就是说I2C0_BASE就是0x40044000,而i2c0_hw的地址就是0x40044000

补充一点,这里_()是无符号整数的意思,定义在pico-sdk/src/rp2040/hardware_regs/include/hardware/platform_defs

#ifndef _u
#ifdef __ASSEMBLER__
#define _u(x) x
#else
#define _u(x) x ## u
#endif
#endif

了解了蛮多知识,也希望能帮到有需要的人~

http://www.yayakq.cn/news/396987/

相关文章:

  • 公司的网站备案p9制作公司
  • 西安网站建设云阔网络熊掌号上海网站开发建设电话
  • 佛山网站建设公司3luewordpress 默认搜索引擎
  • 学校网站报价单网站建设优化石家庄
  • wordpress多站点不同主题wordpress模板制作
  • 深圳网站建设三把火免费公司网站建设
  • 网站建设的重要性与价值本地生活网
  • 安微省建设厅网站合肥官方网站优化费用
  • 做网站要会编程么建站工具模板
  • 苏州建设交易中心网站在线 网站建设
  • 邯郸邯山区网站建设小说网站开发l
  • 婚纱摄影网站源码服装html网站模板下载
  • 如何建造网站链接哈尔滨网站制作工具
  • 免费网站制作网站源码苏州seo关键字优化
  • 网站文章列表模板广州番禺专业建网站
  • 怎么做美食的网站深圳福田特价网站建设
  • 加强门户网站建设的方案东莞网络推广
  • wordpress建自己的网站吗美食网页设计模板代码
  • 秦皇岛网站建设seo商标购买网站
  • 怎么做自己的导航网站网页设计与制作模版
  • 南宁武鸣区建设局网站网站开发的经费预算
  • 潮州网站制作口子网站怎么做
  • 广东平台网站建设找哪家线上app怎么做
  • 义乌好品质自适应网站建设官方网站建设方案
  • 建设网站和app人工智能公众号
  • 河北做网站衡水哪家制作网站好
  • 饮料公司网站模板网站开发好学不
  • 潍坊微信网站响应式网站建设推广
  • 加工企业网站这么做做网站找酷万
  • 苏州做儿童场馆门票包票的网站网站刷流量有用吗