STM32模拟IIC读写24C02程序代码
STM32 模拟IIC读写24C02程序代码
最近用到STM32F103V来读写A T24C02 EEPROM 于是从原来51单片机的程序代码的基础上修改了下,移植到了STM32,测试工作正常。
引脚定义和配置:
#define SCL GPIO_Pin_6 //24C02 SCL
#define SDA GPIO_Pin_7 //24C02 SDA
void GPIO_Configuration(void)
{
RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 |RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD |
RCC_APB2Periph_GPIOE, ENABLE);
GPIO_InitStructure.GPIO_Pin = SCL; //24C02 SC L
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = SDA; //24C02 SDA 作为输出
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void AT24C02_SDA_IO_SET(unsigned char io_set) //SDA引脚输入输出设置
{
if(io_set==0)
{
GPIO_InitStructure.GPIO_Pin = SDA; //24C02 SDA 作为输出
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
else if(io_set==1)
{
GPIO_InitStructure.GPIO_Pin = SDA; //24C02 SDA 作为输入GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入GPIO_Init(GPIOB, &GPIO_InitStructure);
}
else
{;}
}
////////////////////////////////////主程序////////////////////////////////////////////////////////////////////// ////////
int main(void)
{ uchar i;
uchar data_24c02;
RCC_Configuration(); //时钟配置
GPIO_Configuration();//GPIO配置
USARTx_configuration();//串口配置
WIN24C02_init();
delayms(5000);//延时
for(i=0;i<20;i++) //写EEPROM数据
{ WIN24C02_write(0x00+i,i);delayms(100);}//存数据到EEPROM
delayms(1000);//延时
while(1)//串口3发送读取的EEPROM的数据
{
for(i=0;i<20;i++)
{ data_24c02=WIN24C02_read(0x00+i);//读取24C02数据
USART_SendData(USART3 ,data_24c02);
while(USART_GetFlagStatus(USART3,
USART_FLAG_TC)==RESET);
}
delayms(5000);//延时
}
/////////////////////////////////////////////////////////////////// //////////////////////////////////////////////
WIN_24C02.H头文件
/**********************中文版本*******************************/
/*****功能描述: STM32 24C02 读写程序*****/
/*****作者: 郑文(ClimberWin) *****/
/*****编写日期: 2013年1月21日*****/
/*****版本信息: V1.0 *****/
/*****修改日期: *****/
/*************************************************************/ #ifndef __WIN24C02_H__
#define __WIN24C02_H__
#include"STM32_Config.h"
#define uchar unsigned char
#define uint unsigned int
uchar WIN24C02_read(uchar address); //从24c02的地址address中读取一个字节数据
void WIN24C02_write(uchar address,uchar info); //向24c02的address地址中写入一字节数据info
void WIN24C02_init(); //24c02初始化子程序
void delay_nop(void);
void delay2(uint x);
void start();
void stop();
void writex(uchar j);
uchar readx();
void clock();
void delay2(uint x)
{
uint i;
for(i=0;i
}
void delay_nop(void)
{
uint8_t i=10; //i=10延时1.5us//这里可以优化速度,经测试最低到5还能写入while(i--);
}
void WIN24C02_init()
{
//SCL=1;
GPIO_SetBits(GPIOB,SCL);
delay_nop();
//SDA=1;
GPIO_SetBits(GPIOB,SDA);
delay_nop();
}
void start()
{
//SDA=1;
GPIO_SetBits(GPIOB,SDA);
delay_nop();
//SCL=1;
GPIO_SetBits(GPIOB,SCL); delay_nop();
//SDA=0;
GPIO_ResetBits(GPIOB, SDA); delay_nop();
//SCL=0;
GPIO_ResetBits(GPIOB, SCL); delay_nop();
}
void stop()
{
//SDA=0;
GPIO_ResetBits(GPIOB, SDA); delay_nop();
//SCL=1;
GPIO_SetBits(GPIOB,SCL); delay_nop();
//SDA=1;
GPIO_SetBits(GPIOB,SDA); delay_nop();
}
void writex(uchar j)
{
uchar i,temp,temp1;
temp=j;
//A T24C02_SDA_IO_SET(0); for (i=0;i<8;i++)
{
temp1=temp & 0x80;
temp=temp<<1;
//SCL=0;
GPIO_ResetBits(GPIOB, SCL);
delay_nop();
//SDA=CY;
if(temp1==0x80)
{GPIO_SetBits(GPIOB, SDA);} else {GPIO_ResetBits(GPIOB, SDA);} delay_nop(); // SCL=1;
GPIO_SetBits(GPIOB,SCL);
delay_nop();
}
//A T24C02_SDA_IO_SET(0);
//SCL=0;
GPIO_ResetBits(GPIOB, SCL);
delay_nop();
//SDA=1;
GPIO_SetBits(GPIOB,SDA);
delay_nop();
}
uchar readx()
{
uchar i,j,k=0;
//SCL=0;
GPIO_ResetBits(GPIOB, SCL);
delay_nop();
//SDA=1;
GPIO_SetBits(GPIOB,SDA);
AT24C02_SDA_IO_SET(1);
for (i=0;i<8;i++)
{
delay_nop();
//SCL=1;
GPIO_SetBits(GPIOB,SCL);
delay_nop();
//if (SDA==1) j=1;
if( GPIO_ReadInputDataBit(GPIOB,SDA)==1 ) {j=1;}
else
{j=0;}
k=(k<<1)|j;
//SCL=0;
GPIO_ResetBits(GPIOB, SCL);
}
AT24C02_SDA_IO_SET(0);
delay_nop();
return(k);
}
{
uint i=0;
AT24C02_SDA_IO_SET(1);
//SCL=1;
GPIO_SetBits(GPIOB,SCL);
delay_nop();
while
((GPIO_ReadInputDataBit(GPIOB,SDA)==1)&&(i<5000))i++;
//SCL=0;
GPIO_ResetBits(GPIOB, SCL);
delay_nop();
AT24C02_SDA_IO_SET(0);
}
uchar WIN24C02_read(uchar address)
{
uchar i;
start();
writex(0xa0);
clock();
writex(address);
clock();
start();
writex(0xa1);
clock();
i=readx();
stop();
//delay2(10);
delay2(50);
return(i);
}
void WIN24C02_write(uchar address,uchar info) {
start();
writex(0xa0);
clock();
writex(address);
writex(info);
clock();
stop();
//delay2(50);
delay2(250); }
#endif
STM32----6----I2C读写AT24C02 文章发表于:2011-05-09 13:51 STM32作为主机I2C,读写24C02 EEPROM 1、时钟和数据的传输:开始和停止条件,数据在SCL的高电平期间有效,在SCL的低电平期间改变。 2、开始条件:在SCL高电平期间,SDA产生一个下降沿 3、停止条件:在SCL高电平期间,SDA产生一个上升沿 4、应答:成功接收到数据(地址和数据),产生一个应答位(在第9个时钟周期,将SDA拉低) 下面是源程序:原理上说,下面程序再移植时,只要将数据类型变化,可以应用到任何处理器 AT24c02.h #ifndef __24CXX_H #define __24CXX_H #include "i2c.h" /*************************************************************** - 说明:以下参数是AT24Cxx的寻址空间,C0x ,X 表示XK 如C01表示1K - 127表示2^7 1Kbit/8=128Byte 128字节 - 255表示2^8 2Kbit/8=256Byte 256字节 - 512表示2^9 4Kbit/8=512Byte 512字节 - ***************************************************************/ #define AT24C01 127 #define AT24C02 255 #define AT24C04 511 #define AT24C08 1023 #define AT24C16 2047 #define AT24C32 4095 #define AT24C64 8191 #define AT24C128 16383 #define AT24C256 32767 /************************************************************** --板子使用的是24c02,所以定义EE_TYPE为AT24C02 **************************************************************/ #define EE_TYPE AT24C02
STM32模拟IIC读写24C02程序代码 STM32 模拟IIC读写24C02程序代码 最近用到STM32F103V来读写A T24C02 EEPROM 于是从原来51单片机的程序代码的基础上修改了下,移植到了STM32,测试工作正常。 引脚定义和配置: #define SCL GPIO_Pin_6 //24C02 SCL #define SDA GPIO_Pin_7 //24C02 SDA void GPIO_Configuration(void) { RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 |RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE, ENABLE); GPIO_InitStructure.GPIO_Pin = SCL; //24C02 SC L GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = SDA; //24C02 SDA 作为输出 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); } void AT24C02_SDA_IO_SET(unsigned char io_set) //SDA引脚输入输出设置 { if(io_set==0) { GPIO_InitStructure.GPIO_Pin = SDA; //24C02 SDA 作为输出
本程序是HCS系列都可以本人已通过实验下面是程序代码 /*****************头文件*****************************************/ #include
为了练习STM32的模拟IIC 写了与24C01的通信并测试通过 用了STM32的PC0—SCL PC1—SDA void GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOC,&GPIO_InitStructure); } #include"stm32f10x.h" #include"about_24c01.h" void IIC_Delay(void); #define SDA_H GPIOC->BSRR=GPIO_Pin_1 #define SDA_L GPIOC->BRR=GPIO_Pin_1 #define SCL_H GPIOC->BSRR=GPIO_Pin_0 #define SCL_L GPIOC->BRR=GPIO_Pin_0 #define SDA_Read GPIOC->IDR&GPIO_Pin_1 bool IIC_Start(void) { SCL_H; SDA_H; IIC_Delay(); if(!SDA_Read) return FAILED; SDA_L;
if(SDA_Read) return FAILED; SCL_L; IIC_Delay(); return PASS; } void IIC_Stop(void) { SCL_H; SDA_L; IIC_Delay(); SDA_H; IIC_Delay(); } bool IIC_WriteByte(uint8_t byte) { uint8_t i=8; uint8_t mask=0x80; while(i--) { SCL_L; IIC_Delay(); if(byte&mask) { SDA_H; } else { SDA_L; } mask>>=1; IIC_Delay(); SCL_H; IIC_Delay(); } SCL_L; SDA_H; IIC_Delay(); SCL_H;
24c02典型程序
#include
***************************************** ***/ void delayms(uchar j) { uint i; for(;j>0;j--) { for(i=0;i<125;i++) {;} } } /**************************************** *** 函数名称:rom_write() 功能:循环写进num个字节 参数:如下 返回值:无 ***************************************** ***/ void rom_write(uchar date[],uchar
address,uchar num) { uchar i; // 循环次数 iic_start(); iic_write(adwrite); // 24c02写地址 iic_ack(); iic_write(address); // 24c02起始存储地址写入可自动+1 iic_ack(); for(i=0;i 如果是使用硬件IIC,这里使用的是STM32的固件库,硬件模块使用之前必须配置其参数,IIC的配置如下: void IIC_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; IIC_InitTypeDef IIC_InitStructure; RCC_ClocksTypeDef rcc_clocks; /* GPIO Peripheral clock enable */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOB|RCC_AHB1Periph_GPIO C, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_IIC1|RCC_APB1Periph_IIC2|RCC_APB1Periph_IIC3, ENABLE); /* Reset IICx IP */ RCC_APB1PeriphResetCmd(RCC_APB1Periph_IIC1|RCC_APB1Periph_IIC2|RCC_APB1Periph_IIC3, ENABLE); /* Release reset signal of IICx IP */ RCC_APB1PeriphResetCmd(RCC_APB1Periph_IIC1|RCC_APB1Periph_IIC2|RCC_APB1Periph_IIC3, DISABLE); /*IIC1 configuration*/ GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_IIC1); //注意,此处不能合并写成GPIO_PinSource6|GPIO_PinSource7 GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_IIC1); //PB6: IIC1_SCL PB7: IIC1_SDA GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOB, &GPIO_InitStructure); /* IIC Struct Initialize */ IIC_DeInit(IIC1); IIC_InitStructure.IIC_Mode = IIC_Mode_IIC; IIC_InitStructure.IIC_DutyCycle = IIC_DutyCycle_2; IIC_InitStructure.IIC_OwnAddress1 = 0x00; IIC_InitStructure.IIC_Ack = IIC_Ack_Enable; IIC_InitStructure.IIC_ClockSpeed = 100000; IIC_InitStructure.IIC_AcknowledgedAddress = IIC_AcknowledgedAddress_7bit; IIC_Init(IIC1, &IIC_InitStructure); /* IIC Initialize */ ATMEGA16读写iic(24c02) C语言程序测试通过 #include while(1) {/* I2C_Write('n',0x00); I2C_Write('c',0x01); I2C_Write('e',0x02); I2C_Write('p',0x03); I2C_Write('u',0x04); */ i=I2C_Read(0x00); //LCD_write_char(0,0,i); USART_TXD(i); i=I2C_Read(0x01); //LCD_write_data(i); USART_TXD(i); i=I2C_Read(0x02); //LCD_write_data(i); USART_TXD(i); i=I2C_Read(0x03); //LCD_write_data(i); USART_TXD(i); i=I2C_Read(0x04); //LCD_write_data(i); USART_TXD(i); } } /*上面上主函数部分*/ #include 24C02断电记忆功能 本人在学习IIC过程中,想要实现AT24C02的断电记忆功能,但在网上找了很多资料,都找不到方向。有人说需要电源检测芯片。后来请教别人,得到了一些启示,不使用电源检测芯片即可显示断电记忆的现象,特此与广大电子爱好者一同分享。 本人使用数码管来显示断电记忆的现象。在开发板上选通一位数码管,使数码管从0~F间隔一秒左右循环显示,比如显示到“C“,将开发板断电或按键复位,断电或按键复位后,数码管不会从0开始显示,而是继续从”C”开始显示,“C——D——E——F——0——1……”。在此将源程序与大家分享。 /********writer:XUWU********/ /********DATE:2016.9.11********/ /*程序中开始、停止、应答、写数据等程序都是参照郭天祥老师的视频教程*/ #include //实验24C02连接在PF口 //WP、A0、A1、A2都接地 #include "stm32f10x_flash.h" #include "stm32f10x_gpio.h" #include "stm32f10x_rcc.h" #define AT24C02 0xa0 //AT24C02 地址 /******************************** 变量定义---------------------------------------------------------*/ GPIO_InitTypeDef GPIO_InitStructure; //GPIO ErrorStatus HSEStartUpStatus; unsigned char Count1 , Count2; unsigned int USEC; static vu32 TimingDelay; unsigned char Readzfc; unsigned char pDat[8] = {0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55}; unsigned char R_Dat[8]; /*********************************声明函数-----------------------------------------------*/ void RCC_Configuration(void); void SysTick_Configuration(void); void Delay_us_24C02(u32 nTime); /************************************24C02硬件接口******************************/ #define SData GPIO_Pin_6 //I2C 时钟 #define SCLK GPIO_Pin_7 //I2C 数据 /********************************宏定义*******************************************/ #define SCL(x) x ? GPIO_SetBits(GPIOF , SCLK) : GPIO_ResetBits(GPIOF , SCLK) #define SDA(x) x ? GPIO_SetBits(GPIOF , SData) : GPIO_ResetBits(GPIOF , SData) /********************************变量*******************************************/ u8 ack; /******************************************************************* 起动总线函数 函数原型: void Start_I2c(); 功能: 启动I2C总线,即发送I2C起始条件. ********************************************************************/ void Start_I2c() 应广单片机读写24C02程序代码 #include "extern. h〃 #include ,z main. h" ] f • 1 • • I • • I • • I • • I • • I • • I • • I • • 1 • • I • • I • • I • • I • • I • • I • • I • • 1 • • I • • I • • I • • I •• I • • I • • I • • 1 • • I • • I • • I • • I • • I • • I • • I • • 1 • • I • • I • • I • • I • • I • • I • • I • • 1 • • I • • I • • I • • I • • I • • I • • I • • 1 • • I • • I • 1 / t f ^ 实验八 24C02读写实验 一、实验概述 使用I2C对24C02进行读写,记录开机的次数。 二、实验目的 1、掌握单片机IO模拟I2C总线的方法。 2、了解EEPROM保存数据的特性。 三、实验预习要求 1、AT24C02是一个2K位串行CMOS E2PROM,内部含有256个8位字节,CATALYST公 司的先进CMOS技术实质上减少了器件的功耗。AT24C02有一个16字节页写缓冲器。该器件通过IIC总线接口进行操作,有一个专门的写保护功能。 2、器件寻址: 前八位是地址地址信号,从最高位(MSB)开始,其中前四位是固定值1010,后三位有管脚A0、A1、A2的基地情况确定。最后一位是读写控制信号,0表示写,1表示读。若与SDA线发送过来的地址比较一致,则器件输出应答0,否则将返回等待状态。器件内部地址寻址是在器件寻址之后,对256个字节进行寻址,直接传送8位地址信 号(00-FF)对应于器件内部的地址。 四、实验原理 在实际的应用中,保存在单片机 RAM 中的数据,掉电后就丢失了,保存在单片机的FLASH 中的数据,又不能随意改变,也就是不能用它来记录变化的数值。但是在某些场合,我们又确实需要记录下某些数据,而它们还时常需要改变或更新,掉电之后 数据还不能丢失,比如我们的家用电表度数,电视机里边的频道记忆,一般都是使用EEPROM 来保存数据,特点就是掉电后不丢失。本实验使用的这个器件是 24C02,是 一个容量大小是 2Kbits,也就是 256 个字节的 EEPROM。一般情况下,EEPROM 拥有30 万到 100 万次的寿命,也就是它可以反复写入 30-100 万次,而读取次数是无限的。 24C02 是一个基于 I2C 通信协议的器件,因此,使用24C02还需要了解I2C通信协议。I2C 多用于板内通信,比如单片机和EEPROM 之间的通信。 STM32用GPIO模拟IIC通讯C语言源码实测可用以下是一段用于STM32的GPIO模拟IIC(I2C)通讯的C语言源码:```c #include "stm32f10x.h" //定义SDA和SCL的GPIO端口和引脚 #define SDA_GPIO GPIOB #define SDA_PIN GPIO_Pin_7 #define SCL_GPIO GPIOB #define SCL_PIN GPIO_Pin_6 //定义IIC的延时函数 void IIC_Delay volatile int i = 100; while (i--); //IIC开始信号 void IIC_Start //先置SDA和SCL为高电平 GPIO_SetBits(SDA_GPIO, SDA_PIN); GPIO_SetBits(SCL_GPIO, SCL_PIN); IIC_Delay(; //再拉低SDA,产生开始信号 GPIO_ResetBits(SDA_GPIO, SDA_PIN); IIC_Delay(; GPIO_ResetBits(SCL_GPIO, SCL_PIN); //IIC停止信号 void IIC_Stop //先置SDA为低电平 GPIO_ResetBits(SDA_GPIO, SDA_PIN); IIC_Delay(; //再拉高SDA,产生停止信号 GPIO_SetBits(SDA_GPIO, SDA_PIN); IIC_Delay(; GPIO_SetBits(SCL_GPIO, SCL_PIN); //IIC发送一个字节数据 void IIC_WriteByte(uint8_t data) uint8_t i; for (i = 0; i < 8; i++) //先将SCL拉低 GPIO_ResetBits(SCL_GPIO, SCL_PIN); hal库iic读写 使用HAL库进行I2C读写,首先需要配置I2C的引脚和频率,然后利用HAL库提供的函数进行读写操作。 以下是一个简单的例子,假设我们正在使用STM32F4xx系列微控制器,我们将配置I2C1,并将其设置为从设备: ```c // 使用STM32CubeMX工具进行引脚和时钟配置 // 使能I2C1和对应的时钟 // 初始化I2C1 HAL_I2C_Init(&hi2c1); // 设置I2C1的地址 hi2c1.Instance = I2C1; hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; hi2c1.Init.OwnAddress1 = 0x30; hi2c1.Init.BusTimeout = I2C_TIMEOUT_RANGE_DEFAULT; hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; hi2c1.Init.OwnAddress2 = 0xFFU; hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; if (HAL_I2C_Init(&hi2c1) != HAL_OK) { // 初始化错误处理代码 } ``` 然后,我们可以使用以下函数进行读写操作: ```c uint8_t data[2] = {0x00, 0x01}; // 写入的数据 uint8_t readData[2]; // 读取的数据 uint16_t DevAddress = 0x30; // 设备地址 uint16_t DevReg = 0x00; // 寄存器地址 // 从设备寄存器中写入数据 HAL_I2C_Master_Transmit(&hi2c1, (DevAddress << 1) | I2C_Direction_Transmitter, (uint8_t*)data, 2, HAL_MAX_DELAY); // 从设备寄存器中读取数据 HAL_I2C_Master_Receive(&hi2c1, (DevAddress << 1) | I2C_Direction_Receiver, readData, 2, HAL_MAX_DELAY); ``` 以上代码示例仅适用于STM32F4xx系列微控制器,并且使用了HAL 库。不同的微控制器和库可能会有不同的代码,但是基本的概念是一样的。在使用I2C时,需要注意设备地址和寄存器地址,并确保数据传输的正确性。 1. AT24C02写操作 首先我们来看一下写AT24C02。 一般步骤是: 1) 发送起始信号 2) 发送写器件地址 3) 等待应答 4) 发送要写入的24C02 的地址 5) 等待应答 6) 发送要写入的数据 7) 等待应答 8) 发送数据结束发送结束信号 具体程序如下: /****************************************************************************** * * 函数名: AT24Cxx_WriteOneByte * 函数功能: 24c02写一个字节地址数据 * 输入: addr dt * 输出: 无 ********************************************/ void AT24Cxx_WriteOneByte(u16 addr,u8 dt) { I2C_Start(); if(EE_TYPE>AT24C16) { I2C_Send_Byte(0xA0); I2C_Wait_Ack(); I2C_Send_Byte(addr>>8); //发送数据地址高位 } else { I2C_Send_Byte(0xA0+((addr/256)<<1));//器件地址+数据地址 } I2C_Wait_Ack(); I2C_Send_Byte(addr%256);//双字节是数据地址低位 //单字节是数据地址低位 I2C_Wait_Ack(); I2C_Send_Byte(dt); I2C_Wait_Ack(); I2C_Stop(); delay_ms(10); } 2. AT24C02读操作 那么读取AT24C02 的步骤是: 总结IIC协议学习心得 无论在51或者stm32的学习中,我们都会使用到IIC总线的数据传送,从当初51到现在的stm32的学习。iic一直都是只会简单的使用并未很仔细的去研究中间每一个过程或者时序。今天用了一天的时间去理解IIC。当然这都是建立在以往的学习经验之中而得。一下都是我自己的一些理解和对照程序而写的一些IIC的使用过程。 iic总线时序理解: 24C04 引脚: NC (1)VCC(8) A1 (2)WP (7) A2 (3)SCL(6) GBD(4)SDA(5) 注:SCL 设置start信号和stop信号,由于此时是STM32对24c02发送信号,所以SCL和SDA设置为输出状态,即:SDA_OUT(); 由时序图可知: START:SCL=1,SDA=1,delay(),SDA=0,delay(),SCL=0,//时钟线为高,数据线从高到低的跳变 STOP :SCL=0,SDA=0,delay(),SCL=1,delay(),SDA=1,//时钟线为高,数据线从低到高的跳变 STM32程序: 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总线,准备发送或接收数据 } 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); } iic每成功传送完一个字节后,接收器都必须产生一个应答信号,应答器件在第九个时钟周期讲SDA拉低,表示已经接 收到8位,此时对于24c02有两种可能的工作方式,第一种是24c02工作于读,另一种则是工作于写。 @当工作于读的方式时,SDA为输入状态,即:SDA_IN();此时24c02发送完一个8位数据之后,释放SDA线,将SDA 为输出状态,即:SDA_OUT();并等待stm32发送一个应答信号,若接收到应答信号,则SDA又切换为输入状态,即:SDA_IN(); 然后继续发送下一个8位数据;若没有接受到应答信号,则不切换SDA的工作方式。等待STM32发送停止信号。 @当工作于写的方式时,则在每接收一个8位字节之后响应一个应答信号。 由时序图可知: 产生应答信号:SCL=0;SDA_OUT();SDA=0,delay(),SCL=1,delay(),SCL=1; 51单片机IIC总线操作及24c02指定地址的读写 (单片机用STC89C58RD+) //24c02数据读写操作。程序实现每一秒钟往24c02的指定地址内写入数据(既每一秒钟保存一次当前值)。 //共计时100秒,计时同步显示到数码管上,同时由8个led灯指示十位数的编码值。 //两个按键:单片机上电后按key6按键读取上次关机时存储到24c02内的数据,接着此数据继续计时显示。 //按key5按键计时停止。 #include uchar cont=0; uchar write=0; //标志位 uchar code table[]={0x28,0xeb,0x32,0xa2,0xe1,0xa4,0x24,0xea,0x20,0xa0}; void delay() { _nop_(); _nop_(); _nop_(); } void delay1(uchar x) { uchar a,b; for(a=x;a>0;a--) for(b=100;b>0;b--); } /***以下为24c02的IIC总线操作及读写数据的通用程序,IIC总线部分的程序可以用在其他IIC器件中 如题所示,本文是使用VHDL语言编写的IIC 总线的24C02的读写例程,程序加了中文注释便于想我一样的初学者理解,写使用的写一个字节,读使用的随机读,具体参考24c02的手册 library IEEE; use IEEE.std_logic_1164.all; useIEEE.std_logic_arith.all; useIEEE.std_logic_unsigned.all; entityiic_com is port( clk: in STD_LOGIC; rst_n: in STD_LOGIC; sw1_en: in STD_LOGIC; --读使能 sw2_en: in STD_LOGIC; --写使能 scl: out STD_LOGIC; sda: inout STD_LOGIC; dis_data: out STD_LOGIC_VECTOR (7 downto 0) ); end entity iic_com; architectureiic_communication of iic_com is signalsw_state: STD_LOGIC; signalcnt_delay: STD_LOGIC_VECTOR (8 downto 0); signalscl_pos: STD_LOGIC; signalscl_hig: STD_LOGIC; signalscl_neg: STD_LOGIC; signalscl_low: STD_LOGIC; signaldb_r: STD_LOGIC_VECTOR (7 downto 0); signalread_data: STD_LOGIC_VECTOR (7 downto 0); signalsda_r: STD_LOGIC; signalsda_in: STD_LOGIC; signalsda_link: STD_LOGIC; signal num: STD_LOGIC_VECTOR (3 downto 0); constant DEVICE_READ: STD_LOGIC_VECTOR (7 downto 0) := "10100001";--器件地址读 constant DEVICE_WRITE: STD_LOGIC_VECTOR (7 downto 0) := "10100000";--器件地址写constant WRITE_DATA: STD_LOGIC_VECTOR (7 downto 0) := "11000011"; --写入的数据 constant BYTE_ADDR: STD_LOGIC_VECTOR (7 downto 0) := "00000011";--写入的地址 type state is (IDLE,START1,ADD1,ACK1,ADD2,ACK2,START2,ADD3,ACK3,DATA,ACK4,STOP1,STOP2); signalcstate: state; signal temp_sw1,temp_sw2:Std_LOGIC; begin ---------------------- process(clk,rst_n)STM32F407的硬件IIC最全配置及读取写入函数解释
ATMEGA16读写iic(TWI)(24c02) C语言程序
24C02掉电记忆程序
STM32F103读写24C02程序,使用过肯定能用
应广单片机读写24C02程序代码
电气化自动技术 实验8-- 24C02读写-实验指导书
STM32用GPIO模拟IIC通讯C语言源码实测可用
hal库iic读写
24C02(IIC)读写操作
总结IIC协议学习心得
51单片机IIC总线操作及24c02指定地址的读写
VHDL编写IIC程序