实验功能为:系统运行时, 数码管右 3 位显示 0,按 K1 键将数据 写入到 EEPROM 内保存, 按 K2 键读取 EEPROM内保存的数据, 按K3 键显示数据加 1, 按K4 键显示数据清零,最大能写入的数据是 255。
学习视频:22.8-I2C-EEPROM实验--软件编程--创建多文件工程_哔哩哔哩_bilibili
首先第一步操作:对文件进行管理
有如下几个文件夹:
《Public》 存放常规设置的接口和常用的函数,比如延时函数。
《APP》 存放IO设备相关设置的接口和调用函数 。
《User》 存放main.c;
《Public》包含public.h.c 和public.h。代码如下:
// public.h
#ifndef _public_H
#define _public_H
#include "reg52.h"
typedef unsigned int u16; // 定义类型 u16代表int类型
typedef unsigned char u8; // 定义类型 u8代表char类型
void delay10us(u16 ten_us); // 包含延时程序
#endif
// public.c
#include "public.h"
void delay10us(u16 ten_us)
{
while(ten_us--);
}
《APP》包含key.c和key.h(按键函数)、smg.c和smg.h(数码管函数)、iic.c和iic.h(IIC协议函数)、24c02.c和24c02.h(EEPROM读取函数)。代码分别如下:
key.c和key.h(按键函数):
// key.c
#include "key.h"
u8 key_scan(u8 mode)
{
static u8 key = 1;
if(mode) key = 1;
if(key = 1&&(KEY1==0||KEY2==0||KEY3==0||KEY4==0))
{
delay10us(1000);
key = 0;
if(KEY1==0)
return KEY1_PRESS;
else if(KEY2==0)
return KEY2_PRESS;
else if(KEY3==0)
return KEY3_PRESS;
else if(KEY4==0)
return KEY4_PRESS;
}
else if(KEY1==1 && KEY2==1 && KEY3==1 && KEY4==1)
{
key = 1;
}
return KEY_UNPRESS;
}
// key.h
#ifndef _key_H
#define _key_H
#include "public.h"
sbit KEY1 = P3^1;
sbit KEY2 = P3^0;
sbit KEY3 = P3^2;
sbit KEY4 = P3^3;
#define KEY1_PRESS 1 // 定义返回值函数
#define KEY2_PRESS 2
#define KEY3_PRESS 3
#define KEY4_PRESS 4
#define KEY_UNPRESS 0
u8 key_scan(u8 mode); // 包含按键扫描函数
#endif
smg.c和smg.h(数码管函数):
// smg.c
#include "smg.h"
u8 gsmg_code[18] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
0x77,0x7c,0x39,0x5e,0x79,0x71,0x00,0x40};
void smg_display(u8 det[],u8 pos) // 数码管显示函数,输入要显示数组的首地址 及 数码管控制位
{
u8 i = 0;
u8 pos_temp = pos-1;
for(i=pos_temp;i<8;i++)
{
switch(i)
{
case 0: LSC = 1;LSB = 1;LSA = 1; break;
case 1: LSC = 1;LSB = 1;LSA = 0; break;
case 2: LSC = 1;LSB = 0;LSA = 1; break;
case 3: LSC = 1;LSB = 0;LSA = 0; break;
case 4: LSC = 0;LSB = 1;LSA = 1; break;
case 5: LSC = 0;LSB = 1;LSA = 0; break;
case 6: LSC = 0;LSB = 0;LSA = 1; break;
case 7: LSC = 0;LSB = 0;LSA = 0; break;
}
SMG_A_DP_PORT = gsmg_code[det[i-pos_temp]];
delay10us(500);
SMG_A_DP_PORT = 0x00;
}
}
// smg.h
#ifndef _smg_H
#define _smg_H
#include "public.h"
#define SMG_A_DP_PORT P0
sbit LSA = P2^2;
sbit LSB = P2^3;
sbit LSC = P2^4;
extern u8 gsmg_code[18];
void smg_display(u8 det[],u8 pos);
#endif
iic.c和iic.h(IIC协议函数):
// iic.c
#include "iic.h"
void iic_start(void) // IIC 起始信号
{
IIC_SCL=1;
IIC_SDA=1;
delay10us(1);
IIC_SDA=0;
delay10us(1);
}
void iic_stop(void) // IIC 终止信号
{
IIC_SCL=1;
IIC_SDA=0;
delay10us(1);
IIC_SDA=1;
delay10us(1);
}
void iic_ack(void) // IIC 应答信号
{
IIC_SCL=0;
IIC_SDA=0;
delay10us(1);
IIC_SCL=1;
delay10us(1);
IIC_SCL=0;
}
void iic_nack(void) // IIC 未应答信号
{
IIC_SCL=0;
IIC_SDA=1;
delay10us(1);
IIC_SCL=1;
delay10us(1);
IIC_SCL=0;
}
u8 iic_wait_ack(void) // IIC 等待应答信号
{
u8 time_temp = 0;
IIC_SCL=1;
delay10us(1);
while(IIC_SDA)
{
time_temp++;
if(time_temp>100)
{
iic_stop();
return 1;
}
IIC_SCL=0;
return 0;
}
}
void iic_write_byte(u8 dat) // IIC 写入一个字节
{
u8 i = 0;
IIC_SCL=0;
for(i=0;i<8;i++)
{
if((dat&0x80)>0)
IIC_SDA=1;
else
IIC_SDA=0;
dat<<=1;
IIC_SCL=1;
delay10us(1);
IIC_SCL=0;
delay10us(1);
}
}
u8 iic_read_byte(u8 ack) // IIC 读出一个字节
{
u8 i = 0;
u8 receive = 0;
for(i=0;i<8;i++)
{
IIC_SCL=0;
delay10us(1);
IIC_SCL=1;
delay10us(1);
receive<<=1;
if(IIC_SDA) receive++;
}
if(!ack) iic_nack();
else iic_ack();
return receive;
}
// iic.h
#ifndef _iic_H
#define _iic_H
#include "public.h"
sbit IIC_SCL = P2^1;
sbit IIC_SDA = P2^1;
void iic_start(void);
void iic_stop(void);
void iic_ack(void);
void iic_nack(void);
u8 iic_wait_ack(void);
void iic_write_byte(u8 dat);
u8 iic_read_byte(u8 ack);
#endif
24c02.c和24c02.h(EEPROM读取函数):
// 24c02.c
#include "24c02.h"
#include "iic.h"
void at24c02_write_one_byte(u8 addr, u8 dat) // EEPROM写入函数
{
iic_start();
iic_write_byte(0xa0);
iic_wait_ack();
iic_write_byte(addr);
iic_wait_ack();
iic_write_byte(dat);
iic_wait_ack();
iic_stop();
delay10us(1000);
}
u8 at24c02_read_byte(u8 addr) // EEPROM读出函数
{
u8 temp=0;
iic_start();
iic_write_byte(0xa0);
iic_wait_ack();
iic_write_byte(addr);
iic_wait_ack();
iic_start();
iic_write_byte(0xa1);
iic_wait_ack();
temp=iic_read_byte(0);
iic_stop();
return temp;
}
// 24c02.h
#ifndef _24c02_H
#define _24c02_H
#include "public.h"
void at24c02_write_one_byte(u8 addr, u8 dat);
u8 at24c02_read_byte(u8 addr);
#endif
《User》包含main.c,代码如下:
#include "public.h"
#include "key.h" // 包含与独立按键相关函数
#include "smg.h" // 包含与数码管相关函数
#include "24c02.h" // 包含与EEPROM读取相关函数
#define EEPROM_ADDRESS 0
void main()
{
u8 key_temp = 0;
u8 save_value = 0;
u8 save_buf[3];
while(1)
{
key_temp=key_scan(0);
if(key_temp==KEY1_PRESS) // 若按键1按下,则将数据写入EEPROM
{
at24c02_write_one_byte(EEPROM_ADDRESS,save_value);
}
else if(key_temp==KEY2_PRESS) // 若按键2按下,则读出EEPROM的数据
{
save_value=at24c02_read_byte(EEPROM_ADDRESS);
}
else if(key_temp==KEY3_PRESS) // 若按键3按下,则将数据加一
{
save_value++;
if(save_value==255) save_value=255;
}
else if(key_temp==KEY4_PRESS) // 若按键4按下,则将数据置零
{
save_value=0;
}
save_buf[0]=save_value/100;
save_buf[1]=save_value%100/10;
save_buf[2]=save_value%100%10;
smg_display(&save_buf[0],6); // 数码管显示数据
}
}
以上内容,学习参考所用。如有侵权,Call我必删。