学习单片机已经有一段时间了,但是很多程序都缺少模块化的思想,之前以为只要把单个的功能封装在一个函数里面就是模块化,但是在公司经过了十多天实习,才真正有了模块化的编程思想,这里将我编写的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模块化编程
原文:http://blog.csdn.net/yagnruinihao/article/details/18892029