1、GPIO的工作模式有八种。IIC的SCL可设置为输出,但是SDA需要收发信号,所以要设置为输入和输出两种形式。

#define SDA_IN()  {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)8<<28;}
#define SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)3<<28;}//IO操作函数
#define IIC_SCL    PBout(6) //位带操作调用SCL输出时的PIN脚
#define IIC_SDA    PBout(7) //位带操作调用SDA输出时的PIN脚
#define READ_SDA   PBin(7)  //位带操作调用SDSA输入时的PIN脚

解释一下SDA_INT()的宏定义是给PB7引脚设置为推完输出模式。
在GPIO寄存器中,每个引脚占用四个位。CRL寄存器是32,用来控制0-7的八个引脚。8的二进制是1000,8<<28后的值为:1000 0000 0000 0000 0000 0000 0000 0000 此时从左到右每四位控制从P7到P0的一个GPIO 可见刚好是P7引脚别设为1000,其他引脚为0.查询GPIO->CRL寄存器的定义可知,此时的引脚被设定为推完出书模式。SDA_OUT与之类似。

下面是一些IIC协议的组成函数:

void IIC_Init(void);                //初始化IIC的IO口//即初始化IIC的两个引脚,空闲时为高电平
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信号

1、起始信号和终止信号:
前者是在SCL为高电平期间SDA产生下降沿,后者是SCL高电平期间SDA产生上升沿。

void IIC_Start(void)
{SDA_OUT();     //设置sda线输出IIC_SDA=1;         IIC_SCL=1;delay_us(4);IIC_SDA=0;        //产生下降沿delay_us(4);IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
}
//产生IIC停止信号
void IIC_Stop(void)
{SDA_OUT();//sda线输出IIC_SCL=0;IIC_SDA=0;//产生上升压delay_us(4);IIC_SCL=1; IIC_SDA=1;//发送I2C总线结束信号delay_us(4);
}

可见IIC协议在空闲时刻为高电平,若设备要钳主SCL线准备发送数据,就要持续拉低SCL。
2、读写一个字节:

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);   //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();//发送nACKelseIIC_Ack(); //发送ACK   return receive;
}

3、应答信号:

//不产生应答,即在第九个时钟沿持续设置SDA为高
void IIC_NAck(void)
{IIC_SCL=0;SDA_OUT(); //设置数据输出方向IIC_SDA=1;  //持续拉高SDAdelay_us(2);IIC_SCL=1;  //产生第九个时钟沿delay_us(2);IIC_SCL=0; //第九个时钟沿结束
}

同理,产生应答就是在第九个时钟将SDA拉低后释放。等待设备应答就是设置SDA方向为输入,然后在第九个时钟沿到来前将SDA拉高等待从机设备将SDA拉低产生应答信号。


24C02写一个字节的时序如上图:
首先发送一个开始信号,然后发送设备地址,设备地址的最后一位表示本次操作是读(0)还是写(1),然后等待从设备应答,接着发送要写入的地址,等待从机应答,最后写入要写入的数据,等待从机应答,然后主机发出停止信号,结束本次操作。

void at_writeByte(u8 addr,u8 data)
{IIC_Start()    ;IIC_Send_Byte(ADDR+W);    IIC_Wait_Ack();IIC_Send_Byte(addr);IIC_Wait_Ack();IIC_Send_Byte(data);IIC_Wait_Ack();IIC_Stop();delay_ms(10);
}


读取指定地址中的一个字节数据如上图:
前部分与写相同,只不过是在主机发送完要读的地址并收到从机的应答信号后,在发一次开始信号,进入读操作,接着发送设备地址和读信号,收到应答后将SDA的方向设置为输入开始读取从设备发的信号,接收完毕后可以选择发出应答或者不应答给从设备,最后产生停止信号结束本次操作。

u8 at_readByte(u8 addr)
{u8 temp;IIC_Start();IIC_Send_Byte(0xA0);   IIC_Wait_Ack();IIC_Send_Byte(addr);IIC_Wait_Ack();IIC_Start(); IIC_Send_Byte(0xA1); IIC_Wait_Ack();temp=IIC_Read_Byte(0);IIC_Stop();return temp;
}

这里在24c02中的某一个地址写入一个数据,然后读出来校验是否正确。

   at_writeByte( addr,0x25); //在addr中写入0x25i= at_readByte( addr);  //读取addr数据while(1){USART_SendData(USART1, i);  //通过串口发送while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);}

运行结果:

显示从24C02中读取的数据是25(十六进制),与写入的数据相同。

24C02比起flash的优点是:可以直接操作某个字节,而FLASH则是需要擦除某个扇区或者整个存储空间。也就是说24C02可以直接访问某个字节(注意容量)
24C02比起flash的相同点:两者都是ROM,都可以在掉电的时候保存数据。
24C02比起flash的缺点是:容量普遍小,一般只有几K到十几Kbite。

喜欢就点个赞吧!一路走来,不断学习。

STM32的IIC(模拟)读写AT24c02相关推荐

  1. STM32CubeMx HAL库使用硬件IIC读写AT24C02

    介绍使用硬件IIC接口读写AT24C02,STM32自带硬件IIC,比较好用,没必要千篇一律的使用模拟IIC.作为一个IIC的使用例子,可以适当修改用于其他IIC接口设备通信控制. 一.测试环境 ST ...

  2. 基于STM32的I2C通信 2(读写AT24C02)

    本文采用STM32的模拟I2C对 EEPROM(AT24C02)进行读写操作. 1.EEPROM(24C02):I2C接口 1.1-24C02器件介绍: AT24C02的总容量是256个字节,也就是2 ...

  3. stm32之IIC应用实例(AT24C02芯片,硬件和软件方式驱动)

    目录 1.物理层: 2.协议层: 3.数据的传输: 4.程序设计 写完回头一看发现字数还不少,如果你觉得文字太枯燥,那么可以跳到后面程序设计,直接动手做实验.如果想仔细了解关于IIC协议的细节,那么希 ...

  4. STC12C5A60S2使用模拟IIC通信与AT24C02芯片编程

    文章目录 一.前言 二.IIC通讯详解 2-1.IC协议简介 2-2.常用的IIC通讯设备 2-3.IIC物理层特点 2-4.IIC协议层特点 2-4-1.IIC基本读写过程 2-4-2.通讯起始和停 ...

  5. 【STM32】IIC的基本原理(实例:普通IO口模拟IIC时序读取24C02)(转载)

    版权声明:本文为博主原创文章,允许转载,但希望标注转载来源. https://blog.csdn.net/qq_38410730/article/details/80312357 IIC的基本介绍 I ...

  6. linux下at24c02驱动程序,Linux下iic(i2c)读写AT24C02

    linux内核上已有iic的驱动,因此只需要对该iic设备文件进行读写则能够控制外围的iic器件.这里以AT24C02为对象,编写一个简单的 linux内核上已有iic的驱动,因此只需要对该iic设备 ...

  7. 基于stm32单片机的模拟IIC时序(附源码)

    我下面要说的是基于stm32单片机的模拟IIC时序,以及是一些要注意的事项:结合自己所做的MMA7455加速度传感器,我把模拟IIC的源代码贴了出来,大家可以参考一下. 1.因为在IIC协议中,当总线 ...

  8. STM32基于软件模拟IIC进行AHT21B温湿度采集

    STM32基于软件模拟IIC进行AHT21B温湿度采集 一. IIC简介 1.1 IIC简介 1.2 实现方式 1.3 实现方式对比 二. AHT21B简介 2.1 简介 2.2 产品特点 2.3 外 ...

  9. STM32 IIC协议 读写EEPROM

    EEPROM.MCU6050和OLED显示屏外设都是通过IIC协议[半双工]进行通信. 除此之外,另一个广泛地使用在系统内多个集成电路间的通讯协议:SPI. 目录 一.IIC物理层: 二.IIC协议层 ...

  10. stm32 i2c/IIC读写HP303S气压传感器

    该款芯片的详细信息可以看其数据手册 ,这里不多做介绍. 读写HP303S的操作是基于IIC通讯的.本实验采用的是硬件IIC通讯,所以器件地址是0x77,值得注意的是,在stm32的硬件IIC 读写操作 ...

最新文章

  1. Java 技术篇 - 连接oracle数据库执行sql使用close()关闭createStatement()无效无法清除游标缓存问题解决,报“ORA-01000: 超出打开游标的最大数“错误解决方法
  2. 图像间距pitch是什么?(linesize、stride)(指图像中的一行图像数据所占的存储空间的长度)
  3. 2021 网易创新企业大会来了
  4. solr中的ik分词器的原理是什么
  5. Leetcode--1028. 从先序遍历还原二叉树(Java)
  6. 超越软件上云 讲述每天1亿公里行驶背后的大生意
  7. TensorFlow11CNN和全卷积神经网络
  8. 程序设计C++使大家容易陷入重复劳动
  9. Cadence PSpice 模型3:从官网或者技术支持得到的PSpice模型与Capture库关联方法图文教程
  10. ORACLE 12C连接时报ORA28040和ORA01017的错误
  11. CAD如何导出PDF格式
  12. Word2010中插入多级列表编号将默认标题样式变成多级编号
  13. 秒的换算:ms(毫秒),μs(微秒),ns(纳秒),ps(皮秒)
  14. 王垠《清华梦破碎》沉思与反省
  15. 记录自己在pyqt5用电脑摄像头拍照并保存照片过程中发现的问题
  16. SpMV矩阵格式自动调优
  17. 怎么查验佳能EOS单反相机是否正品
  18. 梦幻仙缘剧情java_梦幻仙缘新春赚红包版
  19. LINUX嵌入式开发板上配置FTP 服务
  20. (2018)Oruxmaps最新离线地图(地图包)制作教程

热门文章

  1. 数据分析 波士顿房价预测
  2. css3边框线border
  3. 江西赣州移动宽带DNS
  4. keyshot聚光灯_【干货】如何在KeyShot中创建和使用物理灯光!
  5. 133 十面埋伏的并发(二):自旋锁
  6. 美国大学生数学建模matlab,2019MCM美国大学生数学建模竞赛A题赛后总结
  7. LPDDR4x 的 学习总结(4) - SDRAM chip的组织结构
  8. 超融合一定会成为主流
  9. 计算机硬件清理步骤,怎么清理电脑内存(如何深度清理电脑内存步骤)
  10. 浅谈白化(Whitening) 、PCA白化、ZCA白化