I2C总线程序
I2C总线芯片AT24C02程序设计
I2C总线芯片AT24C02程序设计I2C总线芯片AT24C02是一种常用的存储器芯片,在嵌入式系统中广泛应用。
本文将介绍如何使用AT24C02进行程序设计,包括芯片初始化、读取数据和写入数据等操作。
为了简化整个流程,本文将只介绍关键的代码部分。
首先,我们需要了解AT24C02芯片的连接方式和寄存器地址。
AT24C02通过I2C总线连接到控制器,其中使用两根信号线SCL和SDA进行通信。
芯片的I2C地址为0xA0,并且有256个存储器单元,每个单元8位,总共可以存储2KB的数据。
接下来,我们需要进行芯片的初始化。
初始化过程包括初始化I2C总线、设置AT24C02的I2C地址和其他必要的配置。
以下是AT24C02初始化的代码示例:```c#include <Wire.h>#define AT24C02_ADDRESS 0xA0 // AT24C02芯片的I2C地址void setupWire.begin(; // 初始化I2C总线void loop//主程序代码```在进行读取数据之前,我们需要指定要读取的存储器单元的地址,并将其发送给AT24C02芯片。
以下是读取数据的代码示例:```c#include <Wire.h>#define AT24C02_ADDRESS 0xA0 // AT24C02芯片的I2C地址#define MEMORY_ADDRESS 0x00 // 要读取的存储器单元的地址void setupWire.begin(; // 初始化I2C总线Wire.beginTransmission(AT24C02_ADDRESS); // 开始I2C通信Wire.write(MEMORY_ADDRESS); // 发送存储器单元的地址Wire.endTransmission(; // 结束I2C通信void loop//主程序代码```在进行写入数据之前,我们需要指定要写入的存储器单元的地址,并将数据发送给AT24C02芯片。
I2C总线AT24C02存储器读写程序
write_byte(date);//在芯片第address位置写date.
respons();//写完后调用应答函数
stop();//I2C结束时钟函数
}
uchar read_add(uchar address)
{
uchar date;
{ start();//I2C开始时钟函数
write_byte(0xa0);//at24c02的固定地址A,1010,AO-A3都接地都为0。
respons();//写完后调用应答函数
write_byte(address);//确定从at24c02的第address位置写数据。
aa=k;
ee=aa*2200;
if(D4==0)
{
delay (100);
if(D4==1)
{
aa++;
delay (1);
init();//写直址,最后低位应为0。
write_add(2,aa);//23为at24c02内部储存地址,0xaa为写到23地址的数据。
#include <reg52.h>
#define uint unsigned int //定义unsigned int 为uint
#define uchar unsigned char //定义unsigned char 为uchar
#define uchar unsigned char //定义unsigned char 为uchar
delay (1);
k=read_add(2);//送到P1口显示。//从23地址读数据
i2c读写程序的详细讲解
i2c读写程序的详细讲解i2c是Inter-IntegratedCircuit的缩写,是一种主从机多总线的通信协议,也就是说,它可以允许多个电子设备在同一个信号线上通信。
i2c是分布式共享总线,它支持主机和多个从机之间的双向传输数据,因此本范文将针对i2c读写程序进行详细的讲解。
首先,我们来看一下i2c协议的特性:i2c协议使用两根信号线,分别是SCL(时钟线)和SDA(数据线),以及一个地线。
其中,SCL线用于传输时钟信号,SDA线用于传输数据,而地线用于给一个共同的参考电位。
i2c的数据传输是先信号再数据,即SCL脉冲先于SDA脉冲,且SDA数据根据SCL时钟的上升沿来储存和传输。
i2c协议的常见的特性包括节点重用,三线模式,通用性,简单性等。
接下来,我们来看一下i2c读写程序。
i2c读写程序是基于i2c协议来操作i2c总线上分布式设备的软件。
它包括一系列的控制参数,如速率、时钟频率、地址空间等,以及一系列读写操作。
i2c读操作通常有三种形式,分别为单字节读取、多字节读取和8位快速读取。
其中,单字节读取是i2c读操作中最常见的模式,其工作机制如下:首先,从主机发出一个读控制信号,只有当从机完成该信号指令后,才会将数据发送给主机;随后,主机收到数据后,发出一个确认信号来确认接收到了数据,从机收到信号后,就会发送下一个字节的数据。
多字节读取和单字节读取有很多相似之处,主要的不同在于它支持一次读取多字节的数据,首先,主机发出一个读控制信号,只有当从机完成该信号指令后,才会将数据发送给主机;随后,主机持续接收数据,直到接收到所有的数据为止。
8位快速读取模式是i2c总线上读取操作中最快的模式,它和其他读取模式有很多相同之处,主要是有一个专门的8位快速读指令,使用这个指令可以实现一次读取多字节数据的功能,而不需要反复发出读控制信号。
另外,i2c读写程序还支持写操作,其工作机制大致相同,只是在发出控制信号后,主机会将数据发送给从机,而不是从机将数据发送给主机。
I2C总线AT24C01读写程序(汇编和C)
NOP
NOP
MOV C,SDA
RLC A
CLR SCL
DJNZ B,I2C_RECEIVE8IT_A
RET
C语言写的24C01 单字节读写程序
LCALL I2C_SEND8BIT
LCALL I2C_ACK
JC I2C_READ_A ;=1,表示无确认,再次发送
MOV A,Address
LCALL I2C_SEND8BIT
LCALL I2C_ACK
unsigned char i2c_read(unsigned char Address)
{
unsigned char c;
do{
i2c_start();
i2c_send8bit(0xA0);
}while(i2c_ack()); //=1,表示无确认,再次发送
; 24C01存储器I2C总线实验 汇编语言例子
; =======================================================
SDA EQU P2.0
SCL EQU P2.1
i2c_write(地址,数据),写一个字节
=======================================================*/
void i2c_write(unsigned char Address,unsigned char Data)
{
do{
I2C总线AT24C01读写程序(汇编和C)
--------------------------------------------------------------------------------
I2C总线简介(很经典)
I2C总线简介1.概述:I²C是Inter-Integrated Circuit的缩写,发音为"eye-squared cee" or"eye-two-cee", 它是一种两线接口。
I²C 只是用两条双向的线,一条 Serial Data Line (SDA) ,另一条Serial Clock (SCL)。
SCL:上升沿将数据输入到每个EEPROM器件中;下降沿驱动EEPROM器件输出数据。
(边沿触发)SDA:双向数据线,为OD门,与其它任意数量的OD与OC门成"线与"关系。
2.输出级每一个I2C总线器件内部的SDA、SCL引脚电路结构都是一样的,引脚的输出驱动与输入缓冲连在一起。
其中输出为漏极开路的场效应管,输入缓冲为一只高输入阻抗的同相器,这种电路具有两个特点:1)由于SDA、SCL为漏极开路结构(OD),因此它们必须接有上拉电阻,阻值的大小常为1k8, 4k7 and 10k ,但1k8 时性能最好;当总线空闲时,两根线均为高电平。
连到总线上的任一器件输出的低电平,都将使总线的信号变低,即各器件的SDA及SCL都是线"与"关系。
2)引脚在输出信号的同时还将引脚上的电平进行检测,检测是否与刚才输出一致,为"时钟同步"和"总线仲裁"提供了硬件基础。
3.主设备与从设备系统中的所有外围器件都具有一个7位的"从器件专用地址码",其中高4位为器件类型,由生产厂家制定,低3位为器件引脚定义地址,由使用者定义。
主控器件通过地址码建立多机通信的机制,因此I2C总线省去了外围器件的片选线,这样无论总线上挂接多少个器件,其系统仍然为简约的二线结构。
终端挂载在总线上,有主端和从端之分,主端必须是带有CPU的逻辑模块,在同一总线上同一时刻使能有一个主端,可以有多个从端,从端的数量受地址空间和总线的最大电容 400pF的限制。
I2C总线协议AT24c02程序
I2C总线协议(AT24c02)程序主:STC89C54从:AT24C02电路图时序图下面是代码#include ;#define uchar unsigned char#define addr_x 0xae//写#define addr_d 0xaf//读sbit sda = P2^1;//数据管脚sbit scl = P2^0;//时钟管脚bit ack;void DelayUs2x(unsigned char t)//延时1{while(--t);}void DelayMs(unsigned char t)//延时2{ while(t--){ //大致延时1mS DelayUs2x(245); DelayUs2x(245);}}void delay() //延时大于4μs{;;}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 1nak{sda = _ack;//ack或者nakscl = 1;//拉高时钟delay();//延时大于 4μsscl = 0;//拉低时钟delay();//延时大于 4μs}void 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}uchari2_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(addr_x);//设备地址+写信号i2_fs(addr);//寄存器内部地址i2_fs(Data);//写入设备的数据i2_tz();//停止信号}uchar i2_sj_d(uchar addr)//读取数据(参数寄存器地址){ucharData;i2_qs();//起始信号i2_fs(addr_x);//设备地址+写信号i2_fs(addr);//寄存器内部地址i2_qs();//起始信号i2_fs(addr_d);//设备地址+读信号Data =i2_js();//读取数据i2_ack(0);//ACK应答i2_tz();//停止信号return Data;//返回读取的数据}voidmain(void){uchar dat;i2_sj_x(3,0x0f); //数据写入24c02DelayMs(50);dat = i2_sj_d(3); //从24c02中读取数据P1 = dat;//使用8个LED显示读出的数据while(1){;}}以上代码只是简单的实现I2C总线的读写。
I2C通信原理及程序详细讲解
I2C通信原理及程序详细讲解I2C(Inter-Integrated Circuit)是一种串行通信协议,常用于连接微控制器、传感器和其他外部设备。
I2C通信协议由荷兰飞利浦公司于1982年开发,它使用两根信号线(SDA和SCL)进行数据传输。
I2C通信协议采用主从结构,一个主设备(如微控制器)可以连接多个从设备(如传感器)。
主从设备之间通过SDA和SCL线进行数据传输。
SDA线是双向数据线,用于传输数据,SCL线是时钟线,用于同步数据传输。
I2C通信协议中,设备的地址是一个重要概念。
每个设备都有一个唯一的地址,通过该地址可以选择和通信特定的设备。
地址由7个位组成,其中最高位是固定的,并取决于设备是主设备还是从设备。
如果最高位为0,则表示该设备是主设备;如果最高位为1,则表示该设备是从设备。
通过以下步骤,让我们详细了解如何在I2C总线上进行通信。
1.初始化I2C总线:在程序开始时,需要初始化I2C总线。
这通常包括初始化SDA和SCL引脚,设置时钟频率等。
具体的初始化步骤取决于使用的硬件和软件环境。
2.发送开始信号:开始信号表示I2C数据传输的开始。
它由主设备发送,并且SDA线从高电平转为低电平时发出。
发送开始信号后,SDA线上的数据将被解释为地址数据。
3.发送设备地址:主设备发送一个包含设备地址和读/写位(R/W)的数据字节。
设备地址是唯一的,并且由主设备选择。
读/写位指示从设备是要读取数据还是写入数据。
4.等待从设备响应:主设备发送设备地址后,会等待从设备的响应。
从设备将响应一个应答位(ACK)来确认地址接收成功。
如果收到ACK位,则继续进行下一步,否则可能是设备未连接或通信错误。
5.发送数据:主设备发送数据给从设备。
数据可以是命令、配置或实际数据,具体取决于应用场景。
发送数据的方式是将每个数据字节传输到SDA线上,并在每个数据字节后发送一个ACK位。
6.接收数据:从设备将数据发送给主设备。
数据可以是传感器读数、存储器数据等。
stm32的i2c读写程序的详细讲解
一、概述STMicroelectronics瑞士意法半导体公司的STM32系列微控制器被广泛应用于各种嵌入式系统中,其强大的性能和丰富的外设功能受到了众多开发者的青睐。
其中,STM32的I2C总线通信功能在实际应用中具有重要意义,本文将对STM32的I2C读写程序进行详细讲解。
二、I2C总线介绍I2C(Inter-Integrated Circuit)总线是一种串行通信接口协议,由Philips公司推出。
它具有双向传输数据线(SDA)、时钟线(SCL)、起始条件、停止条件、数据传输的应答信号等特点。
I2C总线在各种传感器、存储器、外设等设备之间进行通信时,具有简单高效的优势。
三、STM32的I2C外设1. STM32的I2C外设功能STM32系列微控制器内置了丰富的外设功能,其中包括了I2C总线通信。
STM32的I2C外设支持主机和从机模式,可以实现与各种I2C设备的通信和数据交换。
2. STM32的I2C外设配置在使用STM32的I2C外设之前,需要对其进行配置,包括设置时钟、GPIO、寄存器参数等。
通过正确的配置,可以使STM32的I2C外设正常工作,并与其他设备进行可靠的通信。
四、STM32的I2C读写程序详解1. 初始化I2C外设在使用I2C总线进行读写操作之前,首先需要对STM32的I2C外设进行初始化设置。
具体步骤包括设置GPIO管脚为I2C功能模式、配置时钟、设置I2C的工作模式、设定传输速率等。
2. 发送起始信号当I2C通信开始时,主机会发送起始信号(Start),表明要开始一次通信过程。
起始信号的发送方式是通过在SDA线上拉低电平,同时保持SCL线处于高电平状态。
3. 选择设备位置区域在发送起始信号后,主机需要选择要通信的设备位置区域。
针对每个I2C设备,都有唯一的位置区域标识,主机需要向目标设备发送其位置区域信息。
位置区域信息由设备的7位位置区域和读写方向位组成。
4. 数据传输经过起始信号和设备位置区域选择后,接下来进行数据的传输。
I2C总线读写程序通用
//==========================头文件加载===============================#include <reg52.h> //加载52系列单片机头文件//===========================端口声明================================sbit CLK=P3^6; //74hc574时钟信号线sbit G=P2^4; //74hc574使能sbit IIC_SDA=P2^6; //声明IIC总线的数据线接在单片机的P2。
5端口。
sbit IIC_SCL=P2^5; //声明IIC总线的时钟线接在单片机的P2。
7端口。
unsigned char tabl[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x0BF,0x8C};//0,1,2,3,4,5,6,7,8,9,-,P//===========================函数声明================================ void display(unsigned char aa);void delay(unsigned int t);void delay_IIC(void);void IIC_Init(void);void IIC_start(void);void IIC_stop(void);bit IIC_Tack(void);void IIC_single_byte_write(unsigned char Daddr,unsigned char Waddr,unsigned char Data);unsigned char IIC_single_byte_read(unsigned char Daddr,unsigned char Waddr);void IIC_write_byte(unsigned char Data);unsigned char IIC_read_byte(void);//============================主函数================================= void main() //主函数{unsigned char Data=2,addr=0x01;//—-——-—--—————————-——--————-系统初始化——-—-—--—-—-—————-—---———-IIC_Init();//初始化IIC总线。
IIC总线读写程序
IIC总线读写程序//-----------------------函数声明,变量定义--------------------------------------------------------#include <reg51.h>#include <intrins.h>sbit SDA=P1^0; // 将p1.0口模拟数据口sbit SCL=P1^1; // 将p1.1口模拟时钟口#define NUM 10 // 接收和发送缓存区的深度#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};unsigned char idata sendbuf[NUM]; // 数据发送缓冲区unsigned char idata receivebuf[NUM]; // 数据接收缓冲区bit bdata SystemError; // 从机错误标志位//--------------------------------------------------------------------------------------------------// 函数名称:iic_start()// 函数功能:启动I2C总线子程序//--------------------------------------------------------------------------------------------------void iic_start(void){ EA=0; //时钟保持高,数据线从高到低一次跳变,I2C通信开始SDA = 1;SCL = 1;delayNOP(); // 延时5usSDA = 0;delayNOP();SCL = 0;}//--------------------------------------------------------------------------------------------------// 函数名称:iic_stop()// 函数功能:停止I2C总线数据传送子程序//--------------------------------------------------------------------------------------------------void iic_stop(void){SDA = 0; //时钟保持高,数据线从低到高一次跳变,I2C通信停止SCL = 1;delayNOP();SDA = 1;delayNOP();SCL = 0;}//--------------------------------------------------------------------------------------------------// 函数名称:slave_ACK// 函数功能:从机发送应答位子程序//-------------------------------------------------------------------------------------------------- void slave_ACK(void){SDA = 0;SCL = 1;delayNOP();SDA = 1;SCL = 0;}//-------------------------------------------------------------------------------------------------- // 函数名称:slave_NOACK// 函数功能:从机发送非应答位子程序,迫使数据传输过程结束//-------------------------------------------------------------------------------------------------- void slave_NOACK(void){SDA = 1;SCL = 1;delayNOP();SDA = 0;SCL = 0;}//-------------------------------------------------------------------------------------------------- // 函数名称:check_ACK// 函数功能:主机应答位检查子程序,迫使数据传输过程结束//-------------------------------------------------------------------------------------------------- void check_ACK(void){SDA = 1; // 将p1.0设置成输入,必须先向端口写1SCL = 1;F0 = 0;if(SDA == 1) // 若SDA=1表明非应答,置位非应答标志F0F0 = 1;SCL = 0;}//--------------------------------------------------------------------------------------------------// 函数名称:IICSendByte// 入口参数:ch// 函数功能:发送一个字节//-------------------------------------------------------------------------------------------------- void IICSendByte(unsigned char ch){unsigned char idata n=8; // 向SDA上发送一位数据字节,共八位while(n--){if((ch&0x80) == 0x80) // 若要发送的数据最高位为1则发送位1 {SDA = 1; // 传送位1SCL = 1;delayNOP();SDA = 0;SCL = 0;}else{SDA = 0; // 否则传送位0SCL = 1;delayNOP();SCL = 0;}ch = ch<<1; // 数据左移一位}}//-------------------------------------------------------------------------------------------------- // 函数名称:IICreceiveByte// 返回接收的数据// 函数功能:接收一字节子程序//-------------------------------------------------------------------------------------------------- unsigned char IICreceiveByte(void){unsigned char idata n=8; // 从SDA线上读取一上数据字节,共八位unsigned char tdata;while(n--){SDA = 1;SCL = 1;tdata = tdata<<1; // 左移一位,或_crol_(temp,1)if(SDA == 1)tdata = tdata|0x01; // 若接收到的位为1,则数据的最后一位置1 elsetdata = tdata&0xfe; // 否则数据的最后一位置0SCL=0;return(tdata);}//-------------------------------------------------------------------------------------------------- // 函数名称:writeNbyte// 入口参数:slave_add从机地址,n要发送的数据个数// 函数功能:发送n位数据子程序//-------------------------------------------------------------------------------------------------- void writeNbyte(unsigned char slave_add, unsigned char n){unsigned char idata send_da,i=0;iic_start(); // 启动I2CIICSendByte(slave_add); // 发送地址位check_ACK(); // 检查应答位if(F0 == 1){SystemError = 1;return; // 若非应答表明器件错误或已坏,置错误标志位SystemError }while(n--){send_da = sendbuf[i++];IICSendByte(send_da);check_ACK(); // 检查应答位if (F0 == 1){SystemError=1;return; // 若非应答表明器件错误或已坏,置错误标志位SystemError }}iic_stop(); // 全部发完则停止}//-------------------------------------------------------------------------------------------------- // 函数名称:receiveNbyte// 入口参数:slave_add从机地址,n要接收的数据个数// 函数功能:接收n位数据子程序//-------------------------------------------------------------------------------------------------- void receiveNbyte(unsigned char idata slave_add, unsigned char n){unsigned char idata receive_da,i=0;iic_start();IICSendByte(slave_add);check_ACK();if(F0 == 1){SystemError = 1;return;}while(n--){receive_da=IICreceiveByte();receivebuf[i++]=receive_da;slave_ACK(); // 收到一个字节后发送一个应答位}slave_NOACK(); // 收到最后一个字节后发送一个非应答位iic_stop();}。
I2C总线读时序的详解(新手必看)
_Nop();
_Nop();
_Nop();
SCL=1; //通知单片机检测数据线是高电平还是低电平
_Nop();
_Nop();
retc=retc<<1;
if(SDA==1)retc=retc+1; //读数据位,接收的数据位放入retc中
_Nop();
_Nop();
}
SCL=0;
_Nop();
_Nop();
return(retc);
}
以下是读时序还要注意的细节,对比下面两段for循环中的读取8位数据的程序
程序一
unsigned char RcvByte()
{
unsigned char retc;
unsigned char BitCnt;
retc=0;
SDA=1; //置数据线为输入方式
for(BitCnt=0;BitCnt<8;BitCnt++)
{
SCL=1;
_Nop();
_Nop();
_Nop();
_Nop();
retc=retc<<1;
if(SDA==1)retc=retc+1;
_Nop();
_Nop();
SCL=0;//执行这语句后,接下来就会执行i++,相当于延时了一段时间
retc=0;
SDA=1; //置数据线为输入方式
for(BitCnt=0;BitCnt<8;BitCnt++)
{
SCL=0;
SCL=1;//没有时间给芯片放出数据到数据线上,就通知单片机检测电平,错误!
i2c标准时序
I2C(Inter-Integrated Circuit)是一种常用的串行通信协议,用于在集成电路之间进行通信。
I2C协议定义了一种标准的时序,以下是I2C标准时序的一般流程:
1. 开始条件(Start Condition):由主设备发出一个低电平的SDA(Serial Data)信号,然后再发出一个低电平的SCL(Serial Clock)信号。
这表示一个新的传输周期的开始。
2. 地址传输(Address Transmission):主设备发送目标设备的地址,包括一个7位的设备地址和一个读/写位。
地址的最高位为1表示读操作,为0表示写操作。
3. 应答(Acknowledgement):在每个字节传输完成后,接收设备发送一个应答信号。
如果接收设备收到了正确的数据字节,它会拉低SDA线发送一个低电平的应答信号(ACK)。
如果接收设备没有正确接收到数据,它将不发送应答信号(NACK)。
4. 数据传输(Data Transmission):主设备通过SDA和SCL 线传输数据。
数据以8位为一个单位进行传输,每个字节的最高位先传输。
每个字节传输完成后,接收设备发送一个应答信号。
5. 停止条件(Stop Condition):由主设备发出一个高电平的SDA信号,然后再发出一个高电平的SCL信号。
这表示传输周期的结束。
以上是I2C标准时序的一般流程。
然而,具体的时序可
能会受到设备和应用的限制或要求而有所不同。
因此,在实际使用中,您可能需要参考特定设备的文档或规范来了解其精确的时序要求。
iic标准程序
IIC(Inter-Integrated Circuit)是一种串行通信协议,用于连接微控制器、传感器、存储器和其他外围设备。
以下是IIC标准程序的示例代码,用于在微控制器和外围设备之间进行通信:#include <stdio.h>#include <stdint.h>#include <unistd.h>#include <fcntl.h>#include <sys/ioctl.h>#include <linux/i2c-dev.h>int main(){int file;char *filename = "/dev/i2c-1"; // I2C bus 1 的设备文件路径uint8_t address = 0x50; // I2C 设备的地址char *buffer = malloc(2); // 用于存储从I2C 设备读取的数据的缓冲区// 打开I2C 总线设备文件file = open(filename, O_RDWR);if (file < 0) {perror("Failed to open i2c bus");return -1;}// 设置I2C 总线设备的地址和速率if (ioctl(file, I2C_SLAVE, address) < 0) {perror("Failed to acquire bus access and/or talk to slave");return -1;}// 向I2C 设备写入数据buffer[0] = 0x01; // 要写入的数据的第一个字节buffer[1] = 0x0A; // 要写入的数据的第二个字节int n = write(file, buffer, 2); // 将数据写入I2C 设备if (n < 1) {perror("Write failed");return -1;}// 从I2C 设备读取数据n = read(file, buffer, 1); // 从I2C 设备读取一个字节的数据到缓冲区中if (n < 1) {perror("Read failed");return -1;}printf("Read data: %x\n", buffer[0]); // 打印读取的数据的十六进制表示形式// 关闭I2C 总线设备文件close(file);free(buffer);return 0;}以上代码使用了Linux下的I2C-dev驱动,需要包含`<linux/i2c-dev.h>`头文件。
完整的I2C 模拟总线 C 程序
if ( I2C_SDA )
i2c_ack=1;
else
i2c_ack=0;
I2C_SCL = 0;
delay(1);
}
//‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
//‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
// 读取 24xx 一字节数据 ‥‥‥‥‥‥‥
nop();
// delay(2); // 延迟 47uSec
}
// nop();
I2C_SCL = 0;
nop();
//-------
SDAIO = 1;
I2C_SDA = 1;
//-------
delay(1);
I2C_SCL=1;
//‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
// I2C 模拟总线
//‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
//-----------
unsigned char dfefer[8];
delay(1);
I2C_SCL = 0;
}
// }
}
stop_i2c();
}
//‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥
/**********END**************/
// 程序结束
// SCLIO = 0;
nop();
I2C_SDA = 1;
nop();
I2C_SCL = 1;
delay(1); // 24LCxx 要求建立时间大于 Delay40uSec
I2C程序(AT24C1024)测试通过的
_nop_();
}
//*********************************************
//从机接收一位数据应答0
//*********************************************
voidACK(void)
{
SDA=0;
_nop_();
void write_byte(uchar ch)
{
uchar i, n=8;//向SDA发送一个字节数据,8位
for(i=0;i<n;i++)
{
if((ch&0x80)==0x80)
{//若要发送的位为1,则SDA=1
SDA=1;
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
_nop_();
_nop_();
_nop_();
SDA=1;
_nop_();
}
//*********************************************
{
receive_data[i]=read_byte();//读出来的数据存到receivedata[]数组中
if(i==15)//是否读完,未读完全部数据,则应答0
NoACK();
else
ACK();
}//停止总线
stop();
}
void main()
i2c读写程序的详细讲解
i2c读写程序的详细讲解I2C即Inter-IntegratedCircuit(内部集成电路),是一种同步串行总线技术,它可以用来连接多个芯片,并使用它们之间的2条双向数据总线进行通信。
I2C总线可以通过5根线实现,其中2条用于数据传输,另外3条用于控制传输过程:SCL(时间同步线)、SDA(数据线)、VCC(电源线)。
I2C在光学芯片、DSP和ARM芯片等领域都得到了广泛应用,能够实现在一个系统或介质中共享数据,有助于节省系统开发成本和实现系统节能。
第二部分:I2C读写程序I2C读写程序是通过I2C总线实现数据读写的特定程序,主要由以下步骤构成:1、设置I2C总线:通过一系列硬件设置完成I2C总线的初始化,以满足对应数据读写的要求;2、发送I2C开始信号:在进行数据读写前,需要发送一个开始信号,以通知主从端可以进行通信;3、发送I2C地址:根据读写操作,发送I2C地址;4、发送I2C数据:根据读写操作,发送相关数据;5、接收I2C数据:根据读写操作,接收相关数据;6、发送I2C停止信号:发送I2C停止信号,结束数据读写过程。
第三部分:I2C读写程序实例下面以C语言为例,介绍在I2C通讯操作中读写程序的编写流程: 1、I2C总线的初始化:可以使用如下函数来设置I2C总线的参数,完成I2C总线的初始化:#include <linux/i2c.h>#include <linux/i2c-dev.h>int i2c_init (int busno);其中busno表示I2C总线号;2、发送I2C开始信号:可以使用如下函数来发送I2C开始信号:int i2c_smbus_write_start(int busno, int addr);其中busno表示I2C总线号,addr表示要发送的I2C地址;3、发送I2C地址:可以使用如下函数来发送I2C地址:int i2c_smbus_write_byte(int busno, int addr);其中busno表示I2C总线号,addr表示要发送的I2C地址;4、发送I2C数据:可以使用如下函数发送I2C数据:int i2c_smbus_write_byte_data(int busno, int addr, int data);其中busno表示I2C总线号,addr表示要发送的I2C地址,data 表示要发送的数据;5、接收I2C数据:可以使用如下函数接收I2C数据:int i2c_smbus_read_byte_data(int busno, int addr);其中busno表示I2C总线号,addr表示要读取的I2C地址;6、发送I2C停止信号:可以使用如下函数发送I2C停止信号:int i2c_smbus_write_stop(int busno);其中busno表示I2C总线号;第四部分:结论以上就是I2C读写程序的详细讲解,可以看出,I2C读写程序的实现步骤非常简单,只需要对每个步骤做出正确的设置,就可以实现I2C数据读写操作。
I2C总线读写程序通用
//==========================头文件加载===============================#include <reg52.h> //加载52系列单片机头文件//===========================端口声明================================sbit CLK=P3^6; //74hc574时钟信号线sbit G=P2^4; //74hc574使能sbit IIC_SDA=P2^6; //声明IIC总线的数据线接在单片机的P2.5端口。
sbit IIC_SCL=P2^5; //声明IIC总线的时钟线接在单片机的P2.7端口。
unsigned char tabl[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x0BF,0x8C};//0,1,2,3,4,5,6,7,8,9,-,P//===========================函数声明================================void display(unsigned char aa);void delay(unsigned int t);void delay_IIC(void);void IIC_Init(void);void IIC_start(void);void IIC_stop(void);bit IIC_Tack(void);void IIC_single_byte_write(unsigned char Daddr,unsigned char Waddr,unsigned char Data);unsigned char IIC_single_byte_read(unsigned char Daddr,unsigned char Waddr);void IIC_write_byte(unsigned char Data);unsigned char IIC_read_byte(void);//============================主函数=================================void main() //主函数{u nsigned char Data=2,addr=0x01;//---------------------------系统初始化--------------------------I IC_Init();//初始化IIC总线。
I2C程序和流程图
程序和流程图:IIC.hvoid Init_IIC(void);void EEPROM_ByteWrite(unsigned char nAddr,unsigned char nVal); unsigned char EEPROM_RandomRead(unsigned char nAddr); unsigned char EEPROM_CurrentAddressRead(void);void EEPROM_AckPolling(void);void Init_CLK(void);void Init_IIC_Port(void);Main.C/*******************************************IIC for AT24c16 OR AT24CXXX 系列只要控制好IICRM IICSTP IICSTT 其硬件会自动完成SCL SDA的一系列时序只要注意各个发送与接收的控制标志位.******************************************/#include <MSP430x16x.h>#include "IIC.h"volatile unsigned char Data[6];void main(void){//volatile unsigned char Data[6];//停止看门狗WDTCTL = WDTPW+WDTHOLD;//初始化端口Init_IIC_Port();//初始化时钟Init_CLK();//I2C初始化Init_IIC(); //置传输方式及控制方式//打开中断_EINT();//写入数据EEPROM_ByteWrite(0x0000,0x12);//等待写操作完成EEPROM_AckPolling();//写入数据EEPROM_ByteWrite(0x0001,0x34);//等待写操作完成EEPROM_AckPolling();//写入数据EEPROM_ByteWrite(0x0002,0x56);//等待写操作完成EEPROM_AckPolling();//写入数据EEPROM_ByteWrite(0x0003,0x78);//等待写操作完成EEPROM_AckPolling();//写入数据EEPROM_ByteWrite(0x0004,0x9A);//等待写操作完成EEPROM_AckPolling();//写入数据EEPROM_ByteWrite(0x0005,0xBC);//等待写操作完成EEPROM_AckPolling();//读出数据,随机读Data[0] = EEPROM_RandomRead(0x0000); //地址自动加1 //读出数据,当前地址读Data[1] = EEPROM_CurrentAddressRead();//读出数据,当前地址读Data[2] = EEPROM_CurrentAddressRead();//读出数据,当前地址读Data[3] = EEPROM_CurrentAddressRead();//读出数据,当前地址读Data[4] = EEPROM_CurrentAddressRead();//读出数据,当前地址读Data[5] = EEPROM_CurrentAddressRead();}IIC.C#include <MSP430x16x.h>#include "IIC.h"#define SLAVEADDR 0x50;int tx_count;int rx_count;unsigned char I2CBuffer[3];void Init_IIC(void){//将P3.1和P3.3设置为I2C管脚P3SEL = 0x0A;//设置P3.1和P3.3管脚的方向P3DIR &= ~0x0A;//选择为I2C模式U0CTL |= I2C + SYNC;//禁止I2C模块U0CTL &= ~I2CEN;//设置I2C为7位地址模式,不使用DMA,//字节模式,时钟源为SMCLK,//设置成传输模式I2CTCTL = I2CTRX + I2CSSEL_2;//定义从器件地址I2CSA = SLAVEADDR;//设置本身的地址I2COA = 0x01A5;//I2C时钟为SMCLK / 160I2CPSC = 159;//SCL 高电平为:5 *I2C 时钟I2CSCLH = 0x03;//SCL 低电平为:5 *I2C 时钟I2CSCLL = 0x03;//I2C 模块有效U0CTL |= I2CEN;tx_count = 0;rx_count = 0;}void I2CWriteInit(void) //对于AT24CXXX的写操作是置成主模式并置位中断使能. {//主(Master)模式U0CTL |= MST;//传输模式,R/W 为:0I2CTCTL |= I2CTRX;//清除中断标志I2CIFG &= ~TXRDYIFG;//发送中断使能I2CIE = TXRDYIE;}void I2CReadInit(void){//接收模式,R/W 为:1I2CTCTL &= ~I2CTRX;//接收中断使能I2CIE = RXRDYIE;}void EEPROM_ByteWrite(unsigned char nAddr, unsigned char nVal){//等待I2C模块完成所有操作 //在选定的地址写入数据.while (I2CDCTL&I2CBUSY) ;//设置地址数据I2CBuffer[1] = nAddr;//设置数据I2CBuffer[0] = nVal;//设置缓冲区指针tx_count = 1;//写数据初始化I2CWriteInit(); //设置为主模式//发送数据的长度//1个控制字节,2个数据字节I2CNDAT = 2;//开始和停止条件产生//开始I2C通信I2CTCTL |= I2CSTT+I2CSTP;return;}unsigned char EEPROM_CurrentAddressRead(void){//等待I2C模块完成所有操作while (I2CDCTL&I2CBUSY);//读操作的初始化I2CReadInit();//主(Master)模式U0CTL |= MST;//接收1个字节的数据I2CNDAT = 1;//清除中断标志I2CIFG &= ~ARDYIFG;//开始接收,产生重新起始和停止条件I2CTCTL |= I2CSTT + I2CSTP;//等待传输完成while ((~I2CIFG)&ARDYIFG) ;//返回数据return I2CBuffer[0];}unsigned char EEPROM_RandomRead(unsigned char nAddr) {//等待I2C模块完成所有操作while (I2CDCTL&I2CBUSY);//设置地址I2CBuffer[0] = nAddr;//设置缓冲区指针tx_count = 0;//写操作初始化I2CWriteInit();//传输数据长度//1个控制字节和一个地址数据I2CNDAT = 1;//清除中断标志I2CIFG &= ~ARDYIFG;//起始条件产生I2CTCTL |= I2CSTT;//等待传输完成while ((~I2CIFG)&ARDYIFG);//读操作初始化I2CReadInit();//接收一个字节的数据I2CNDAT = 1;//清除中断标志I2CIFG &= ~ARDYIFG;//开始接收,产生重新起始和停止条件 I2CTCTL |= I2CSTT + I2CSTP;//等待传输完成while ((~I2CIFG)&ARDYIFG);//返回数据return I2CBuffer[0];}void EEPROM_AckPolling(void){unsigned int count;//等待I2C模块完成所有操作while (I2CDCTL&I2CBUSY);count=0;//清除I2CEN位U0CTL &= ~I2CEN;I2CTCTL |= I2CRM;//使能I2C模块U0CTL |= I2CEN;//设置NACKIFG标志I2CIFG = NACKIFG;while (NACKIFG & I2CIFG){//清除中断标志I2CIFG=0x00;//主(Master)模式U0CTL |= MST;//设置传输模式I2CTCTL |= I2CTRX;//产生起始条件I2CTCTL |= I2CSTT;//等待I2CSTT被清除while (I2CTCTL & I2CSTT) ; //产生停止条件I2CTCTL |= I2CSTP;//等待停止条件复位while (I2CDCTL & I2CBUSY) ; count = count + 1;}//清除I2CEN位U0CTL &= ~I2CEN;I2CTCTL &= ~I2CRM;//使能I2CU0CTL |= I2CEN;return;}#if __VER__ < 200interrupt [USART0TX_VECTOR] void ISR_I2C(void)#else#pragma vector=USART0TX_VECTOR__interrupt void ISR_I2C(void)#endif //上面的程序其实只要编写 ://#pragma vector=USART0TX_VECTOR __interrupt void ISR_I2C(void)就行. {switch (I2CIV){case I2CIV_AL:{//仲裁中断break;}case I2CIV_NACK:{//NACK中断break;}case I2CIV_OA:{//自己地址中断break;}case I2CIV_ARDY:{//访问准备好中断break;}case I2CIV_RXRDY:{//接收准备好中断I2CBuffer[0]=I2CDRB;break;}case I2CIV_TXRDY:{//发送准备好中断I2CDRB = I2CBuffer[tx_count];tx_count = tx_count - 1;if (tx_count < 0){//禁止发送中断I2CIE &= ~TXRDYIE;}break;}case I2CIV_GC:{//一般调用中断break;}case I2CIV_STT:{//起始条件中断break;}}}void Init_IIC_Port(void){//初始化端口寄存器与IIC口无关的PX口关闭以便于对编写系统板的综合程序. //P1DIR = 0xFF;//P2DIR = 0xFF;P3DIR = 0xF5;//P4DIR = 0xFF;P5DIR = 0x7F;//P6DIR = 0xFF;//P4OUT = 0X11;//P5OUT &= 0XF0;P3SEL|=BIT1+BIT3; //在这里如果设置成}void Init_CLK(void){unsigned int i;//将寄存器的内容清零//XT2震荡器开启//LFTX1工作在低频模式//ACLK的分频因子为1BCSCTL1 = 0X00;do{// 清除OSCFault标志IFG1 &= ~OFIFG;for (i = 0x20; i > 0; i--);}while ((IFG1 & OFIFG) == OFIFG); // 如果OSCFault =1//open XT2, LFTX2 选择低频率BCSCTL1 &= ~(XT2OFF + XTS); //BCSCTL1=0X00 功能一样//DCO Rsel=7(Freq=3200k/25摄氏度)BCSCTL1 |= RSEL0 + RSEL1 + RSEL2;BCSCTL1 |= 0x07;//MCLK的时钟源为TX2CLK,分频因子为1BCSCTL2 += SELM1;//SMCLK的时钟源为TX2CLK,分频因子为1BCSCTL2 += SELS;}//对于系统时钟的选择关系到整个程序运行稳定性./*************************************************************文件名:msp430f169i2c.c*整体描述:MSP430F169单片机硬件IIC软件,字节方式,主方式* IIC接口:P3.3=SCL,P3.1=SDA;(开漏输出)* 相应寄存器:地址寄存器I2COA 用于存放自身从地址(从方式时才有用)* 地址寄存器I2CSA 用于存放外围的从机地址(主方式时才有用)* 控制寄存器U0CTL 硬件I2C的设置、使能、模式等。
IIC通信详解
IIC通信详解(1)概述I2C(Inter-Integrated Circuit BUS) 集成电路总线,该总线由NXP(原PHILIPS)公司设计,多⽤于主控制器和从器件间的主从通信,在⼩数据量场合使⽤,传输距离短,任意时刻只能有⼀个主机等特性。
经常IIC和SPI接⼝被认为指定是⼀种硬件设备,但其实这样的说法是不尽准确的,严格的说他们都是⼈们所定义的软硬结合体,分为物理层(四线结构)和协议层(主机,从机,时钟极性,时钟相位)。
IIC,SPI的区别不仅在与物理层,IIC⽐SPI有着⼀套更为复杂的协议层定义。
下⾯来分别说明⼀下IIC的物理层和协议层。
(2)IIC的物理层a.只要求两条总线线路,⼀条是串⾏数据线SDA,⼀条是串⾏时钟线SCL。
(IIC是半双⼯,⽽不是全双⼯)。
b.每个连接到总线的器件都可以通过唯⼀的地址和其它器件通信,主机/从机⾓⾊和地址可配置,主机可以作为主机发送器和主机接收器。
c.IIC是真正的多主机总线,(⽽这个SPI在每次通信前都需要把主机定死,⽽IIC可以在通讯过程中,改变主机),如果两个或更多的主机同时请求总线,可以通过冲突检测和仲裁防⽌总线数据被破坏。
d.传输速率在标准模式下可以达到100kb/s,快速模式下可以达到400kb/s。
e.连接到总线的IC数量只是受到总线的最⼤负载电容400pf限制。
⼀个典型的IIC接⼝如下图(1)所⽰图(1)(3)IIC的协议层IIC的协议层才是掌握IIC的关键。
现在简单概括如下:a.数据的有效性在时钟的⾼电平周期内,SDA线上的数据必须保持稳定,数据线仅可以在时钟SCL为低电平时改变。
如图(2)所⽰:图(2)b.起始和结束条件起始条件:当SCL为⾼电平的时候,SDA线上由⾼到低的跳变被定义为起始条件,结束条件:当SCL为⾼电平的时候,SDA线上由低到⾼的跳变被定义为停⽌条件,要注意起始和终⽌信号都是由主机发出的,连接到I2C总线上的器件,若具有I2C总线的硬件接⼝,则很容易检测到起始和终⽌信号。
单片机控制的I2C总线高频头程序
DELAY(DELAY_TIME)
{
/*发送完一个字节后检验设备的应答信号*/
SDA=1;
SCL=1;
DELAY(DELAY_TIME);
}
}
/***********************************主程序*********************************/
void main()
{
system_init(); //系统初始化
//Start-C2-ACK-05-ACK-8A-CE-ACK-ACK-A4-ACK-STOP
}
I2C_Start();//I2C总线开始
WriteI2CByte(ADD);
ChAck();
WriteI2CByte(DB1);
ChAck();
WriteI2CByte(DB2);
SEND_1();
else
SEND_0();
}
void system_init(void)//系统初始化
{
SCON = 0x50; //串口方式1,允许接收
PCON= 0x80; // SMOD=1, 波特率加倍
if(NDB>471 && NDB<863) PB=0X30; //频段计算
WriteI2CByte(PB); //频段控制
ChAck();
I2C_Stop(); //I2C总线停止
delay_ms(100);
}
F0=SDA;
DELAY(DELAY_TIME);
SCL=0;
DELAY(DELAY_TIME);
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
return(0);
}
I2C_SendB(c); //发送数据
if(!I2C_Ack)
{
return(0);
}
I2C_Stop(); //结束总线
return(1);
}
/********************************** I2C_IRcvB *********************************
/******解释:I2C 总线在空闲状态下都是被上拉为高电平的,所以当它们处于低电平时就表
示忙的状态.***/
_nop_();
_nop_();
}
/************************************ I2C_Stop ********************************
/********************************** I2C 总线驱动 ******************************
#i nclude "AT89X52.h"
#i nclude <intrins.h>
#define SomeNOP(); {_nop_();_nop_();_nop_();_nop_();_nop_();} //定义空指令
bit I2C_CheckAck(void)
{
uchar errtime = 255; // 因故障接收方无 Ack,超时值为255
SDA = 1; //发送器先释放SDA
SomeNOP();
SCL = 1;
SomeNOP(); //时钟电平周期大于 4 us
while(SDA) //判断SDA 是否被拉低
应答信号.
_nop_();
_nop_();
}
/************************************ I2C_RcvB ********************************
uchar I2C_RcvB()
{
uchar retc;
uchar BitCnt; //位
void I2C_Start()
{
SDA = 1; //发送起始条件的数据信号
_Nop();
SCL = 1;
SomeNOP(); //起始条件建立时间大于4.7us,延时
SDA = 0; //发送起始信号
SomeNOP(); //起始条件建立时间大于4us,延时
SCL = 0; //钳住I2C 总线准备发送或接收数据
sbit SDA = P1^3; //模拟I2C 数据传输位
sbit SCL = P1^2; //模拟I2C 时钟控制位
bit bdata I2C_Ack; //应答标志位
/************************************ I2C_Start *******************************
}
/************************************ I2C_Ackn ********************************
void I2C_Ackn(bit a)
{
if(a==0) //在此发送应答或非应答信号
{
SDA = 0;
}
else
{
SDA = 1;
{
return(0);
}
I2C_Start(); //重复起始条件
I2C_SendB(sla+1); //发送读操作的地址
if(!I2C_Ack)
{
return(0);
}
*c = I2C_RcvB(); //读取数据
I2C_Ackn(1); //发送非应答位
I2C_Stop(); //结束总线
bit I2C_IRcvB(uchar sla, uchar suba, uchar *c)
{
I2C_Start(); //启动总线
I2C_SendB(sla);
if(!I2C_Ack)
{
return(0);
}
I2C_SendB(suba); //发送器件子地址
if(!I2C_Ack)
retc = 0;
SDA = 1; //置数据总线为输入方式,作为接收方要释放SDA.
for(BitCnt=0;BitCnt<8;BitCnt++)
{
_nop_();
SCL = 0; //置时钟线为低准备接收数据位
SomeNOP(); //时钟低电平周期大于4.7us
SCL = 1; //置时钟线为高使数据有效
return(1);
}
}
_nop_();
_nop_();
SCL = 1; //置时钟线为高通知被控器开始接收数据位
SomeNOP(); //保证时钟高电平周期大于 4us
SCL = 0;
}
_nop_();
_nop_();
I2C_Ack = I2C_CheckAck(); //检验应答信号,作为发送方,所以要检测接收器反馈的
bit I2C_ISendB(uchar sla, uchar suba, uchar c)
{
I2C_Start(); //启动总线
I2C_SendB(sla); //发送器件地址
if(!I2C_Ack)
{
return(0);
}
I2C_SendB(suba); //发送器件子地址
if(!I2C_Ack)
{
errtime--;
if(errtime==0)
{
I2C_Stop();
return(0);
}
}
SCL = 0;
_nop_();
return(1);
}
/Hale Waihona Puke *********************************** I2C_SendB *******************************
_nop_();
_nop_();
retc = retc<<1;
if(SDA==1)
{
retc = retc + 1; //读数据位,接收的数据放入retc 中
}
_nop_();
_nop_();
}
SCL = 0;
_nop_();
_nop_();
return(retc);
}
SomeNOP();
SCL = 1;
SomeNOP(); //时钟电平周期大于 4 us
SCL = 0; //清时钟线钳住I2C 总线以便继续接收
_nop_();
_nop_();
}
/******************************** I2C_ISendB **********************************
void I2C_SendB(uchar c)
{
uchar BitCnt;
for (BitCnt=0; BitCnt<8; BitCnt++) //要传送的数据长度为8 位
{
if((c<<BitCnt)&0x80) //判断发送位(从高位起发送)
{
SDA = 1;
}
else
{
SDA = 0;
void I2C_Stop()
{
SDA = 0; //发送结束条件的数据信号
_Nop();
SCL = 1; //发送结束条件的时钟信号
SomeNOP();//结束条件建立时间大于4us,延时
SDA = 1; //发送I2C 总线结束信号
SomeNOP();
}
/************************************ I2C_CheckAck ****************************