STM32F103读写24C02 C程序 有硬件电路图和程序
24C02读写C程序

//选择性读操作,从 address 地址中读出 1 个字节 uchar Read24c02(uchar address) {
uchar ch; //伪写操作 Start(); Write8Bit(WriteDeviceAddress); //发送从器件地址,且方式为写。 while(TestAck()); Write8Bit(address); while(TestAck());
}
//从 24c02 中读出 8 个 bit uchar Read8Bit() {
unsigned char temp,rbyte=0; for(temp=8;temp!=0;temp--) {
SCL=1; rbyte=rbyte<<1; rbyte=rbyte|((unsigned char)(SDA)); SCL=0; } return(rbyte); }
#define WriteDeviceAddress 0xa0 #define ReadDeviceAddress 0xa1 sbit SCL=P2^7; sbit SDA=P2^6;
//定义器件在 IIC 总线中的地址,且方式为写 //定义器件在 IIC 总线中的地址,且方式为读
sbit P10=P1Stop();
//主机产
生停止信号 return(ch);
}
//本课试验写入一个字节到 24c02 并读出来
void main(void) // 主程序 {
uchar c1,c2; c1=Read24c02(0x02);
//从 24c02 中读出 1 个字节
Write24c02(0x88,0x03); c2=Read24c02(0x03); P3=c2;
24C02读写C程序
24c02读写程序大全

24c02读写程序大全2C总线的应用(24C02子程序)// 对24C02的读、写// extern void DelayMs(unsigned int);// extern void Read24c02(unsigned char *RamAddress,unsigned char Ro mAddress,unsigned char bytes);// extern void Write24c02(unsigned char *RamAddress,unsigned char Ro mAddress,unsigned char bytes);/***************************************************************************/#define WriteDeviceAddress 0xa0#define ReadDviceAddress 0xa1#include <reg52.h>#include <stdio.h>#include <absacc.h>/***************************************************************************/sbit SCL=P2^7;sbit SDA=P2^6;bit DOG;/***************************************************************************/void DelayMs(unsigned int number) {unsigned char temp;for(;number!=0;number--,DOG=!DOG) {for(temp=112;temp!=0;temp--) {}}}/***************************************************************************/void Start() {SDA=1;SCL=1;SDA=0;SCL=0;}/***************************************************************************/void Stop() {SCL=0;SDA=0;SDA=1;}/***************************************************************************/void Ack() {SDA=0;SCL=1;SCL=0;SDA=1;}/***************************************************************************/void NoAck() {SDA=1;SCL=1;SCL=0;}/***************************************************************************/bit TestAck() {bit ErrorBit;SDA=1;SCL=1;ErrorBit=SDA;SCL=0;return(ErrorBit);}/***************************************************************************/void Write8Bit(unsigned char input) {unsigned char temp;for(temp=8;temp!=0;temp--) {SDA=(bit)(input&0x80);SCL=1;SCL=0;input=input<<1;}}/***************************************************************************/void Write24c02(unsigned char *Wdata,unsigned char RomAddress,unsign ed char number) {Write8Bit(WriteDeviceAddress);TestAck();Write8Bit(RomAddress);TestAck();for(;number!=0;number--) {Write8Bit(*Wdata);TestAck();Wdata++;}Stop();DelayMs(10);}/***************************************************************************/ unsigned char Read8Bit() {unsigned char temp,rbyte=0;for(temp=8;temp!=0;temp--) {SCL=1;rbyte=rbyte<<1;rbyte=rbyte|((unsigned char)(SDA));SCL=0;}return(rbyte);}/***************************************************************************/void Read24c02(unsigned char *RamAddress,unsigned char RomAddress, unsigned char bytes) {//unsigned char temp,rbyte;Start();Write8Bit(WriteDeviceAddress);TestAck();Write8Bit(RomAddress);TestAck();Start();Write8Bit(ReadDviceAddress);TestAck();while(bytes!=1) {*RamAddress=Read8Bit();RamAddress++;bytes--;}*RamAddress=Read8Bit();NoAck();Stop();}[单片机应用]24c02的读写程序电子工匠发表于2007-1-4 22:33:07;---------------从24C02整组读数据RD_INI: LCALL DELAYRD_AREA: LCALL DELAYLCALL STARTLCALL DELAYLCALL WRITE ;24C02信息的读入LCALL DELAYLCALL ACKLCALL DELAYJC RD_AREAMOV R2, #8CLR P1.7 ;起始地址为00 ADDR_0: LCALL DELAYLCALL DELAYSETB P1.6LCALL DELAYLCALL DELAYCLR P1.6LCALL DELAYDJNZ R2, ADDR_0LCALL ACKLCALL DELAYJC RD_AREALCALL DELAYLCALL STARTMOV R0, #SAVE0MOV R3, #8 ;6个字节LCALL DELAYLCALL READLCALL DELAYLCALL ACKJC RD_AREARD_R_0: LCALL DELAYLCALL DELAYLCALL RD_INFOLCALL DELAYINC R0DJNZ R3, RD_R_1lcall ack_2lcall delayLCALL STOPRETrd_r_1: lcall ack_1sjmp rd_r_0;---------------向24C02整组写数据WR_INI: LCALL DELAYLCALL STARTLCALL DELAYLCALL WRITELCALL DELAYLCALL ACKLCALL DELAYJC WR_INICLR P1.7MOV R2, #8WR_W_0: LCALL DELAY ;写地址SETB P1.6LCALL DELAYLCALL DELAYCLR P1.6LCALL DELAYDJNZ R2, WR_W_0LCALL DELAYLCALL ACKLCALL DELAYJC WR_INIMOV R0, #SAVE0MOV R3, #8 ;6个字节WR_W_1: LCALL WR_INFOLCALL DELAYLCALL ACKLCALL DELAYJC WR_INIINC R0DJNZ R3, WR_W_1LCALL DELAYLCALL STOPRET;---------------24C02启动START: SETB P1.7SETB P1.6LCALL DELAYCLR P1.7LCALL DELAYCLR P1.6RET;---------------24C02读命令字;片选为"00";---------------------------- READ: MOV A, #10100001B MOV R2, #8RD1: RLC AMOV P1.7, CSETB P1.6LCALL DELAYCLR P1.6LCALL DELAYDJNZ R2, RD1RET;---------------24C02写命令字;片选为"00";---------------------------- WRITE: MOV A, #10100000B MOV R2, #8WR1: RLC AMOV P1.7, CSETB P1.6LCALL DELAYCLR P1.6CLR P1.7LCALL DELAYDJNZ R2, WR1RET;---------------24C02结束命令字STOP: CLR P1.7LCALL DELAYSETB P1.6LCALL DELAYSETB P1.7LCALL DELAYCLR P1.6RET;---------------24C02的应答信息ACK: SETB P1.7SETB P1.6LCALL DELAYmov a, p1MOV C, a.7LCALL DELAYCLR P1.6RETack_1: CLR P1.7 ;应答SETB P1.6lcall delayCLR P1.6lcall delaySETB P1.7lcall delayRETack_2: SETB P1.7 ;非应答SETB P1.6lcall delayCLR P1.6CLR P1.7lcall delayRET;---------------24C02的读;R0:数据的存储地址;-------------------------------- RD_INFO: SETB P1.7LCALL DELAYMOV R2, #8MOV R7, #0MOV A, #0RD_I_0: SETB P1.6LCALL DELAYMOV A, P1MOV C, A.7LCALL DELAYCLR P1.6MOV A, R7RLC AMOV R7, ALCALL DELAYDJNZ R2, RD_I_0MOV @R0, ARET;---------------24C02的写;R0:数据的写数据地址;-----------------------------------WR_INFO: MOV A, @R0MOV R2, #8WR_O_0: RLC AMOV P1.7, CLCALL DELAYSETB P1.6LCALL DELAYLCALL DELAYCLR P1.6LCALL DELAYDJNZ R2, WR_O_0RET24Cxx I2C EEPROM字节读写驱动程序,芯片A0-A1-A2要接GND(24C65接VCC,具体看DataSheet)。
24c02读写程序大全

24c02读写程序大全2C总线的应用(24C02子程序)// 对24C02的读、写// extern void DelayMs(unsigned int);// extern void Read24c02(unsigned char *RamAddress,unsigned char Ro mAddress,unsigned char bytes);// extern void Write24c02(unsigned char *RamAddress,unsigned char Ro mAddress,unsigned char bytes);/***************************************************************************/#define WriteDeviceAddress 0xa0#define ReadDviceAddress 0xa1#include <reg52.h>#include <stdio.h>#include <absacc.h>/***************************************************************************/sbit SCL=P2^7;sbit SDA=P2^6;bit DOG;/***************************************************************************/void DelayMs(unsigned int number) {unsigned char temp;for(;number!=0;number--,DOG=!DOG) {for(temp=112;temp!=0;temp--) {}}}/***************************************************************************/void Start() {SDA=1;SCL=1;SDA=0;SCL=0;}/***************************************************************************/void Stop() {SCL=0;SDA=0;SDA=1;}/***************************************************************************/void Ack() {SDA=0;SCL=1;SCL=0;SDA=1;}/***************************************************************************/void NoAck() {SDA=1;SCL=1;SCL=0;}/***************************************************************************/bit TestAck() {bit ErrorBit;SDA=1;SCL=1;ErrorBit=SDA;SCL=0;return(ErrorBit);}/***************************************************************************/void Write8Bit(unsigned char input) {unsigned char temp;for(temp=8;temp!=0;temp--) {SDA=(bit)(input&0x80);SCL=1;SCL=0;input=input<<1;}}/***************************************************************************/void Write24c02(unsigned char *Wdata,unsigned char RomAddress,unsign ed char number) {Write8Bit(WriteDeviceAddress);TestAck();Write8Bit(RomAddress);TestAck();for(;number!=0;number--) {Write8Bit(*Wdata);TestAck();Wdata++;}Stop();DelayMs(10);}/***************************************************************************/ unsigned char Read8Bit() {unsigned char temp,rbyte=0;for(temp=8;temp!=0;temp--) {SCL=1;rbyte=rbyte<<1;rbyte=rbyte|((unsigned char)(SDA));SCL=0;}return(rbyte);}/***************************************************************************/void Read24c02(unsigned char *RamAddress,unsigned char RomAddress, unsigned char bytes) {//unsigned char temp,rbyte;Start();Write8Bit(WriteDeviceAddress);TestAck();Write8Bit(RomAddress);TestAck();Start();Write8Bit(ReadDviceAddress);TestAck();while(bytes!=1) {*RamAddress=Read8Bit();RamAddress++;bytes--;}*RamAddress=Read8Bit();NoAck();Stop();}[单片机应用]24c02的读写程序电子工匠发表于2007-1-4 22:33:07;---------------从24C02整组读数据RD_INI: LCALL DELAYRD_AREA: LCALL DELAYLCALL STARTLCALL DELAYLCALL WRITE ;24C02信息的读入LCALL DELAYLCALL ACKLCALL DELAYJC RD_AREAMOV R2, #8CLR P1.7 ;起始地址为00 ADDR_0: LCALL DELAYLCALL DELAYSETB P1.6LCALL DELAYLCALL DELAYCLR P1.6LCALL DELAYDJNZ R2, ADDR_0LCALL ACKLCALL DELAYJC RD_AREALCALL DELAYLCALL STARTMOV R0, #SAVE0MOV R3, #8 ;6个字节LCALL DELAYLCALL READLCALL DELAYLCALL ACKJC RD_AREARD_R_0: LCALL DELAYLCALL DELAYLCALL RD_INFOLCALL DELAYINC R0DJNZ R3, RD_R_1lcall ack_2lcall delayLCALL STOPRETrd_r_1: lcall ack_1sjmp rd_r_0;---------------向24C02整组写数据WR_INI: LCALL DELAYLCALL STARTLCALL DELAYLCALL WRITELCALL DELAYLCALL ACKLCALL DELAYJC WR_INICLR P1.7MOV R2, #8WR_W_0: LCALL DELAY ;写地址SETB P1.6LCALL DELAYLCALL DELAYCLR P1.6LCALL DELAYDJNZ R2, WR_W_0LCALL DELAYLCALL ACKLCALL DELAYJC WR_INIMOV R0, #SAVE0MOV R3, #8 ;6个字节WR_W_1: LCALL WR_INFOLCALL DELAYLCALL ACKLCALL DELAYJC WR_INIINC R0DJNZ R3, WR_W_1LCALL DELAYLCALL STOPRET;---------------24C02启动START: SETB P1.7SETB P1.6LCALL DELAYCLR P1.7LCALL DELAYCLR P1.6RET;---------------24C02读命令字;片选为"00";---------------------------- READ: MOV A, #10100001B MOV R2, #8RD1: RLC AMOV P1.7, CSETB P1.6LCALL DELAYCLR P1.6LCALL DELAYDJNZ R2, RD1RET;---------------24C02写命令字;片选为"00";---------------------------- WRITE: MOV A, #10100000B MOV R2, #8WR1: RLC AMOV P1.7, CSETB P1.6LCALL DELAYCLR P1.6CLR P1.7LCALL DELAYDJNZ R2, WR1RET;---------------24C02结束命令字STOP: CLR P1.7LCALL DELAYSETB P1.6LCALL DELAYSETB P1.7LCALL DELAYCLR P1.6RET;---------------24C02的应答信息ACK: SETB P1.7SETB P1.6LCALL DELAYmov a, p1MOV C, a.7LCALL DELAYCLR P1.6RETack_1: CLR P1.7 ;应答SETB P1.6lcall delayCLR P1.6lcall delaySETB P1.7lcall delayRETack_2: SETB P1.7 ;非应答SETB P1.6lcall delayCLR P1.6CLR P1.7lcall delayRET;---------------24C02的读;R0:数据的存储地址;-------------------------------- RD_INFO: SETB P1.7LCALL DELAYMOV R2, #8MOV R7, #0MOV A, #0RD_I_0: SETB P1.6LCALL DELAYMOV A, P1MOV C, A.7LCALL DELAYCLR P1.6MOV A, R7RLC AMOV R7, ALCALL DELAYDJNZ R2, RD_I_0MOV @R0, ARET;---------------24C02的写;R0:数据的写数据地址;-----------------------------------WR_INFO: MOV A, @R0MOV R2, #8WR_O_0: RLC AMOV P1.7, CLCALL DELAYSETB P1.6LCALL DELAYLCALL DELAYCLR P1.6LCALL DELAYDJNZ R2, WR_O_0RET24Cxx I2C EEPROM字节读写驱动程序,芯片A0-A1-A2要接GND(24C65接VCC,具体看DataSheet)。
STM32-24C02读写程序(亲自编写测试可用)

本文档内容为在STM32条件下的24C02读写程序。
全文共分四部分,第一部分24C02的C程序,第二部分为24C02的.h程序,第三部分为端口与时钟配置函数,第四部分为主函数。
下面分别进行介绍。
第一部分:24C02的.c函数******************************************************************************/ #include "stm32f10x.h"#include "system_config.h"#include "24C02.h"u8 savedata[10]={10,9,8,7,6,5,4,3,2,1};/****************************************************************************** ** Function Name : AT24C02_SDA_IO_SET(uchar io_set)* Description : SDA方向控制* Input : None* Output : None* Return : None******************************************************************************* /void AT24C02_SDA_IO_SET(unsigned char io_set){GPIO_InitTypeDef GPIO_InitStructure;if(io_set){GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 ;//SDA 设置为输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(GPIOB, &GPIO_InitStructure);}else{GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 ;//SDA 设置为输入GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOB, &GPIO_InitStructure);}}/****************************************************************************** ** Function Name : delay2* Description : 延时函数* Input : None* Output : None* Return : None******************************************************************************* /void delay2(u8 x){u8 i;for(i=0;i<x;i++);}/****************************************************************************** ** Function Name : delay2* Description : 延时函数* Input : None* Output : None* Return : None******************************************************************************* /void delay_nop(void){uint8_t i=10;//延时1.5uswhile(i--);}/****************************************************************************** ** Function Name : 24C02_init()* Description : 初始化函数* Input : None* Output : None* Return : None******************************************************************************* /void I2C_init(void){//SCL=1SCL_H;delay_nop();//SDA=1SDA_H;delay_nop();}/****************************************************************************** ** Function Name : I2C_start()* Description : 开始信号* Input : None* Output : None* Return : None******************************************************************************* /void I2C_start(){SDA_H;delay_nop();SCL_H;delay_nop();SDA_L;delay_nop();SCL_L;delay_nop();}/****************************************************************************** ** Function Name : I2C_stop()* Description : 开始信号* Input : None* Output : None* Return : None******************************************************************************* /void I2C_stop(){SDA_L;delay_nop();SCL_H;delay_nop();SDA_H;delay_nop();}/****************************************************************************** ** Function Name : I2C_write_bit()* Description : 开始信号* Input : None* Output : None* Return : None******************************************************************************* /void I2C_write_bit(int j){int i,temp,temp1;temp=j;//AT24C02_SDA_IO_SET(1);//发送数据for(i=0;i<8;i++){temp1=temp&0x80;//高位在前相与temp=temp<<1;SCL_L;//时钟线设为低delay_nop();if(temp1==0x80)//发送数据到SDA线上{SDA_H;delay_nop();}else{SDA_L;delay_nop();}SCL_H;//时钟线设为高,开始传输数据delay_nop();}SCL_L;//一个字节发送完成delay_nop();SDA_H;delay_nop();}/****************************************************************************** ** Function Name : I2C_read_bit()* Description : 读取一个字节数据* Input : None* Output : None* Return : None******************************************************************************* /u8 I2C_read_bit(){u8 i,j,k=0;SCL_L;delay_nop();SDA_H;delay_nop();A T24C02_SDA_IO_SET(0);//SDA设置为输入for(i=0;i<8;i++){delay_nop();SCL_H;delay_nop();if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7)==1)j=1;elsej=0;k=(k<<1)|j;SCL_L;delay_nop();}A T24C02_SDA_IO_SET(1);//SDA设置为输出delay_nop();return(k);}/****************************************************************************** ** Function Name : I2C_reply()* Description : 读取应答信号* Input : None* Output : None* Return : None******************************************************************************* /void I2C_reply(){u16 i=0;A T24C02_SDA_IO_SET(0);//SDA设置为输入SCL_H;delay_nop();while((GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7)==1)&&(i<5000))i++;SCL_L;delay_nop();A T24C02_SDA_IO_SET(1);//SDA设置为输出}/****************************************************************************** ** Function Name : I2C_write_addr()* Description : 指定地址写* Input : None* Output : None* Return : None******************************************************************************* /void I2C_write_addr(u8 addr,u8 data){I2C_start();//开始信号I2C_write_bit(0xa0);//发送写命令I2C_reply();//等待应答I2C_write_bit(addr);//发送写地址I2C_reply();//等待应答I2C_write_bit(data);//发送写数据I2C_reply();//等待应答I2C_stop();//停止信号delay2(250);}/****************************************************************************** ** Function Name : I2C_read_addr()* Description : 指定地址读* Input : None* Output : None* Return : None******************************************************************************* /int I2C_read_addr(int addr){int i=0;I2C_start();//开始信号I2C_write_bit(0xa0);//发送写命令因为要先写入要读的地址I2C_reply();//等待应答I2C_write_bit(addr);//发送读地址I2C_reply();//等待应答I2C_start();//开始信号I2C_write_bit(0xa1);//发送读命令I2C_reply();//等待应答i=I2C_read_bit();I2C_stop();//停止信号delay2(250);return(i);}第二部分:24C02的.h函数#define SCL_H GPIO_SetBits(GPIOB,GPIO_Pin_6)#define SCL_L GPIO_ResetBits(GPIOB,GPIO_Pin_6)#define SDA_H GPIO_SetBits(GPIOB,GPIO_Pin_7)#define SDA_L GPIO_ResetBits(GPIOB,GPIO_Pin_7)#define Write_able GPIO_ResetBits(GPIOB,GPIO_Pin_5)//24C02写使能控制引脚void AT24C02_SDA_IO_SET(unsigned char io_set);void delay2(u8 x) ;void delay_nop(void);void I2C_init(void);void I2C_start();void I2C_stop();void I2C_write_bit(int j);u8 I2C_read_bit();void I2C_reply();void I2C_write_addr(u8 addr,u8 data) ;int I2C_read_addr(int addr) ;第三部分:端口与时钟配置函数由于我们使用的是PB6作为时钟线,PB7作为数据线,所以端口配置PB6,PB7就可以了。
I2C24LC02C读写例程(PIC单片机)

I2C24LC02C读写例程(PIC单片机)I2C 24LC02 C读写例程(PIC单片机)[单片机]发布时间:2008-04-22 10:11:001 I2C总线特点I2C总线最主要的优点是其简单性和有效性。
由于接口直接在组件之上,因此I2C总线占用的空间非常小,减少了电路板的空间和芯片管脚的数量,降低了互联成本。
总线的长度可高达25英尺,并且能够以10Kbps的最大传输速率支持40个组件。
I2C总线的另一个优点是,它支持多主控(multimastering),其中任何能够进行发送和接收的设备都可以成为主总线。
一个主控能够控制信号的传输和时钟频率。
当然,在任何时间点上只能有一个主控。
2 I2C总线工作原理I2C总线上的数据稳定规则,SCL为高电平时SDA上的数据保持稳定,SCL为低电平时允许SDA变化。
如果SCL处于高电平时,SDA 上产生下降沿,则认为是起始位,SDA上的上升沿认为是停止位。
通信速率分为常规模式(时钟频率100kHz)和快速模式(时钟频率400kHz)。
同一总线上可以连接多个带有I2C接口的器件,每个器件都有一个唯一的地址,既可以是单接收的器件,也可以是能够接收发送的器件。
每次数据传输都是以一个起始位开始,而以停止位结束。
传输的字节数没有限制。
最高有效位将首先被传输,接收方收到第8位数据后会发出应答位。
数据传输通常分为两种:主设备发送从设备接收和从设备发送主设备接收。
这两种模式都需要主机发送起始位和停止位,应答位由接收方产生。
从设备地址一般是1或2个字节,用于区分连接在同一I2C上的不同器件。
I2C总线在传送数据过程中共有三种类型信号,它们分别是:开始信号、结束信号和应答信号。
开始信号:SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据。
结束信号:SCL为高电平时,SDA由低电平向高电平跳变,结束传送数据。
应答信号:接收数据的IC在接收到8bit数据后,向发送数据的IC 发出特定的低电平脉冲,表示已收到数据。
单片机程序设计实践教程_第17章_EEPROM器件AT24C02读写

4
图17-1 24C02读写项目的电路原理图 17- 24C02读写项目的电路原理图
5
17.3 系统板上硬件连线
PMY单片机开发板上24C02读写控制项目的连接插线设置如图 17-2所示。
24C02读写项目的连接插线设置 图17-2 开发板上24C02读写项目的连接插线设置 17- 开发板上24C02
3
17.2 项目任务
24C02读写控制项目的电路原理图如图17-1所示。在第17章已 经介绍过,STC89C52RC单片机本身不包含I2C总线通信控制器的 功能,为了与具有I2C总线通信和存储功能的EEPROM器件24C02 芯片进行数据交换,STC89C52RC单片机必须利用自身的两根 I/O线(这里是P14和P15引脚),作为I2C的SDA和SCL信号线,利 用 软 件 模 拟 产 生 I2C 通 信 协 议 规 定 的 传 输 数 据 信 号 , 以 完 成 与 24C02芯片之间的数据交换。 本次项目应完成以下程序设计:通过C51嵌入式软件对24C02指 定的多个连续地址写入指定数值,再读出已写入24C02器件地址的 数值,并在七段LED数码管上进行显示。
14
如何在项目中实现24C02 24C02的读写 17.6.3 如何在项目中实现24C02的读写
程序中的_24C02_WriteByte函数是向指定从地址器件的特定寄 存器地址写入一个字节数据,虽然与数字钟设计项目程序中的 PCF8563_WRINIT函数功能类似,但只是完成了向从器件传送一 个字节数据的功能。而PCF8563_WRINIT函数则完成向从器件指 定地址写入多个指定字节数据,在本项目主程序main中的以下语 句同样可以实现主器件(STC89C52RC)向指定从器件(24C02) 的指定地址连续写入多个字节的功能: /*************以下语句为向24C02写入数据*****************/ _24C02_Fillbyte(20,0xff); //将前20字节用0xff填充 for(i=0;i<16;i++) _24C02_WriteByte(i,DispDat[i]); //将数组DispDat设定的 显示代码写入到24C02 /*************以上语句为向24C02写入数据*****************/
STM32模拟IIC读写24C02程序代码

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 SDAvoid 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 LGPIO_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);}//存数据到EEPROMdelayms(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 intuchar WIN24C02_read(uchar address); //从24c02的地址address中读取一个字节数据void WIN24C02_write(uchar address,uchar info); //向24c02的address地址中写入一字节数据infovoid 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<x;i++);< p="">}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</x;i++);<>。
24c02读写程序

//===================================================================//
//==========================================================
i=readx(); stop();
delay1(10);
return(i);
}
void x24c02_write(uchar address,uchar info)
{
EA=0;
start(); writex(0xa0);
clock(); writex(address);
clock(); writex(info);
clock(); stop();
EA=1;
delay1(50);
}
//====================================================================//
main (){
}
uchar readx()
{
uchar i,j,k=0;
scl=0; flash(); sda=1;
for (i=0;i<8;i++){
flash(); scl=1; flash();
if (sda==1) j=1;
else j=0;
uchar x24c02_read(uchar address); //从24c02的地址address中读取一个字节数据
void x24c02_write(uchar address,uchar info);
24c02读写实验c程序

Init();//初始化
DispBuf[2]=Hidden;
DispBuf[3]=Hidden;
for(;;)
{
Calc(RecBuf[1],RomDat[0]);//分别显示地址和数据
if(Rec)//接收到数据
{Rec=0;//清除标志
if(RecBuf[0]==0)//第一种功能,写入
TR1=1;
}
void Calc(uchar Dat1,uchar Dat2)//第一个参数放在第1、2位,第二个参数放入第5、6位
{DispBuf[0]=Dat1/16;
DispBuf[1]=Dat1%16;
DispBuf[4]=Dat2/16;
DispBuf[5]=Dat2%16;
}
void main()
/**************************************************
24C02.C
功能描述:
PC端发送3个数据n0,n1,n2.
n0=0,写,将n1写入n2地址中
n0=1,读,读出n1地址中的数据,n2不起作用,但必须有
收到一个字节后,将其地址值显示在数码管第1、2位上,数值显示在第5、6位上
sbit we=P2^7;
sbit du=P2^6;
uchar code dispbit[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
uchar code disptab[]={0x3f,0x6,0x5b,0x4f,0x66,
0x6d,0x7d,0x27,0x7f,0x6f,0x77,0x7c,0x39,0x5e,
Rec=1;//置位标志
24C02数据读写

一这物行时每如一、认识IIC 这是最常用、物理结构上,行信息 传输。
时钟。
信息传每个器件都有如:存储器)C 总线的工作方最典型的II IIC 系统由一。
在数据传输传输的对象和方有一个唯一的地。
发送器或接方式C 总线连接方一条串行数据输时,由主机初方向以及信息地址,而且可接收器可以在IIC 时方式。
据线SDA 和一条初始化一次数息传输的开始可以是单接收的在主模式或从模时序24C02的条串行时钟线数据传输,主和终 止均由的器件(例如模式下操作,的操作 线SCL 组成。
主机使数据在S 主机决定。
如:LCD 驱动器这取决于芯片主机按一定的SDA 线上传输器)或者可以接片是否必须启的通信协议向输的同时还通过接收也可以发启动数据的传从机寻址和进过SCL 线传输发送的器件(例传输还是仅仅被进输例被寻1I 在低2I 寻址。
1.总线上数据IIC 总线是以在时钟线高电低电平时,才2.总线上的信IIC 总线在传据的有效性串行方式传输电平期间数据线才允许数据线上信号送数据过程中输数据,从数据线上必须保持上的电平状态中共有四种类据字节的最高持稳定 的逻辑态变化,如图类型信号,它们高位开始传送,辑电平状态,11-2所示。
们分别是:开,每一个数据位高电平为数据开始信号、停止位在SCL 上都据1,低电平为止信号、重新都有一个时钟为数据0。
只新开始信号和应脉冲相对应。
有在时钟线为应答信号。
为开的停停重之所开始信号(STA 的时候,例如停止信号(STO 停止信号,结重新开始信号之前,主机通所示,当SCL ART):如图1如,没有主动设OP):如图11结束数据通信。
号(Repeated S 通过发送重新开L为高电平时,1-3所示,当设备在使用总-3所示,当。
START):在I 开始信号,可,SDA由高电当SCL 为高电总线(SDA 和S SCL 为高电平IC 总线上,由可以转换与当电平向低电平跳平时,SDA 由CL 都处于高电平时,SDA 由低由主机发送一前从机的通信跳变,产生重由高电平向低电电平),主机通低电平向高电一个开始信号启信模 式,或是重新开始信号,电平跳变,产通过发送开始电平跳变,产生启动一次通信是切换到与另,它的本质就产生开始信号始(START)信号生停止信号。
24C02经典程序

总线上主和从(即发送和接收)的关系不是一成不变的,而是取决于此时数据传送的方向。SDA和SCL均为双向I/O线,通过上拉电阻接正电源。当总线空闲时,两根线都是高电平。连接总线的器件的输出级必须是集电极或漏极开路,以具有线“与”功能。I2C总线的数据传送速率在标准工作方式下为100kbit/s,在快速方式下,最高传送速率可达400kbit/s。
当主器件发送完一个字节的数据后,接着发出对应于SCL线上的一个时钟(ACK)认可位,在此时钟内主器件释放SDA线,一个字节传送结束,而从器件的响应信号将SDA线拉成低电平,使SDA在该时钟的高电平期间为稳定的低电平。从器件的响应信号结束后,SDA线返回高电平,进入下一个传送周期。
I2C总线还具有广播呼叫地址用于寻址总线上所有器件的功能。若一个器件不需要广播呼叫寻址中所提供的任何数据,则可以忽略该地址不作响应。如果该器件需要广播呼叫寻址中提供的数据,则应对地址作出响应,其表现为一个接收器。
5.总线竞争的仲裁 总线上可能挂接有多个器件,有时会发生两个或多个主器件同时想占用总线的情况。例如,多单片机系统中,可能在某一时刻有两个单片机要同时向总线发送数据,这种情况叫做总线竞争。I2C总线具有多主控能力,可以对发生在SDA线上的总线竞争进行仲裁,其仲裁原则是这样的:当多个主器件同时想占用总线时,如果某个主器件发送高电平,而另一个主器件发送低电平,则发送电平与此时SDA总线电平不符的那个器件将自动关闭其输出级。总线竞争的仲裁是在两个层次上进行的。首先是地址位的比较,如果主器件寻址同一个从器件,则进入数据位的比较,从而确保了竞争仲裁的可*性。由于是利用I2C总线上的信息进行仲裁,因此不会造成信息的丢失。
clr p1.0 ;发开始信号
mov a,r3 ;送器件地址
51单片机的24c02电子时钟程序和电路图

fen++;
if(fen==60)fen=0;
write_sfm(shi,fen,miao);
write_cmd(0xc0+7);
write_add(2,fen);
}
if(s1num==3)
{
shi++;
if(shi==60)shi=0;
write_sfm(shi,fen,miao);
write_cmd(0xc0+4);
}
void keyscan()
{
if(s1==0)//如果功能按键1按下
{
delayms(5);//去抖动
if(s1==0)
{
while(!s1);//等待松手
s1num++;//主要还是记下次数
di();//蜂鸣器响
if(s1num==1)//按一下秒钟
{
TR0=0;
write_cmd(0xc0+10);//指针显示闪烁
sbit lcdrs=P2^4;//液晶的控制角
sbit lcdrw=P2^5;
sbit lcden=P2^6;
sbit s1=P3^0;//三个调时钟的按键
sbit s2=P3^1;
sbit s3=P3^2;
sbit beep=P2^3;//蜂鸣器
uchar count,s1num;
char miao,shi,fen;
delayms(1);
}
void write_sfm(uchar s,uchar f,uchar m)//数据在液晶显示
{
uchar ss,sg,fs,fg,ms,mg;
ss=s/10;sg=s%10;
基于STM32F103的I2C总线EEPROM的读写(带超时检测)

基于STM32F103的I2C总线EEPROM的读写(带超时检测)————————————————————————————————作者:————————————————————————————————日期:【原创】基于STM32F103的I2C总线EEPROM的读写(带超时检测)本人最近参考了st 公司关于STM32的I2C的例程,觉得不是很适合我的应用,于是自己写了一个基于STM32F103的I2C总线EEPROM(24C256)的读写程序,总线的最高速度可达400K,现在将源代码原原本本的公布如下,希望得到高手的指点,也希望能够给和我有同样想法的同仁们一些参考价值。
注意:最好将固件库升级一下,st网站上面有V2。
03库的补丁。
u32 ulTimeOut_Time;/***********************************************************************************************************I2C_EE_WriteStr()** Description : 将一个数据块写入EEPROM 的指定的地址**Argument(s) : xChip - 从器件地址* xAddr — EEPROM存储空间地址*xpBuf —数据缓冲区指针* xLen - 数据长度**Return(s) : none.**Caller(s) : Application.** Note(s) :(1)*——--—-——----————--—-——---——--—--—---—-—----———--—-—-————-——-——---—-—--—————----——--—————-—-——--——-———--*Modified by :* Modified date :* Description :*—---———----———-—------——--—--—-——————-—-————-——-———-——---—--——-——————--—————----———-—---—-——-——-—-——--—**********************************************************************************************************/void I2C_EE_WriteStr(u8 xChip, u16 xAddr, u8 *xpBuf, u16 xLen){u8 *pbuf;u8 err;u8 retry;u16 addr;u16 len;个人收集整理,勿做商业用途本文为互联网收集,请勿用作商业用途//pbuf = xpBuf;addr = xAddr;len = xLen;I2C_EE_Drv_BusEn(); // 允许总线,写允许retry = 5; // 重试5次while(len){err = I2C_EE_Drv_WriteByte(xChip,addr, *pbuf);if(err){if(--retry == 0 ) // 已经试了5次,写下一个数据{retry = 5;pbuf++;addr++;len——;}}else // 顺利,写下一个数据{pbuf++;addr++;len--;}}I2C_EE_Drv_BusDis(); // 失能总线,写保护}/*********************************************************************************************************** I2C_EE_ReadStr()**Description :从EEPROM 的指定的地址读出一个数据块** Argument(s) : xChip —从器件地址* xAddr - EEPROM存储空间地址*xpBuf - 数据缓冲区指针*xLen - 数据长度**Return(s) : none.** Caller(s) : Application。
24c02读写程序

E2PROM芯片24C02的读写程序一、实验目的:给24C02的内部RAM写入一组数据,数据从24C02内部RAM的01h开始存放。
然后再把这组数据读出来,检验写入与读出就是否正确。
在这里我们给24C02中写入0、1、2的段码,然后把它读出来,送到数码管显示。
二、理论知识准备:上面两个实验主要学习的就是利用单片机的串口进行通讯,本实验要介绍的就是基于I2C 总线的串行通讯方法,下面我们先介绍一下I2C总线的相关理论知识。
(一)、I2C总线概念I2C总线就是一种双向二线制总线,它的结构简单,可靠性与抗干扰性能好。
目前很多公司都推出了基于I2C总线的外围器件,例如我们学习板上的24C02芯片,就就是一个带有I2C总线接口的E2PROM存储器,具有掉电记忆的功能,方便进行数据的长期保存。
(二)、I2C总线结构I2C总线结构很简单,只有两条线,包括一条数据线(SDA)与一条串行时钟线(SCL)。
具有I2C 接口的器件可以通过这两根线接到总线上,进行相互之间的信息传递。
连接到总线的器件具有不同的地址,CPU根据不同的地址进行识别,从而实现对硬件系统简单灵活的控制。
一个典型的I2C总线应用系统的组成结构如下图所示(假设图中的微控制器、LCD驱动、E2PROM、ADC各器件都就是具有I2C总线接口的器件):我们知道单片机串行通讯的发送与接收一般都各用一条线TXD与RXD,而I2C总线的数据线既可以发送也可以接受,工作方式可以通过软件设置。
所以,I2C总线结构的硬件结构非常简洁。
当某器件向总线上发送信息时,它就就是发送器,而当其从总线上接收信息时,又成为接收器。
(三)、I2C总线上的数据传送下面我们瞧瞧I2C总线就是如何进行数据传送的。
我们知道,在一根数据线上传送数据时必须一位一位的进行,所以我们首先研究位传送。
1、位传输I2C总线每传送一位数据必须有一个时钟脉冲。
被传送的数据在时钟SCL的高电平期间保持稳定,只有在SCL低电平期间才能够改变,示意图如下图所示,在标准模式下,高低电平宽度必须不小于4、7us。
stm32f103 硬件iic读写函数

stm32f103 硬件iic读写函数STM32F103是一款广泛应用于嵌入式系统的32位微控制器,具有强大的性能和丰富的外设功能。
其中,硬件IIC(Inter-Integrated Circuit)是一种常用的串行通信接口,可以实现与其他设备之间的数据传输。
本文将介绍STM32F103中硬件IIC的读写函数及其使用方法。
我们需要了解一下硬件IIC的基本原理。
IIC总线由两根线组成,一根是数据线(SDA),用于传输数据;另一根是时钟线(SCL),用于同步数据传输。
在IIC总线上,每个设备都有一个唯一的地址,通过地址来确定通信对象。
在STM32F103中,我们可以通过设置控制寄存器来配置IIC的工作模式、时钟频率等参数。
在STM32F103中,硬件IIC的读写操作主要涉及以下几个寄存器:1. CR1寄存器:用于配置IIC的工作模式、时钟频率等。
通过设置CR1寄存器的相应位可以使能IIC、设置主从模式、选择时钟频率等。
2. CR2寄存器:用于配置IIC的通信速度和地址模式。
通过设置CR2寄存器的相应位可以选择标准模式(100kHz)或快速模式(400kHz),以及设置自身的地址。
3. OAR1和OAR2寄存器:用于配置自身的地址。
OAR1寄存器用于配置自身的7位地址,OAR2寄存器用于配置自身的10位地址。
4. DR寄存器:用于存放接收或发送的数据。
在使用硬件IIC读写函数之前,我们首先需要对IIC进行初始化配置。
以下是一个简单的初始化函数示例:```void I2C_Init(void){// 使能IIC时钟RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;// 配置IIC引脚GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;GPIO_InitStruct.Pull = GPIO_PULLUP;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);// 配置IIC参数I2C1->CR1 = 0x0000;I2C1->CR2 = 0x0000;I2C1->OAR1 = 0x0000;I2C1->OAR2 = 0x0000;I2C1->CCR = 0x0000;I2C1->TRISE = 0x0000;// 使能IICI2C1->CR1 |= I2C_CR1_PE;}```上述代码中,首先使能了IIC的时钟,然后配置了IIC的引脚,这里使用的是GPIOB的6、7引脚作为SDA和SCL。
stm32F103模拟I2C读写24c02

/*********文件名:i2c_ee.h**********//* Define to prevent recursive inclusion ------------------------------------ */#ifndef __I2C_EE_H#define __I2C_EE_H/* Includes ------------------------------------------------------------------*/#include "stm32f10x.h"/* Exported macro ------------------------------------------------------------*/#define ADDR_24CXX 0xA0#define SCLH GPIOB->BSRR = GPIO_Pin_6#define SCLL GPIOB->BRR = GPIO_Pin_6#define SDAH GPIOB->BSRR = GPIO_Pin_7#define SDAL GPIOB->BRR = GPIO_Pin_7#define SCLread GPIOB->IDR & GPIO_Pin_6#define SDAread GPIOB->IDR & GPIO_Pin_7/* Exported functions ------------------------------------------------------- */void I2C_EE_Init(void);uint8_t I2C_EE_BufferWrite(uint8_t *psrc_data,uint8_t adr,uint8_t nbyte); uint8_t I2C_EE_BufferRead(uint8_t *pdin_data,uint8_t adr,uint8_t nbyte);#endif /* __I2C_EE_H *//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////*********文件名:i2c_ee.c**********/#include "i2c_ee.h"enum ENUM_TWI_REPLY{TWI_NACK=0,TWI_ACK=1};enum ENUM_TWI_BUS_STATE{TWI_READY=0,TWI_BUS_BUSY=1,TWI_BUS_ERROR=2};void I2C_EE_Init(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);// Configure I2C1 pins: SCL and SDAGPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;GPIO_Init(GPIOB, &GPIO_InitStructure);}void TWI_delay(void){uint8_t i=10; //i=10延时1.5us//这里可以优化速度,经测试最低到5还能写入while(i--);}/**************************************************************************延时ms:延时的毫秒数CYCLECOUNTER / 72000000***************************************************************************/void DelayMs(uint16_t ms){uint16_t iq0;uint16_t iq1;for(iq0 = ms; iq0 > 0; iq0--){for(iq1 = 11998; iq1 > 0; iq1--); // ( (6*iq1+9)*iq0+15 ) / 72000000}}uint8_t TWI_Start(void){SDAH;SCLH;TWI_delay();if(!SDAread)return TWI_BUS_BUSY; //SDA线为低电平则总线忙,退出SDAL;TWI_delay();if(SDAread) return TWI_BUS_ERROR; //SDA线为高电平则总线出错,退出 SCLL;TWI_delay();return TWI_READY;}/*void TWI_Stop(void){SCLL;TWI_delay();SDAL;SCLH;TWI_delay();SDAH;TWI_delay();}*/void TWI_Stop(void) {SDAL;SCLL;TWI_delay();SCLH;TWI_delay();SDAH;TWI_delay();}void TWI_Ack(void) {SCLL;TWI_delay();SDAL;TWI_delay();SCLH;TWI_delay();SCLL;TWI_delay();}void TWI_NoAck(void) {SCLL;TWI_delay();SDAH;TWI_delay();SCLH;SCLL;TWI_delay();}uint8_t TWI_WaitAck(void) //返回为:=1有ACK,=0无ACK {SCLL;TWI_delay();SDAH;TWI_delay();SCLH;TWI_delay();if(SDAread){SCLL;return 0;}SCLL;return 1;}void TWI_SendByte(uint8_t SendByte) //数据从高位到低位// {uint8_t i=8;while(i--){SCLL;TWI_delay();if(SendByte&0x80)SDAH;elseSDAL;SendByte<<=1;TWI_delay();SCLH;TWI_delay();}SCLL;}uint8_t TWI_ReceiveByte(void) //数据从高位到低位//{uint8_t i=8;uint8_t ReceiveByte=0;SDAH;while(i--){ReceiveByte <<= 1;SCLL;TWI_delay();SCLH;TWI_delay();if(SDAread){ReceiveByte |= 0x01;}}SCLL;return ReceiveByte;}//返回:3写入成功;0写器件地址出错,1总线忙,2出错//写入1字节数据SendByte:待写入数据WriteAddress:待写入地址uint8_t TWI_WriteByte(uint8_t SendByte, uint8_t WriteAddress){uint8_t i;uint16_t j;i = TWI_Start();if(i)return i;TWI_SendByte( ADDR_24CXX & 0xFE);//写器件地址写入:地址最低位是0,读取:地址最低位是1if(!TWI_WaitAck()){TWI_Stop();return 0;}TWI_SendByte(WriteAddress); //设置起始地址TWI_WaitAck();TWI_SendByte(SendByte); //写数据TWI_WaitAck();TWI_Stop();//注意:因为这里要等待EEPROM写完,可以采用查询或延时方式(10ms) DelayMs(12); //写入延时12ms 写周期大于10ms即可return 3;}//返回:0写器件地址出错,1总线忙,2出错,//读出1字节数据//ReadAddress:待读出地址uint8_t TWI_ReadByte( uint8_t ReadAddress){uint8_t i,temp;i = TWI_Start();if(i)return i;TWI_SendByte((ADDR_24CXX & 0xFE));//写器件地址,先执行一次伪写操作if(!TWI_WaitAck()){TWI_Stop();return 0;}TWI_SendByte(ReadAddress); //设置起始地址TWI_WaitAck();TWI_Start();TWI_SendByte((ADDR_24CXX & 0xFE)|0x01); //读器件地址写入:地址最低位是0,读取:地址最低位是1TWI_WaitAck();//*pDat = TWI_ReceiveByte();temp = TWI_ReceiveByte();TWI_NoAck();TWI_Stop();return temp;//返回的如果是0,1,2则与错误代码相同了,再考虑一下}/***************************************************************************向24c256中写多个字节psrc_data:指向要写入数据数组的指针adr:24c256中要写入数据的首地址nbyte:写入的字节数返回值: 0:执行完毕;1:执行出现错误形参中:C02只有一个地址adr;C256中有高位地址hadr和低位地址ladr***************************************************************************/uint8_t I2C_EE_BufferWrite(uint8_t *psrc_data,uint8_t adr,uint8_t nbyte){uint8_t i;for(;nbyte!=0;nbyte--){i = TWI_Start();if(i)return i;TWI_SendByte( ADDR_24CXX & 0xFE);//写器件地址if(!TWI_WaitAck()){TWI_Stop();return 0;}TWI_SendByte(adr); //设置起始地址TWI_WaitAck();TWI_SendByte(*psrc_data); //写数据TWI_WaitAck();psrc_data++; //指向待写数据的指针加1adr++; //对24C08的操作地址加1TWI_Stop();//注意:因为这里要等待EEPROM写完,可以采用查询或延时方式(10ms) DelayMs(12); //写入延时12ms 写周期大于10ms即可}return 0;}/***************************************************************************从24c02读多个字节pdin_data:指向要保存读出数据的数组的指针adr:24c02中要读出数据的首地址nbyte:读出的字节数返回值: 0:执行完毕;1:执行出现错误***************************************************************************/uint8_t I2C_EE_BufferRead(uint8_t *pdin_data,uint8_t adr,uint8_t nbyte) {uint8_t i;i = TWI_Start();if(i)return i;TWI_SendByte((ADDR_24CXX & 0xFE));//写器件地址,先执行一次伪写操作if(!TWI_WaitAck()){TWI_Stop();return 0;}TWI_SendByte(adr); //设置起始地址TWI_WaitAck();TWI_Start();TWI_SendByte((ADDR_24CXX & 0xFE)|0x01); //读器件地址写入:地址最低位是0,读取:地址最低位是1TWI_WaitAck();while(nbyte!=1) //读入前(nbyte-1)个字节{*pdin_data = TWI_ReceiveByte(); //循环从24C02中读数据,存入pdin_data所指的存储器中TWI_Ack(); //IIC应答pdin_data++; //指向存储读入数据的存储器指针加1nbyte--; //剩余要读入的字节减1};*pdin_data = TWI_ReceiveByte(); //读入最后一个字节TWI_NoAck(); //IIC无应答操作TWI_Stop();return 0;}/*void TWI_24CXX_Write(uint8_t* pDat, uint8_t nAddr, uint8_t nLen) {uint16_t i;for(i=0;i<nLen;i++){TWI_WriteByte(*(pDat+i), nAddr+i);}}void TWI_24CXX_Read(uint8_t* pDat, uint8_t nAddr, uint8_t nLen) {uint16_t i;for(i=0; i<nLen; i++)*(pDat+i) = TWI_ReadByte(nAddr+i);}*/。
STM32作为主机I2C,读写24C02EEPROM

STM32作为主机I2C,读写24C02EEPROM1、时钟和数据的传输:开始和停止条件,数据在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/************************************************************** --EEPROM的操作函数--24CXX驱动函数**************************************************************/u8 AT24CXX_ReadOneByte(u16 ReadAddr); //指定地址读取一个字节void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite); //指定地址写入一个字节void AT24CXX_WriteLenByte(u16 WriteAddr,u32 DataToWrite,u8 Len);//指定地址开始写入指定长度的数据u32 AT24CXX_ReadLenByte(u16 ReadAddr,u8 Len); //指定地址开始读取指定长度数据void AT24CXX_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite); //从指定地址开始写入指定长度的数据void AT24CXX_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead); //从指定地址开始读出指定长度的数据u8 AT24CXX_Check(void); //检查器件void AT24CXX_Init(void); //初始化IIC#endif----------------------------------------------------------------------------------------------------------------------------------------- AT24c02.c#include "at24cxx.h"#include "delay.h"/************************************************************** *************- 功能描述:STM32f103 EEPORM初始化函数- 隶属模块:STM32 EEPROM操作- 函数属性:外部,使用户使用- 参数说明:无- 返回说明:无- 函数功能:实现I2C的初始化。
STM32F0单片机用 I2C HAL 库读写24C02

STM32F0单片机快速入门九: 用I2C HAL 库读写24C02发表评论1.24C02介绍24C02 现在基本是开发板的标配,对于需要掉电存储的应用来说确是不二选择。
现在单片机因为内部集成了Flash存储器,一般也都支持数据的掉电保存,但相对于24C02 这种EEPROM 来说,使用单片机内部的Flash 有一些需要注意的问题:1.Flash 写入数据之前需要先执行擦除操作,而且擦除以扇区为单位。
2.Flash读写次数比EEPROM 少很多。
3.容易误操作,把Flash 内部的代码擦除掉。
4.影响中断的响应时间。
24C02 有256 字节的数据,一般说来也够用了。
它的地址是可以通过引脚配置的,这样一条I2C 总线上就可以挂多个24C02。
如下:我们把A2,A1,A0 都接地,这样地址为A0。
然后SCL,SDA 脚接MCU 的PB8 和PB9。
需要注意SCL,和SDA 需要加上拉电阻。
1.代码下面我们在一个I2C 例程上面修改代码来实现24C02 的读写。
大家可以看到使用库函数的好处,基本上不用看STM32F030 的手册,很快就能实现我们想要实现的功能。
我们用Keil 打开下面这个工程:STM32Cube_FW_F0_V1.11.0\Projects\STM32F030R8-Nucleo\Examples\I2C\I2C_TwoBoards_ComPolling\MDK-AR M\Project.uvprojxStep 1, 把I2C 地址改为跟我们硬件一致:Step 2, 根据实际使用的I2C 模块和引脚进行配置:Step 3, 把地址模式改为7BIT:Step 4, 操作EEPROM,我们不使用例子中的HAL_I2C_Master_Transmit 和HAL_I2C_Master_Receive,这两个函数适用于两个I2C 器件之间进行数据传输。
我们这里要用的是下面这两个函数:HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, // 使用的I2C 模块的Handle 的指针uint16_t DevAddress, // I2C 器件的地址,这里是24C02 的地址0xA0uint16_t MemAddress, // 存储器内部地址uint16_t MemAddSize, // 存储器内部地址位数8BIT or 16BIT ?uint8_t *pData, // 发送数据缓冲区指针uint16_t Size, // 数据长度uint32_t Timeout // 超时设置);HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, // 使用的I2C 模块的Handle 的指针uint16_t DevAddress, // I2C 器件的地址,这里是24C02 的地址0xA0uint16_t MemAddress, // 存储器内部地址uint16_t MemAddSize, // 存储器内部地址位数8BIT or 16BIT ?uint8_t *pData, // 接收数据缓冲区指针uint16_t Size, // 接收数据长度uint32_t Timeout // 超时设置);在此我们写入数据用的24C02 的Page Write 命令,每次写入8个字节的数据,然后存储器写入地址加8。
STM32 读写 EEPROM 24C02方法

//In the case of a single data transfer disable ACK before reading the data I2C_AcknowledgeConfig(I2Cx, DISABLE);
//Send STRAT condition a second time I2C_GenerateSTART(I2Cx, ENABLE);
//Test on EV6 and clear it while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
printf("\r\n The slave address is %x \r\n", I2C_ReceiveData(I2Cx));
//
printf("\r\n The I2C1 succeed 2 \r\n");
#endif }
}
/*-----------------------------------------------------------函数名:EEPROM_24C02_Read 函数功能:读取 24C02 EEPROM 的内部数据 参数:I2Cx,选定 STM32 的 I2C 接口,x 可以是 1 或 2
while((number - 1) > 0) {
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
向有子地址器件读取多字节数据函数
函数原型: bit RecndStr(UCHAR sla,UCHAR suba,ucahr *s,UCHAR no);
功能: 从启动总线到发送地址,子地址,读数据,结束总线的全过程,从器件
地址 sla,子地址 suba,读出的内容放入 s 指向的存储区,读 no 个字节。
Delay_us_24C02(1);
//发送结束条件的时钟信号
SCL(1) ; //SCL=1; 结束条件建立时间大于 4μs
Delay_us_24C02(5);
SDA(0); //SDA=1; 发送 I2C 总线结束信号
Delay_us_24C02(4);
}****************************************** 字节数据发送函数
注意:
如果返回 1 表示操作成功,否则操作有误。 使用前必须已结束总线。
********************************************************************/
u8 IRcvStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no)
//实验 24C02 连接在 PF 口 //WP、A0、A1、A2 都接地,如下图所示。 //单片机:STM32F103
#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 硬件接口 ******************************/
unsigned char RcvByte()
{
unsigned char retc;
unsigned char BitCnt;
retc=0;
SDA(1); //SDA=1 置数据线为输入方式 for(BitCnt=0;BitCnt<8;BitCnt++)
{ Delay_us_24C02(1); SCL(0); //SCL=0 置时钟线为低,准备接收数据位 Delay_us_24C02(5); //时钟低电平周期大于 4.7μs
void Ack_I2c(u8 a)
{
if(a==0)
SDA(0); //SDA=0;在此发出应答或非应答信号 else
SDA(1); //SDA=1; Delay_us_24C02(3);
SCL(1); //SCL=1; Delay_us_24C02(4); //时钟低电平周期大于 4μs
SCL(0) ; //SCL=0; 清时钟线,钳住 I2C 总线以便继续接收 Delay_us_24C02(2);
结束总线函数
函数原型: void Stop_I2c();
功能: 结束 I2C 总线,即发送 I2C 结束条件.
********************************************************************/
void Stop_I2c()
{
SDA(0); //SDA=0; //发送结束条件的数据信号
SCL(1);
//SCL=1 置时钟线为高,通知被控器开始接收数据位
Delay_us_24C02(5); //保证时钟高电平周期大于 4μs
SCL(0);
//SCL = 0
}
Delay_us_24C02(2); SDA(1); //SDA=1 位发送完后释放数据线,准备接收应答位 Delay_us_24C02(2); SCL(1); //SCL=1 Delay_us_24C02(3); if(GPIO_ReadInputDataBit(GPIOF ,SData)==1)ack=0; else ack=1; //判断是否接收到应答信号 SCL(0); //SCL=0; Delay_us_24C02(3); }
SCL(1); //SCL=1 置时钟线为高使数据线上数据有效 Delay_us_24C02(2); retc=retc<<1; if(GPIO_ReadInputDataBit(GPIOF , SData)== 1)retc=retc+1; // SDA == 1 读数据位,接 收的数据位放入 retc 中 Delay_us_24C02(2); } SCL(0); // SCL=0; Delay_us_24C02(2); return(retc); }
}
//AT2402 的功能函数 /*******************************************************************
向有子地址器件发送多字节数据函数 函数原型: bit ISendStr(UCHAR sla,UCHAR suba,ucahr *s,UCHAR no); 功能: 从启动总线到发送地址,子地址,数据,结束总线的全过程,从器件
SendByte(*s); if(ack==0)return(0); s++; } Stop_I2c();
/*发送数据*/ /*结束总线*/
return(1); }
/*******************************************************************
/*******************************************************************
起动总线函数
函数原型: void Start_I2c();
功能: 启动 I2C 总线,即发送 I2C 起始条件.
********************************************************************/
/*******************************************************************
字节数据接收函数
函数原型: UCHAR RcvByte();
功能:
用来接收从器件传来的数据,并判断总线错误(不发应答信号),
发完后请用应答函数应答从机。
********************************************************************/
/********************************************************************
应答子函数
函数原型: void Ack_I2c(bit a);
功能:
主控器进行应答信号(可以是应答或非应答信号,由位参数 a 决定)
********************************************************************/
SCL(0);
//SCL=0;
Delay_us_24C02(2);
}
/*发送起始信号*/ // 起始条件锁定时间大于 4μs
/*钳住 I2C 总线,准备发送或接收数据 */
/*******************************************************************
{
unsigned char i;
Start_I2c();
/*启动总线*/
SendByte(sla); if(ack==0)return(0); SendByte(suba); if(ack==0)return(0);
void Start_I2c()
{
SDA(1); //SDA=1; 发送起始条件的数据信号
Delay_us_24C02(1);
SCL(1);
//SCL=1;
Delay_us_24C02(5);
//起始条件建立时间大于 4.7us,延时
SDA(0); //SDA=0;
Delay_us_24C02(5);
地址 sla,子地址 suba,发送内容是 s 指向的内容,发送 no 个字节。 如果返回 1 表示操作成功,否则操作有误。 注意: 使用前必须已结束总线。
********************************************************************/ u8 ISendStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no) {