历史上的今天
返回首页

历史上的今天

今天是:2025年02月12日(星期三)

正在发生

2019年02月12日 | 【stm32f407】I2C实验

2019-02-12 来源:eefocus

一.I2C介绍


IIC(Inter-IntegratedCircuit)总线是一种由PHILIPS公司开发的两线式串行总线,用于连接微控制器及其外围设备。它是由数据线SDA和时钟SCL构成的串行总线,可发送和接收数据。在CPU与被控IC之间、IC与IC之间进行双向传送,高速IIC总线一般可达400kbps以上。如图:



I2C协议一共有6种协议信号


①        空闲状态


②        开始信号


③        停止信号


④        应答信号


⑤        数据的有效性


⑥        数据传输


1) 空闲信号


I2C总线总线的SDA和SCL两条信号线同时处于高电平时,规定为总线的空闲状态。此时各个器件的输出级场效应管均处在截止状态,即释放总线,由两条信号线各自的上拉电阻把电平拉高。如图红框内:



2) 开始信号


当SCL为高期间,SDA由高到低的跳变;启动信号是一种电平跳变时序信号,而不是一个电平信号。如图:



3) 停止信号


当SCL为高期间,SDA由低到高的跳变;停止信号也是一种电平跳变时序信号,而不是一个电平信号。如图:



4) 应答信号


5) 发送器每发送一个字节,就在时钟脉冲9期间释放数据线,由接收器反馈一个应答信号。应答信号为低电平时,规定为有效应答位(ACK简称应答位),表示接收器已经成功地接收了该字节;应答信号为高电平时,规定为非应答位(NACK),一般表示接收器接收该字节没有成功。 


对于反馈有效应答位ACK的要求是,接收器在第9个时钟脉冲之前的低电平期间将SDA线拉低,并且确保在该时钟的高电平期间为稳定的低电平。如果接收器是主控器,则在它收到最后一个字节后,发送一个NACK信号,以通知被控发送器结束数据发送,并释放SDA线,以便主控接收器发送一个停止信号P。



6) 数据的有效性


I2C总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。


即:数据在SCL的上升沿到来之前就需准备好。并在在下降沿到来之前必须稳定。



7) 数据传输

在I2C总线上传送的每一位数据都有一个时钟脉冲相对应(或同步控制),即在SCL串行时钟的配合下,在SDA上逐位地串行传送每一位数据。数据位的传输是边沿触发


二.软件模拟I2C

以下是参考原子模拟I2C的代码,因为ST公司可能为了规避飞利浦I2C的专利为题,把I2C设计的很复杂,并且不稳定


模拟I2C.h


//IO方向设置

#defineSDA_IN() {GPIOB->MODER&=~(3<

#defineSDA_OUT() {GPIOB->MODER&=~(3<

//IO操作函数 

#defineIIC_SCL    PBout(8) //SCL

#defineIIC_SDA    PBout(9) //SDA       

#defineREAD_SDA   PBin(9)  //输入SDA 

 

//IIC所有操作函数

voidIIC_Init(void);                //初始化IIC的IO口                                     

voidIIC_Start(void);                                     //发送IIC开始信号

voidIIC_Stop(void);                          //发送IIC停止信号

voidIIC_Send_Byte(u8 txd);                       //IIC发送一个字节

u8IIC_Read_Byte(unsigned char ack);//IIC读取一个字节

u8IIC_Wait_Ack(void);                              //IIC等待ACK信号

voidIIC_Ack(void);                                        //IIC发送ACK信号

voidIIC_NAck(void);                                     //IIC不发送ACK信号

 

voidIIC_Write_One_Byte(u8 daddr,u8 addr,u8 data);

u8 IIC_Read_One_Byte(u8 daddr,u8 addr);   

模拟I2C.c


#include"myiic.h"

#include"delay.h"

      

//初始化IIC

voidIIC_Init(void)

{                           

  GPIO_InitTypeDef  GPIO_InitStructure;

 

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能GPIOB时钟

 

  //GPIOB8,B9初始化设置

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 |GPIO_Pin_9;

  GPIO_InitStructure.GPIO_Mode =GPIO_Mode_OUT;//普通输出模式

  GPIO_InitStructure.GPIO_OType =GPIO_OType_PP;//推挽输出

  GPIO_InitStructure.GPIO_Speed =GPIO_Speed_100MHz;//100MHz

  GPIO_InitStructure.GPIO_PuPd =GPIO_PuPd_UP;//上拉

  GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化

         IIC_SCL=1;

         IIC_SDA=1;

}

//产生IIC起始信号

voidIIC_Start(void)

{

         SDA_OUT();     //sda线输出

         IIC_SDA=1;                

         IIC_SCL=1;

         delay_us(4);

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

         delay_us(4);

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

}          

//产生IIC停止信号

voidIIC_Stop(void)

{

         SDA_OUT();//sda线输出

         IIC_SCL=0;

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

        delay_us(4);

         IIC_SCL=1; 

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

         delay_us(4);                                                                  

}

//等待应答信号到来

//返回值:1,接收应答失败

//        0,接收应答成功

u8IIC_Wait_Ack(void)

{

         u8 ucErrTime=0;

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

         IIC_SDA=1;delay_us(1);     

         IIC_SCL=1;delay_us(1);   

         while(READ_SDA)

         {

                   ucErrTime++;

                   if(ucErrTime>250)

                   {

                            IIC_Stop();

                            return 1;

                   }

         }

         IIC_SCL=0;//时钟输出0            

         return 0;  

//产生ACK应答

voidIIC_Ack(void)

{

         IIC_SCL=0;

         SDA_OUT();

         IIC_SDA=0;

         delay_us(2);

         IIC_SCL=1;

         delay_us(2);

         IIC_SCL=0;

}

//不产生ACK应答             

voidIIC_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,无应答                        

voidIIC_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   

u8IIC_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;

}



推荐阅读

史海拾趣

Hayashi Denko Co Ltd公司的发展小趣事

HARTING公司自1945年成立以来,在电子行业里经历了多个重要的发展阶段,以下是五个与HARTING公司发展相关的事实性故事:

1. 创立与初期发展

创立背景:1945年,Wilhelm和Marie Harting在德国创立了HARTING公司,起初以生产日常所需的设备为主,如节能灯泡、电炉等。随着德国工业的发展,他们逐渐意识到新兴行业对技术产品的需求,于是将公司转向开发和生产电气连接器及连接系统。这一转变标志着HARTING正式进入电子行业,并为其后续发展奠定了基础。

初期产品:早期,HARTING开发的Han®连接器在市场上取得了巨大成功,该连接器以其坚固耐用、易于操作的特点,迅速成为行业内的标准产品,为HARTING在电子行业树立了良好的口碑。

2. 技术创新与全球化拓展

技术创新:HARTING始终致力于技术创新,不断推出新产品以满足市场需求。例如,他们研发的矩形连接器在1965年问世后,迅速替代了传统的圆形军用规格连接器,成为工业连接的新标准。此外,HARTING还在数据通信、网络技术、芯片卡、多媒体技术等领域取得了显著成就。

全球化拓展:随着业务的不断发展,HARTING开始在全球范围内设立子公司和生产工厂。目前,HARTING已在40多个国家设立了附属公司,生产工厂遍布德国、英国、瑞士、美国、罗马尼亚及中国等7个国家。这种全球化布局不仅提升了HARTING的市场占有率,还使其能够更好地服务全球客户。

3. 进入中国市场

中国市场布局:1988年,HARTING正式进入中国市场,并在珠海投资兴建了生产基地。这一举措标志着HARTING对中国市场的重视和承诺。随着在中国市场的不断深耕,HARTING已在中国设立了多个销售和服务中心,覆盖了包括香港、珠海、深圳、广州在内的多个城市。

本地化生产与服务:为了更好地服务中国客户,HARTING在中国实现了本地化生产和服务。他们不仅提供高质量的产品,还为客户提供设计咨询、系统集成、定制化解决方案等一系列专业服务。这些举措使HARTING在中国市场赢得了广泛认可。

4. 工业4.0与数字化转型

工业4.0引领者:面对工业4.0和数字化转型的浪潮,HARTING积极投入研发和创新,推出了多款面向未来的产品和技术。例如,HARTING MICA®是一款将工业4.0功能引入现有机器和设备的工业边缘网关,它能够帮助企业实现生产过程的智能化和自动化。

数字化转型服务:除了产品创新外,HARTING还为客户提供数字化转型的解决方案和服务。他们利用自身在连接技术领域的优势,帮助企业构建高效、可靠的数字化生产体系,提升生产效率和产品质量。

5. 定制化解决方案与行业应用

定制化解决方案:HARTING深知不同行业对连接技术的不同需求,因此他们始终致力于为客户提供定制化的解决方案。无论是电力、通信、自动化还是航空、汽车等行业,HARTING都能根据客户的具体需求,提供最适合的连接技术和产品。

行业应用案例:在多个行业领域,HARTING的产品和技术都得到了广泛应用。例如,在汽车行业,HARTING的3D-MID技术帮助客户将复杂的电子设备集成到汽车中,提高了汽车的安全性和舒适性;在轨道交通行业,HARTING的连接器产品被广泛应用于信号传输和电源分配等领域,确保了轨道交通的安全运行。

通过以上五个故事,我们可以看出HARTING公司在电子行业里的发展历程和成就。从创立初期的艰难探索到如今的全球化布局和技术创新,HARTING始终保持着对技术的热爱和追求,为客户提供高质量的产品和服务。

AMOTECH(阿莫泰克)公司的发展小趣事

在多年的发展中,AMOTECH始终坚持以技术创新为核心竞争力。除了压敏电阻技术的突破外,公司还在多个领域取得了显著成果。例如,在LED照明和传感器领域,AMOTECH通过不断研发和创新,成功在韩国安山建立了第四工厂,进一步提升了公司的技术实力和产能规模。这些技术的不断突破和创新,使得AMOTECH在电子行业中始终保持领先地位。

Boyd Corporation公司的发展小趣事

为了进一步扩大市场份额和提升技术实力,Boyd Corporation进行了一系列战略收购。其中,收购Aavid Thermalloy是其中的重要一环。Aavid在热管理领域拥有卓越的技术和工程团队,通过合并,Boyd Corporation成功将Aavid的技术和团队纳入旗下,进一步增强了其在热管理领域的市场地位。

Beta Dyne Inc公司的发展小趣事

随着社会对环保问题的关注度不断提高,Beta Dyne也积极响应国家号召,将环保理念融入公司的经营发展中。公司采用环保材料和生产工艺,减少生产过程中的污染排放。同时,Beta Dyne还积极参与社会公益事业,为当地社区的发展做出了积极贡献。

这些故事虽然是以虚构的形式呈现,但它们反映了电子行业中许多公司可能经历的发展阶段和挑战。每个公司都有其独特的发展历程和故事,Beta Dyne Inc也不例外。如果您对该公司的具体发展情况感兴趣,建议查阅相关资料或联系该公司以获取更准确的信息。

High Voltage Power Solutions Inc公司的发展小趣事

随着国内市场的饱和,Beta Dyne开始将目光投向海外市场。公司制定了一套完整的国际化战略,包括在海外设立研发中心、建立销售渠道以及与当地企业建立合作关系等。通过不断的努力,Beta Dyne的产品逐渐打入国际市场,公司的知名度和影响力也得到了显著提升。

Force Technologies Ltd公司的发展小趣事

背景:在电子行业竞争日益激烈的背景下,Force Technologies Ltd意识到通过并购整合可以迅速扩大规模、提升竞争力。

发展:公司精心挑选了几家在特定领域具有优势的企业作为并购目标,并成功完成了多起并购案。这些并购不仅为公司带来了先进的技术和人才资源,还极大地丰富了产品线和市场布局。通过并购整合,Force Technologies Ltd在多个细分领域均占据了领先地位。

问答坊 | AI 解惑

单脉冲序列对双激式开关电源变压器铁心的磁化开关电源原理与设计(连载53)

2-1-1-4.脉冲序列对双激式开关电源变压器铁心的磁化 双激式变压器与单激式变压器的区别主要是两者输入电压的参数不一样。单激式变压器输入的电压是单极性直流脉冲,而双激式变压器输入的电压是双极性交流脉冲。为了简单起见,我们把双激式变压器 ...…

查看全部问答>

数字视频监控硬件设计经验谈

数字视频监控系统主要包括DVR、DVS、IP-Camera等,涉及到嵌入式系统技术、视频编解码技术、音频编解码技术、联网及域名处理技术等。硬件对于系统而言,相当于建筑的地基,地基牢,建筑才可靠,才能够经历风风雨雨的考验。     概述 & ...…

查看全部问答>

LED结构、发光原理、光源特点及应用

replyreload += \',\' + 384127;Timson,如果您要查看本帖隐藏内容请回复…

查看全部问答>

IOCTL CODE DeviceIoControl

我做摄像头的数据采集,用CreateFile打开设备,然后调用DeviceIoControl函数,第二个参数需要的是控制CODE,这个CODE需要驱动来提供?不是标准调用吧。如果驱动没有提供读数据的控制CODE,那我是不是就没有办法用DeviceIoControl得到数据了?…

查看全部问答>

vhdl, 怎么实现让输出维持一段时间后撤销

vhdl, 怎么实现让输出维持一段时间后撤销~~~~~ 请大侠,帮忙~…

查看全部问答>

PCI 接口 IO读写 驱动

driverStudio 生成的驱动程序 实现 IO读写功能 驱动程序代码中两个操作如下: NTSTATUS RW6070Device::RW6070_IOCTL_800_Handler(KIrp I) {         NTSTATUS status = STATUS_SUCCESS;         //t …

查看全部问答>

stm32sd卡咨询

                                 各位大侠请问,stm32有没有通过spi读取sd卡的例程,或者哪位大哥自己做过这一块可以指点一下小弟,我刚开始做这一 ...…

查看全部问答>

ST中国微控制器中文下载怎么都挂了?

                                 RT…

查看全部问答>

RT-Thread开源实时操作系统/STM32F103VB0.3.0b3版本

这个版本更新有些多,RT-Thread/STM32F103VB 0.3.0 beta3更改记录:- 内核,添加IAR EWARM 5.x工程,在内核定义中做相应的平台定义;- 添加文件系统组件DFS,DFS是一套虚拟文件系统(类似Linux的VFS,但几乎不占 ...…

查看全部问答>

有关2812的资料其寄存器都没有地址,谁那有?

有关2812的资料其寄存器都没有地址,所见的都是C语言的头文件,用了结构体和共用体,找不出起物理地址了,想用一段汇编,找不到外设和寄存器的地址,没法编那.谁有这方面的资料?或给指点一下…

查看全部问答>