STM32F103读写24C02 C程序-有硬件电路图和程序
- 格式:doc
- 大小:93.50 KB
- 文档页数:10
//实验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; //GPIOErrorStatus 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(){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); // 起始条件锁定时间大于4μsSCL(0); //SCL=0; /*钳住I2C总线,准备发送或接收数据 */Delay_us_24C02(2);}/*******************************************************************结束总线函数函数原型: void Stop_I2c();功能: 结束I2C总线,即发送I2C结束条件.********************************************************************/ void Stop_I2c(){SDA(0); //SDA=0; //发送结束条件的数据信号Delay_us_24C02(1); //发送结束条件的时钟信号SCL(1) ; //SCL=1; 结束条件建立时间大于4μsDelay_us_24C02(5);SDA(0); //SDA=1; 发送I2C总线结束信号Delay_us_24C02(4);}/*******************************************************************字节数据发送函数函数原型: void SendByte(UCHAR c);功能: 将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对此状态位进行操作.(不应答或非应答都使ack=0)发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
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读写程序大全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读写程序。
全文共分四部分,第一部分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单片机)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 发出特定的低电平脉冲,表示已收到数据。
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连接在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; //GPIOErrorStatus 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(GPIOB, SCLK) : GPIO_ResetBits(GPIOB, SCLK) #define SDA(x) x ? GPIO_SetBits(GPIOB, SData) : GPIO_ResetBits(GPIOB, SData) /********************************变量*******************************************/u8 ack;/*******************************************************************起动总线函数函数原型: void Start_I2c();功能: 启动I2C总线,即发送I2C起始条件.********************************************************************/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); // 起始条件锁定时间大于4μsSCL(0); //SCL=0; /*钳住I2C总线,准备发送或接收数据*/Delay_us_24C02(2);}/*******************************************************************结束总线函数函数原型: void Stop_I2c();功能: 结束I2C总线,即发送I2C结束条件.********************************************************************/void Stop_I2c(){SDA(0); //SDA=0; //发送结束条件的数据信号Delay_us_24C02(1); //发送结束条件的时钟信号SCL(1) ; //SCL=1; 结束条件建立时间大于4μsDelay_us_24C02(5);SDA(0); //SDA=1; 发送I2C总线结束信号Delay_us_24C02(4);}/*******************************************************************字节数据发送函数函数原型: void SendByte(UCHAR c);功能: 将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对此状态位进行操作.(不应答或非应答都使ack=0)发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
********************************************************************/ void SendByte(unsigned char c){unsigned char BitCnt;for(BitCnt=0;BitCnt<8;BitCnt++) //要传送的数据长度为8位{if((c<<BitCnt)&0x80) SDA(1); //SDA=1; 判断发送位else SDA(0); // SDA=0Delay_us_24C02(1);SCL(1); //SCL=1 置时钟线为高,通知被控器开始接收数据位Delay_us_24C02(5); //保证时钟高电平周期大于4μsSCL(0); //SCL = 0}Delay_us_24C02(2);SDA(1); //SDA=1 位发送完后释放数据线,准备接收应答位Delay_us_24C02(2);SCL(1); //SCL=1Delay_us_24C02(3);if(GPIO_ReadInputDataBit(GPIOF ,SData)==1)ack=0;else ack=1; //判断是否接收到应答信号SCL(0); //SCL=0;Delay_us_24C02(3);}/*******************************************************************字节数据接收函数函数原型: UCHAR RcvByte();功能: 用来接收从器件传来的数据,并判断总线错误(不发应答信号),发完后请用应答函数应答从机。
********************************************************************/ 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μsSCL(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);}/********************************************************************应答子函数函数原型: void Ack_I2c(bit a);功能: 主控器进行应答信号(可以是应答或非应答信号,由位参数a决定)********************************************************************/void Ack_I2c(u8 a){if(a==0)SDA(0); //SDA=0;在此发出应答或非应答信号elseSDA(1); //SDA=1;Delay_us_24C02(3);SCL(1); //SCL=1;Delay_us_24C02(4); //时钟低电平周期大于4μsSCL(0) ; //SCL=0; 清时钟线,钳住I2C总线以便继续接收Delay_us_24C02(2);}//AT2402的功能函数/*******************************************************************向有子地址器件发送多字节数据函数函数原型: bit ISendStr(UCHAR sla,UCHAR suba,ucahr *s,UCHAR no);功能: 从启动总线到发送地址,子地址,数据,结束总线的全过程,从器件地址sla,子地址suba,发送内容是s指向的内容,发送no个字节。
如果返回1表示操作成功,否则操作有误。
注意:使用前必须已结束总线。
********************************************************************/u8 ISendStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no) {unsigned char i;Start_I2c(); /*启动总线*/SendByte(sla); /*发送器件地址*/if(ack==0)return(0);SendByte(suba); /*发送器件子地址*/if(ack==0)return(0);for(i=0;i<no;i++){SendByte(*s); /*发送数据*/if(ack==0)return(0);s++;}Stop_I2c(); /*结束总线*/return(1);}/*******************************************************************向有子地址器件读取多字节数据函数函数原型: bit RecndStr(UCHAR sla,UCHAR suba,ucahr *s,UCHAR no);功能: 从启动总线到发送地址,子地址,读数据,结束总线的全过程,从器件地址sla,子地址suba,读出的内容放入s指向的存储区,读no个字节。