54。I2C通信实验

发布者:正在搬砖的河马71最新更新时间:2018-10-17 来源: eefocus关键字:I2C  通信实验 手机看文章 扫描二维码
随时随地手机看文章

C语言小知识:

如何定义字符串:

可以通过字符数组或字符指针来定义字符串,也可以用宏定义对常量字符串进行定义。

 //定义字符串的几种方式

char names2[ ] = "jack";   字符串数组

char * names3 = "jack";    字符串指针

字符串是按ASSII码表以十六进制码存储的,比如 W就是0x57, a就是0x61

注意:

声明存储字符串的数组时,数组大小至少比所存储的字符串多1,因为编译器会自动在字符串常量的末尾添加空字符\0。


一。IIC通信协议

(一)概述

54。I2C通信实验

IIC器件的连接方式

54。I2C通信实验
每个器件都有自己相应的地址。

IIC(Inter-Integrated Circuit)总线是一种由 PHILIPS 公司开发的两线式串行总线,用于连接微控制器及其外围设备。它是由数据线 SDA 和时钟 SCL 构成的串行总线,可发送和接收数据。在 CPU 与被控 IC 之间、IC 与 IC 之间进行双向传送,高速 IIC 总线一般可达 400kbps 以上。I2C 总线在传送数据过程中共有三种类型信号,  它们分别是:开始信号、结束信号和应答信号。

开始信号:SCL 为高电平时,SDA 由高电平向低电平跳变,开始传送数据。

结束信号:SCL 为高电平时,SDA 由低电平向高电平跳变,结束传送数据。

应答信号:接收数据的 IC 在接收到 8bit 数据后,向发送数据的 IC 发出特定的低电平脉冲,表示已收到数据。 CPU 向受控单元发出一个信号后,等待受控单元发出一个应答信号, CPU 接收到应答信号后,根据实际情况作出是否继续传递信号的判断。若未收到应答信号,由判断为受控单元出现故障。

(二)IIC协议

54。I2C通信实验

1. 空闲状态

54。I2C通信实验
SCL和SDA分别接两个上拉电阻,以使IIC在空闲的时候为高电平。

2. 开始信号和停止信号

54。I2C通信实验

3. 应答信号

54。I2C通信实验
有效应答ACK必须在第9个时钟脉冲为高电平期间保持稳定,因此先要将SCL拉低,然后发出ACK信号,再拉高SCL,再把SCL拉低。

4. 数据的有效性

54。I2C通信实验
数据必须要在SCL为高电平期间保持稳定,因此要先把SCL拉低,然后发送数据,再把SCL拉高,再把SCL拉低,这样就保证了在SCL为高电平期间数据是稳定的,再把SCL拉低,在SCL为低电平期间数据才允许变化。

5. 数据传输

54。I2C通信实验

(三)IIC底层驱动程序

 

54。I2C通信实验

STM32 的 CRH 控制着每组 IO 端口(A~G)的高 8 位的模式。每个 IO 端口的位占用 CRL 的 4 个位,高两位为 CNF,低两位为 MODE。

 0X3 表示推挽输出模式(做输出口用,50M 速率)、0X8 表示上/下拉输入模式(做输入口用)。

myiic.h

//IO方向设置,控制IO工作模式

 

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

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

//IO操作函数  

#define IIC_SCL    PBout(10) //SCL

#define IIC_SDA    PBout(11) //SDA  

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

myiic.c

//初始化IIC

void IIC_Init(void)

{     

GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE ); //使能GPIOB时钟

  

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11;

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_10|GPIO_Pin_11); //PB6,PB7 输出高,因为IIC总线在空闲是都为高电平

}

54。I2C通信实验

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

}

54。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);  

}

54。I2C通信实验
要先把SCL拉低,然后准备好ACK应答数据,再拉高SCL,这样就可以保证在SCL为高电平期间ACK信号是稳定的。

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

}

54。I2C通信实验
同样是先把SCL拉低,然后准备好数据,再拉高SCL,然后再拉低SCL,这样是为了保证在SCL为高电平期间数据是稳定的,数据只有在SCL为低电平时才允许改变。

//IIC发送一个字节

//返回从机有无应答

//1,有应答

//0,无应答  

void IIC_Send_Byte(u8 txd)

{                        

    u8 t;   

SDA_OUT();    

    IIC_SCL=0;//拉低时钟开始数据传输

    for(t=0;t<8;t++)

    {              

if((txd&0x80)>>7)  //判断数据最高位是不是1

IIC_SDA=1;    //是1 , SDA输出高

else

IIC_SDA=0;   //是0,SDA输出低

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;

}

    

二。24C02操作

54。I2C通信实验
A0,A1,A2为地址线,确定IIC器件的地址

54。I2C通信实验
24C02容量为2K,A0,A1,A2都接地, 读为1,写为0

所以这里24C02读地址为 1010 0001,也就是A1,写地址为 1010 0000,也就是A0。

24cxx.c文件

初始化程序

//初始化IIC接口

void AT24CXX_Init(void)

{

IIC_Init();

}

写一个字节程序

54。I2C通信实验

//在AT24CXX指定地址写入一个数据

//WriteAddr  :写入数据的目的地址    

//DataToWrite:要写入的数据

void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite)

{          

    IIC_Start();  

if(EE_TYPE>AT24C16)

{

IIC_Send_Byte(0XA0);    //发送写命令,这里24C02写地址为A0

IIC_Wait_Ack();

IIC_Send_Byte(WriteAddr>>8);//发送高地址

  }else

{

IIC_Send_Byte(0XA0+((WriteAddr/256)<<1));   //发送器件地址0XA0,写数据,为了兼容其他型号                                                                                              的IIC芯片

}  

IIC_Wait_Ack();   

    IIC_Send_Byte(WriteAddr%6);   //发送低地址

IIC_Wait_Ack();     

IIC_Send_Byte(DataToWrite);     //发送字节   

IIC_Wait_Ack();         

    IIC_Stop();//产生一个停止条件 

delay_ms(10);  

}

读一个字节程序

54。I2C通信实验
前面一段为DUMMY WRITE,后面才读入一个DATA

//在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)<<1));   //发送器件地址0XA0,写数据,为了兼容其他型号                                                                                                 的IIC芯片  

IIC_Wait_Ack(); 

    IIC_Send_Byte(ReadAddr%6);   //发送低地址

IIC_Wait_Ack();    

IIC_Start();     

IIC_Send_Byte(0XA1);           //进入接收模式 ,这里24C02读地址为A1 

IIC_Wait_Ack();  

    temp=IIC_Read_Byte(0);   

    IIC_Stop();//产生一个停止条件    

return temp;

}

三。实验程序讲解

//要写入到24c02的字符串数组

const u8 TEXT_Buffer[]={"WarShipSTM32 IIC TEST"};  //定义一个字符串数组

#define SIZE sizeof(TEXT_Buffer) //SIZE为数组大小,比定义的数组大1,因为编译器自动在字符串结尾加了                                                           一个结束符 \0

 int main(void)

 {  

u8 a,key;

u16 i=0;

u8 datatemp[SIZE];

delay_init();     //延时函数初始化  

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级

uart_init(115200); //串口初始化为115200

LED_Init();   //初始化与LED连接的硬件接口

LCD_Init();   //初始化LCD

KEY_Init(); //按键初始化

AT24CXX_Init(); //IIC初始化 

  POINT_COLOR=RED;//设置字体为红色 

LCD_ShowString(30,50,200,16,16,"WarShip STM32");

LCD_ShowString(30,70,200,16,16,"IIC TEST");

LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");

LCD_ShowString(30,110,200,16,16,"2015/1/15");

LCD_ShowString(30,130,200,16,16,"KEY1:Write  KEY0:Read"); //显示提示信息

  while(AT24CXX_Check())//检测不到24c02

{

LCD_ShowString(30,150,200,16,16,"24C02 Check Failed!");

delay_ms(500);

LCD_ShowString(30,150,200,16,16,"Please Check!      ");

delay_ms(500);

LED0=!LED0;//DS0闪烁

}

LCD_ShowString(30,150,200,16,16,"24C02 Ready!");    

  POINT_COLOR=BLUE;//设置字体为蓝色

  

while(1)

{

key=KEY_Scan(0);

if(key==KEY1_PRES)//KEY_UP按下,写入24C02

{

LCD_Fill(0,170,239,319,WHITE);//清除半屏    

  LCD_ShowString(30,170,200,16,16,"Start Write 24C02....");

AT24CXX_Write(0,(u8*)TEXT_Buffer,SIZE);  //写入字符串数组

LCD_ShowString(30,170,200,16,16,"24C02 Write Finished!");//提示传送完成

}

if(key==KEY0_PRES)//KEY1按下,读取字符串并显示

{

  LCD_ShowString(30,170,200,16,16,"Start Read 24C02.... ");

AT24CXX_Read(0,datatemp,SIZE);    //读出字符串数组

LCD_ShowString(30,170,200,16,16,"The Data Readed Is:  ");//提示传送完成

LCD_ShowString(30,190,200,16,16,datatemp);//显示读到的字符串

}

i++;

delay_ms(10);

if(i==20)

{

LED0=!LED0;//提示系统正在运行

i=0;

}   

}

}


关键字:I2C  通信实验 引用地址:54。I2C通信实验

上一篇:55.SPI接口原理与配置
下一篇:53.PWM DAC实验

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

I2C总线万能程序C语言
reg51.h #include intrins.h unsigned char SystemError; sbit SCL= P1^6; //定义串行时钟线所在口 使用时根据自己的需要来定义 sbit SDA= P1^7; //定义串行数据线所在口 使用时根据自己的?枰?炊ㄒ? #define SomeNOP(); {_nop_();_nop_();_nop_();_nop_();} /*-------------------------------------------------------------------------------- 调用方式:void AD7416_I2CStart(void) 2003/05
[单片机]
STM32小白入门(第12天)-------I2C协议
一、概述 二、信号概念 三、AT24C02(EEPROM电可擦除ROM)--配合单片机存贮掉电前需要保存的数据,类似单片机的硬盘 1、写时序 2、读时序 思考题2:在24c02控制时钟的时候,为什么要进行5us的延时,小于5us延时或许大于5us的延时是否可以,示例代码如下: //设置SCL高电平 SCL=1; delay_us(5); //设置SCL低电平 SCL=0; delay_us(5); 回答:大于5us是可以的,如果使用5ms是可以的。但是延时是不能低于1.2us,详细描述如下图。 3、起始信号和停止信号 //sda输
[单片机]
STM32小白入门(第12天)-------<font color='red'>I2C</font>协议
STM32 HAL库 I2C 学习
static void MX_I2C1_Init(void) { hi2c1.Instance = I2C1; \ 设置I2C实体 hi2c1.Init.ClockSpeed = 100000; \ 设置clk速率,从而设置TRISE,CCR,DUTY等寄存器 hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2; \ 设置占空比T low /T high = 2 (CCR寄存器14位) hi2c1.Init.OwnAddress1 = 100; \ 设置地址A0,8位地址 hi2c1.Init.AddressingMode = I
[单片机]
26.3.4.2内核下的I2C驱动(一)
1.硬件协议 1.1mini2440 I2C设备如图所示 1.2 I2C协议如下: 1.3启动和停止信号如下图 1.4 I2C总线数据传输时序: 1.5 2440只负责发送,不知道数据含义,只有外设知道。如何写一个字节?参考AT24CXX手册 。 注意:I2C设备读之前先写! 2.软件框架 2.1总线-设备-驱动模型如下图所示   把某个结构体,左右的放入链表,一一比较,匹配调用probe函数   设备链表 driver链表, 总线提供了match函数 linux-2.6.22.6Documentationi2cinstantiating-devices 2.2如何构造I2C_CLIENT?设
[单片机]
26.3.4.2内核下的<font color='red'>I2C</font>驱动(一)
STM8S103硬件I2C的操作注意事项
1. STM8的SCL和SDA这两个引脚标注了T,即纯开漏引脚。纯开漏引脚输0时为低,输出1为高阻态,而不是高电平。所以,这两个脚需要加上拉电阻。 2. SCL设置为OUTPUT没有毛病,SDA在STM8作为主机读取从机数据时要设置为输入、作为主机向从机写数据时要设置为输出,这里PB_CR1就要设置为0(输出时为开漏,输入时为浮空)。SDA作为输出时,其输出的速率被限定在 O1= slow(up to 2MHz),所以PB_CR2的对应 bit 就没有必要设置为1(output时),另外设置为1时(且SDA引脚为input时)会否触发中断?(初步思考:应该不会吧,都I2C了,不是GPIO) 3.寄存器I2C_CR2中的 b
[单片机]
I2C总线相关常见问题,这些器件可以关注下
内部集成电路总线(I2C)是一种同步串行数据通信总线,是一种极为常见的协议,用于连接微控制器及其外围设备。这种在每一个工程师的设计中几乎都可能遇到的总线技术,却总是可能因为各种不经意的问题为大家的设计带来不大不小的挑战。比如,一般器件都提供开漏输出,表示它们只能稍微下拉,这在实现双向通信的同时也意味着需要上拉才能在总线上实现高电平状态。如何确定上拉的大小?这是设计人员常常会提出的一个问题。 在网上找到许多相关资料,但是最后发现,需要满足的所有电气规格都已在如下的表中列出。在确定应用计划的数据速率运行之后,查看规格表找到所需的上升时间即可。如果不知道总线的电容,可以估测一个值,例如每个器件30微微法拉,然后据此实施调节。但是上拉
[模拟电子]
<font color='red'>I2C</font>总线相关常见问题,这些器件可以关注下
51单片机串口通信实验电路详解
  51单片机是对所有兼容Intel 8031指令系统的单片机的统称。该系列单片机的始祖是Intel的8004单片机,后来随着Flash rom技术的发展,8004单片机取得了长足的进展,成为应用最广泛的8位单片机之一,其代表型号是ATMEL公司的AT89系列,它广泛应用于工业测控系统之中。   很多公司都有51系列的兼容机型推出,今后很长的一段时间内将占有大量市场。51单片机是基础入门的一个单片机,还是应用最广泛的一种。需要注意的是51系列的单片机一般不具备自编程能力。   单片机的串口通信看起来是很复杂的,主要是因为他用到了更多的寄存器,与前面的知识相比他更具综合能力,写起来考虑的问题自然也变多了。而前面学习过的定时器
[单片机]
51单片机串口<font color='red'>通信</font><font color='red'>实验</font>电路详解
凌特推出具有板载ADC的四通道I2C热插拔控制器
凌特公司推出的新型四电源热插拔(Hot Swap)控制器LTC4245具有8位片上ADC和I2C兼容接口。LTC4245拥有支持3.3V、5V和±12V CompactPCI或12V、3.3V和辅助3.3V PCI Express的灵活性,通过测量板卡电压、电流和记录故障状态提供集成的数字电源监视功能。 在这样的高可用性系统中,仔细监视电源分配网络是否处于正常状态及其统一性是至关重要的。对于每个电源而言,ADC寄存器中的信息均可以通过I2C总线来查询,以确定板卡的工作状态是否正常。LTC4245对凌特公司的单通道LTC4215以及高压正和负48V热插拔控制器LTC4260和LTC4261起到了补充作用,这两款高压器件也具有片上A
[新品]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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