⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2c9.c

📁 c语言和汇编语言混合编程实例详解.rar
💻 C
字号:
/* =========================================================================
*  文件名: I2C9.C
*  功  能:这是mcs-51和EEPROM AT24C512 I2C总线接口器件接口的例子 。
* =========================================================================*/
#include <reg52.h>
#define HIGH 1
#define LOW 0
#define FALSE 0
#define TRUE ~FALSE
#define function
#define end_if
#define end_for
#define uchar unsigned char
#define uint unsigned int
#define WRITE 0xA0                       /* 定义24C512的器件地址SLA和方向位W */
#define READ 0xA1                        /* 定义24C512的器件地址SLA和方向位R */
#define BLOCK_SIZE 32                    /* 定义指定字节个数 */
uchar idata  EAROMImage[BLOCK_SIZE];     /* 在RAM中定义存储映象单元 */
uchar idata  EAROMImage2[BLOCK_SIZE];    /* 在RAM中定义存储映象单元 */
uint Addr;
uchar con;
void eeprom24c32r(uint Address,uchar count);
void eeprom24c32w(uint Address,uchar count);
void timedelay(uint timess);
sbit SCL=0xb2;//p3.2
sbit SDA=0xb3;//p3.3

/****************************************************************************
*    函数原型: void function delay(void);
*    功    能: 本函数实际上只有一条返回指令, 在具体应用中可视具体要求增加延时
*              指令。
****************************************************************************/
void function delay( void ) {
        uchar i ;
	for ( i=0 ; i<6 ; i++ ){ ;}
 }

/****************************************************************************
*    函数原型: void function I_start(void);
*    功    能: 提供I2C总线工作时序中的起始位。
****************************************************************************/
void function I_start( void ) {
	SCL = HIGH ;
	delay() ;
	SDA = LOW ;
	delay() ;
	SCL = LOW ;
	delay() ;
 }

/****************************************************************************
*    函数原型: void function I_stop(void);
*    功    能: 提供I2C总线工作时序中的停止位。
****************************************************************************/
void function I_stop( void ) {
	SDA = LOW ;
	delay() ;
	SCL = HIGH ;
	delay() ;
	SDA = HIGH ;
	delay() ;
	SCL = LOW ;
	delay() ;
 }

/****************************************************************************
*    函数原型: void function I_init(void);
*    功    能: I2C总线初始化。在main()函数中应首先调用本函数, 然后再调用
*              其它函数。
****************************************************************************/
void function I_init( void ) {
	SCL = LOW ;
	I_stop() ;
}

/****************************************************************************
*    函数原型: bit function I_clock(void);
*    功    能: 提供I2C总线的时钟信号, 并返回在时钟电平为高期间SDA 信号线上状
*              态。本函数可用于数据发送, 也可用于数据接收。
****************************************************************************/
bit function I_clock( void ) {
	bit sample ;
	SCL = HIGH ;
	delay() ;
	sample = SDA ;
	SCL = LOW ;
	delay() ;
	return ( sample ) ;
 }

/****************************************************************************
*    函数原型: bit function I_send(uchar I_data);
*    功    能: 向I2C总线发送8位数据, 并请求一个应答信号ACK。如果收到ACK应答
*              则返回1(TRUE), 否则返回0(FALSE)。
****************************************************************************/
bit function I_send( uchar I_data ) {
	uchar i ;
	/* 发送8位数据 */
	for ( i=0 ; i<8 ; i++ ) {
		SDA = (bit)( I_data & 0x80 ) ;
		I_data = I_data << 1 ;
		I_clock() ;
	end_for}
	/* 请求应答信号ACK */
	SDA = HIGH ;
	return ( ~I_clock() ) ;
  }

/****************************************************************************
*    函数原型: uchar function I_receive(void);
*    功    能: 从I2C总线上接收8位数据信号, 并将接收到8位数据作为一个字节
*              返回, 不回送应答信号ACK。主函数在调用本函数之前应保证SDA信
*              号线处于浮置状态, 即使8051的P1.7脚置1。
****************************************************************************/
uchar function I_receive( void ) {
	uchar I_data = 0 ;
	uchar i ;
	for ( i=0 ; i<8 ; i++ ) {
		I_data *= 2 ;
		if ( I_clock() )
			I_data++ ;
		end_if
	end_for }
	return ( I_data ) ;
}

/****************************************************************************
*    函数原型: void function I_Ack(void);
*    功    能: 向I2C总线发送一个应答信号ACK, 一般用于连续数据读取时。
*****************************************************************************/
void function I_Ack( void ) {
	SDA = LOW ;
	I_clock() ;
	SDA = HIGH ;
}

/****************************************************************************
*    函数原型: void function wait_5ms(void);
*    功    能: 提供5ms延时(时钟频率为12MHz)。
****************************************************************************/
void function wait_5ms( void ) {
	uint i ;
	for ( i=0 ; i<3000 ; i++ )
		;
	end_for
 }
/****************************************************************************
*    函数原型: void eeprom24c32r(uint Address,uchar count);
*    功    能: 从24CXX中首址为Address的存储区读取count个字节的数据并转存于
*              数组EAROMImage2[32]中去。采用序列读操作方式从片内连续读取数据。
*****************************************************************************/
void eeprom24c32r(uint Address,uchar count)
 {
	uchar i ;
	    I_start() ;
	    I_send( WRITE );
		I_send( Address>>8);
		I_send( Address&0xff) ;
		I_start() ;
		I_send( READ);
	for ( i=0; i<count;i++ ) {
		EAROMImage2[i] = ( I_receive() ) ;
		if ( i!=(count-1)) { I_Ack() ;}
                else {
		I_clock() ;
		I_stop() ;
		end_if }
                                 }
 }
/****************************************************************************
*    函数原型: void eeprom24c32w(uint Address,uchar count);
*    功    能: 将数组EAROMImage[32]中count个字节的数写入24CXX中Address为首址
*              的存储区中去。
*****************************************************************************/
 void eeprom24c32w(uint Address,uchar count)
 {
	uchar i ;
	    I_start() ;
	    I_send( WRITE );
            I_send( Address>>8);
	    I_send( Address&0xff);

	for ( i=0; i<count;i++ ) {
		I_send( EAROMImage[i] ); }
	I_stop();
        wait_5ms();
}
/****************************************************************************
*    函数原型: void timedelay(uint timess);
*    功    能: 提供延时,延时长度取决于timess。
****************************************************************************/
void timedelay(uint timess)
{
 uint tj;
 for (tj=timess;tj>0;tj--){;}
}
/****************************************************************************
*    函数原型: void innumber(void);
*    功    能: 将0x44填充到数组EAROMImage[16]中。
****************************************************************************/
void innumber()
{
 uchar m;
 for (m=0;m<=31;m++){
    EAROMImage[m]=0x44;}
}
/****************************************************************************
*    函数原型: void outnumber(void);
*    功    能: 将0,2,4,...等16个连续偶数填充到数组EAROMImage2[16]中。
****************************************************************************/
void outnumber()
{
 uchar m;
 for (m=0;m<=31;m++){
    EAROMImage2[m]=m*2;}
}
/****************************************************************************
*    函数原型: void main(void);
*    功    能: 主程序。
****************************************************************************/
void main(void)
{
       SP=0xdf;
       timedelay(10000);
       EA=0;
       I_init();
       Addr=0x0100;
       con=32;
       outnumber();
       eeprom24c32r(Addr,con);  //从24CXX中首址为0x0100的存储区读取32个字节的数据并转存于
                                //数组EAROMImage2[32]中去。
sss:   Addr=0x0100;
       con=32;
       innumber();
       eeprom24c32w(Addr,con);  //将数组EAROMImage[32]中32个字节的数写入24CXX中0x0100为首址
                                //的存储区中去。
bbb:   Addr=0x0100;
       con=32;
       outnumber();
       eeprom24c32r(Addr,con);   // 从24CXX中首址为0x0100的存储区读取32个字节的数据并转存于
                                 //数组EAROMImage2[32]中去。
       while(1);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -