模拟I2C

2023-05-16

I2C具体内容参考资料

https://blog.csdn.net/sternlycore/article/details/85600668
https://blog.csdn.net/qq_43460068/article/details/122409361

以下是在Atmel 300MHz下调试处的400KHz模拟I2C,延时函数需要根据实际内核进行设置

#define I2C_SDA_OUTPUT_DIR(pin)     ioport_set_pin_dir(pin, IOPORT_DIR_OUTPUT);
#define I2C_SDA_INPUT_DIR(pin)      ioport_set_pin_dir(pin, IOPORT_DIR_INPUT);
#define I2C_SDA_SET(pin)            ioport_set_pin_level(pin, IOPORT_PIN_LEVEL_HIGH);
#define I2C_SDA_CLR(pin)            ioport_set_pin_level(pin, IOPORT_PIN_LEVEL_LOW);
#define I2C_PIN_SDA(pin)            ioport_get_pin_level(pin)

#define I2C_SCL_SET(pin)            ioport_set_pin_level(pin, IOPORT_PIN_LEVEL_HIGH);
#define I2C_SCL_CLR(pin)            ioport_set_pin_level(pin, IOPORT_PIN_LEVEL_LOW);

#define BOARD_LOOPSPERMSEC   1300//1300//5126//51262
#define CONFIG_BOARD_LOOPSPER100USEC ((BOARD_LOOPSPERMSEC+5)/10)
#define CONFIG_BOARD_LOOPSPER10USEC  ((BOARD_LOOPSPERMSEC+50)/100)
#define CONFIG_BOARD_LOOPSPERUSEC    ((BOARD_LOOPSPERMSEC+500)/1000)
/*
 *@brief i2c delay  : 0.1us
 */
static void i2c_delay(uint32_t us)
{   
    volatile int i;

    while (us > 1000) {
        for (i = 0; i < BOARD_LOOPSPERMSEC; i++);
        us -= 1000;
    }
    while (us > 100) {
        for (i = 0; i < CONFIG_BOARD_LOOPSPER100USEC; i++);
        us -= 100;
    }
    while (us > 10) {
        for (i = 0; i < CONFIG_BOARD_LOOPSPER10USEC; i++);
        us -= 10;
    }
    while (us > 0) {
        for (i = 0; i < CONFIG_BOARD_LOOPSPERUSEC; i++);
        us--;
    }
}

/*
 *@brief i2c Start
 */
static void i2c_start(I2C_Object *object)
{
    I2C_SDA_OUTPUT_DIR(object->sda);
    I2C_SDA_SET(object->sda);
    I2C_SCL_SET(object->scl);
    i2c_delay(50);
    I2C_SDA_CLR(object->sda);
    i2c_delay(15);
}

/*
 *@brief i2c Stop
 */
static void i2c_stop(I2C_Object *object)
{
    I2C_SDA_OUTPUT_DIR(object->sda);
    I2C_SDA_CLR(object->sda);
    i2c_delay(15);
    I2C_SCL_SET(object->scl);
    i2c_delay(25);
    I2C_SDA_SET(object->sda);
    i2c_delay(25);
}

/*
 *@brief i2c Wait Acknowledge
 * 0:no ack   1:ack
 */
static uint8_t i2c_wait_ack(I2C_Object *object)
{
    uint8_t ret = 1;

    I2C_SDA_SET(object->sda);
    I2C_SDA_INPUT_DIR(object->sda);
    i2c_delay(10);
    I2C_SCL_SET(object->scl);
    i2c_delay(13);
    if(I2C_PIN_SDA(object->sda)){
        ret = 0;
    }
    I2C_SCL_CLR(object->scl);

    return ret; 
}

/*
 *@brief i2c Send Acknowledge
 */
static void i2c_send_ack(I2C_Object *object)
{
    I2C_SDA_OUTPUT_DIR(object->sda);
    I2C_SDA_CLR(object->sda);
    i2c_delay(13);
    I2C_SCL_SET(object->scl);
    i2c_delay(13);
    I2C_SCL_CLR(object->scl);    
}

/*
 *@brief i2c Send No Acknowledge
 */
static void i2c_send_noack(I2C_Object *object)
{
    I2C_SDA_OUTPUT_DIR(object->sda);
    I2C_SDA_SET(object->sda);
    i2c_delay(13);
    I2C_SCL_SET(object->scl);
    i2c_delay(13);
    I2C_SCL_CLR(object->scl);    
}

/*
 *@brief i2c Send Data
 */
static void i2c_send_data(I2C_Object *object, uint8_t data)
{
    uint8_t i = 8;
    
    I2C_SDA_OUTPUT_DIR(object->sda);
    while(i--)
    {
        I2C_SCL_CLR(object->scl);
        i2c_delay(15);
        if(data & 0x80)
        {
            I2C_SDA_SET(object->sda);
        }         
        else
        {
            I2C_SDA_CLR(object->sda);
        }
        
        i2c_delay(5);
        data <<= 1;
        I2C_SCL_SET(object->scl);
        i2c_delay(20);
    }   

    I2C_SCL_CLR(object->scl);
    i2c_delay(5); 
}

/*
 *@brief i2c Receive Data
 */
static uint8_t i2c_receive_data(I2C_Object *object)
{
    uint8_t i = 8;
    uint8_t data = 0;
    
    I2C_SDA_SET(object->sda);
    I2C_SDA_INPUT_DIR(object->sda);
    while(i--)
    {
        data <<= 1;
        I2C_SCL_CLR(object->scl);
        i2c_delay(13);
        I2C_SCL_SET(object->scl);
        i2c_delay(12);
        if(I2C_PIN_SDA(object->sda)) 
            data |= 0x01;
    }
    I2C_SCL_CLR(object->scl);
    
    return(data);    
}

/*
 *@brief Read Data
 */
uint8_t read_datas(I2C_Object *object, I2C_Transaction *transaction)
{
    uint8_t i;
    uint8_t *pdata = (uint8_t*)transaction->readBuf;

    i2c_start(object);
    i2c_send_data(object, transaction->slaveAddress<<1);
    if(i2c_wait_ack(object) == 0)
    {
        i2c_stop(object);
        return 0;
    }
    i2c_send_data(object, ((uint8_t *)transaction->writeBuf)[0]);
    if(i2c_wait_ack(object) == 0)
    {
        i2c_stop(object);
        return 0;
    }
    
    i2c_start(object);
    i2c_send_data(object, (transaction->slaveAddress<<1)|0x01);
    if(i2c_wait_ack(object) == 0)
    {
        i2c_stop(object);
        return 0;
    }
    for(i = 0; i < transaction->readCount; i++)
    {
        *pdata++ = i2c_receive_data(object);
        if(i < (transaction->readCount - 1))
            i2c_send_ack(object);
    }
    i2c_send_noack(object);
    i2c_stop(object);
    
    return 1;    
}

/*
 *@brief i2c Write one byte
 */
static uint8_t i2c_write_one_byte(I2C_Object *object, I2C_Transaction *transaction)
{    
    uint8_t *write_buf = (uint8_t*)transaction->writeBuf;

    i2c_start(object);
    i2c_send_data(object, transaction->slaveAddress<<1);
    if(i2c_wait_ack(object) == 0)
    {
        i2c_stop(object);
        return 0;
    }
    i2c_send_data(object, write_buf[0]);
    if(i2c_wait_ack(object) == 0)
    {
        i2c_stop(object);
        return 0;
    }

    i2c_send_data(object, write_buf[1]);
    if(i2c_wait_ack(object) == 0)
    {
        i2c_stop(object);
        return 0;
    }
    
    i2c_stop(object);
    
    return 1;    
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

模拟I2C 的相关文章

  • i2c信号的ACK与NACK

    nbsp nbsp nbsp nbsp nbsp nbsp nbsp 我们平时在调试I2C的时候可能很少去关注NACK信号 只知道如果Master发送数据 MSB先发 LSB后发 连续发送一个字节 8个bit 之后Slave会回复一个ACK
  • 基于I2C/SPI的温湿度采集与OLED显示

    一 I2c通讯协议 I2C通讯协议 Inter xff0d Integrated Circuit 引脚少 xff0c 硬件实现简单 xff0c 可扩展性强 xff0c 不需要USART CAN等通讯协议的外部收发设备 xff0c 现在被广泛
  • I2C总线和触摸屏驱动移植实战-linux驱动开发第9部分-朱有鹏-专题视频课程

    I2C总线和触摸屏驱动移植实战 linux驱动开发第9部分 9306人已学习 课程介绍 本课程是linux驱动开发的第9个课程 xff0c 主要内容是linux的I2C子系统以及电容触摸屏驱动的移植 学习本课程的核心点在于I2C子系统 xf
  • I2C读取IST8310

    文章目录 I2C简介I2C传输过程I2C仲裁IST8310磁力计Cube配置相关函数HAL I2C Mem Read函数HAL I2C Mem Write函数IST8310的初始化 程序流程代码编写 I2C简介 2C是一种半双工双向二线制的
  • PX4代码中LIDAR-Lite v3激光测距仪I2C驱动

    调试LIDAR Lite v3激光测距仪 xff0c 通读了PX4代码中驱动相关的部分 在这里做一下记录 飞控硬件是pixhawk1 xff0c PX4软件版本为1 7 3 按照官方教程进行接线和配置 xff0c 链接为 https doc
  • PX4通过I2C方式添加自定义传感器(2)

    PX4 I2C通信方式传感器驱动分析 xff08 以ets airspeed为例 xff09 1 说明 这篇文章我们就来看看I2C传感器的驱动过程 xff0c 当然里面也有很多东西我不是很理解 xff0c 所以仅谈我领悟的一些东西 我就以e
  • 首个单芯片超小封装I2C转PWM解决方案

    ZW10I8X系列 高性能工业级16位高精度I2C转PWM接口SOC芯片 接口标准 符合飞利浦的I2C标准规范 xff0c 目前支持的速度为小于100kbit 建议使用50k 1个使能脚 xff08 ZW10I8xE后缀带E的 xff09
  • 串口通信协议【I2C、SPI、UART、RS232、RS422、RS485、CAN、TTL、USB】

    xff08 1 xff09 I2C 集成电路互连总线接口 Inter IC xff1a 同步串行半双工传输总线 xff0c 连接嵌入式处理器及其外围器件 支持器件 xff1a LCD驱动器 Flash存储器 特点 有两根传输线 xff08
  • I2C驱动体系结构一:驱动软件概念与对应硬件的关系

    一 概念 xff1a 1 设备 xff1a struct device xff1a 该数据结构是对物理设备的软件抽象 xff0c 比如I2C slave xff08 对应i2c client xff09 和I2C 适配器 xff08 对应i
  • I2C 简介

    1 I2C 简介 这里的内容参考的是 2014 4 4 的 V 6 版本的官方 I2C Bus 规格书 xff0c 第六章有给出相应的链接 1 1 引脚 I2C 一般而言是一种同步半双工的通信方式 xff0c 所以除了电源引脚之外 xff0
  • I2C接口及时序

    1 I2C学习要点 1 有2条双向串行线 xff0c 一条数据线SDA xff0c 一条时钟线SCL 如果只做master SCL可以只是输出 SDA在PAD上一定是inout pin xff0c 当然转为数字信号时可以分为两组 inout
  • I2C调试工具

    1 I2C调试工具 i2c tools工具是开源I2C调试工具 xff0c 具有获取I2C总线挂载的设备列表及设备地址 xff0c 可对指定设备指定寄存器进行读写的功能 ubuntu安装 xff1a apt get install libi
  • I2C驱动App

    1 查看eeprog c源代码 copyright C by 2009 Guangzhou FriendlyaRM in China email capbily 64 163 com website arm9 net include lt
  • Arduino读取DHT11的温湿度显示在基于I2C的1602上

    背景摘要 又到了周末 xff0c B站的番还未更新 闲来无事 xff0c 搞搞吃灰已久的Arduino 南方的冬天真冷啊 xff0c 测测屋子里的温湿度怎么样 xff01 为了测量屋子里的温湿度 xff0c 就用简单大方的Arduino x
  • STM32设置为I2C从机模式(HAL库版本)

    STM32设置为I2C从机模式 HAL库版本 目录 STM32设置为I2C从机模式 HAL库版本 前言 1 硬件连接 2 软件编程 2 1 步骤分解 2 2 测试用例 3 运行测试 3 1 I2C连续写入 3 2 I2C连续读取 3 3 I
  • BH1750 传感器实战教学 —— 驱动移植篇

    前言 上一篇 BH1750 的实战教学我们说明的实际应用中传感器的硬件设计 BH1750 传感器实战教学 硬件设计篇 我们提到过在本次使用的芯片为 51 内核 I2C 通讯驱动实现与 STM32 上还是有很大区别的 对于我们来说 已经掌握了
  • Linux:从用户空间实例化:eeprom new_device

    环境 x86 Ubuntu 14 04 我想获得类似的东西 i2c0 eeprom eeprom 50 compatible at 24c32 reg lt 0x50 gt 但因为在 x86 中没有可用的设备树 所以我遵循i2c insta
  • 找不到i2c注册宏?

    我正在 raspi 上开发 I2C 驱动程序 register I2C device static static const struct i2c board info rasp i2c devices mbed mbedID in the
  • STM32F207 I2C 测试失败

    我正在使用 STM32F207 微控制器在 STM3220G EVAL 板上学习嵌入式开发 我尝试通过连接同一芯片上的两个 I2C2 和 I2C3 模块并发送 接收字符来测试 I2C 接口 这是我当前编写的代码 使用 mdk arm 5 i
  • 是否有通用 I2C 命令来查看设备是否仍然存在于总线上?

    是否有通用的 I2C 命令来查看设备在初始化一次后是否仍然存在于总线上 例如 OLED 显示器 我问这个的原因是为了避免主程序由于库代码中存在无限循环而冻结 当设备断开连接时 例如 Wire 库 在 MCU 启动时 我想检查设备是否可用 并

随机推荐

  • ros 已经发布topic 但是却echo不出来

    因为是用的docker镜像 xff0c 采用多机通信的方式 xff0c 一台电脑跑仿真 xff0c 一台电脑跑算法 当进入docker的时候 xff0c docker进入了一个莫名其妙的host也就是root 64 jszn arm pla
  • 英文词组

    bonehead 笨蛋 buddy 密友 blow over 经历 i give up you won off duty 下班 20080506 每天一起练口语 健康话题 Health I 39 m going to the hospita
  • openrave 生成ikfast 第一步遇到的问题

    1 rosrun collada urdf urdf to collada jszn robot description with sensor gazebo xacro jszn robot description with sensor
  • 单视图测量 (2D变换、影消点线、单视图重构)

    写在前面 xff1a 本篇Blog仅作为学习笔记 xff0c 学习内容来自于北邮CV XUEBA团队的三维重建 精简版 xff0c 鲁鹏 课程 回顾经典2D变换 等距变换 旋转矩阵 Rotate Matrix 的性质分析 证明 xff1a
  • libpng warning: iCCP: known incorrect sRGB profile 报错

    libpng warning iCCP known incorrect sRGB profile 警告 xff0c 问题解决 目录 libpng warning iCCP known incorrect sRGB profile 警告 xf
  • 卷积神经网络核心概念再复习+Pytorch一维卷积的实现

    蓝色 紫色 红色 深度学习之卷积神经网络 基本的图像分类模型架构 卷积层 xff1a 用来提取图像的底层特征 池化层 xff1a 防止过拟合 xff0c 减小数据维度 全连接层 xff1a 汇总卷积层和池化层得到的底层特征和信息 xff0c
  • Ubuntu20.04安装过程 【磁盘分区】

    前言 首先 要了解你的电脑配置 xff08 我实验室的如下 xff09 xff1a 整个安装Ubuntu系统的过程大致如下 xff1a 华硕主板按F2 F8 xff0c 这个可以百度 也可以重新启动 xff0c 在你的第一个界面上能看到 按
  • KLT光流跟踪特征点对

    前言 本篇所述为KLT光流跟踪两个视频中匹配特征点对的具体实现 61 gt 源码见Github openCV版本 xff1a 4 5 5 函数详解 1 特征提取 1 SIFT特征提取调用方式 sift span class token op
  • Ubuntu 20.04桌面文件夹图标消失及文件系统无法打开

    前言 之前遇到过服务器上桌面图标突然消失的情况 在更换系统语言之后 xff0c 桌面出现过一次这种情况 xff0c 经过重启之后就恢复了 再后来又莫名其妙出现了这么个问题 xff0c 最开始搜索的解决方案是 让你打开任务管理器 gnome
  • 【论文笔记】Deblur-NeRF == HKU ==CVPR‘2022

    蓝色 紫色 红色 Deblur NeRF Neural Radiance Fields from Blurry Images Author From Abstract 神经辐射场 xff08 NeRF xff09 由于其显著的合成质量 xf
  • Linux安装 metashape

    1 下载软件 3D三维建模软件 Agisoft Metashape Pro 2 安装 span class token comment 进入root模式 xff0c 如果之前没有设置过密码 span span class token fun
  • Information Collection

    港澳新地区 香港理工大学 杨波 助理教授 vLAR实验室 欧洲 ETH Z rich Marc Pollefeys Computer Vision and Geometry Group TU Delft 3D geoinformation
  • 804半导体物理 中科院半导体所考研经验

    本人2021考研 xff0c 半导体研究所 xff0c 物理电子学 xff0c 数一英语一 xff0c 专业课804半导体 自己之前在备考的时候就感觉专业课的资料和备考经验比较少 xff0c 现在就写一些自己总结的经验 xff0c 放一些资
  • 一些cmake error fixed

    建完虚拟环境后 运行 pip install 出现报错 xff0c 显示svox2安装出错 xff0c 然后开始进入到svox2中进行手动编译和安装 1 cmake svox2 csrc pybind11找不到 conda span cla
  • metashape-pro python scripts render specified viewpoint

    官方python脚本使用文档 主函数 xff1a render 61 chunk model renderImage 1 实现特定视角的渲染需要通过脚本方式进行 xff0c 原本的metashape pro中是没有这个功能的 首先在meta
  • 【mega-nerf】调包失败&pip install失败解决方案

    Problem 1 调包失败 在这样的层级架构里调包 xff0c 输出无法找到 mega nerf 直接用 sys path append 没有作用 span class token comment import sys span span
  • 使用 rust 开发 stm32:前言

    更多分享内容可访问我的个人博客 https www niuiic top 本系列教程全部置于stm32专栏 本文为使用 rust 开发 stm32 系列教程前言 Why Rust Rust 特性就不用多介绍了 xff0c 有个编译器管着有时
  • docker与virtualbox切换使用

    管理员模式打开cmd 查看hyper v状态 xff1a bcdedit span class token operator span findstr hyperv 若状态显示 hypervisorlaunchtype Auto 则当前可支
  • 内存管理学习

    简单的内存分配算法学习 系统中一块剩余不用的大块连续内存 当需要分配内存块时 xff0c 将从这个大的内存块上分割出相匹配的内存块 xff0c 每个内存块都包含一个管理用的数据头 xff0c 通过这个头把使用块与空闲块用双向链表的方式链接起
  • 模拟I2C

    I2C具体内容参考资料 https blog csdn net sternlycore article details 85600668 https blog csdn net qq 43460068 article details 122