STM32(五)IIC通信原理及IO口软件模拟编程

发布者:名字太长了吗最新更新时间:2019-08-09 来源: eefocus关键字:STM32  IIC通信  IO口  软件模拟 手机看文章 扫描二维码
随时随地手机看文章

一、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

关键字:STM32  IIC通信  IO口  软件模拟 引用地址:STM32(五)IIC通信原理及IO口软件模拟编程

上一篇:stm32 mpu6050 模拟i2c实例实现
下一篇:STM32中I2C协议时序和使用

推荐阅读最新更新时间:2024-11-09 12:04

STM32中断系统笔记
CM3中 STM32参考教程: STM32开发指南V1.0库函数版
[单片机]
<font color='red'>STM32</font>中断系统笔记
用STM32CubeIDE软件实现STM32外部中断实例
本文用STM32CubeIDE软件实现STM32外部中断实例。 新建工程 “File”-“New”-“STM32 Project”。 输入芯片型号STM32F103ZE。 选择相应封装,下一步。 填写项目名,选择工程位置,下一步。 配置时钟、调试模式 选择高速外部时钟。 HCLK总线时钟处输入72,回车,配置使用最高时钟频率。 调试模式选择串行,方便下载程序。 配置管脚外设 本实例中用到了LED1与KEY_LEFT,找到相应电路图。 可见LED1对应PC0管脚,低电平点亮。按键K1对应PE2管脚,低电平有效。 PC0配置为GPIO_Output,GPIO输出模式 PE2配置为GPIO_EX
[单片机]
用STM32CubeIDE<font color='red'>软件</font>实现<font color='red'>STM32</font>外部中断实例
基于主控STM32控制系统的硬件设计喷绘系统设计
0 引言 由于喷绘机喷绘过程中采用的是压电喷头工作原理,为保证喷绘出图像清晰细腻,喷绘机需要在同一温度下提供稳定的驱动电压对压电晶体进行控制。如何在精准的条件下根据室内温度实时、快速、方便地更改驱动电压和配置数据值得研究。 1 系统设计理念 喷头的驱动电压VDD2(t)取决于喷头容积电压Vrank、基于不同厂家不同颜色的油墨粘滞度而提供每色油墨与标准油墨的修正值Voffset电压、不同颜色的油墨在不同温度下需要的驱动电压补偿值Vdiff(t),即VDD2(t)=Vrank+Voffset+Vdiff(t)。不同颜色的油墨在不同的温度下驱动电压的补偿值Vdiff(t),称之为T-V数据。 不同厂家油墨温压数据不同,厂家会根据
[单片机]
基于主控<font color='red'>STM32</font>控制系统的硬件设计喷绘系统设计
STM32开发中的五大嵌入式系统
技术往往更新得非常快,并且总是让我们觉得学起来有难度而且有些迷茫。不过没有关系我们发烧友专注于在快乐中学习,要学习STM32,我们首先了解下五大嵌入式操作系统:μClinux、μC/OS-II、eCos、FreeRTOS和RT-thread。 μClinux μClinux是一种优秀的嵌入式Linux版本,从字面意思看是指微控制Linux。同标准的Linux相比,μClinux的内核非常小,但是它仍然继承了Linux操作系统的主要特性,包括良好的稳定性和移植性、强大的网络功能、出色的文件系统支持、标准丰富的API,以及TCP/IP网络协议等。 μClinux操作系统的中断管理是将中断处理分为两部分:顶半处理和底半处理。在顶半处
[单片机]
<font color='red'>STM32</font>开发中的五大嵌入式系统
stm32利用mqtt与小程序通信
本项目实现的功能如下:通过stm32连接esp8266,然后利用mqtt协议连接到服务器,同时小程序端也连接到服务器,通过订阅和发布主题来使得这两个客户端能进行数据的传输。 stm32连接服务器端 本章所用到的器件如下: STM32F103ZET6最小系统板 ESP8266-01S模块 USB转microUSB数据线 四根杜邦线 连接如下: 32板3.3v----------- ESP8266的3.3v 32板GND---------- ESP8266的GND 32板的PC10-------- ESP8266的RX 32板的PC11-------- ESP8266的TX 在这里说明一下,由于本项目是用在其他项目上的,所以在
[单片机]
<font color='red'>stm32</font>利用mqtt与小程序<font color='red'>通信</font>
【IoT毕业设计】STM32开发板+机智云IoT+智能家居养老机器人
引言 通过对第七次人口普查数据的研究发现 ,我国60周岁及以上老龄人口截至2021年5月已达到全国总人口的18.7%,其中65周岁及以上人口占比13.5%,仅差0.5%我国就将步入老龄社会,人口老龄化所带来的关于养老的众多问题是我国亟待解决的 。目前人工智能技术已比较成熟,将其应用到智能家居养老服务上是一种当下被多方面认可的解决养老问题的方法。 本系统开发者设计的机器人结合了嵌入式人工智能技术,能够实时监测老人的身体健康状态与居家环境数据,同时可以将数据上传到云端平台进行分析,老人及其监护人可以使用移动设备访问平台查看数据分析曲线。此外,机器人还可以自主规划环境数据监测路线,确保对居家环境全方位监测。因此该系统能满足老人和特
[单片机]
【IoT毕业设计】<font color='red'>STM32</font>开发板+机智云IoT+智能家居养老机器人
模拟软件是提升物联网电池性能的关键“抓手”
电池使用寿命是影响物联网设备的关键因素 电池使用寿命对物联网(IoT)基础设施的成本和可靠性有很大影响。消费电子设备的电池使用寿命更是影响消费者购买与否的关键考虑因素。然而在实际情况中,通过计算得出的物联网设备的电池使用寿命往往是不准确的,这对设备制造商来说是一个非常重要的问题。 衡量电池使用寿命的方法之一是用电池容量(以安培小时为单位)除以平均电流消耗(以安培为单位),从而得出电池的运行时间(小时)。然而,在现实世界中,这种计算方法则过于简单了。 事实上,由于设备使用不同的电源模式,包括运行模式、睡眠模式和休眠模式等,因此根据上面的公式可能会得出不准确的结果。此外,恒定功率和恒定电阻等操作模式将以不同方式从电池中获取
[测试测量]
stm32—文件封装
一,环境: 开发环境:MKD5 固件库版本:V3.5(可自行在官网下载) 二,步骤: 1, 在建立工程之前,我们建议用户在电脑的某个目录下面建立一个文件夹,后面所建立的工 程都可以放在这个文件夹下面,这里我们建立一个文件夹为 Template。 2,点击 MDK 的菜单:Project – New Uvision Project ,然后将目录定位到刚才建立的文件夹 Template 之下,在这个目录下面建立子文件夹 USER(我们的代码工程文件都是放在 USER 目录,很多人喜欢新建“Project”目录放在下面,这也是可以的,这个就看个人喜好了), 然后定位到 USER 目录下面,我们的工程文件就都保存到 USER 文件
[单片机]
<font color='red'>stm32</font>—文件封装
小广播
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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