历史上的今天
返回首页

历史上的今天

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

正在发生

2020年09月11日 | 基于STM8的IIC协议通信

2020-09-11 来源:eefocus

一、 综述

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


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


       在往后的模块调试中也经常涉及,是一个很常见并且很好用的协议。


二、STM8S103中手册对I2C简介

 

 

看完中文资料手册,个人觉得比较浅显,具体使用在后面我会贴出来。

 

三、 I2C详细解析

I2C总共由五个核心函数,分别为:

①起始信号

②停止信号

③应答信号

④发送数据

⑤接收数据

 

通过这五个核心基本函数就能于大多数的传感进行通信了。

以下对各个部分进行详细介绍,附上部分主要代码,各位可以参考一下。

3.1 起始信号

当SCL为高电平期间,SDA由高电平到低电平的跳变过程;起始信号是一种电平跳变时序信号,而不是一个电平信号,如上图虚线框所。

1
2
3
4
5
6
7
8
9
10
11
12
void Start_Signal_IIC_(void){
   
  //起始信号:
  GPIO_WriteHigh(GPIOD, GPIO_PIN_2);//数据线
  IIC_Delay_4us();
  GPIO_WriteHigh(GPIOD, GPIO_PIN_3);//时钟线
  IIC_Delay_4us();
  GPIO_WriteLow(GPIOD, GPIO_PIN_2); //数据线
  IIC_Delay_4us();
  GPIO_WriteLow(GPIOD, GPIO_PIN_3); //时钟线
  IIC_Delay_4us();
}

  

3.2 停止信号

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

1
2
3
4
5
6
7
void End_Data_IIC_()
  {
    GPIO_WriteLow(GPIOD, GPIO_PIN_2); //数据线拉低
    IIC_Delay_4us();
    GPIO_WriteHigh(GPIOD, GPIO_PIN_3);//时钟线拉高
    IIC_Delay_4us();
    GPIO_WriteHigh(GPIOD, GPIO_PIN_2);//数据线拉高
1
}

  

3.3 应答信号

 

 

 

应答信号有两种:分别是主动应答信号和主动不应答信号

①Ack(主动拉低SDA形成应答信号)

 I2C总线的数据都是以字节(8位)的方式传送的,发送器件每发送一个字节之后,在时钟的第9个脉冲期间释放数据总线,由接收器发送一个  ACK(把数据总线的电平拉低)来表示数据成功接收。

1
2
3
4
5
6
7
8
9
//主动应答信号
void vIIC_Ack()
{
  GPIO_WriteLow(GPIOD, GPIO_PIN_2);
  IIC_Delay_4us();
  GPIO_WriteHigh(GPIOD, GPIO_PIN_3);
  IIC_Delay_4us();
  GPIO_WriteLow(GPIOD, GPIO_PIN_3);
  IIC_Delay_4us();
}

 

②NAck(主动不拉低SDA不形成应答信号)

在时钟的第9个脉冲期间发送器释放数据总线,接收器不拉低数据总线表示一个NACK,NACK有两种用途:

a. 一般表示接收器未成功接收数据字节;

b. 当接收器是主控器时,它收到最后一个字节后,应发送一个NACK信号,以通知被控发送器结束数据发送,并释放总线,以便主控接收器发送一个停止信号STOP。

1
2
3
4
5
6
7
8
9
10
//主动不应答
void vIIC_NAck()
{
  GPIO_WriteHigh(GPIOD, GPIO_PIN_2);
  IIC_Delay_4us();
  GPIO_WriteHigh(GPIOD, GPIO_PIN_3);
  IIC_Delay_4us();
  GPIO_WriteLow(GPIOD, GPIO_PIN_3);
  IIC_Delay_4us();
}

 ③ReadAck(等待应答信号)

    该信号在主机发送完数据后等待从机应答时候使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
u8 bIIC_ReadACK()
 {
   GPIO_Init(GPIOD, GPIO_PIN_2, GPIO_MODE_IN_PU_IT);//将SDA改为输入模式。
   GPIO_WriteHigh(GPIOD, GPIO_PIN_3);               //拉高时钟线。
   IIC_Delay_4us(); 
   if(IIC_SDA_R != 0)
      {
        //低 有应答
        GPIO_WriteLow(GPIOD, GPIO_PIN_3);
        IIC_Delay_4us();
        GPIO_Init(GPIOD, GPIO_PIN_2, GPIO_MODE_OUT_PP_HIGH_FAST);//SDA
        return 1;
      }
    else
       //高 无应答
      {
       GPIO_WriteLow(GPIOD, GPIO_PIN_3);
       IIC_Delay_4us();
       GPIO_Init(GPIOD, GPIO_PIN_2, GPIO_MODE_OUT_PP_HIGH_FAST);//SDA
       return 0;
      }
 }

  

3.4 发送数据

在发送起始信号后开始通信,主机发送一个8位数据。然后,主机释放SDA线并等待从从机发出得确认信号(ACK)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void Send_Data_IIC_(uint8_t Data){
    int i;
    //拉低数据线和时钟线
    GPIO_WriteLow(GPIOD, GPIO_PIN_3);
    GPIO_WriteLow(GPIOD, GPIO_PIN_2);
  for(i=0;i<8;i++)
  {
      if(Data&0x80)
      GPIO_WriteHigh(GPIOD, GPIO_PIN_2);
    else
      GPIO_WriteLow(GPIOD, GPIO_PIN_2);
     
    Data= Data<<1;
    IIC_Delay_2us();
    GPIO_WriteHigh(GPIOD, GPIO_PIN_3);
    IIC_Delay_4us();
    GPIO_WriteLow(GPIOD, GPIO_PIN_3);
    IIC_Delay_2us();
  }
}

  

3.5 接收数据

在发送起始信号后开始通信,主机发送一个8位数据。然后,从机收到数据返回一个确认信号(ACK)给主机,这时候主机才开始接收数据,待主机接收数据完成后,发送一个NACK信号给从机,以通知接收端结束数据接收。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//接收函数
uint8_t uIIC_RecvByte()
{
  uint8_t i,uReceiveByte = 0;
  GPIO_Init(GPIOD, GPIO_PIN_2, GPIO_MODE_IN_PU_IT);
  for(i=0;i<8;i++)
  {
   
    uReceiveByte <<= 1;
    IIC_Delay_4us();
    GPIO_WriteHigh(GPIOD, GPIO_PIN_3);//高时钟线时读取数据电平
    IIC_Delay_4us();
    if(IIC_SDA_R !=0 )
    {
      uReceiveByte|=0x01;
    }
    IIC_Delay_4us();
    GPIO_WriteLow(GPIOD, GPIO_PIN_3);
    IIC_Delay_4us();
  }
   
   GPIO_Init(GPIOD, GPIO_PIN_2, GPIO_MODE_OUT_PP_HIGH_FAST);
   return uReceiveByte;
}


3.6 I2C通信总过程

 

以下图完美地诠释了iic从接收到发送全过程中,SDA和SCL线的变化线。综合上面的解释和过程代码,这张图可以帮助记忆和理解。


四、例程

 

4.1 编译环境:

        这里用的是IAR进行编译,较为好用,后期使用STM32的开发板可以推荐使用CUBE直接生成初始化函数,与Keil5相互搭配使用,很是方便。


4.2 主芯片:

  我的主芯片是STM8S系列中的103,其中STM8S的003、005、和103、105,配置一样(外设和CPU频率,FLASH),在代码相同的情况下均可进行烧写。


4.3 代码&解析

       iic代码可以驱动几乎市面上的所有时钟模块,所以这里的代码可以与时钟模块的代码相互调用。每个函数我都有加以解释,可以详细了解一下。


      看了上面的代码也可以知道,这个协议是由数据线和时钟线,数据发送接收要求拉高数据线或拉低时钟线。所以这里推荐直接使用库函数的拉高低,如果要方便的话,再加个宏定义可以更加直观方便。

 

五、结尾

以上是iic的核心函数,对于每个函数我已经写的很清楚,下一篇博客我会将基于iic的时钟模块的传感通信博客贴出来,各位可以继续阅读下一篇博客做一下参考。

推荐阅读

史海拾趣

Asia Electronics Ind Co Ltd公司的发展小趣事

随着公司产品的不断成熟和市场的不断扩大,Asia Electronics Ind Co Ltd积极寻求市场拓展的机会。公司加强与国际知名企业的合作,通过参加国际电子展、建立海外销售渠道等方式,不断提升品牌知名度和影响力。同时,公司还注重品牌形象的塑造,通过统一的品牌标识、宣传资料等,增强消费者对品牌的认知度和信任度。

Arctic Silicon Devices公司的发展小趣事

在电子行业的发展过程中,创新合作是推动产业进步的重要动力。Arctic Silicon Devices积极与高校、科研机构等合作,共同开展技术研发和人才培养。通过共享资源、互通有无,公司不仅获得了更多的创新灵感和技术支持,还推动了整个电子行业的技术进步和产业升级。

Calmos Systems Inc公司的发展小趣事

随着国内市场的饱和,Calmos Systems Inc公司开始将目光投向国际市场。公司制定了详细的国际化战略,包括市场调研、产品定位、销售渠道建设等方面。公司派遣专业团队前往海外市场进行考察和交流,了解当地市场需求和文化特点。同时,公司还积极寻求与国际知名企业的合作机会,共同开拓国际市场。在国际化战略的推动下,公司的业务范围不断扩大,国际市场份额逐年提升。

常州星海电子(Starsea)公司的发展小趣事

常州星海电子有限公司,自1990年成立以来,便以生产中英合资的各类二极管为起点,逐渐在电子行业中崭露头角。随着公司业务的不断发展和市场需求的增长,2016年,公司正式更名为常州星海电子股份有限公司,完成了从合资到股份制的转变。这一转变不仅标志着公司管理结构的升级,也预示着公司在未来市场中的更大发展。

Cogent_Computer_Systems公司的发展小趣事

在电子行业的发展过程中,Cogent_Computer_Systems公司深知合作共赢的重要性。公司积极与上下游企业建立紧密的合作关系,共同推动产业升级。通过与供应商的深度合作,公司确保了原材料的稳定供应和质量保障;同时,与客户的紧密沟通也帮助公司更好地把握市场需求,推出更符合消费者期望的产品。这种合作共赢的模式不仅提升了公司的竞争力,也为整个电子行业的发展注入了新的活力。

泽耀科技(Ashining)公司的发展小趣事

泽耀科技(Ashining)深知品质是企业生存和发展的关键。因此,公司始终将品质管理放在首位,从原材料采购到生产流程控制,再到产品出厂检验,每一个环节都严格把控品质。同时,泽耀科技还注重品牌建设,通过提升产品形象和服务水平,逐渐树立了良好的品牌形象。

问答坊 | AI 解惑

康佳挺进汽车电子行业

发动机被称为汽车的“心脏”,控制发动机的电子系统“电喷”又称为发动机的“心脏”。深圳康佳集团成功开发“电喷”系统,不但填补了国内空白,而且标志该集团进入汽车电子领域不久即占据产业与技术的最高端,成为中国汽车电子的主流企业。 “电喷 ...…

查看全部问答>

dsp入门----> dsp的精品课件!

dsp是强大的芯片,设计的技术很多,很杂,特别是一dsp作为核心的时候!现在大致有两种系统,一种是主从式的,说简单一点就是dsp和主机打交道!一种是dsp自成体系的,这个时候所有的控制,处理工作都是有dsp器件完成的,这样的系统一般都有自举引导 ...…

查看全部问答>

Windows CE项目开发实践丛书

《Windows CE项目开发实践丛书》之一,主要讲述操作系统底层驱动软件开发技术,内容还是相当不错的哦~~~…

查看全部问答>

电涡流测功机工作原理

  由电涡流测功机感应子主要由旋转部分和摆动部分(电枢和励磁线圈)组成。转子轴上的感应子形状犹如齿轮,与转子同轴装有一个直流励磁线圈。当励磁线圈组通以直流电流时,其周围便有磁场存在,那么围绕励磁组就产生一闭合磁通。很明显,位于绕组 ...…

查看全部问答>

LM3S8962 MAC地址写入问题

问题: 要修改 LM3S8962 MAC Address 是否从下列圆中输入就行了,如可以要量产时是否也要一片一片板子来修改?? 再请教一下,有没有 LM Flash programmer  S/W  操作手冊可看 答案:    用从标注的选项里面修改。因 ...…

查看全部问答>

请教cadence画原理图问题

请教cadence画原理图时, 我把CPU分成3部分 想画在三个PAGE上 请问怎么才能让这三个PAGE连接起来…

查看全部问答>

uCOS-II在XS128的移植谁做过啊!新人请教。

     目前老师让做uCOS-II在XS128的移植,可是目前手头关于这款单片机的资料很少,不知道怎么用,更不知道怎么写,不知道他和MC9SDG128有什么区别,哪位同情下,给点帮助啊!…

查看全部问答>

关于pb5.0,每次打开要几分钟才响应,是怎么回事呢?

每次打开软件要几分钟才响应,是怎么回事呢?有没什么解决的办法?打开一个工程稍微短一点。显示在打开网页*start*…

查看全部问答>

提个意见:STM32为什么不提供SCH/PCB库?

                                 有用PROTEL的,有用PADS的。别的公司都有了,为什么STM32就没有?…

查看全部问答>

[TI M4申请]自主智能汽车运动控制和姿态测量系统(inemo入围项目)

自主智能汽车运动控制和姿态测量系统一、项目概述1.1 项目摘要本系统的目的是设计一种以IMEMS传感器为主的自主路径识别智能汽车的运动控制和测量系统。本系统采用双MCU架构, STM32F103 MCU负责车身信号的采集,各模块电源的管理和地磁传感器,陀螺 ...…

查看全部问答>