【PIC32MZ】I2C通信

发布者:CyberJolt最新更新时间:2020-04-28 来源: eefocus关键字:PIC32MZ  I2C通信  通讯协议 手机看文章 扫描二维码
随时随地手机看文章

I2C跟串口一样,仅需2根线通讯即可,在某些引脚紧张的应用中非常有用,不过I2C相比于串口,通讯协议更简单一点,距离也更短一些,仅限于板间通信。大多数IC都支持I2C协议。

 

I2C的时序图为:

I2C数据传输是在起始条件和停止条件之间。


起始条件和停止条件都是SCL为高一段时间产生。起始条件为SDA从高变为低,停止条件为SDA从低变为高。


I2C数据传输规则为,第一字节必须为地址,一般器件地址都是7位(也有10位的),放在高7位,最后一位时读写标识,所以,读写地址是不相同的,并且很多IC都可以配置多个地址选择,这是为了在一组I2C上接多个IC,因为I2C是通过地址来识别从机的。


每传输一个字节,从机都要回复一个ACK来表示是否完成接受,回复0继续接受,回复1停止接受。


I2C写操作很简单,传输从机地址以及数据即可。


I2C读也是一样,传输从机地址即可。

 

写操作:

一般而言,写操作要配合DataSheet,有写命令的操作,写数据的操作。

例如一般的OLED就有写命令和写数据两种操作,做法是,写地址命令/数据

标识 一个字节或多个字节命令信息。

一般EEPROM的写操作为:写地址需要写入的EEPROM内部起始地址(1字节或多字节) 1字节或多字节信息(从起始地址开始写入1个字节或者多个字节信息)

 

读操作:

以读EEPROM为例,需要两步:一是写入需要读的地址,写地址需要读的EEPROM内部起始地址(1字节或多字节);二是读地址。读取长度由主机ASK信号来控制,当主机不想继续读取时,ACK回复1。

 

使用流程如下:

 

1、配置驱动

2、配置引脚

3、生成代码,使用I2C


以下为实际封装的函数文件,在app.c或者其它文件中包含再调用即可。

首先要initial(open一个客户端),然后才能读写。


delay函数

   

#ifndef _DELAY_H

#define _DELAY_H

 

#include

#include

#include

#include

#include "system_config.h"

#include "system_definitions.h"

 

void delay_ms(uint32_t milliSeconds)

{

    uint32_t frequencyHz = milliSeconds * (SYS_CLK_SystemFrequencyGet()/2000);  //while occupy 2 period

    while(frequencyHz--);

}

 

void delay_us(uint32_t microSeconds)

{

    uint32_t frequencyHz = microSeconds * (SYS_CLK_SystemFrequencyGet()/2000000);  //while occupy 2 period

    while(frequencyHz--);

}

 

#endif



I2C-Hardware.h

#ifndef _I2C_HARDWARE_H

#define _I2C_HARDWARE_H

 

 

#include "delay.h"

 

typedef struct

{

    DRV_HANDLE i2c_drvHandle;

    DRV_I2C_BUFFER_HANDLE i2c_bufferHandle;

}IIC_DATA;

IIC_DATA i2cData;

 

bool IIC_Initial(void);

 

bool IIC_WriteByte(uint8_t slaveAddr, uint8_t IIC_Byte);

 

bool IIC_WriteBytes(uint8_t slaveAddr, uint8_t *IIC_Bytes, uint8_t length);

 

bool IIC_ReadBytes(uint8_t slaveAddr, uint8_t *IIC_Bytes, uint8_t readLength);

 

#endif


i2c-Hardware.c


#include "i2c-hardware.h"

 

bool IIC_Initial(void)

{

    i2cData.i2c_drvHandle = DRV_I2C_Open(0,DRV_IO_INTENT_READWRITE);

    

    if(i2cData.i2c_drvHandle==NULL)

        return false;

    else

        return true;

}

 

 

DRV_I2C_BUFFER_EVENT IIC_Check_Transfer_Status(DRV_HANDLE drvOpenHandle, DRV_I2C_BUFFER_HANDLE drvBufferHandle)

{

    return (DRV_I2C_TransferStatusGet (drvOpenHandle, drvBufferHandle));

}

 

bool IIC_WriteByte(uint8_t slaveAddr, uint8_t IIC_Byte)

{

    uint8_t tmp[] = {IIC_Byte};

    if ( (i2cData.i2c_bufferHandle == (DRV_I2C_BUFFER_HANDLE) NULL) || 

         (IIC_Check_Transfer_Status(i2cData.i2c_drvHandle,  i2cData.i2c_bufferHandle) == DRV_I2C_BUFFER_EVENT_COMPLETE) || 

         (IIC_Check_Transfer_Status(i2cData.i2c_drvHandle, i2cData.i2c_bufferHandle) == DRV_I2C_BUFFER_EVENT_ERROR)  )

    {

        i2cData.i2c_bufferHandle = DRV_I2C_Transmit(i2cData.i2c_drvHandle,slaveAddr,tmp,1,NULL);

        delay_ms(1);

        return true;

    }

    else

        return false;

 

}

 

 

bool IIC_WriteBytes(uint8_t slaveAddr, uint8_t *IIC_Bytes, uint8_t length)

{

    if ( (i2cData.i2c_bufferHandle == (DRV_I2C_BUFFER_HANDLE) NULL) || 

         (IIC_Check_Transfer_Status(i2cData.i2c_drvHandle,  i2cData.i2c_bufferHandle) == DRV_I2C_BUFFER_EVENT_COMPLETE) || 

         (IIC_Check_Transfer_Status(i2cData.i2c_drvHandle, i2cData.i2c_bufferHandle) == DRV_I2C_BUFFER_EVENT_ERROR)  )

    {

        i2cData.i2c_bufferHandle = DRV_I2C_Transmit(i2cData.i2c_drvHandle,slaveAddr,IIC_Bytes,length,NULL);

        delay_ms(1);

        return true;

    }

    else

        return false;

 

}

 

bool IIC_ReadBytes(uint8_t slaveAddr, uint8_t *IIC_Bytes, uint8_t readLength)

{

    if ( (i2cData.i2c_bufferHandle == (DRV_I2C_BUFFER_HANDLE) NULL) || 

    (IIC_Check_Transfer_Status(i2cData.i2c_drvHandle,  i2cData.i2c_bufferHandle) == DRV_I2C_BUFFER_EVENT_COMPLETE) || 

        (IIC_Check_Transfer_Status(i2cData.i2c_drvHandle, i2cData.i2c_bufferHandle) == DRV_I2C_BUFFER_EVENT_ERROR)  )

    {

        i2cData.i2c_bufferHandle = DRV_I2C_Receive(i2cData.i2c_drvHandle,

                                                                    slaveAddr,

                                                                    IIC_Bytes, readLength, NULL);

        delay_ms(1);

        return true;

    }

    else

        return false;

}





注意:

I2C不连接Device时,会导致没收到回应而卡死在system_interrupt.c的error_instancex里面,这是到2.03版本harmony的bug,可以自行仿照下面方式添加函数来避免,注意intance与i2c通路的对应,这里是intance0-instance4对应i2c1-i2c5





void __ISR(_I2C1_MASTER_VECTOR, ipl1AUTO) _IntHandlerDrvI2CMasterInstance0(void)

{

    DRV_I2C_Tasks(sysObj.drvI2C0);

}

 

 

void __ISR(_I2C1_BUS_VECTOR, ipl1AUTO) _IntHandlerDrvI2CErrorInstance0(void)

{

    PLIB_INT_SourceFlagClear( INT_ID_0, INT_VECTOR_I2C1_BUS );    

    PLIB_I2C_Disable (I2C_ID_1);     

    PLIB_I2C_Enable (I2C_ID_1);

    SYS_ASSERT(false, "I2C Driver Instance 0 Error");

}

 

 

   

 

 

void __ISR(_I2C2_MASTER_VECTOR, ipl1AUTO) _IntHandlerDrvI2CMasterInstance1(void)

{

    DRV_I2C_Tasks(sysObj.drvI2C1);

}

 

 

void __ISR(_I2C2_BUS_VECTOR, ipl1AUTO) _IntHandlerDrvI2CErrorInstance1(void)

{

    PLIB_INT_SourceFlagClear( INT_ID_0, INT_VECTOR_I2C2_BUS );    

    PLIB_I2C_Disable (I2C_ID_2);     

    PLIB_I2C_Enable (I2C_ID_2);

    SYS_ASSERT(false, "I2C Driver Instance 1 Error");

}

 

 

 

 

 

void __ISR(_I2C3_MASTER_VECTOR, ipl1AUTO) _IntHandlerDrvI2CMasterInstance2(void)

{

    DRV_I2C_Tasks(sysObj.drvI2C2);

}

 

  

void __ISR(_I2C3_BUS_VECTOR, ipl1AUTO) _IntHandlerDrvI2CErrorInstance2(void)

{

    PLIB_INT_SourceFlagClear( INT_ID_0, INT_VECTOR_I2C3_BUS );    

    PLIB_I2C_Disable (I2C_ID_3);     

    PLIB_I2C_Enable (I2C_ID_3);

    SYS_ASSERT(false, "I2C Driver Instance 2 Error");

}

 

 

     

   

 

void __ISR(_I2C4_MASTER_VECTOR, ipl1AUTO) _IntHandlerDrvI2CMasterInstance3(void)

{

    DRV_I2C_Tasks(sysObj.drvI2C3);

}

 

 

void __ISR(_I2C4_BUS_VECTOR, ipl1AUTO) _IntHandlerDrvI2CErrorInstance3(void)

{

    PLIB_INT_SourceFlagClear( INT_ID_0, INT_VECTOR_I2C4_BUS );    

    PLIB_I2C_Disable (I2C_ID_4);     

    PLIB_I2C_Enable (I2C_ID_4);

    SYS_ASSERT(false, "I2C Driver Instance 3 Error");

}

 

     

   

 

 

void __ISR(_I2C5_MASTER_VECTOR, ipl1AUTO) _IntHandlerDrvI2CMasterInstance4(void)

{

    DRV_I2C_Tasks(sysObj.drvI2C4);

}

 

void __ISR(_I2C5_BUS_VECTOR, ipl1AUTO) _IntHandlerDrvI2CErrorInstance4(void)

{

    PLIB_INT_SourceFlagClear( INT_ID_0, INT_VECTOR_I2C5_BUS );    

    PLIB_I2C_Disable (I2C_ID_5);     

    PLIB_I2C_Enable (I2C_ID_5);

    SYS_ASSERT(false, "I2C Driver Instance 4 Error");

}

关键字:PIC32MZ  I2C通信  通讯协议 引用地址:【PIC32MZ】I2C通信

上一篇:【PIC32MZ】USB HID通信
下一篇:【dsPIC33E】内部Flash读写

推荐阅读最新更新时间:2024-11-10 18:51

电力自动化系统通讯协议转换及标准化解决方案
随着我国电力工业的发展,电力自动化技术日益推广和普及,电力自动化(电力调度自动化、厂站自动化、变电站自动化、配电网自动化)也广泛地在非电力行业推广。从事自动化工程行业的商家推出的自动化设备种类越来越繁多,在自动化系统联网中通信协议的多样化问题,越来越突出,已严重影响到自动化系统的性能、工期、成本和系统稳定。各厂家的现场调试时间和费用主要集中在自动化系统中各厂家设备的通信协议转换和联网上。造成大量人力物力浪费,大大影响工程进度。解决电力自动化系统通信协议转换的简化及通信标准化的问题意义重大。 NetEasy系统的主要内容是建立脱离于具体通讯设备的接口通讯服务平台,依据其开放的动态实时数据库,简化电力系统中异种协议的转换和系统联网过程,
[嵌入式]
PIC32MZ tutorial -- Blinky LED
  Today I finish the Blinky LED application on PIC32MZ starter kit. This application let LED1 blink with 0.5HZ frequency. The pseudo code is like LOOP: LED ON Delay 1 second LED OFF Delay 1 second   It uses Timer1 to control the delay time. So first I implement the three Timer1 functions. /**
[单片机]
rs485总线接口通讯协议定义标准以及管脚引脚介绍
RS485总线标准是工业中(考勤,监控,数据采集系统)使用非常广泛的双向、平衡传输标准接口,支持多点连接,允许创建多达32个节点的网络;最大传输距离1200m,支持1200 m时为100kb/s的高速度传输,抗干扰能力很强,布线仅有两根线很简单。 RS485通信网络接口是一种总线式的结构,上位机(以个人电脑为例)和下位机(以51系列单片机http://www.51hei.com为例)都挂在通信总线上,RS485物理层的通信协议由RS485标准和51单片机的多机通讯方式。由于RS-485是从RS-422基础上发展而来的,所以RS-485许多电气规定与RS-422相仿。如都采用平衡传输方式、都需要在传输线上接终接电阻等。RS-485可
[嵌入式]
STM32F3硬件I2C与LSM303DLHC通信
I2C(Inter-Integrated Circuit)总线是一种两线式串行总线,用于连接微控制器及其外围设备。和SPI一样,也是一种常用的串行通信方式。 STM32微控制器提供硬件I2C,对它进行相应配置就可以用来进行多个设备之间的通信。 使用步骤: 1. Enable peripheral clock 2. Enable SDA, SCL and SMBA (when used) GPIO clocks 3. Peripherals alternate function: Call GPIO_Init() function. 4. Program the Mode, Timing , Own address, Ack
[单片机]
浅谈物联网与新一代的互联网通讯协议IPv6
物联网(Internet of Things, IoT)一词首先由美国麻省理工学院Auto-ID中心主任爱斯顿(Kevin Ashton)所提出。而比尔盖兹在1995年《未来之路》一书中提及物联网的概念。下面就随网络通信小编一起来了解一下相关内容吧。 物联网的发展技术首先由人连物,具体的实作类似透过web的技术连上硬件,如冰箱空调等等。随着半导体制程以及感测技术的进步。传感器以及运算单元可以微缩在一个便宜又微小的装置上,这导致物联网的概念慢慢地被实作在各种的领域上。 浅谈物联网与新一代的互联网通讯协议IPv6 物联网的基本网络链接方式有人连物以及物连物。人连物可以泛指一般可连网的智能系统,如智能家电、网络摄影机等等。基本
[网络通信]
STM32F10x_硬件I2C主从通信(轮询发送,中断接收)
Ⅰ、写在前面 关注我分享文章的朋友应该知道我在前面讲述过(软件、硬件)I2C主机控制从机EEPROM的例子。在I2C通信主机控制程序是比较常见的一种,可以说在实际项目中,很多应用都会使用到I2C通信。但在实际项目中作为I2C从机的应用相对要少的多,本文主要讲述关于【STM32F10x_硬件I2C主从通信】中STM32作为从机的例子。 在学习本问内容之前,如果对I2C协议还不太了解的朋友请先去了解一下I2C协议,或看我之前关于I2C通信的文章(我微信公众号和博客都有)。 关于STM32硬件I2C作为从机的文章网上很少(我在写本文之前也在百度、谷歌等网站上搜索了解过),我猜测大概的原因主要是两点:1.使用该功能的人比较少; 2.说
[单片机]
PIC32MZ tutorial -- External Interrupt
  In my older blog PIC32MZ tutorial -- Key Debounce , I shows how to acheive key debounce with port polling. At this moment, I write an application which uses External Interrupt. Therefore, only generates interrupt and starts debounce when the falling or raising edge happens, so it will eliminate the MCU load of port
[单片机]
三菱变频器MODBUS通讯协议的RTU方式和ASCII方式传送
Modbus是Modicon公司为其PLC与主机之间的通讯而发明的串行通讯协议。其物理层采用RS232、485等异步串行标准。由于其开放性而被大量的PLC及RTU厂家采用。Modbus通讯方式采用主从方式的查询-相应机制,只有主站发出查询时,从站才能给出响应,从站不能主动发送数据。主站可以向某一个从站发出查询,也可以向所有从站广播信息。从站只响应单独发给它的查询,而不响应广播消息。MODBUS通讯协议有两种传送方式:RTU方式和ASCII方式。三菱700系列变频器能够从RS-485端子使用ModbusRTU通讯协议,进行通讯运行和参数设定。 对象: 1. 三菱PLC:FX2N+FX2N-485-BD 2. 三菱变频器:F700
[嵌入式]
三菱变频器MODBUS<font color='red'>通讯协议</font>的RTU方式和ASCII方式传送
热门资源推荐
热门放大器推荐
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
  • 学习ARM开发(16)
    ARM有很多东西要学习,那么中断,就肯定是需要学习的东西。自从CPU引入中断以来,才真正地进入多任务系统工作,并且大大提高了工作效率。采 ...
  • 学习ARM开发(17)
    因为嵌入式系统里全部要使用中断的,那么我的S3C44B0怎么样中断流程呢?那我就需要了解整个流程了。要深入了解,最好的方法,就是去写程序 ...
  • 学习ARM开发(18)
    上一次已经了解ARM的中断处理过程,并且可以设置中断函数,那么它这样就可以工作了吗?答案是否定的。因为S3C44B0还有好几个寄存器是控制中 ...
  • 嵌入式系统调试仿真工具
    嵌入式硬件系统设计出来后就要进行调试,不管是硬件调试还是软件调试或者程序固化,都需要用到调试仿真工具。 随着处理器新品种、新 ...
  • 最近困扰在心中的一个小疑问终于解惑了~~
    最近在驱动方面一直在概念上不能很好的理解 有时候结合别人写的一点usb的例子能有点感觉,但是因为arm体系里面没有像单片机那样直接讲解引脚 ...
  • 学习ARM开发(1)
  • 学习ARM开发(2)
  • 学习ARM开发(4)
  • 学习ARM开发(6)
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved