在蓝桥杯电子类单片机组历年的省赛以及国赛中,EEPROM模块常常被考察到。而组委会为减轻考生负担,提前给出了关于EEPROM模块的代码,剩下的便需要我们自己去编写(以第十届为例)。
现在,我们来介绍以下EEPROM模块剩余代码的编写以及模块的运用方法。
1、补全模块C文件
#include "reg52.h"
#include "intrins.h"
#define DELAY_TIME 5
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1
sbit SDA = P2^1;
sbit SCL = P2^0;
void IIC_Delay(unsigned char i)
{
do{_nop_();}
while(i--);
}
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 0;
}
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 1;
IIC_Delay(DELAY_TIME);
}
void IIC_SendAck(bit ackbit)
{
SCL = 0;
SDA = ackbit; // 0£ºÓ¦´ð£¬1£º·ÇÓ¦´ð
IIC_Delay(DELAY_TIME);
SCL = 1;
IIC_Delay(DELAY_TIME);
SCL = 0;
SDA = 1;
IIC_Delay(DELAY_TIME);
}
bit IIC_WaitAck(void)
{
bit ackbit;
SCL = 1;
IIC_Delay(DELAY_TIME);
ackbit = SDA;
SCL = 0;
IIC_Delay(DELAY_TIME);
return ackbit;
}
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++)
{
SCL = 0;
IIC_Delay(DELAY_TIME);
if(byt & 0x80) SDA = 1;
else SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 1;
byt <<= 1;
IIC_Delay(DELAY_TIME);
}
SCL = 0;
}
unsigned char IIC_RecByte(void)
{
unsigned char i, da;
for(i=0; i<8; i++)
{
SCL = 1;
IIC_Delay(DELAY_TIME);
da <<= 1;
if(SDA) da |= 1;
SCL = 0;
IIC_Delay(DELAY_TIME);
}
return da;
}
//************************下面的代码需要自己写***********************//
void write_24c02(unsigned char add,unsigned char date)
{
EA=0;
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_SendByte(date);
IIC_WaitAck();
IIC_Stop();
EA=1;
}
unsigned char read_24c02(unsigned char add)
{
unsigned char temp;
EA=0;
IIC_Start();
IIC_SendByte(0XA0);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0XA1);
IIC_WaitAck();
temp=IIC_RecByte();
IIC_WaitAck();
IIC_Stop();
EA=1;
return temp;
}
//************************上面的代码需要自己写***********************//
2、补全模块H文件
#ifndef _IIC_H
#define _IIC_H
void IIC_Start(void);
void IIC_Stop(void);
bit IIC_WaitAck(void);
void IIC_SendAck(bit ackbit);
void IIC_SendByte(unsigned char byt);
unsigned char IIC_RecByte(void);
void IIC_SendByte(unsigned char byt);
unsigned char IIC_RecByte(void);
//************************下面的代码需要自己写***********************//
void write_24c02(unsigned char add,unsigned char date);
unsigned char read_24c02(unsigned char add);
//************************上面的代码需要自己写***********************//
#endif
3、在主函数中运用EEPROM模块
#include "STC15F2K60S2.H"
#include "iic.h"
#define u8 unsigned char
u8 code t_display[]={ //????
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
//black - H J K L N o P U t G Q r M y
0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46}; //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1
u8 code T_COM[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //??
void Timer0Init(void) //1??@11.0592MHz
{
AUXR |= 0x80; //?????1T??
TMOD &= 0xF0; //???????
TL0 = 0xCD; //??????
TH0 = 0xD4; //??????
TF0 = 0; //??TF0??
TR0 = 1; //???0????
ET0 = 1;
EA = 1;
}
u8 EEPROM[8];
u8 open_number;
void main()
{
P0=~0x00;P2=0X80;P2=0X00;
P2=0XA0;P0=0X00;P2=0X00;
open_number=read_24c02(1);
write_24c02(1,++open_number);
Timer0Init();
while(1)
{
EEPROM[0]=t_display[open_number%10];
}
}
void Timer0() interrupt 1//1??@11.0592MHz
{
static int smg_count=0,i=0;
smg_count++;
if(smg_count==2)
{
smg_count=0;
P2=0XC0;P0=0;P2=0;
P2=0XE0;P0=~EEPROM[i];P2=0;
P2=0XC0;P0=T_COM[i];P2=0;
i++;
if(i==8){i=0;}
}
}
4、另外,在运用EEPROM模块的时候还涉及到了数码管模块。大家可以参照下面的blog链接:https://blog.csdn.net/qq_44629819/article/details/104490649
祝大家在蓝桥杯比赛中获得优异的成绩!
——南昌大学 电子183刘昊