寒假学习之stm32(16)----IIC通信协议

发布者:alpha11最新更新时间:2017-10-09 来源: eefocus关键字:stm32  IIC  通信协议 手机看文章 扫描二维码
随时随地手机看文章

背景知识: 

https://zh.wikipedia.org/wiki/I%C2%B2C


stm32中的IIC描述:

I2C功能描述:

I2C模块接收和发送数据,并将数据从串行转换成并行,或并行转换成串行。可以开启或禁止中断。接口通过数据引脚(SDA)和时钟引脚(SCL)连接到I2C总线。允许连接到标准(高达100kHz)或快速(高达400kHz)的I2C总线

模式选择

默认情况下,I2C接口总是工作在从模式。从从模式切换到主模式,需要产生一个起始条件。 
接口可以下述4种模式中的一种运行: 
● 从发送器模式 
● 从接收器模式 
● 主发送器模式 
● 主接收器模式 
该模块默认地工作于从模式。接口在生成起始条件后自动地从从模式切换到主模式;当仲裁丢失或产生停止信号时,则从主模式切换到从模式。允许多主机功能。

关于 stm32的IIC的硬件上,在网上多数都在讨论各种bug,比如无法加入外部中断之类,所以,我们用两个引脚模拟出IIC通信的过程,在结合外部支持IIC协议的外设,从而实现IIC功能

模拟IIC通信:

我们可以定义两个引脚的其中一个为SDA(数据线),SCL(时钟线) 
为了让两个引脚模拟出IIC通信,我们首先应该了解一下一个完整的IIC通信过程所经历的几个步骤:

a. 起始信号:

        在不进行通信时,IIC的通信引脚(SDA,SCL)应当同时置高,这就是IIC通信的空闲状态,且看:
void IIC_Init(void)
{                        
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE ); //使能GPIOB时钟

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7);  //PB6,PB7 输出高
}1234567891011

    ```
    //产生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总线,准备发送或接收数据 
    }    123456789101112

b. 数据传输:

SCL串行时钟的配合下,在SDA上逐位地串行传送每一位数据。数据位的传输是边沿触发。但是要注意数据传输时候的数据有效性判断。

在IIC中,SCL为高电平期间SDA的电平必须保持不变,该数据才允许被传输,否则为无效数据,如图:

这里写图片描述

代码如下:
//IIC发送一个字节//返回从机有无应答//1,有应答//0,无应答           void IIC_Send_Byte(u8 txd)
{                        
    u8 t;   
    SDA_OUT();      
    IIC_SCL=0;//拉低时钟开始数据传输
    for(t=0;t>7;
        if((txd&0x80)>>7)
            IIC_SDA=1;        else
            IIC_SDA=0;
        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;
}12345678910111213141516171819202122232425262728293031323334353637383940414243444546

c. 应答信号:

在IIC中,数据的传输不允许连续进行,在每个字节(byte)传送完成之后,必须给一个应答信号才会继续进行下一个字节的传输。
对于反馈有效应答位ACK的要求是,接收器在第9个时钟脉冲之前的低电平期间将SDA线拉低,并且确保在该时钟的高电平期间为稳定的低电平。 (那前八个脉冲呢?当然是给了传输的那个字节用了!一个字也八位啊!!)

这里写图片描述

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

d. 停止信号

与起始信号相反,在SCL为高期间,将SDA置为高(此时,IIC总线有重新归于空闲状态)
//产生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);                                
}1234567891011

一个使用模拟IIC通信控制EEPROM的实例:

//初始化IIC接口void AT24CXX_Init(void)
{
    IIC_Init();
}//在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);//发送高地址
        IIC_Wait_Ack();      
    }else IIC_Send_Byte(0XA0+((ReadAddr/256)>8);//发送高地址
    }else
    {
        IIC_Send_Byte(0XA0+((WriteAddr/256)<(8*t))&0xff);
    }                                                   
}//在AT24CXX里面的指定地址开始读出长度为Len的数据//该函数用于读出16bit或者32bit的数据.//ReadAddr   :开始读出的地址 //返回值     :数据//Len        :要读出数据的长度2,4u32 AT24CXX_ReadLenByte(u16 ReadAddr,u8 Len)
{   
    u8 t;    u32 temp=0;    for(t=0;t


关键字:stm32  IIC  通信协议 引用地址:寒假学习之stm32(16)----IIC通信协议

上一篇:寒假学习之stm32(17)----SPI通信协议
下一篇:从一无所知的开始 学习stm32

推荐阅读最新更新时间:2024-03-16 15:39

STM32中断向量表偏移地址配置方法
以将中断向量表偏移地址改到0x8005000为例 第一种方式: 设置system_stm32f1xx.c文件 #defineVECT_TAB_OFFSET 0x5000 在void SystemInit (void)函数中通过“SCB- VTOR =FLASH_BASE | VECT_TAB_OFFSET”命令实现地址偏移 第二种方式:运用库函数时,可以在main()函数开头,加上 NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x5000);__ASM( CPSIE I ); 命令实现地址偏移 NVIC_VectTab_FLASH 和 FLASH_BASE 都为 0x08000000 要实
[单片机]
STM32——MDK4与MDK5中设置系统各部分时钟对比
/******************************************************************************* * 函数名 : RCC_Configuration * 函数描述 : 在MDK4中设置系统各部分时钟 * 输入参数 : 无 * 输出结果 : 无 * 返回值 : 无 *******************************************************************************/ void RCC_Configuration(void) { /* 定义枚举类型变量 HSEStartUpStatus */
[单片机]
意法半导体发布远距离无线微控制器,提高智能计量、智能建筑和工业监控的连接能效
新的STM32系统芯片低功耗,支持多种无线通信协议,简化各种用途的无线系统设计 中国,2023年11月24日 - 服务多重电子应用领域、全球排名前列的半导体公司意法半导体(STMicroelectronics,简称ST;) 发布了一款新的融合无线芯片设计专长与高性能、高能效STM32系统架构的微控制器(MCU)。全新的节能功能将这款无线MCU的电池续航时间延长到15年以上。 在远距离部署的应用领域,包括能源计量、监控设备、报警系统、执行器,以及智能建筑、智能工厂和智能城市的传感器,STM32WL3无线MCU的特别有用,有助于控制功耗,并给工作划分优先级。这些高能效MCU可以改善用户体验,提供服务,减少环境足迹。通过
[嵌入式]
意法半导体发布远距离无线微控制器,提高智能计量、智能建筑和工业监控的连接能效
MC9S12XDP512下IIC模块的应用总结
IIC应用笔记 IIC总线相关知识: 1.起始信号: 时钟线保持高电平时,数据线上出现由高变低的信号。 2.停止信号:时钟线保持高电平时,数据线上出现由低变高的信号。 3.数据传输:时钟线为高电平时,数据线上的逻辑状态必须保持一致。时钟线为低电平时,允许数据线上的电平发生变化(即传输)。 4.起始信号和停止信号都由主控制器产生,应答信号在每个数据传输后的第9个时钟周期由接收器产生,低电平有效。当主控制器为接收方时,接收到最后一个字节时,不应发送应答信号。 5. 写过程:启动IIC→发送从机地址→发送要写单元地址→发送写数据(一个或者连续写) →发送停止信号,关闭IIC。 6.读过程:主机发送开始信号,启
[单片机]
STM32项目(三)——通用LIN控制器
需求: LIN马达控制器:AFS(DHL+AFL)——弯道辅助照明系统 DHL:上极限,下极限,零位,马达老化循环; AFL:左极限,右极限,零位,马达老化循环; 所有参数可配置:上极限,下极限,零位,左极限,右极限,马达循环上极限,马达循环下极限,马达循环次数,马达循环等待时间; 保存至少30款产品的配置,配置界面需要有添加,读取,查找,删除功能。 方案:STM32 + LIN + 串口(使用NXP的串口屏,TJA系列的LIN芯片) STM32的LIN接口作为主节点,马达作为从节点。 系统设计:RTX多任务设计,串口处理任务,显示屏处理任务,LIN发送任务; (1)、串口处理任务:点击串口屏会获取到点击的坐标值,串口中断接受
[单片机]
智林STM32程序源代码的分析和整理01
一、目的 1、前些天,编写了开发板上键盘扫描、字符输入和简单shell的程序,该程序的编写是在以前工程的基础上修改而成的,源代码的组织比较乱,也没有很好的注释。这两天,先把代码整理一下,加上比较详细的注释,使得可读性、扩展性更好。 2、乘这个机会,也把程序里与STM32硬件相关的部分好好学习一下。 二、开发板配置分析 1、PA口 PA0对应按键PB3,开发板右下角。 PA1用于模拟电位器,JP1在这里。 PA2用定时器的PWM产生液晶的背光电源。PA4-PA7用于SPI模式操作SD卡。PA9,PA10用于串口0通信。PA11,PA12是USB差分线。PA13、PA14、PA15是JTAG的三个脚。 PA3、
[单片机]
TCRT5000+STM32红外循迹小车程序
用正点原子的精英版作为主控,红外循迹用TCRT5000芯片。 单片机源程序如下: /* Includes ------------------------------------------------------------------*/ #include stm32f10x.h #include stm32f10x_tim.h #include stm32f10x_flash.h #include stm32f10x_exti.h #include stm32f10x_rcc.h #include systick.h #include stdio.h #include misc.h #define in
[单片机]
基于单片机的井场仪表参数无线传输系统设计
  目前,全国油田钻井现场基本都是有线数据传输。有线传输有很多缺点,现场布线复杂而且存在安全隐患,钻井是流动作业,每钻一口井就要重新布一次线,这样既费时又费力,有时还会由于布线走向的问题导致线路被碰断。一般说来,数据线都是空中架设,风吹日晒使数据线老化的较快,这样就带来直接的经济损失。钻井现场有很多公司在作业,有些参数各公司是共用的,同一个参数每个公司都要读取一次,就需要在同一个测量点上安装两台甚至更多的变送器,这样既造成了浪费又使得现场变送器安装位置紧张。   本系统采用无线通信技术,一点发射多点接收,可以实现信息共享,避免了布线的麻烦,而且流动作业时可以方便地安装和拆卸,很好地提高了工作效率。    2系统硬件设计   
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved