概要

IIC(IIC,inter-Integrated circuit),两线式串行总线,用于MCU和外设间的通信。 
IIC只需两根线:数据线SDA和时钟线SCL。以半双工方式实现MCU和外设之间数据传输,速度可达400kbps。

多主机I2C总线结构

注意SDA和SCL两根总线需要上拉,使总线处于空闲状态。

这里写图片描述

IIC协议

空闲状态

协议规定,SDA和SCL同时为高电平时,总线处于空闲状态。上拉电阻保证电平处于高电平。

起始信号和停止信号

起始信号:SCL为高电平时,SDA电平发生高到低的跳变 
停止信号:SCL为高电平时,SDA电平发生低到高的跳变

这里写图片描述

应答信号

发送器每发送完一个字节(8个脉冲),在第9个脉冲间释放总线,接收器返回一个ACK信号,协议规定,低电平为有效应答,高电平为无效应答。

这里写图片描述

数据有效性

协议对有效数据进行了规定:即时钟信号为高电平期间,数据必须保持稳定,时钟信号低电平期间,数据线上的电平才允许变化。也就是说,数据在时钟信号到来前必须准备好,并保持到时钟信号的下降沿之后。

这里写图片描述

数据传输

I2C为同步传输,时钟控制数据位的传输,边沿触发。

驱动程序

直接引用实验中的代码。测试没问题。

起始信号


//产生IIC起始信号

void IIC_Start(void)

{

    SDA_OUT();     //sda线输出

    IIC_SDA=1;        

    IIC_SCL=1;

    delay_us(4);

    IIC_SDA=0;//START:when CLK is high,DATA change form high to low 

    delay_us(4);

    IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 

}   

停止信号


//产生IIC停止信号

void IIC_Stop(void)

{

    SDA_OUT();//sda线输出

    IIC_SCL=0;

    IIC_SDA=0;//STOP:when CLK is high DATA change form low to high

    delay_us(4);

    IIC_SCL=1; 

    IIC_SDA=1;//发送I2C总线结束信号

    delay_us(4);                                

}

有效应答


//产生ACK应答

void IIC_Ack(void)

{

    IIC_SCL=0;

    SDA_OUT();

    IIC_SDA=0;

    delay_us(2);

    IIC_SCL=1;

    delay_us(2);

    IIC_SCL=0;

}

无效应答


//不产生ACK应答          

void IIC_NAck(void)

{

    IIC_SCL=0;

    SDA_OUT();

    IIC_SDA=1;

    delay_us(2);

    IIC_SCL=1;

    delay_us(2);

    IIC_SCL=0;

}   

发送单字节


//IIC发送一个字节

//返回从机有无应答

//1,有应答

//0,无应答           

void IIC_Send_Byte(u8 txd)

{                        

    u8 t;   

    SDA_OUT();      

    IIC_SCL=0;//拉低时钟开始数据传输

    for(t=0;t<8;t++)

    {              

        IIC_SDA=(txd&0x80)>>7;

        txd<<=1;      

        delay_us(2);   //对TEA5767这三个延时都是必须的

        IIC_SCL=1;

        delay_us(2); 

        IIC_SCL=0;  

        delay_us(2);

    }    

接收单字节


//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   

u8 IIC_Read_Byte(unsigned char ack)

{

    unsigned char i,receive=0;

    SDA_IN();//SDA设置为输入

    for(i=0;i<8;i++ )

    {

        IIC_SCL=0; 

        delay_us(2);

        IIC_SCL=1;

        receive<<=1;

        if(READ_SDA)receive++;   

        delay_us(1); 

    }                    

    if (!ack)

        IIC_NAck();//发送nACK

    else

        IIC_Ack(); //发送ACK   

    return receive;

}

EEPROM

24C02为IIC接口,容量为256字节。

封装如下图:

这里写图片描述

管脚定义:

这里写图片描述

设备地址的高四位固定,中间为地址线定义的地址,最后一位为读写位。 
由于A0,A1,A2设置为0,所以 
读的时候:Device Address = 0xA1; 
写的时候:Device Address = 0xA0;

这里写图片描述

24C02字节写时序


起始信号

写设备地址,Device Address = 0xA0;

等待应答

确定写入的EEPROM地址即WORD ADDRESS

等待应答

向SDA数据线上写入数据DATA

等待应答

停止信号

这里写图片描述


//在AT24CXX指定地址写入一个数据

//WriteAddr  :写入数据的目的地址    

//DataToWrite:要写入的数据

void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite)

{                                                                                            

    IIC_Start();  

    if(EE_TYPE>AT24C16)

    {

        IIC_Send_Byte(0XA0);        //发送写命令

        IIC_Wait_Ack();

        IIC_Send_Byte(WriteAddr>>8);//发送高地址   

    }else IIC_Send_Byte(0XA0+((WriteAddr/256)<<1));   //发送器件地址0XA0,写数据   

    IIC_Wait_Ack();    

    IIC_Send_Byte(WriteAddr%256);   //发送低地址

    IIC_Wait_Ack();                                                        

    IIC_Send_Byte(DataToWrite);     //发送字节                             

    IIC_Wait_Ack();                    

    IIC_Stop();//产生一个停止条件 

    delay_ms(10);    

}

24C02字节读时序


起始信号

写设备地址,Device Address = 0xA0;

等待应答

确定写入的EEPROM地址即WORD ADDRESS

等待应答

起始信号

读设备地址,Device Address = 0xA1;

等待应答

读SDA上数据

等待应答

停止信号

这里写图片描述

//在AT24CXX指定地址读出一个数据

//ReadAddr:开始读数的地址  

//返回值  :读到的数据

u8 AT24CXX_ReadOneByte(u16 ReadAddr)

{                 

    u8 temp=0;                                                                               

    IIC_Start();  

    if(EE_TYPE>AT24C16)

    {

        IIC_Send_Byte(0XA0);       //发送写命令

        IIC_Wait_Ack();

        IIC_Send_Byte(ReadAddr>>8);//发送高地址      

    }else IIC_Send_Byte(0XA0+((ReadAddr/256)<<1));   //发送器件地址0XA0,写数据      

    IIC_Wait_Ack(); 

    IIC_Send_Byte(ReadAddr%256);   //发送低地址

    IIC_Wait_Ack();     

    IIC_Start();           

    IIC_Send_Byte(0XA1);           //进入接收模式            

    IIC_Wait_Ack();  

    temp=IIC_Read_Byte(0);         

    IIC_Stop();//产生一个停止条件       

    return temp;

}

参考


STM32F3与 F4 系列 Cortex M4 内核编程手册 

STM32F4xxx中文参考手册 

STM32F4xxx英文参考手册 

STM32F4 开发指南(寄存器版)


关键字:STM32  IIC应用 引用地址:STM32的IIC应用详解1

上一篇:STM32的IIC应用详解2
下一篇:STM32F030控制LED

推荐阅读

  在未来20 - 30年中,自动驾驶汽车(AV)将改变我们的驾驶习惯、运输行业并更广泛地影响社会。 我们不仅能够将汽车召唤到我们的家门口并在使用后将其送走,自动驾驶汽车还将挑战个人拥有汽车的想法,并对环境和拥堵产生积极影响。市场调研公司ABI Research预测:到2030年,道路上四分之一的汽车将会是自动驾驶汽车。  行业专家已经为自动驾驶的发...
9月10日,上海联络浙江的10千伏青浦—嘉善互联工程建成投运。作为促进长三角地区跨区域电力融合、实现长三角能源可靠保障的重要举措,该线路的投运将有效提升青浦、嘉善交界区域电网末端供电能力。 据了解,目前各省级电网主要通过500千伏及以上输电网络联络,但省间配电网,特别是10千伏及以下配电网之间并无互联保障机制,而省际边界往往是电网末端...
据外媒报道,加州大学圣地亚哥分校(UC San Diego)的科学家发现一种新负极材料,可以使锂离子电池在数分钟内安全充电,并且可以承受数千次的充放电循环。这种新型负极名为无序岩盐,由地球上储量丰富的锂、钒和氧原子组成,其排列方式与厨房里用的普通食盐相似,但是更加随机。在需要高能量密度和高功率的商业应用领域,如电动汽车、真空吸尘器或电钻,...
智东西(公众号:zhidxcom)作者 | 健恩编辑 | 云鹏智东西9月11日报道,昨天,世界机器人大会再次在北京亦庄拉开帷幕,智东西记者一大早便跨越整个北京城来到这里打探这场大会的最新消息。世界机器人大会自2015年开始举办,迄今为止已成功举办过5次。它不仅是国内一年一度规模最大的机器人产业顶级展会,也是国内机器人产业风向的集中展示。智东西了解...

史海拾趣

问答坊 | AI 解惑

三角波参数测试仪——09年四川

本帖最后由 paulhyde 于 2014-9-15 04:14 编辑 [local]2[/local]“TI”杯时我们三人的作品。 三角波参数测试仪。  …

查看全部问答∨

关于可视对讲,一直疑惑的问题

做了这么多年的门禁和可视对讲,做过了好多的产品,现在市场上的产品真的是五花八门, 国内到底谁家, 才是工程商的不二选择......…

查看全部问答∨

cycloneIII_3c25的原装开发板到手了-发资料

整快板子上的外设不是很多,但是存储器资源丰富。并预留了一个HSMC接口,可以用来扩展。有三张光盘,一张是介绍开发板的使用,例程,入门指导,另两张是Quartus2的软件,常用库,NIOS2开发资料。先简单介绍到这里,把开发板的资料传上来共享(全部 ...…

查看全部问答∨

DSP2407在转速测定中的应用

DSP2407在转速测定中的应用…

查看全部问答∨

空调板上的数码灯的问题

显示温度的时候,数码灯上未点亮的部分有闪烁现象,什么原因…

查看全部问答∨

【设计工具】Xilinx SRAM 型FPGA抗辐射设计技术研究

针对XILINX SRAM型FPGA在空间应用中的可行性,分析了Xilinx SRAM型 FPGA的结构,以及空间辐射效应对这种结构FPGA的影响,指出SRAM型的FPGA随着工艺水平的提高、器件规模的增大和核电压的降低,抗总剂量效应不断提高,抵抗单粒子效应,尤其是单粒子 ...…

查看全部问答∨

LAunchPad的2线控制LCD12864

很给力哦,解决LaunchPad的 IO口不够用,很有价值~~~   我用的开发板是g2553~~~ [ 本帖最后由 574937246 于 2012-7-20 14:46 编辑 ]…

查看全部问答∨

问锁定放大电路中的一个问题

请教坛中大侠:  锁定放大中的移相电路部分,其移相作用是调整好就可以了,还是要以后经常性的调整?换句话说:移相部分的可调电阻最后能不能换成固定的?…

查看全部问答∨

ZIGBEE CC2530协议栈跑呼吸灯问题。

在协议栈中我操作定时器 1(T1)产生PWM波,避免与定时器3-4系统定时器冲突。在裸机中我用定时器1跑通PWM了的。可是我加载到协议栈貌似遇到很多问题,希望大家跟我给点建议。上图 这个是定时器TI的驱动程序。 这是电脑给协调器串口写数据并通 ...…

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

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

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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