学习单片机已经有一段时间了,但是很多程序都缺少模块化的思想,之前以为只要把单个的功能封装在一个函数里面就是模块化,但是在公司经过了十多天实习,才真正有了模块化的编程思想,这里将我编写的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 ################*/
注意:这里图片可能无法全部显示,可以选择右键另存到电脑或者新标签页打开。然后查看
希望大家给予指正!!!