蓝桥杯单片机EEPROM掉电不掉数据
这个是自己第一次写关于EEPROM的代码,若有问题欢迎留言!
首先是官方驱动的魔改(也就是后面加了一点点😂)
首先是iic.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 write_EEPROM(unsigned char add,unsigned char dat);
unsigned char read_RRPROM(unsigned char add);
#endif
然后是iic.c
/*
程序说明: IIC总线驱动程序
软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台 8051,12MHz
日 期: 2011-8-9
*/
#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;
}
//通过I2C总线发送数据
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;
}
//从I2C总线上接收数据
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_EEPROM(unsigned char add,unsigned char dat)
{
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
}
unsigned char read_RRPROM(unsigned char add)
{
unsigned char temp;
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(add);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0xa1);
IIC_WaitAck();
temp=IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
return temp;
}
最后就是main.c
#include"reg52.h"
#include"intrins.h"
#include"iic.h"
char code xianshi[13]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf,0xc6};
unsigned char number;
unsigned char number_2;
void Delay300us() //@11.0592MHz
{
unsigned char i, j;
_nop_();
_nop_();
i = 4;
j = 54;
do
{
while (--j);
} while (--i);
}
void choose573(unsigned int n)
{
switch(n)
{
case(4):P2=(P2&0x1f)|0x80;break;
case(5):P2=(P2&0x1f)|0xa0;break;
case(6):P2=(P2&0x1f)|0xc0;break;
case(7):P2=(P2&0x1f)|0xe0;break;
case(0):P2=(P2&0x1f)|0x00;break;
}
}
void clean(void)
{
choose573(4);
P0=0xff;
choose573(5);
P0=0x00;
choose573(0);
P0=0x00;
}
void SMG_display(int wei,int dat)
{
choose573(6);
P0=0x80>>(wei-1);
choose573(7);
P0=xianshi[dat];
}
void SMG_play()
{
SMG_display(1,number%10);
Delay300us();
SMG_display(2,number/10);
Delay300us();
SMG_display(3,10);
Delay300us();
SMG_display(4,10);
Delay300us();
SMG_display(5,10);
Delay300us();
SMG_display(6,10);
Delay300us();
SMG_display(7,10);
Delay300us();
SMG_display(8,10);
Delay300us();
}
void write_number()
{
number++;
write_EEPROM(0x00,number);
}
void read_number()
{
number=read_RRPROM(0x00);
}
void main()
{
clean();
read_number();
write_number();
while(1)
{
SMG_play();
}
}
代码直接复制就可以使用了
我感觉我应该已经调好了😮💨
如果喜欢可以点赞,还会更新关于蓝桥杯单片机的东西😉