单片机控制IIC协议EEPROM芯片AT24C02模块化编程

学习单片机已经有一段时间了,但是很多程序都缺少模块化的思想,之前以为只要把单个的功能封装在一个函数里面就是模块化,但是在公司经过了十多天实习,才真正有了模块化的编程思想,这里将我编写的51单片机控制1602液晶屏的程序共享一下,一是希望没有模块化编程思想的后来者看看,二是希望前辈们给予斧正 。

(补充:以下代码只需要修改.h文件中含有 “选择” 字样的部分,就可以达到复用的效果)

       (因为里面用到的宏比较多一点,建议大家利用 source insight工具建一个工程然后查看)

/*################at24c02.h start ################*/

#ifndef __AT24C02_H__
#define __AT24C02_H__

#include <reg52.h>

sbit AT24C02_SCL_BIT = P2^1 ;/*根据硬件连接选择*/
sbit AT24C02_SDA_BIT = P2^0 ;/*根据硬件连接选择*/

#define HIGT_LEVEL	1
#define LOW_LEVEL	0

#define AT24C02_DEVICE0		0
#define AT24C02_DEVICE1		1
#define AT24C02_DEVICE2		2
#define AT24C02_DEVICE3		3
#define AT24C02_DEVICE4		4
#define AT24C02_DEVICE5		5
#define AT24C02_DEVICE6		6
#define AT24C02_DEVICE7		7

#define AT24C02_DEVICE_BASE_VALUE	0xa0
#define AT24C02_DEVICE_WRITE		0X00
#define AT24C02_DEVICE_READ			0X01


#define AT24C02_DEVICE_ADDRESS_ERROR		-1



extern void at24c02Init(void);
extern char at24c02DataClear(unsigned char deviceNumber);

extern char at24c02AddressWriteByte(unsigned char deviceNumber, unsigned char deviceInnerAddress,unsigned char dat);
extern char at24c02AddressWritePage(unsigned char deviceNumber,unsigned char deviceInnerAddress, unsigned char *table)	;

extern unsigned char at24c02RandomAddressReadByte(unsigned char deviceNumber, unsigned char deviceInnerAddress);
extern char at24c02DataClear(unsigned char deviceNumber);



#endif /*__AT24C02_H__*/


/*################at24c02.h end ################*/


/*################at24c02.c start ################*/

#include "at24c02.h"
#include <intrins.h>

/******************************************************************
FuncationName	:delay3us
Author			:yangrui
Date			:20140131_22_23
Input			:N/A
Output			:N/A
Return 			:N/A
Note			:N/A
/******************************************************************/
static void delay3us(void)
{
	unsigned char i;

	i = 6;
	while (--i);
}

/******************************************************************
FuncationName	:delay5ms
Author			:yangrui
Date			:20140131_22_23
Input			:N/A
Output			:N/A
Return 			:N/A
Note			:N/A
/******************************************************************/
static void delay5ms(void)
{
	unsigned char i, j;

	_nop_();
	_nop_();
	i = 59;
	j = 89;
	do
	{
		while (--j);
	} while (--i);
}

/******************************************************************
FuncationName	:at24c02Init
Author			:yangrui
Date			:20140131_22_23
Input			:N/A
Output			:N/A
Return 			:N/A
Note			:AT24C02 initialization
/******************************************************************/
void at24c02Init(void)
{
	AT24C02_SCL_BIT = HIGT_LEVEL ;
	AT24C02_SDA_BIT = LOW_LEVEL ;
}


/******************************************************************
FuncationName	:at24c02StartSignal
Author			:yangrui
Date			:20140131_22_23
Input			:N/A
Output			:N/A
Return 			:N/A
Note			:AT24C02 start signal
/******************************************************************/
static void at24c02StartSignal(void)
{
	AT24C02_SDA_BIT = HIGT_LEVEL ;
	delay3us();
	AT24C02_SCL_BIT = HIGT_LEVEL ;
	delay3us();
	AT24C02_SDA_BIT = LOW_LEVEL ;
	delay3us();
}

/******************************************************************
FuncationName	:at24c02StopSignal
Author			:yangrui
Date			:20140131_22_23
Input			:N/A
Output			:N/A
Return 			:N/A
Note			:AT24C02 stop signal
/******************************************************************/
static void at24c02StopSignal(void)
{
	AT24C02_SDA_BIT = LOW_LEVEL ;
	delay3us();
	AT24C02_SCL_BIT = HIGT_LEVEL ;
	delay3us();
	AT24C02_SDA_BIT = HIGT_LEVEL;

	/*停止信号后AT24C02内部需要一段时间twr来进行内部数据处理,所以延时长一点,参考数据手册datasheet的trw*/
	delay5ms();
}

/******************************************************************
FuncationName	:at24c02WriteByt
Author			:yangrui
Date			:20140131_22_23
Input			:Byte data which will to be writed to at24c02
Output			:N/A
Return 			:N/A
Note			:写字节
/******************************************************************/
static void at24c02WriteByt(unsigned char dat)
{
	char i;
	unsigned char temp = dat ;

	for(i=0; i<8; i++)
	{
		AT24C02_SCL_BIT = LOW_LEVEL ;
		delay3us();

		//方法一
		AT24C02_SDA_BIT = (bit)(temp & (0x80>>i)); /*MSB first, LSB last*/

		//方法二
		//temp <<= 1;
		//AT24C02_SDA_BIT = CY ;

		delay3us();
		AT24C02_SCL_BIT = HIGT_LEVEL;
		delay3us();
	}
	AT24C02_SCL_BIT = LOW_LEVEL ;
	delay3us();
	AT24C02_SDA_BIT = HIGT_LEVEL;
	delay3us();
}

/******************************************************************
FuncationName	:at24c02ReadByte
Author			:yangrui
Date			:20140131_22_23
Input			:N/A
Output			:N/A
Return 			:Byte data which read from at24c02
Note			:读字节
/******************************************************************/
static unsigned char at24c02ReadByte(void)
{
	char i;
	unsigned dat = 0x00 ;

	AT24C02_SCL_BIT = LOW_LEVEL ;
	delay3us();
	AT24C02_SDA_BIT = HIGT_LEVEL ;
	delay3us();

	for(i=0; i<8 ; i++)
	{
		AT24C02_SCL_BIT = HIGT_LEVEL;
		delay3us();
		dat <<= 1;
		dat |= AT24C02_SDA_BIT ;
		delay3us();
		AT24C02_SCL_BIT = LOW_LEVEL ;
		delay3us();
	}

	return dat ;
}

/******************************************************************
FuncationName	:at24c02Acknowledge
Author			:yangrui
Date			:20140131_22_23
Input			:N/A
Output			:N/A
Return 			:N/A
Note			:N/A
/******************************************************************/
static void at24c02Acknowledge(void)
{
	unsigned char i=0 ;

	AT24C02_SCL_BIT = HIGT_LEVEL  ;
	delay3us();
	while(AT24C02_SDA_BIT && (i<250))
	{
		i++;
	}
	AT24C02_SCL_BIT = LOW_LEVEL ;
}

/******************************************************************
FuncationName	:at24c02AddressWriteByte
Author			:yangrui
Date			:20140131_22_23
Input			:deviceNumber		:器件编号
				 deviceInnerAddress	:器件内部地址
				 dat				:要写入器件的数据				 
Output			:N/A
Return 			:0(OK)  or -1(error)
Note			:AT24C02器件写字节数据
/******************************************************************/
char at24c02AddressWriteByte(unsigned char deviceNumber, unsigned char deviceInnerAddress,unsigned char dat)
{
	if(deviceNumber < AT24C02_DEVICE0 || deviceNumber > AT24C02_DEVICE7)
	{
		return AT24C02_DEVICE_ADDRESS_ERROR ;
	}

	at24c02StartSignal();

	at24c02WriteByt(AT24C02_DEVICE_BASE_VALUE | AT24C02_DEVICE_WRITE | deviceNumber);
	at24c02Acknowledge();

	at24c02WriteByt(deviceInnerAddress);
	at24c02Acknowledge();

	at24c02WriteByt(dat);
	at24c02Acknowledge();

	at24c02StopSignal();

	return 0;
}

/******************************************************************
FuncationName	:at24c02AddressWritePage
Author			:yangrui
Date			:20140131_22_23
Input			:deviceNumber		:器件编号
				 deviceInnerAddress	:器件内部地址
				 table				:将要写入到器件内部的数据组成的数组
Output			:N/A
Return 			:0(OK) or -1(error)
Note			:AT24C02页写操作
/******************************************************************/
char at24c02AddressWritePage(unsigned char deviceNumber,unsigned char deviceInnerAddress,const unsigned char *table)	  
{
	char i;
	
	if(deviceNumber < AT24C02_DEVICE0 || deviceNumber > AT24C02_DEVICE7)
	{
		return AT24C02_DEVICE_ADDRESS_ERROR ;
	}
	
	at24c02StartSignal();
	
	at24c02WriteByt(AT24C02_DEVICE_BASE_VALUE | deviceNumber | AT24C02_DEVICE_WRITE);
	at24c02Acknowledge();

	at24c02WriteByt(deviceInnerAddress);
	at24c02Acknowledge();

	for(i=0 ; i < 8 ; i++)
	{
		at24c02WriteByt(*table) ;
		at24c02Acknowledge();
		table++;
	}

	at24c02StopSignal();

	 return 0;
}

/******************************************************************
FuncationName	:at24c02RandomAddressReadByte
Author			:yangrui
Date			:20140131_22_23
Input			:deviceNumber		:器件编号
				 deviceInnerAddress	:器件内部地址
Output			:N/A
Return 			:Byte data read from random address in AT24C02‘s inner
Note			:AT24C02随机地址读字节数据
/******************************************************************/
unsigned char at24c02RandomAddressReadByte(unsigned char deviceNumber, unsigned char deviceInnerAddress)
{
	unsigned dat;

	if(deviceNumber < AT24C02_DEVICE0 || deviceNumber > AT24C02_DEVICE7)
	{
		//exit(0) ;/*这里需要完善*/
		;
	}

	at24c02StartSignal();

	at24c02WriteByt(AT24C02_DEVICE_BASE_VALUE | deviceNumber | AT24C02_DEVICE_WRITE) ;
	at24c02Acknowledge();
	at24c02WriteByt(deviceInnerAddress);
	at24c02Acknowledge();
	at24c02StartSignal();
	at24c02WriteByt(AT24C02_DEVICE_BASE_VALUE | deviceNumber | AT24C02_DEVICE_READ) ;
	at24c02Acknowledge();
	dat = at24c02ReadByte();

	at24c02StopSignal();

	return dat;	
}

/******************************************************************
FuncationName	:at24c02DataClear
Author			:yangrui
Date			:20140131_22_23
Input			:deviceNumber		:器件编号
Output			:N/A
Return 			:0(OK) or -1(error)
Note			:initialization at24c02‘s all data to ‘0‘
/******************************************************************/
char at24c02DataClear(unsigned char deviceNumber)
{
	unsigned int i;

	unsigned char table[8]={‘0‘,‘0‘,‘0‘,‘0‘,‘0‘,‘0‘,‘0‘,‘0‘};
	
	if(deviceNumber < AT24C02_DEVICE0 || deviceNumber > AT24C02_DEVICE7)
	{
		return AT24C02_DEVICE_ADDRESS_ERROR ;
	}

	for(i=0; i<256; i++)
	{
		at24c02AddressWritePage(deviceNumber,i*8, table);
	}

	return 0;
}


/*################at24c02.c end ################*/

案例代码:

/*################main.c start ################*/

#include <reg52.h>
#include "../ok/lcd1602.h"
#include "at24c02.h"

unsigned char code author[]="Author:YangRui";
unsigned char table[]={‘0‘,‘1‘,‘2‘,‘3‘,‘4‘,‘5‘,‘6‘,‘7‘,‘8‘,‘9‘,‘a‘,‘b‘,‘c‘,‘d‘,‘e‘,‘f‘};
unsigned char read[]={‘0‘,‘0‘,‘0‘,‘0‘,‘0‘,‘0‘,‘0‘,‘0‘,‘0‘,‘0‘,‘0‘,‘0‘,‘0‘,‘0‘,‘0‘,‘0‘};

void main(void)
{
	int i;

	lcd1602Init();  
	at24c02Init();
	at24c02DataClear(0);
	
	//Row 0
	lcd1602WriteCommand(LCD1602_ROW0_ADDRESS_START);
	for(i=0; i<sizeof(author)-1; i++)
	{
		lcd1602WriteData(author[i]);		
	}

	at24c02AddressWritePage(0, 0x00, table);
	

	//Row 1
	for(i=0;i < 8 ; i++)
	{
		read[i] = at24c02RandomAddressReadByte(0,i);
		lcd1602AddressWriteData(i,1, read[i]);
	}

	while(1)
		;
}



/*################main.c end ################*/

注意:这里图片可能无法全部显示,可以选择右键另存到电脑或者新标签页打开。然后查看

单片机控制IIC协议EEPROM芯片AT24C02模块化编程

希望大家给予指正!!!


单片机控制IIC协议EEPROM芯片AT24C02模块化编程

上一篇:LeetCode OJ:Longest Palindromic Substring


下一篇:arc的一点简单的学习记录