历史上的今天
返回首页

历史上的今天

今天是:2025年08月09日(星期六)

2019年08月09日 | STM32(五)IIC通信原理及IO口软件模拟编程

2019-08-09 来源:eefocus

一、IIC概述

        I2C(IIC,Inter-Integrated Circuit),两线式串行总线,由PHILIPS公司开发用于连接微控制器及其外围设备。

       它是由数据线SDA和时钟SCL构成的串行总线,可发送和接收数据。在CPU与被控IC之间、IC与IC之间进行双向传送,高速IIC总线一般可达400kbps以上。

       IIC是半双工通信方式。

       多主机I2C总线系统结构:

二、I2C协议

1、空闲状态

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


2、开始信号

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


3、停止信号

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


4、应答信号

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


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


5、数据的有效性

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


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



6、数据传输

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

        ALIENTEK MiniSTM32 开发板板载的 EEPROM 芯片型号为 24C02。该芯片的总容量是 256个字节,该芯片通过 IIC 总线与外部连接。

       目前大部分 MCU 都带有 IIC 总线接口,STM32 也不例外。但是这里我们不使用 STM32的硬件 IIC 来读写 24C02,而是通过软件模拟。STM32 的硬件 IIC 非常复杂,更重要的是不稳定,故不推荐使用。


     本章实验功能简介:开机的时候先检测24C02是否存在,然后在主循环里面检测两个按键,其中 1 个按键(WK_UP)用来执行写入 24C02 的操作,另外一个按键(KEY0)用来执行读出操作,在 TFTLCD 模块上显示相关信息。同时用 DS0 提示程序正在运行。


         

    24C02 的 SCL 和 SDA 分别连在 STM32 的 PC12 和 PC11 上。


三、代码驱动

//打开 myiic.c 文件,代码如下:

#include "myiic.h"

#include "delay.h"

//初始化IIC

void IIC_Init(void)

{      

GPIO_InitTypeDef GPIO_InitStructure;

//RCC->APB2ENR|=1<<4;//先使能外设IO PORTC时钟 

RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC, ENABLE );

   

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_11;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //推挽输出

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOC, &GPIO_InitStructure);

 

IIC_SCL=1;

IIC_SDA=1;

 

}

//产生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);    

}

//等待应答信号到来

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

//        0,接收应答成功

u8 IIC_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应答

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;

}

//打开 myiic.h 文件,代码如下:

//该部分为 IIC 驱动代码:

//实现包括 IIC 的初始化(IO 口)、IIC 开始、IIC 结束、ACK、IIC读写等功能

//在其他函数里面,只需要调用相关的 IIC 函数就可以和外部 IIC 器件通信了

//头文件 myiic.h 的代码,里面有两行代码为直接通过寄存器操作设置 IO 口的模式为输入还是输出

//代码如下:

#define SDA_IN() {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=8<<12;}

#define SDA_OUT() {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=3<<12;}

//完整代码如下:

#ifndef __MYIIC_H

#define __MYIIC_H

#include "sys.h"

           

//IO方向设置

#define SDA_IN()  {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=8<<12;}

#define SDA_OUT() {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=3<<12;}

 

//IO操作函数  

#define IIC_SCL    PCout(12) //SCL

#define IIC_SDA    PCout(11) //SDA  

#define READ_SDA   PCin(11)  //输入SDA 

 

//IIC所有操作函数

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

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

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

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

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

u8 IIC_Wait_Ack(void); //IIC等待ACK信号

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

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

 

void IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data);

u8 IIC_Read_One_Byte(u8 daddr,u8 addr);   

#endif

推荐阅读

史海拾趣

HARTING公司的发展小趣事

Hanghsing Enterprise Co., Ltd. 的五个发展故事

故事一:初创与起步

Hanghsing Enterprise Co., Ltd.(以下简称“Hanghsing”)成立于台湾,起初是一家专注于精密零部件制造的小型公司。公司位于No. 1, Lane 39, Seuwe St., Tali City, Taichung Hsien, Taiwan 412,凭借对品质的不懈追求和对市场的敏锐洞察,Hanghsing逐渐在行业内崭露头角。公司初期主要生产Valve Shafts、Nuts、Screws等精密不锈钢部件,这些产品广泛应用于电子、机械等多个领域。通过不断优化生产工艺和质量控制体系,Hanghsing逐渐建立了良好的市场口碑。

故事二:技术突破与产品升级

随着电子行业的快速发展,Hanghsing意识到技术创新的重要性。公司加大了对研发的投入,引进了一批高素质的技术人才,致力于新产品的开发和现有产品的升级。经过不懈努力,Hanghsing成功推出了一系列高精度、高可靠性的电子产品零部件,如Sleeve Barrels、Toggles和Mandrels等。这些产品不仅满足了市场对高品质零部件的需求,还进一步巩固了公司在电子行业供应链中的地位。

故事三:市场拓展与国际合作

随着产品质量的不断提升和市场份额的逐步扩大,Hanghsing开始将目光投向国际市场。公司积极参加各类国际展会,与全球知名电子企业建立合作关系,将产品销往世界各地。同时,Hanghsing还注重与国际技术标准的接轨,确保产品符合国际市场的严格要求。通过不断的市场拓展和国际合作,Hanghsing在国际上的知名度和影响力得到了显著提升。

故事四:产业升级与多元化发展

面对电子行业的快速发展和市场竞争的日益激烈,Hanghsing积极寻求产业升级和多元化发展的路径。公司开始涉足电子元器件的制造和研发领域,通过引进先进的生产设备和工艺技术,不断提升产品的附加值和市场竞争力。同时,Hanghsing还积极拓展上下游产业链,与原材料供应商和终端客户建立紧密的合作关系,形成了完整的产业生态体系。

故事五:绿色生产与可持续发展

在追求经济效益的同时,Hanghsing始终不忘履行社会责任。公司积极响应国家环保政策,致力于绿色生产和可持续发展。通过引进环保设备和工艺技术,减少生产过程中的污染物排放和资源消耗。同时,Hanghsing还加强了对员工的环保教育和培训,提高员工的环保意识和责任感。这些举措不仅有助于提升公司的社会形象和市场竞争力,还为推动电子行业的绿色发展做出了积极贡献。

Corex Intervest Inc公司的发展小趣事

随着公司规模的不断扩大和市场竞争的加剧,Corex Intervest Inc公司意识到单打独斗已经无法满足市场需求。因此,公司开始积极寻求与其他企业的战略合作,共同推动电子行业的发展。公司与多家知名企业建立了战略合作关系,共同研发新产品、开拓新市场,实现了资源共享和互利共赢。

AdaptivEnergy公司的发展小趣事

随着公司规模的不断扩大和市场竞争的加剧,Corex Intervest Inc公司意识到单打独斗已经无法满足市场需求。因此,公司开始积极寻求与其他企业的战略合作,共同推动电子行业的发展。公司与多家知名企业建立了战略合作关系,共同研发新产品、开拓新市场,实现了资源共享和互利共赢。

Ambersil公司的发展小趣事

在电子行业的初期,Ambersil公司以其创新的技术和产品迅速崭露头角。公司研发团队成功开发出一种高效的电子清洁剂,能够去除电路板上的顽固污垢,提高电子设备的性能和稳定性。这一创新产品迅速获得了市场的认可,Ambersil公司因此获得了大量的订单,销售额逐年攀升。

锋鸣电子(Fengming)公司的发展小趣事

福斯特集团在半导体封测领域也展现了强大的实力。集团旗下拥有安徽龙芯微科技有限公司和泸州龙芯微科技有限公司等多家子公司,这些公司均配备有全球领先的集成电路封装测试线。通过不断的技术创新和设备升级,福斯特集团能够满足客户全方位的器件封测要求,为客户提供高质量、高效率的封测服务。此外,公司还积极投入研发,推出多项新技术和新产品,进一步巩固其在半导体封测领域的领先地位。

Franz Binder GmbH & Co公司的发展小趣事

福斯特集团(FIRST SEMI)作为另一家以“FIRST”为品牌的企业,在半导体芯片领域也取得了显著成绩。该集团成立于2010年,总部位于中国深圳,是一家集半导体芯片研发、方案设计、封装制造、测试编带、产品销售为一体的国家级高新技术企业。公司产品广泛应用于无人机、机器人、笔记本电脑、液晶电视等多个领域。通过在全球设立代理销售公司,福斯特集团的销售网络覆盖全球多个国家和地区,服务合作客户超过3000家。

问答坊 | AI 解惑

麻烦问下,哪位高手这个电阻是什么作用哈?

本帖最后由 paulhyde 于 2014-9-15 09:48 编辑 这个就是 一个简单的分压测输出电压的电路。 请问哪位知道,那个 R2的作用是什么?  …

查看全部问答>

A/D转换问题

我是新手,第一次发求助贴,请别见笑,也希望能获得各位朋友的帮助, 我采用的A/D是0804的,通过电位器调节输入A/D电压信号,转换后获取到的值放在P1口,建了个整型变量,假设为conv,执行以下语句后,可以实现数码管动态扫描显示数值: conv=P1; unsigned ...…

查看全部问答>

prote在06版本制作的封装在winter09版本上显示有错误

是焊盘和外边的黄线有部分重合 不知道如何修改规则??? 求助…

查看全部问答>

IoCallDriver的问题

原贴在[url=http://topic.eeworld.net/u/20100321/21/3856c90d-07f4-41bc-94ae-873f39577b92.html?83762][/url],我快挂掉了,大牛们快来帮帮忙!…

查看全部问答>

读Isochronous pipe的问题

小弟是驱动菜鸟,望各位达人指教。 最近在写一个从Isochronous pipe读取数据的驱动,但是总是失败。 我在adddevice的时候创建了一个Request,然后用WdfUsbTargetPipeFormatRequestForUrb构建这个Request,并设置complete事件,但是在complete的时 ...…

查看全部问答>

怎么实现512X512LED双基色点阵屏的灰度控制,8位,256级灰度''''''

怎么实现512X512LED双基色点阵屏的灰度控制,8位,256级灰度\'\'\'\'\'\' 哪位有实现方法 我查到那种发送256次数据,与列驱动自带灰度调制的驱动芯片外,,,,,,还有其它方法吗,…

查看全部问答>

小弟,ARM开发我自学要入门,高手们给指条明路

我大学是电子信息专业毕业的学过汇编和C 51之类但是不精模电还可以,现在想自学ARM开发!(偏软件方面的)请各位高手指条明路啊…

查看全部问答>

PFC中的磁性元件及其作用

以最常用的BOOST PFC电路为例,一个完整的PFC电路如图1所示,其中的磁性元件有Boost储能电感、EMI 滤波电感(共模电感和差模电感)以及抑制输出二极管反向恢复电流的尖峰抑制器。另外在新型的无源无损软开关 PFC和ZVT有源软开关PFC电路中,辅助谐 ...…

查看全部问答>

STM32F103RDT6能否接受到200KHz的外部中断?

                                 现在有一个应用,输入量是8个IO口的开关量,然后有一个选通信号,最高可能达到200KHz,准备将这个选通信号连接 ...…

查看全部问答>

鼠标,键盘,游戏手柄完成,带重力加速感应(第2页有视频演示)!!!

鼠标,键盘,游戏手柄三位一体外加重力感应半成品,我设计的,目前进度是调完键盘部分,重力感应还没加上,鼠标部分用现成鼠标拆一个。 mcu: stc11f16xe usb: pdiusbd12 G-SENSOR : mma7455 这块板子还没焊上 神马?飞机,非也,是键盘 键盘面 ...…

查看全部问答>