基于51单片机i2c多字节的读写
I2C读写EEPROM文档说明

通过I2C通讯协议对EEPROM进行读写操作发送串口进行通讯一.描述I2CI2C协议有启动,终止,应答,非应答四种信号,有按位发送数据,按位接收数据,有读操作和写操作。
1.启动I2C程序如下,保持SCL为高电平,SDA为高电平,当检测到SDA下降沿时,启动传送,如果2个信号没有被高则返回0。
程序启动成功返回1。
uint8 I2C_Start(void){CyDelayUs(10);SDA_Write(1);CyDelayUs(10);SCL_Write(1);CyDelayUs(10);if ( SDA_Read() == 0) return 0;if ( SCL_Read() == 0) return 0;SDA_Write(0);CyDelayUs(10);SCL_Write(0);CyDelayUs(10);return 1;}上面是模仿I2C启动时序2.终止传送程序如下SDA保持低电平SCL保持高电平而后拉高SDA,系统检测到SDA上升沿则终止传送。
void I2C_Stop(void){CyDelayUs(10);SDA_Write(0);CyDelayUs(10);SCL_Write(1);CyDelayUs(10);SDA_Write(1);CyDelayUs(10);}3.模拟应答信号,让SDA的低电平时间大于SCL的高电平时间,即可应答;也就是SDAvoid I2C_Ack(void){CyDelayUs(10);SDA_Write(0);CyDelayUs(10);SCL_Write(1);CyDelayUs(10);SCL_Write(0);CyDelayUs(10);}4.模拟非应答信号,让SDA的高电平时间大于SCL高电平时间,就是非应答void I2C_Nack(void){CyDelayUs(10);SDA_Write(1);CyDelayUs(10);SCL_Write(1);CyDelayUs(10);SCL_Write(0);CyDelayUs(10);}5.按位发送数据,按位发送数据的要求是数据位高电平的时间大于SCL,SCL高电平时不允许数据位电平变化,只有SCL低电平时才可以任意变换。
实验八 51系列单片机IIC

I2C总线上的所有器件连接在一个公共的总线上,因此,主器件在进行数据传输前选择需要通信的从器件,即进行总线寻址。 I2C总线上所有外围器件都需要有惟一的地址,由器件地址和引脚地址两部分组成,共7位。器件地址是I2C器件固有的地址编码,器件出厂时就已经给定,不可更改。引脚地址是由I2C总线外围器件的地址引脚(A2,A1,A0)决定,根据其在电路中接电源正极、接地或悬空的不同,形成不同的地址代码。引脚地址数也决定了同一种器件可接入总线的最大数目。 地址位与一个方向位共同构成I2C总线器件寻址字节。寻址字节的格式如表所示。方向位(R/)规定了总线上的主器件与外围器件(从器件)的数据传输送方向。当方向位R/=1,表示主器件读取从器件中的数据;R/=0,表示主器件向从器件发送数据。
从地址中读取一个字节的数据
INT8U read_random(INT8U RomAddress) { INT8U Read_data; I_Start(); I_Write8Bit(WriteDeviceAddress); I_TestAck(); I_Write8Bit(RomAddress); I_TestAck(); I_Start(); I_Write8Bit(ReadDeviceAddress); I_TestAck(); Read_data=I_Read8Bit(); I_NoAck(); I_Stop(); return (Read_data); }
8.4.1 串行EEPROM存储器简介
串行EEPROM存储器是一种采用串行总线的存储器,这类存储器具有体积小、功耗低、允许工作电压范围宽等特点。目前,单片机系统中使用较多的EEPROM芯片是24系列串行EEPROM。其具有型号多、容量大、支持I2C总线协议、占用单片机I/O端口少,芯片扩展方便、读写简单等优点。 目前,Atmel、MicroChip、National等公司均提供各种型号的I2C总线接口的串行EEPROM存储器。下面以Atmel公司的产品为例进行介绍。 AT24C01/02/04/08系列是Atmel公司典型的I2C串行总线的EEPROM。这里以AT24C08为例介绍。AT24C08具有1024×8位的存储容量,工作于从器件模式,可重复擦写100万次,数据可以掉电保存100年。8引脚DIP封装的AT24C08的封装结构,如图所示。
I2C存储器读写(计数器,并能断电存储)

任务二:I2C存储器读写(计数器,并能断电存储)实验原理1)I2C总线概述I2C总线是PHLIPS公司推出的一种串行总线,是具备多主机系统所需的包括总线裁决和高低速器件同步功能的高性能串行总线。
2)I2C信号线I2C总线只有两根双向信号线。
一根是数据线SDA,另一根是时钟线SCL。
I2C总线通过上拉电阻接正电源。
当总线空闲时,两根线均为高电平。
连到总线上的任一器件输出的低电平,都将使总线的信号变低,即各器件的SDA及SCL都是线“与”关系。
图3 I2C总线框图3)I2C总线的数据传送a)数据位的有效性规定I2C总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。
图4 SDA与SCL的工作时序图b) 起始和终止信号SCL线为高电平期间,SDA线由高电平向低电平的变化表示起始信号SCL线为高电平期间,SDA线由低电平向高电平的变化表示终止信号。
起始和终止信号都是由主机发出的,在起始信号产生后,总线就处于被占用的状态;在终止信号产生后,总线就处于空闲状态。
c) I2C总线的数据传送速率I2C总线的通信速率受主机控制,能快能慢,最高速率限制为100Kb/sd) I2C总线的数据传送格式主机向从机发送数据从机向主机发送数据图5 I2C总线的数据传送格式S:起始位SA: 从机地址,7位W/:写标志位,1位R:读标志位,1位A:应答位,1位A/:非应答位,1位D:数据,8位P:停止位阴影:主机产生的信号无阴影:从机产生的信号4)总线的寻址I2C总线协议有明确的规定:采用7位的寻址字节(寻址字节是起始信号后的第一个字节)。
寻址字节的位定义D7~D1位组成从机的地址。
D0位是数据传送方向位,为“0”时表示主机向从机写数据,为“1”时表示主机由从机读数据。
主机发送地址时,总线上的每个从机都将这7位地址码与自己的地址进行比较,如果相同,则认为自己正被主机寻址,根据R/位将自己确定为发送器或接收器。
MPU6050使用I2C协议读出X轴原始数据的51单片机程序

MPU6050使用I2C协议读出X轴原始数据的51单片机程序主:STC89C54下面代码#include <reg51.h>#define uchar unsigned char//#define addr_x 0xae // 写//#define addr_d 0xaf // 读sbit sda = P2^1; //数据管脚sbit scl = P2^0; //时钟管脚bit ack;//****************************************// 定义MPU6050内部地址//****************************************#define SMPLRT_DIV 0x19 //陀螺仪采样率,典型值:0x07(125Hz)#define CONFIG 0x1A //低通滤波频率,典型值:0x06(5Hz)#define GYRO_CONFIG 0x1B //陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)#define ACCEL_CONFIG 0x1C //加速计自检、测量范围及高通滤波频率,典型值:0x01(不自检,2G,5Hz)#define ACCEL_XOUT_H 0x3B#define ACCEL_XOUT_L 0x3C#define ACCEL_YOUT_H 0x3D#define ACCEL_YOUT_L 0x3E#define ACCEL_ZOUT_H 0x3F#define ACCEL_ZOUT_L 0x40#define TEMP_OUT_H 0x41#define TEMP_OUT_L 0x42#define GYRO_XOUT_H 0x43#define GYRO_XOUT_L 0x44#define GYRO_YOUT_H 0x45#define GYRO_YOUT_L 0x46#define GYRO_ZOUT_H 0x47#define GYRO_ZOUT_L 0x48#define PWR_MGMT_1 0x6B //电源管理,典型值:0x00(正常启用)#define WHO_AM_I 0x75 //IIC地址寄存器(默认数值0x68,只读)#define SlaveAddress 0xD0 //IIC写入时的地址字节数据,+1为读取void DelayUs2x(unsigned char t) //延时1{while(--t);}void DelayMs(unsigned char t) //延时2{while(t--){//大致延时1mSDelayUs2x(245);DelayUs2x(245);}}void delay() //延时大于4μs//*******************I2C操作协议******************************void i2_qs() //起始信号{sda = 1; //拉高数据scl = 1; //拉高时钟delay(); //延时大于 4μssda = 0; //拉低数据产生起始信号(下降沿)delay(); //延时大于 4μsscl = 0; //拉低时钟delay(); //延时大于 4μs}void i2_tz() //停止信号{sda = 0; //拉低数据scl = 1; //拉高时钟delay(); //延时大于 4μssda = 1; //拉高时钟产生结束信号(上升沿)delay(); //延时大于 4μs}void i2_ack(bit _ack) //入口产生 0 ack 1 nak{sda = _ack; //ack或者nakscl = 1; //拉高时钟delay(); //延时大于 4μsscl = 0; //拉低时钟delay(); //延时大于 4μsvoid i2_fs(uchar Data) //发送8位数据{uchar i;for(i=0;i<8;i++) //8位计数{Data <<= 1; //把最高位移送到进制标志位中(CY)sda = CY; //把进制位中的数据赋值给数据线scl = 1; //拉高时钟delay(); //延时大于 4μsscl = 0; //拉低时钟//这里}//下面代码是接收ACK的代码delay();//延时大于 4μssda = 1; //拉高数据准备接收ACKscl = 1; //拉高时钟产生稳定的有效的数据(相对的)if(sda==1) //确认接收的是ACK还是NAKack = 0;//ackelseack = 1;//nakscl = 0; //拉低时钟delay(); //延时大于 4us}uchar i2_js() //接收8位数据{uchar i,Data = 0;sda = 1; //使能内部上拉,准备读取数据for(i=0;i<8;i++) //8位计数器{Data <<= 1; //移出数据的最高位scl = 1; //拉高时钟delay(); //延时大于 4usData |= sda;//接收数据scl = 0; //拉低时钟delay(); //延时大于 4us}return Data;}void i2_sj_x(uchar addr,uchar Data) //往设备内写入数据(参数1、寄存器地址 2、写入的数据){i2_qs(); //起始信号i2_fs(SlaveAddress); //设备地址+写信号i2_fs(addr); //寄存器内部地址i2_fs(Data); //写入设备的数据i2_tz(); //停止信号}uchar i2_sj_d(uchar addr) //读取数据(参数寄存器地址){uchar Data;i2_qs(); //起始信号i2_fs(SlaveAddress); //设备地址+写信号i2_fs(addr); //寄存器内部地址i2_qs(); //起始信号i2_fs(SlaveAddress+1); //设备地址+读信号Data = i2_js(); //读取数据i2_ack(0); //ACK应答i2_tz(); //停止信号return Data; //返回读取的数据}//*******************I2C操作协议******************************void mup6050(){i2_sj_x(PWR_MGMT_1, 0x00);i2_sj_x(SMPLRT_DIV, 0x07);i2_sj_x(CONFIG, 0x06);i2_sj_x(GYRO_CONFIG, 0x18);i2_sj_x(ACCEL_CONFIG, 0x01);/*Single_WriteI2C(PWR_MGMT_1, 0x00); //解除休眠状态Single_WriteI2C(SMPLRT_DIV, 0x07); //陀螺仪采集频率Single_WriteI2C(CONFIG, 0x06);//低通滤波频率Single_WriteI2C(GYRO_CONFIG, 0x18);//陀螺仪自检及测量范围Single_WriteI2C(ACCEL_CONFIG, 0x01);//加速计自检、测量范围及高通滤波频率*/}/**************************************串口**********************************/void CSH (void) //初始化串口SCON = 0x50; // SCON: 模式 1, 8-bit UART, 使能接收TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit 重装TH1 = 0xFD; // TH1: 重装值9600 波特率晶振11.0592MHzTR1 = 1; // TR1: timer 1 打开EA = 1; //打开总中断//ES = 1; //打开串口中断}void SendByte(unsigned char dat) //发送一个字符{SBUF = dat; //SBUF 串行数据缓冲器while(!TI); //TI发送中断标志位 (当数据发送完毕后由硬件置 1 否则等待硬件置 1)TI = 0;}/************************************************************** **********************/void main(void){uchar dat1,dat2,i;mup6050();CSH();/*i2_sj_x(3,0x0f); //数据写入24c02DelayMs(50);dat = i2_sj_d(3); //从24c02中读取数据//P1 = dat; //使用8个LED显示读出的数据while(1){dat1 = i2_sj_d(GYRO_XOUT_H);dat2 = i2_sj_d(GYRO_XOUT_H+1);P1 = dat1;for(i=0;i<100;i++)DelayMs(10);P1 = dat2;for(i=0;i<100;i++)DelayMs(10);SendByte(dat1);SendByte(dat2);}}。
MCU-51 多字节连接操作EEPROM(C语言程序)

//-----------------------------------------------
sfr IAP_DATA = 0xC2; //IAP数据寄存器
sfr IAP_ADDRH = 0xC3; //IAP地址寄存器高字节
//#define ENABLE_IAP 0x87 //if SYSCLK<1MHz
//测试地址
#define IAP_ADDRESS 0x0400
void IapIdle();
BYTE IapReadByte(WORD addr);
void IapProgramByte(WORD addr, BYTE dat);
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
/*---------------------------------------------------------------------*/
/* --- STC MCU Limited ------------------------------------------------*/
/* --- STC15F4K60S4 系列 内部EEPROM举例--------------------------------*/
void InitUart();
BYTE SendData(BYTE dat);
51单片机综合学习系统之 IIC总线学习篇.

大家好,通过以前的学习,我们已经对51单片机综合学习系统的使用方法及学习方式有所了解与熟悉,学会了使用无线遥控模块的基本知识,体会到了综合学习系统的易用性与易学性,这一期我们将一起学习IIC总线的基本原理与应用实例。
先看一下我们将要使用的51单片机综合学习系统能完成哪些实验与产品开发工作:分别有流水灯,数码管显示,液晶显示,按键开关,蜂鸣器奏乐,继电器控制,IIC 总线,SPI总线,PS/2实验,AD模数转换,光耦实验,串口通信,红外线遥控,无线遥控,温度传感,步进电机控制等等。
上图是我们将要使用的51单片机综合学习系统硬件平台,如图1所示,本期实验我们用到了综合系统主机、板载的AT24C02芯片,综合系统其它功能模块原理与使用详见前几期《电子制作》杂志及后期连载教程介绍。
在很多电子设备中都有要随时存取数据作为历史记录或标志位。
目前常用的存储器有24CXX系列和93CXX系列,前者是I2C总线结构,后者是SPI总线结构,本小节先介绍I2C结构的EEPROM(24CXX)作用方法,在后面小节中再介绍SPI结构的EEPROM(93CXX)使用方法。
I2C总线基本概念I2C总线,是INTERINTEGRATEDCIRCUITBUS的缩写,即“内部集成电路总线”。
I2C总线是Philips公司推出的一种双向二线制总线。
目前Philips公司和其它集成电路制造商推出了很多基于I2C总线的外围器件。
I2C总线包括一条数据线(SDA)和一条时钟线(SCL)。
协议允许总线接入多个器件,并支持多主工作。
总线中的器件既可以作为主控器也可以作为被控器,既可以是发送器也可以是接收器。
总线按照一定的通信协议进行数据交换。
在每次数据交换开始,作为主控器的器件需要通过总线竞争获得主控权,并启动一次数据交换。
系统中各个器件都具有唯一的地址,各器件之间通过寻址确定数据接收方。
I2C总线的系统结构一个典型的I2C总线标准的IC器件,其内部不仅有I2C接口电路,还可将内部各单元电路划分成若干相对独立的模块,它只有二根信号线,一根是双向的数据线SDA,另一根是时钟线SCL。
51单片机i2c读写程序的详细讲解

51单片机i2c读写程序的详细讲解下载提示:该文档是本店铺精心编制而成的,希望大家下载后,能够帮助大家解决实际问题。
文档下载后可定制修改,请根据实际需要进行调整和使用,谢谢!本店铺为大家提供各种类型的实用资料,如教育随笔、日记赏析、句子摘抄、古诗大全、经典美文、话题作文、工作总结、词语解析、文案摘录、其他资料等等,想了解不同资料格式和写法,敬请关注!Download tips: This document is carefully compiled by this editor. I hope that after you download it, it can help you solve practical problems. The document can be customized and modified after downloading, please adjust and use it according to actual needs, thank you! In addition, this shop provides you with various types of practical materials, such as educational essays, diary appreciation, sentence excerpts, ancient poems, classic articles, topic composition, work summary, word parsing, copy excerpts, other materials and so on, want to know different data formats and writing methods, please pay attention!《51单片机i2c读写程序的详细讲解》一、概述51单片机是一种常用的单片机,在很多应用中使用的最多的是i2c接口,那么如何在51单片机上进行i2c的读写操作呢?下面将详细讲解i2c读写操作的程序设计过程。
I2C总线规范与I2C器件C51读写程序

I2C总线规范可以参考有关资料,本文仅给出有关硬件操作的基本概念。
2.1、I2C 总线名词解释:
发送器:发送数据到总线上的器件
接收器:从总线上接收数据的器件
主器件:启动数据传送并产生时钟信号的器件
从器件:被主器件寻址的器件
2.2、I2C总线时序定义:
起始位:SCL=1时,在SDA上有下降延
应答检测:采用应答检测读命令测试从机是否<页写>结束(通过从应答来识别)
*当从器件完成内部写周期后将发送一个应答信号(从应答)给主器件,以便可以继续进行下一次读操作
3、I2C器件C51读写程序
3.1、数据定义说明:
sbit sda=P0^0; //I2C器件SDA数据线
sbit scl=P0^1; //I2C器件SCL时钟线
for(i=0;i<8;i++){
_nop_();
scl=0; //置时钟线为低,准备接收数据位
nops();
scl=1; //置时钟线为高,使数据线上数据有效
_nop_();
c<<=1;
if(sda)c+=1; //读数据位,将接收的数据存c
}
scl=0;
return c;
}
uchar i;
i2c_start();
send_byte(ad_main); //发送器件地址
send_byte(ad_sub); //发送器件子地址
for(i=0;i<num;i++){
send_byte(*buf); //发送数据*buf
buf++;
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基于51单片机i2c多字节的读写
使用Keil的编译环境下载,确实能够下载,但是入口的地址是如下黄色的那行显示所示,如果单步执行(F11)或全速运行(F5),程序始终在原位置不动(0x1FFF4252),如果强制的将PC指针的值和SP的值修改为
0x8000000与0x2000000,然后在点击运行,则能够跑到main()函数,再全速运行,能够看到客户板子上的LED灯的闪烁。
但是如果不强制修改PC和SP指针的值,则程序不执行。
所以问题就变成为什幺程序下载进去后的地址是
0x1FFF4252?0x1FFF4252又是什幺地址呢?查阅相应的手册,发现
0x1FFF4252是处在了Systemmemory区域。
用万用表测量了客户板上的Boot0引脚的电平,发现电平不对,达到1.6V,这幺高的电平可以被视为高电平了。
对照客户的原理图,原来Boot有上拉和下拉的电阻,焊接的时候将这两个电阻都焊接上去了,去掉上拉电阻,使的BOOT0的引脚接地为低电平,再编译下载进入Keil的环境,程序能够被正常执行了。
问题找到了。