【联盛德W806上手笔记】七、I2C

目录

  • WM_SDK_W806_v0.6.0的库函数
    • 函数
    • 参数
    • 应用示例
      • 初始化
      • 使用
      • 测试
  • I2C 控制器
    • 功能概述
    • 主要特性
    • 功能描述
      • 传输速率选择
      • 中断及启动停止可控
      • 快速输出及检测信号
    • 寄存器描述
      • 寄存器列表
      • 时钟分频寄存器_1
      • 时钟分频寄存器_2
      • 控制寄存器
      • 数据寄存器
      • 收发控制寄存器
      • TXR 读出寄存器
      • CR 读出寄存器
  • iosetting大佬 维护的wm-sdk-w806
    • 函数
    • 参数
    • 应用示例
      • 初始化
      • 引脚复用
      • 使用
    • 测试

Windows 10 20H2
HLK-W806-V1.0-KIT
WM_SDK_W806_v0.6.0


       摘自《W806 芯片设计指导书 V1.0》、《W806 MCU 芯片规格书 V2.0》、《WM_W800_寄存器手册 V2.1》

WM_SDK_W806_v0.6.0的库函数

我们打开wm_i2c.h,有如下的函数声明:

函数

HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c);
//用于配置所用I2C的引脚HAL_StatusTypeDef HAL_I2C_DeInit(I2C_HandleTypeDef *hi2c);
//将初始化之后的I2C引脚恢复成默认的状态–各个寄存器复位时的值HAL_StatusTypeDef HAL_I2C_Write(I2C_HandleTypeDef *hi2c, uint8_t DevAddress, uint8_t MemAddress, uint8_t *pData, uint16_t Size);
//用于向从器件某地址写入数据HAL_StatusTypeDef HAL_I2C_Read(I2C_HandleTypeDef *hi2c, uint8_t DevAddress, uint8_t MemAddress, uint8_t *pData, uint16_t Size);
//用于由从器件某地址读取数据

参数

结构体和枚举类型

typedef struct
{GPIO_TypeDef *SCL_Port;uint32_t SCL_Pin;GPIO_TypeDef *SDA_Port;uint32_t SDA_Pin;
} I2C_HandleTypeDef;

(看着是不是有点怪

#define I2C_SDA_H(HANDLE)	HAL_GPIO_WritePin(HANDLE->SDA_Port, HANDLE->SDA_Pin, GPIO_PIN_SET)#define I2C_SDA_L(HANDLE)	HAL_GPIO_WritePin(HANDLE->SDA_Port, HANDLE->SDA_Pin, GPIO_PIN_RESET)#define I2C_SCL_H(HANDLE)	HAL_GPIO_WritePin(HANDLE->SCL_Port, HANDLE->SCL_Pin, GPIO_PIN_SET)#define I2C_SCL_L(HANDLE)	HAL_GPIO_WritePin(HANDLE->SCL_Port, HANDLE->SCL_Pin, GPIO_PIN_RESET)#define I2C_SDA_OUT(HANDLE)	SET_BIT(HANDLE->SDA_Port->DIR, HANDLE->SDA_Pin)#define I2C_SDA_IN(HANDLE)	CLEAR_BIT(HANDLE->SDA_Port->DIR, HANDLE->SDA_Pin)#define I2C_SDA_GET(HANDLE)	HAL_GPIO_ReadPin(HANDLE->SDA_Port, HANDLE->SDA_Pin)

应用示例

初始化

I2C_HandleTypeDef hi2c;
//...
static void I2C_Init(void);
//...
static void I2C_Init(void)
{hi2c.SCL_Port = GPIOA;hi2c.SCL_Pin = GPIO_PIN_1;hi2c.SDA_Port = GPIOA;hi2c.SDA_Pin = GPIO_PIN_4;HAL_I2C_Init(&hi2c);
}

使用

    I2C_Init();//...HAL_I2C_Write(&hi2c, DEVICE_ADDR, 地址, 数据缓冲区首地址, 数据长度);//...HAL_I2C_Read(&hi2c, DEVICE_ADDR, 地址, 数据缓冲区首地址, 数据长度)

测试

这里用的测试程序见【0.96寸 OLED屏实现1500Fps的帧率】STM32 软件、硬件SPI、I2C驱动总结
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

我们再打开wm_i2c.c:
在这里插入图片描述
可以看到 WM_SDK_W806_v0.6.0 库函数里i2c的实现竟然是模拟i2c
在这里插入图片描述
但在数据手册中是有硬件i2c相关的描述的:

I2C 控制器

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

功能概述

       I2C 总线是一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息。
       主器件用于启动总线传送数据,并产生时钟以开放传送的器件,此时任何被寻址的器件均被认为是从器件.在总线上主和从、发和收的关系不是恒定的,而取决于此时数据传送方向。如果主机要发送数据给从器件,则主机首先寻址从器件,然后主动发送数据至从器件,最后由主机终止数据传送;如果主机要接收从器件的数据,首先由主器件寻址从器件.然后主机接收从器件发送的数据,最后由主机终止接收过程。在这种情况下.主机负责产生定时时钟和终止数据传送。

主要特性

APB 总线协议标准接口
只可作为主设备控制器使用
I2C 工作速率可配,100KHz~400KHz
多路 GPIO 可复用成 I2C 的通信接口
可快速输出和检测时序信号

功能描述

传输速率选择

       通过设置寄存器 PRERlo 和寄存器 PRERhi 就可以将 I2C 总线上的数据传输速率配置在 100KHz 到400KHz 之间的任意总线频率整数分频值。

中断及启动停止可控

       通过设置寄存器 CTR 的 Bit6 允许或者禁止 I2C 控制器产生中断,并且还可以通过设置 Bit7 来随时启动或者停止 I2C 控制器的工作。

快速输出及检测信号

       通过设置寄存器 CR_SR 的相应位可以使控制器快速输出或者检测总线 START 信号,总线 STOP 信号,总线 ACK 信号,总线 NACK 信号。在主模式下,I2C 接口启动数据传输并生成时钟信号。 一个串行数据传输始终以启动信号开始,以停止信号结束。一旦在总线上生成启动信号,就选择了主设备模式。

寄存器描述

寄存器列表

在这里插入图片描述
在这里插入图片描述

时钟分频寄存器_1

在这里插入图片描述

时钟分频寄存器_2

在这里插入图片描述
在这里插入图片描述

控制寄存器

在这里插入图片描述

数据寄存器

在这里插入图片描述
在这里插入图片描述

收发控制寄存器

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

TXR 读出寄存器

在这里插入图片描述

CR 读出寄存器

在这里插入图片描述

iosetting大佬 维护的wm-sdk-w806

IOsetting的CSDN主页

git clone https://gitee.com/iosetting/wm-sdk-w806.git

可以看到,已有硬件I2C的实现:
在这里插入图片描述
打开wm_i2c.h,有如下声明:

函数

HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c);
//用于配置I2C接口的引脚、速率、优先级等HAL_StatusTypeDef HAL_I2C_DeInit(I2C_HandleTypeDef *hi2c);
//将初始化之后的I2C接口恢复成默认的状态–各个寄存器复位时的值void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c);
//用于启用I2C时钟,选择复用引脚void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c);
//用于禁用I2C时钟,将对应引脚恢复成默认的状态HAL_StatusTypeDef HAL_I2C_Write(I2C_HandleTypeDef *hi2c, uint8_t DevAddress, uint8_t MemAddress, uint8_t *pData, uint16_t Size);
//用于向从器件某地址写入数据HAL_StatusTypeDef HAL_I2C_Read(I2C_HandleTypeDef *hi2c, uint8_t DevAddress, uint8_t MemAddress, uint8_t *pData, uint16_t Size);
//用于由从器件某地址读取数据

参数

结构体和枚举类型

typedef struct __I2C_HandleTypeDef
{I2C_TypeDef                 *Instance;      /*!< I2C registers base address               */uint32_t                    Frequency;HAL_LockTypeDef             Lock;           /*!< Object lock                              */__IO uint32_t               ErrorCode;      /*!< I2C Error code                           */
} I2C_HandleTypeDef;

宏参数

#define I2C                             ((I2C_TypeDef *)I2C_BASE)

应用示例

初始化

I2C_HandleTypeDef hi2c;
#define DEVICE_ADDR    0xA0 //八位地址static void I2C_Init(void);
static void GPIO_Init(void);//...static void I2C_Init(void)
{hi2c.Instance = I2C;hi2c.Frequency = 400000;HAL_I2C_Init(&hi2c);
}static void GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct = {0};__HAL_RCC_GPIO_CLK_ENABLE();GPIO_InitStruct.Pin = GPIO_PIN_1;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT;GPIO_InitStruct.Pull = GPIO_PULLUP;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);GPIO_InitStruct.Pin = GPIO_PIN_4;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT;GPIO_InitStruct.Pull = GPIO_PULLUP;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

引脚复用

void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
{__HAL_RCC_I2C_CLK_ENABLE();__HAL_AFIO_REMAP_I2C_SCL(GPIOA, GPIO_PIN_1);__HAL_AFIO_REMAP_I2C_SDA(GPIOA, GPIO_PIN_4);
}void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)
{__HAL_RCC_I2C_CLK_DISABLE();HAL_GPIO_DeInit(GPIOA, GPIO_PIN_1);HAL_GPIO_DeInit(GPIOA, GPIO_PIN_4);
}

使用

    GPIO_Init();I2C_Init();//...HAL_I2C_Write(&hi2c, DEVICE_ADDR, 地址, 数据缓冲区首地址, 数据长度);//...HAL_I2C_Read(&hi2c, DEVICE_ADDR, 地址, 数据缓冲区首地址, 数据长度)

测试

经过一晚上的测试,我发现两个引脚存在互相干扰的现象,已经严重影响正常通讯(原因暂时未知)
在这里插入图片描述
即使是使用 iosetting大佬的OLED Demo(见联盛德 HLK-W806 (六): I2C驱动SSD1306 128x64 OLED液晶屏 —— IOsetting),我也只在通讯速率为1MHz下能跑通:
在这里插入图片描述在这里插入图片描述

尽管我已在运行Demo前事先延时5s以跳过电平不稳定阶段:
在这里插入图片描述

但在其他速率下仍难以通讯
400kHz:
在这里插入图片描述
在这里插入图片描述
100kHz:此情况下为完全黑屏
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/400093.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WordPress如何获取文章所属分类ID、名称或别名?

https://boke112.com/bkwd/4269.html 在 wordpress 主题制作过程中&#xff0c;我们可能会经常用到当前分类 ID&#xff0c;如&#xff1a;在文章页获取该文章分类下的相关文章&#xff0c;这时就可能用到当前分类 ID&#xff0c;即当前文章所在的分类 ID。那么&#xff0c;wor…

【联盛德W806上手笔记】八、SPI及其DMA

目录高速 SPI 设备控制器库函数函数参数宏应用示例初始化引脚复用中断相关使用注意事项DataAlignmentDirection测试main.cwm_hal_msp.cwm_it.c其他改动实验现象Windows 10 20H2 HLK-W806-V1.0-KIT WM_SDK_W806_v0.6.0 摘自《W806 芯片设计指导书 V1.0》、《W806 MCU 芯片规格书…

安装配置 radicale

为什么80%的码农都做不了架构师&#xff1f;>>> 可以直接pip安装,也可以下载源码安装,如果要存储到sql里面,则需要下载源码包,用里面的schema.sql 建表 默认安装后没有相应的配置文件,源码包里面也包含了 logging 和config,放到/etc/radicale 下 安装没什么说的,下…

散分,并如何判断时间段上有重叠冲突。

比如某个会议室的预订信息表 roomBookInfo(id,title,beginTime,endTime), 现在有一个新的预订请求 bTime, eTIme 分别 代表 开始、结束时间。请检查下表中的记录&#xff0c;查看是否有时间上的冲突。create table roomBookInfo (id int auto_increment primary key, title var…

wordpress 根据文章ID获取分类ID和标签ID

//wordpress 根据文章ID获取分类ID $categoryget_the_category( $post_ID ); $catid$category[0]->term_id; //wordpress 根据文章ID获取标签ID $tagswp_get_post_tags( $post_ID ); $tagid$tags[0]->term_id; 查看完整内容&#xff1a;http://web.zhaicool.net/366…

实现复选框的单选效果

<!DOCTYPE><html><head><title>实现复选框的单选效果</title></head><body><form methodpost action""><input type"checkbox" name"aa" οnclick"bb(this)"><input type&q…

【联盛德W806上手笔记】九、DMA

目录DMA 控制器功能概述功能描述DMA 通道DMA 数据流DMA 循环模式DMA 传输模式DMA 外设选择DMA 链表模式DMA 中断中断请求库函数函数参数宏应用Windows 10 20H2 HLK-W806-V1.0-KIT WM_SDK_W806_v0.6.0 摘自《W806 MCU 芯片规格书 V2.0》、《WM_W800_寄存器手册 V2.1》 DMA 控制…

MySql创建一个存储过程

MySQL 存储过程是从 MySQL 5.0 新功能。存储过程的长处有一箩筐。只是最基本的还是运行效率和SQL 代码封装。特别是 SQL 代码封装功能&#xff0c;假设没有存储过程&#xff0c;在外部程序訪问数据库时&#xff08;比如 PHP&#xff09;&#xff0c;要组织非常多 SQL 语句。特别…

attr与prop的区别

我们在获取checked属性值的时候&#xff0c;如果被选中则值为"checked"没选中获取值就是undefined. &#xff08;引述他人&#xff09;因为在有些浏览器中比如说只要写disabled&#xff0c;checked就可以了&#xff0c;而有的要写成disabled "disabled"&a…

定制化WordPress后台的6个技巧

WordPress后台并非千篇一律&#xff0c;你可以通过一些代码定制化一个你喜欢的后台&#xff0c;本文所述代码都应写在主题的functions.PHP中。 移除后台某些菜单 如果你不想客户因为点了错误的菜单选项而删除付费主题&#xff0c;或者搞乱后台的设置&#xff0c;那么把你不希望…

SNF快速开发平台MVC-自由排序组件

1. 自由排序功能使用 在一些需要排序优先级的数据进行调整处理&#xff0c;如民族数据&#xff0c;在北方实施的时候汉族比较多&#xff0c;希望把汉族放在第一位。在蒙古实施项目时&#xff0c;蒙古族人最多把蒙古族放在第一选择位。 1.1. 效果展示 图 1.1 1.2. …

Tip:强制执行exchange DAG节点之间的数据库副本移动

当exchange后端服务器MBX的小版本号不一致&#xff0c;比如都是exchange 2010 SP3 RU8的版本&#xff0c;但是小版本号不一致&#xff0c;这个时候我们去运行平衡exchange DAG分布的脚本的时候&#xff0c;低版本服务器上面的DAG数据库可能无法正常转移到优选节点&#xff0c;这…

系统边界确定

先说说系统边界的确定。这是在工程开发中紧接着需求分析的第二步。顾名思意&#xff0c;这个过程就是要确定我们要开发的系统和外部环境之间的界限&#xff0c;也就是要区分系统本身和它的外部环境。其中的外部环境可能包括用户,其它系统,软硬件条件等。 举个例子&#xff0c;一…

【联盛德W806上手笔记】十、ADC

目录ADCADC 电路设计库函数函数参数宏Demo中的例程main.cwm_hal_msp.cwm_it.cWindows 10 20H2 HLK-W806-V1.0-KIT WM_SDK_W806_v0.6.0 摘自《W806 芯片设计指导书 V1.0》、《W806 MCU 芯片规格书 V2.0》 ADC 基于 Sigma-Delta ADC 的采集模块&#xff0c;集成 4 路 16 比特 AD…

php导入excel到mysql的方法

PhpSpreadsheet 实测 1. https://phpspreadsheet.readthedocs.io/en/latest/ 2 . 查看 phpinfo() 时&#xff0c;发现 php_zip 没有启动 , PHP如何开启自带的ZipArchive类&#xff0c;实现压缩解压功能 [转载]phpspreadsheet开发手记 使用PhpSpreadsheet导入&导出Excel&…

delphi中TStringGrid数据的导出

没什么好说的&#xff0c;就是一个导出Excel的功能&#xff0c;代码如下&#xff1a; function TExportToExcel.Export(SGrid_List: TStringGrid;filename:string;out Errstr:string): Boolean; varexcelapp:Variant;page:Variant;i,j:Integer;savedialog:TSaveDialog;strsavef…

常用插件整理

easydialog&#xff0c;简单易用的模态对话框弹窗 http://www.h-ui.net/easydialog-v2.0/index.html superslide&#xff0c;非常好用的电脑端滚动切换等特效插件 http://www.superslide2.com/ swiper&#xff0c;非常好用且完善的手机端滚动触摸滑动特效插件 http://www.swipe…

【电路补习笔记】8、稳压电路 —— 线性电源及LDO

目录有名的电源芯片品牌DCDC电源分类开关电源vs线性稳压器线性电源参数线性电源工作原理集成稳压器78/79系列&#xff08;固定输出电压&#xff09;正、负对称输出两组电源的稳压电路扩展输出电压扩大输出电流LM317/LM337&#xff08;可调输出电压&#xff09;正、负对称输出两…

ajax代码整理

$.ajax({ type: "post", 【以POST或GET的方式请求。默认GET。PUT和DELETE也可以用&#xff0c;有的浏览器不支持】 url: url, 【请求的目的地址&#xff0c;须是一个字符串。】 contentType: "application/json", 【以哪种数据类型发送请求】 data: data, …

创建一个简单的WCF程序

为了使读者对基于WCF的编程模型有一个直观的映像&#xff0c;我将带领读者一步一步地创建一个完整的WCF应用。本应用功能虽然简单&#xff0c;但它涵盖了一个完整WCF应用的基本结构。对那些对WCF不是很了解的读者来说&#xff0c;这个例子将带领你正式进入WCF的世界。 在这个例…