关于51单片机字符串 EEPROM存储与读取的问题

发布者:温暖拥抱最新更新时间:2021-09-02 来源: eefocus关键字:51单片机  字符串  EEPROM  存储与读取 手机看文章 扫描二维码
随时随地手机看文章

题目如下

通过串口助手控制 LCD 显示屏,通过 LCD1602 显示并保存在 EEPROM 中,实现 数据的掉电保存(例 如:串口向单片机发送一串英文字符,该字符在 LCD 上显示出 来,若按下 k1 则实现数据的保存,按下 k2 实 现读取上次保存的数据,显示在 1602 上)


效果如下

在这里插入图片描述
在这里插入图片描述

#include "reg52.h" //此文件中定义了单片机的一些特殊功能寄存器

#include "i2c.h"

#include


typedef unsigned int u16;   //对数据类型进行声明定义

typedef unsigned char u8;


sbit LSA=P2^2;

sbit LSB=P2^3;

sbit LSC=P2^4;


sbit k1=P3^1;

sbit k2=P3^0;

sbit k3=P3^2; //定义按键端口

sbit LCD1602_RS=P2^6;

sbit LCD1602_RW=P2^5;

sbit LCD1602_E=P2^7;


u8 num=0;u8 i,flag;

u8 table[16]="I received is:  ";

u8 table1[16]="My memory is:   ";

u8 table2[16];

u8 table3[16];

u8 count,rec;

u8 dat,flag1,j;

/*******************************************************************************

* 函 数 名         : delay

* 函数功能    : 延时函数,i=1时,大约延时10us

*******************************************************************************/

void delay(u16 i)

{

while(i--);

}


 

void Lcd1602_Delay1ms(u16 c)   //误差 0us

{

    u8 a,b;

for (; c>0; c--)

{

for (b=199;b>0;b--)

{

  for(a=1;a>0;a--);

}      

}

   

}

void write_com(u8 com)

{

LCD1602_E = 0;     //使能

LCD1602_RS = 0;    //选择发送命令

LCD1602_RW = 0;    //选择写入

P0= com;     //放入命令

Lcd1602_Delay1ms(1); //等待数据稳定

LCD1602_E = 1;           //写入时序

Lcd1602_Delay1ms(5);   //保持时间

LCD1602_E = 0;

}

void write_data(u16 dat)

{

LCD1602_E = 1;     //使能

LCD1602_RS = 1;    //选择发送命令

LCD1602_RW = 0;    //选择写入

P0=dat;     //放入命令

Lcd1602_Delay1ms(1); //等待数据稳定

LCD1602_E = 1;           //写入时序

Lcd1602_Delay1ms(5);   //保持时间

LCD1602_E = 0;

}


 void Init()

{

write_com(0x38);

write_com(0x0f);

write_com(0x06);

write_com(0x01);  //清屏

write_com(0x80);  //设置数据指针起点

}


/*******************************************************************************

* 函数名         :Keypros()

* 函数功能 :按键处理函数

* 输入           : 无

* 输出          : 无

*******************************************************************************/

void Keypros()

{


if(k1==0)

{

delay(1000);  //消抖处理

if(k1==0)

{

count=strlen(table2); //计算要记忆的字符串的长度

for(i=0;i {

At24c02Write(5*i+2,table2[i]);   //在对应的地址中放入对应的字符

delay(1000);

}

}

while(!k1);

}


if(k2==0)

{

delay(1000);  //消抖处理

if(k2==0)

{

flag=0;

write_com(0x01);

for(i=0;i<16;i++)

{

write_data(table1[i]); //显示my memory is:

}

write_com(0x80+0x40); //换行

for(i=0;i<16;i++)

{

table3[i]= At24c02Read(5*i+2);

write_data(table3[i]);

delay(1000);

}

}

while(!k2);

}


if(k3==0)

{

delay(1000);  //消抖处理

if(k3==0)

{

write_com(0x01);

}

while(!k3);

}

}


void UsartInit()

{

    SCON = 0x50;

TMOD |= 0x20;

PCON = 0x80;

TH1 = 0xFD;

TL1 = 0xFD;

EA = 1;

ES = 1;

TR1 = 1;

}

void lcdDisplay()

{

write_com(0x01);

for(i=0;i<16;i++)

{

write_data(table[i]);

}

 

write_com(0x80+0x40);

  for(i=0;i   {

      write_data(table2[i]);

  }

  num=0;

  flag=0;

}

/*******************************************************************************

* 函 数 名       : main

* 函数功能 : 主函数

* 输    入       : 无

* 输    出    : 无

*******************************************************************************/

void main()

{

Init();

UsartInit();

while(1)

{    

if(flag==1)

{  

lcdDisplay();

Keypros();

}

}


void Usart() interrupt 4

{

if(RI)

{

table2[num]=SBUF;

RI = 0;

//Usartdelay5ms();

SBUF = table2[num];

while(!TI);

TI = 0;

//Usartdelay5ms();

num++;

flag = 1;

}

}


#include"i2c.h"


/*******************************************************************************

* 函数名         : Delay10us()

* 函数功能    : 延时10us

* 输入           : 无

* 输出          : 无

*******************************************************************************/


void Delay10us()

{

unsigned char a,b;

for(b=1;b>0;b--)

for(a=2;a>0;a--);


}

/*******************************************************************************

* 函数名         : I2cStart()

* 函数功能 : 起始信号:在SCL时钟信号在高电平期间SDA信号产生一个下降沿

* 输入           : 无

* 输出          : 无

* 备注           : 起始之后SDA和SCL都为0

*******************************************************************************/


void I2cStart()

{

SDA=1;

Delay10us();

SCL=1;

Delay10us();//建立时间是SDA保持时间>4.7us

SDA=0;

Delay10us();//保持时间是>4us

SCL=0;

Delay10us();

}

/*******************************************************************************

* 函数名         : I2cStop()

* 函数功能 : 终止信号:在SCL时钟信号高电平期间SDA信号产生一个上升沿

* 输入           : 无

* 输出          : 无

* 备注           : 结束之后保持SDA和SCL都为1;表示总线空闲

*******************************************************************************/


void I2cStop()

{

SDA=0;

Delay10us();

SCL=1;

Delay10us();//建立时间大于4.7us

SDA=1;

Delay10us();

}

/*******************************************************************************

* 函数名         : I2cSendByte(unsigned char dat)

* 函数功能 : 通过I2C发送一个字节。在SCL时钟信号高电平期间,保持发送信号SDA保持稳定

* 输入           : num

* 输出          : 0或1。发送成功返回1,发送失败返回0

* 备注           : 发送完一个字节SCL=0,SDA=1

*******************************************************************************/


unsigned char I2cSendByte(unsigned char dat)

{

unsigned char a=0,b=0;//最大255,一个机器周期为1us,最大延时255us。

for(a=0;a<8;a++)//要发送8位,从最高位开始

{

SDA=dat>>7; //起始信号之后SCL=0,所以可以直接改变SDA信号

dat=dat<<1;

Delay10us();

SCL=1;

Delay10us();//建立时间>4.7us

SCL=0;

Delay10us();//时间大于4us

}

SDA=1;

Delay10us();

SCL=1;

while(SDA)//等待应答,也就是等待从设备把SDA拉低

{

b++;

if(b>200) //如果超过2000us没有应答发送失败,或者为非应答,表示接收结束

{

SCL=0;

Delay10us();

return 0;

}

}

SCL=0;

Delay10us();

  return 1;

}

/*******************************************************************************

* 函数名         : I2cReadByte()

* 函数功能    : 使用I2c读取一个字节

* 输入           : 无

* 输出          : dat

* 备注           : 接收完一个字节SCL=0,SDA=1.

*******************************************************************************/


unsigned char I2cReadByte()

{

unsigned char a=0,dat=0;

SDA=1; //起始和发送一个字节之后SCL都是0

Delay10us();

for(a=0;a<8;a++)//接收8个字节

{

SCL=1;

Delay10us();

dat<<=1;

dat|=SDA;

Delay10us();

SCL=0;

Delay10us();

}

return dat;

}


/*******************************************************************************

* 函数名         : void At24c02Write(unsigned char addr,unsigned char dat)

* 函数功能    : 往24c02的一个地址写入一个数据

* 输入           : 无

* 输出          : 无

*******************************************************************************/


void At24c02Write(unsigned char addr,unsigned char dat)

{

I2cStart();

I2cSendByte(0xa0);//发送写器件地址

I2cSendByte(addr);//发送要写入内存地址

I2cSendByte(dat); //发送数据

I2cStop();

}

/*******************************************************************************

* 函数名         : unsigned char At24c02Read(unsigned char addr)

* 函数功能    : 读取24c02的一个地址的一个数据

* 输入           : 无

* 输出          : 无

*******************************************************************************/


unsigned char At24c02Read(unsigned char addr)

{

unsigned char num;

I2cStart();

I2cSendByte(0xa0); //发送写器件地址

I2cSendByte(addr); //发送要读取的地址

I2cStart();

I2cSendByte(0xa1); //发送读器件地址

num=I2cReadByte(); //读取数据

I2cStop();

return num;

}

关键字:51单片机  字符串  EEPROM  存储与读取 引用地址:关于51单片机字符串 EEPROM存储与读取的问题

上一篇:stc51单片机串口通信程序
下一篇:51 单片机 EEPROM小结(FLASH)

推荐阅读最新更新时间:2024-11-17 10:34

基于51单片机的多路压力测量仪
  1 引言   压力测量对实时监测和安全生产具有重要的意义。在工业生产中,为了高效、安全生产,必须有效控制生产过程中的诸如压力、流量、温度等主要参数。由于压力控制在生产过程中起着决定性的安全作用,因此有必要准确测量压力。为了测到不同位置的压力值,研制了基于C8051F020单片机的测量仪。通过压力传感器将需要测量的位置的压力信号转化为电信号,再经过OP07运算放大器进行信号放大,送至C805lF020单片机内部的高速率12位A/D转换器,然后将模拟信号转换成单片机可以识别的数字信号,再经单片机转换成液晶显示器可以识别的信息,最后显示输出。与此同时,可以利用SD卡存储器将各通道设定的压力值、系统参数存储起来,以便在系统断电或复位
[单片机]
基于<font color='red'>51单片机</font>的多路压力测量仪
手把手教你用51单片机DIY音乐频谱显示器
每当看到家里的音箱功放上的几排小灯,随着播放的音乐如波浪般跳跃,或者在电脑上打开千千静听这个音乐播放软件时,看到那动感的频谱跟随音乐节奏优美的舞动着时,不禁思绪万千,要是自己某天能亲手用普通的单片机DIY这么一个东东,那将是多么有成就感的事情,至少对我们电子爱好者来说,这是许多人曾经梦想过的。伴随音箱里传来的美妙音乐,原本只能“听”的音乐,现在却还能“看”,给人带来视觉上的炫酷享受。 本文将带领你动手探究其中的奥秘,你会发现她不再神秘,只要跟着我一步一步动手做,你一定可以成功做出来。让我们给音乐赋予一个完美的视听极限,你还在等什么?马上动手吧! 下面我们将讲解与制作有关的基础理论知识,我将力求使 音乐频谱 显示的原理通俗易懂。当
[电源管理]
手把手教你用<font color='red'>51单片机</font>DIY音乐频谱显示器
MCS-51单片机指令系统概述 1
MCS-51共有111条指令,可分为5类: . 数据传送类指令(共29条) . 算数运算类指令(共24条) . 逻辑运算及移位类指令(共24条) . 控制转移类指令(共17条) . 布尔变量操作类指令(共17条) 一些特殊符号的意义 在介绍指令系统前,我们先了解一些特殊符号的意义,这对今后程序的编写都是相当有用的。 电子元件邮购网 Rn 当前选中的寄存器区的8个工作寄存器R0 R7(n=0-7)。 Ri 当前选中的寄存器区中可作为地址寄存器的两个寄存器R0和R1(i=0,1) direct 内部数据存储单元的8位地址。包含0 127(
[单片机]
51单片机——I2C总线EEPROM
我们可以把数据保存在EEPROM中,这样断电数据也不会丢失。 常用的串行总线协议: 目前常用的微机与外设之间进行数据传输的串行总线主要有I2C总线、SPI总线和SCI总线。 I2C总线:以同步串行2线方式进行通信(一条时钟线,一条数据线)。 SPI总线:则以同步串行3线方式进行通信(一条时钟线,一条数据输入线,一条数据输出线)。 SCI总线:是以异步方式进行通信(一条数据输入线,一条数据输出线)。 1-wire :即单线总线,又叫单总线。 例子: 1-wire ——数字温度传感器DS18B20 IIC——oled屏幕 I2C串行总线的组成及工作原理 I2C总线是PHLIPS公司推出的一种串行总线
[单片机]
<font color='red'>51单片机</font>——I2C总线<font color='red'>EEPROM</font>
51单片机串口通信(字符串接收和发送)
#include reg52.h //------------------串口通信协议-----------------// /* 客户端数据包格式解释(长度恒为15): 例如:A01_fmq_01Off___# A--------数据包的开始标记(可以为A到Z,意味着数据包可以有26种) 01-----设备代号 fmq_01Off___--------指令(长度恒为10),指令的前4个人字符是指令头部,指令的后6个字符是指令尾部 #---------数据包的结束标记 服务器端数据包格式解释(长度恒为15): 例如:A02_SenT010250# A--------数据包的开始标记(可以为
[单片机]
51单片机矩阵键盘左右流水灯控制C程序
本程序所用的原理图下载: 点这里 ,单片机芯片使用的stc89c52;找到本程序所使用的相应部分即可.这是一整个单片机开发板的电路图其他的忽略. hex文件及其工程文件下载:http://www.51hei.com/f/jzzyou.rar 以下是测试ok的源代码: /* *功能:使用矩阵按键使得按键按下时数码管上显示各自对应的数字的平方数; * 且使用定时器0中断使得彩色流水灯先以20毫秒的速度左移流动4秒后, * 然后使得彩色流水灯以20毫秒的速度右移流动; *日期:2013-05-02-16:46 *作者:徐冉 *特别说明:本程序代码已经通过调试,仅供学习使用; * */ /***********AT89C52-RC 单
[单片机]
51单片机的准备工作
准备工作,首先,你要有一块电路板,无论是学习板还是最小系统板,至少要有一块,因为单片机是实战的技术,没有板子玩不了。就好像你去驾校学开车,教练只跟你说理论,让你看书,不让你上车练习,你能学会开车么?肯定不能。 第二,单片机选型,选择宏晶的STC89C52C,关于宏晶老板姚永平,大家感兴趣的可以在网上搜一下。其实选型的时候,我是用ATMEL的89S52和STC89C52C进行对比了的,因为程序下载的时候89S52还需要一条ISP下载线,而STC89C52C只需要串口线就可以了,而串口线在后面的学习中是会用到的,这样算来,后者貌似成本更低一些。 第三,编译软件,KEIL C,全名是keil uvision,下载地址
[单片机]
学<font color='red'>51单片机</font>的准备工作
linux-2.6.32在mini2440开发板上移植 移植I2C-EEPROM 驱动
1 在内核中配置I2C 驱动 Linux-2.6.32.2 对S2C2440 的I2C 接口提供了完善的驱动,因此我们只需在内核中配置一下即可使用。 在内核源代码目录执行:make menuconfig,进入内核配置主菜单,依次选择进入如下子菜单: Device Drivers --- * I2C support --- I2C Hardware Bus support --- 如图,我们看到这里已经选择好了“ * S3C2410 I2C Driver”,这里的S3C2410 也可以适用于S3C2440,因为它们的I2C 端口及寄存器定义都是完全相同的。 以上配置所对
[单片机]
linux-2.6.32在mini2440开发板上移植 移植I2C-<font color='red'>EEPROM</font> 驱动
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved