历史上的今天
返回首页

历史上的今天

今天是:2024年09月11日(星期三)

正在发生

2018年09月11日 | STM32的IIC应用详解1

2018-09-11 来源:eefocus

概要

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 开发指南(寄存器版)


推荐阅读

史海拾趣

EFC [Electronic Film Capacitors, Inc.]公司的发展小趣事

EFC公司始终坚持“品质至上”的原则。他们严格控制原材料采购,确保每一批材料都符合最高标准。在生产过程中,EFC采用先进的生产设备和工艺,确保产品的稳定性和可靠性。此外,公司还建立了完善的质量检测体系,对每一个出厂的产品都进行严格的检测。正是这种对品质的执着追求,让EFC的产品在市场上赢得了良好的口碑。

General Industrial Controls ( GIC )公司的发展小趣事
根据实际需求调整LM2596的工作模式(如低功耗模式或正常模式),以降低功耗和提高效率。
Changzhou Galaxy Century Microelectronics Co.,Ltd公司的发展小趣事

银河微电在追求经济效益的同时,也积极履行社会责任。公司注重环保和可持续发展,在生产过程中严格控制污染排放,推广绿色生产技术。此外,银河微电还积极参与社会公益事业,捐款捐物支持灾区重建、教育扶贫等项目。这些举措不仅提升了公司的社会形象,也为公司的长远发展积累了良好的口碑。

这五个故事只是银河微电发展历程中的一部分缩影,但它们充分展示了公司在技术创新、市场拓展、资本运作、战略合作和社会责任等方面的努力和成就。正是这些因素的共同作用,使得银河微电在电子行业中脱颖而出,成为一家备受瞩目的高新技术企业。

BOCA公司的发展小趣事

BOCA公司最初是一家小型电子元件制造商,面临着激烈的市场竞争。然而,公司始终坚持研发创新,投入大量资源于新技术的研究。终于,在一次偶然的实验中,BOCA的研发团队成功开发出了一种新型的半导体材料,这种材料在性能上远超当时的行业标准。这一技术突破让BOCA迅速在行业中崭露头角,订单量激增,公司规模迅速扩大。

EICHHOFF公司的发展小趣事

随着全球化趋势的加强,EICHHOFF公司意识到必须加快国际化步伐以拓展更广阔的市场。XX年代初,公司开始在欧洲其他国家设立销售和服务机构,并逐步将业务拓展到亚洲和北美地区。为了更好地适应不同地区的市场需求和文化差异,EICHHOFF公司积极招聘本地人才,并加强与当地企业和机构的合作。

通过实施国际化战略,EICHHOFF公司的品牌影响力得到了显著提升,市场份额也不断扩大。同时,公司也积累了丰富的国际运营经验和管理经验,为未来的发展奠定了坚实基础。

Foxconn_Optical_Interconnect_Technologies__Inc.公司的发展小趣事

EICHHOFF公司成立于XX世纪XX年代,当时由创始人XXX在德国的一个小镇上开设了一个小型的电子元件加工厂。由于XXX对电子技术的热爱和对市场需求的敏锐洞察,他专注于生产高质量的连接器和其他电子组件。在初创阶段,EICHHOFF的产品主要供应给当地的电子制造商和维修店。随着口碑的逐渐传播和产品质量的不断提升,公司开始接到来自更广泛地区的订单。

为了应对不断增长的市场需求,EICHHOFF公司逐步扩大了生产规模,并引入了先进的生产设备和技术。同时,公司也注重人才培养和团队建设,吸引了一批有才华的工程师和技术人员加入。这些努力使得EICHHOFF在电子行业中逐渐崭露头角。

问答坊 | AI 解惑

芳香气体透过性检测方法

芳香气体广泛存在于食品、药品、化妆品和各种日化产品中,例如风味小吃、白酒、香料、中药材、膏药、香水、香皂、洗发水等等。与无机气体和水蒸气不同的是,多数芳香气体是由产品自身散发出来的,而且更是这些产品的重要品质和主要功能(有些也是唯 ...…

查看全部问答>

增强型80C51单片机速成与实战

本帖最后由 paulhyde 于 2014-9-15 08:57 编辑 不错的书0哦  …

查看全部问答>

学了DSP一段时间,感觉嵌入式软件开发好像全是软件的问题呢。

      可能是因为我用的学校提供的现成的试验箱吧,功能比较齐全,北京合众达的DM643的箱子。        从学习DSP开始,都觉得在跑例程、改写、编写程序中,困难最多的都是软件方面的问题,像是基本语法、 ...…

查看全部问答>

装了CE60 R3后怎么编译不了系统,老是停在某个地方,等多久都不动的。不会是CE60 R3的版本问题吧?!

装了CE60 R3后怎么编译不了系统,老是停在某个地方,等多久都不动的。不会是CE60 R3的版本问题吧?!…

查看全部问答>

VS2008与WINCE 5.0问题 请高手不吝赐教

小弟做WM很久。最近公司要做一WINCE 5.0的开发板的程序。废话不多说,问题如下: 用EVC+WINCE 4.2调试速度太慢,于是想换VS2008+WINCE 5.0(因开发版是5.0,所以不能用WINCE6.0) 我用PB 5.0弄好一个WINCE 5.0的模拟器,也生成了相关的SDK。在EVC4 ...…

查看全部问答>

为什么bb5系列无法解网络

为什么NokiaBB5系列无法解网络? 比如说绑定美国cingular的Nokia E62 我做了很多搜索,没找到可以解锁的办法。(除了向cingular索取解锁密码) 在下学浅,觉得电话跟电脑差不多,如果靠密码能解锁的话,一定是软件上的限制,重写成出厂设置应该 ...…

查看全部问答>

IIC学习经历以及CAT1024/25

  对于IIC来说只有两条线来控制数据的传输,SDA和SCL。对于IIC协议的学习,要掌握四种模式,主发送,主接收,从发送和从接收。在对设备的读写操作信号是在发送从地址时将其一起发送出去,比如主发送模式,它要从从设备中读取数据,那么在主设 ...…

查看全部问答>

接插件选型?

        1、每一块电路板上,都会用到接插件,请教下接插件都是怎么选型?谁能上传点接插件的资料。         2、满足以下要求的接插件,有用过得给推荐下:    ...…

查看全部问答>

f28335 eCAN通讯

我用的是中国原创力的一块f28335的开发板,问什么eCAN模块的canh和canl在隐形电平时怎么只有2v,can模块不是标准的2.5v吗?…

查看全部问答>