Cortex-M3 (NXP LPC1788)之EEPROM存储器

2023-05-16

EEPROM是一种非易失性存储器,主要用于存储相对少量的数据,如存储一些系统的配置信息。通过系统的EEPROM控制模块可以轻松的进行EERPOM的存储控制。

要正确使用EEPROM需要配置掉电寄存器EEPWRDWN确定EEPROM的工作模式,配置EEPROM时钟分频器寄存器,使EEPROM工作在375KHZ。下面对EEPROM的读和写数据进行介绍。

EEPROM存储器的访问有三种操作方式:读、写、擦除/编程。对EEPROM中写数据分成两个单独的操作:写和擦除/编程。第一步写操作并不是真正把数据写入EEPROM的存储介质中,而只是更新被称作“页寄存器”的临时数据寄存器。只有执行下一步”擦除/编程“操作才会真正地更新非易失存储器。LPC1788共有4K的片内EEPROM,其中EEPROM的每一页等于页寄存器大小为64Byte,总共有64页。大小正好是64*64=4096Byte=4K。首先我们指定的位数,如8、16或者32位,将数据写入页寄存器,页内的地址偏移由EEPROM地址寄存器的第6位决定。如果需要往页寄存器写入一串数据,写完第一个数据后,页内的偏移地址会自动增加,我们只需把要操作的下一个数据填入EEPROM写数据寄存器即可。当页寄存器的64个字节被写满,必须进行编程操作,将数据写入到EEPROM的存储介质。然后更新页寄存器的偏移地址。

对于EEPROM的读操作,首先要向地址寄存器写入一个12位的地址,高6位为页的偏移,即我们需要读哪个页寄存器。低6位为页内的偏移,即我们需要读当前页的哪个字节。读操作也可以自动的对地址寄存器做后递增,这样就可以对EEPROM存储器进行连续的操作而无需每次读数据都写入一个新地址。

下面的程序将信息写入EEPROM后读出通过串口打印显示:

#include "LPC1788_REG.h"
#include "uart.h"
 
#define rEECMD          (*(volatile unsigned*)(0x00200080))
#define rEEADDR         (*(volatile unsigned*)(0x00200084))
#define rEEWDATA        (*(volatile unsigned*)(0x00200088))
#define rEERDATA        (*(volatile unsigned*)(0x0020008C))
#define rEEWSTATE       (*(volatile unsigned*)(0x00200090))
#define rEECLKDIV       (*(volatile unsigned*)(0x00200094))
#define rEEPWRDWN       (*(volatile unsigned*)(0x00200098))
 
#define rEEINTEN        (*(volatile unsigned*)(0x00200FE4))
#define rEEINTCLR       (*(volatile unsigned*)(0x00200FD8))
#define rEEINTSET       (*(volatile unsigned*)(0x00200FDC))
#define rEEINTSTAT      (*(volatile unsigned*)(0x00200FE0))
#define rEEINTSTATCLR   (*(volatile unsigned*)(0x00200FE8))
#define rEEINTSTATSET   (*(volatile unsigned*)(0x00200FEC))
 
#define EEPROM_PAGE_SIZE 64
void Init_EEPROM(void);
void Write_EEPROM(unsigned char page_num, unsigned char page_offset, char* data, unsigned int count);
void Read_EEPROM(unsigned char page_num, unsigned char page_offset, char* data, unsigned int count);
 
char read_buffer[];
char write_buffer[] = {"\n\r\
\t - Name: Nuncle.lee \n\r\
\t - QQ: 23610603 \n\r\
\t - Email: nuncle.lee@gmail.com\n\r"};
 
int main(void)
{   
    Init_Uart2();
    Init_EEPROM();
    
    
    Write_EEPROM(0, 0, write_buffer, sizeof(write_buffer));
    Write_EEPROM(sizeof(write_buffer)/64, sizeof(write_buffer)%64, '\0', 1);
    
    Read_EEPROM(0, 0, read_buffer, sizeof(write_buffer)+1);
    
    Uart2SendS(read_buffer);
 
    return 0;
}
 
void Init_EEPROM(void)
{
    unsigned int val=0;
    
    rEEPWRDWN = 0;  //不处于掉电模式
    rEECLKDIV = (CCLK/375000)-1;    //设置一个375KHZ的EEPROM时钟
    
    val  = ((((CCLK / 1000000) * 15) / 1000) + 1);      //配置等待状态时间
	val |= (((((CCLK / 1000000) * 55) / 1000) + 1) << 8);
	val |= (((((CCLK / 1000000) * 35) / 1000) + 1) << 16);
    rEEWSTATE = val;
}

void Write_EEPROM(unsigned char page_num, unsigned char page_offset, char* data, unsigned int count)
{
    unsigned int i;
    
    rEEADDR = (page_offset&0x3f);   //确定开始写的页内偏移地址
    for(i=0; i<count; i++)
    {
        rEECMD = 0x3;               //8位写操作
        rEEWDATA = *(data+i);
        while(!(rEEINTSTAT & (0x1<<26)));   //等待写操作完成
        page_offset++;
        
        if(page_offset >= EEPROM_PAGE_SIZE)     //如果当前页写满了64Byte 则启动 编程操作
        {
            rEEINTSTATCLR = 0x1<<28;
            rEEADDR = (page_num&0x3F)<<6;
            rEECMD = 0x6;   //擦除编程
            while(!(rEEINTSTAT & (0x1<<28)));   //等待编程完成
            
            page_offset = 0;
            page_num++;     //写满一页,准备写下一页
            rEEADDR = 0;    //写满一页,从页的开始写
        }
        else if(i==count-1)                 //如果要写入EPPROM的数据写完成,启动编程操作
        {
            rEEINTSTATCLR = 0x1<<28;
            rEEADDR = (page_num&0x3F)<<6;
            rEECMD = 0x6;   //擦除编程
            while(!(rEEINTSTAT & (0x1<<28)));
        }
    }
}
 
void Read_EEPROM(unsigned char page_num, unsigned char page_offset, char* data, unsigned int count)
{
    unsigned int i;
    rEEADDR = (page_num&0x3F)<<6|page_offset&0x3F;      //确定读数据的起始位置,包括页偏移和页内的偏移
    rEECMD = 0x1<<3;                                    //8位读,地址自动递增模式
    for(i=0; i<count; i++)
    {
        while(!(rEEINTSTAT & (0x1<<26)));               //等待上一次读数据完成
        *(data+i) = rEERDATA;
        page_offset++;
        
        if(page_offset >= EEPROM_PAGE_SIZE)             //如果当前页64Byte读完,准备读下一页
        {
            page_offset = 0;
            page_num++;
            rEEADDR = (page_num&0x3F)<<6|page_offset&0x3F;  
            rEECMD = 0x1<<3;
        }
    }
}

程序的执行结果如下图

在这里插入图片描述

程序中,sizeof关键字计算出字符数组的大小,并不包含字符串的结束标志‘\0’。因此还需在sizeof(write_buffer)的位置写入字符串的结束标志。读取时读sizeof(write_buffer)+1个字节,才能正确的通过串口打印数据。当然,也可以自己指定串口打印字符的个数,而不用字符串结束标志去判断。

本文章转载自 Cortex-M3 (NXP LPC1788)之EEPROM存储器

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Cortex-M3 (NXP LPC1788)之EEPROM存储器 的相关文章

  • Linux服务器snmp协议v2/v3配置方法

    Snmp V2 配置方法 1 确保本机已经安装了snmp服务 root 64 idc rpm qa grep snmp net snmp libs 5 1 2 11 EL4 7 net snmp 5 1 2 11 EL4 7 如果没有 xf
  • 论文中AP与AR含义详细解释

    AP的含义和AR的本身含义就是查准率和查全率 这里的AP通过和IOU结合定义出两种分别 xff1a 1 当IOU大于0 5认定为真 2 当IOU大于0 75认定为真 3 从IOU大于0 5开始 xff0c 每次增加0 05 xff0c 分别
  • 学习笔记之ubuntu sudo apt-get update失败已经解决

    ubuntu sudo apt get update失败已经解决 运行sudo apt get update出现的错误如下 xff1a etc apt sudo apt get update Err http security ubuntu
  • oracle之index

    索引与表一样 xff0c 也属于段 xff08 segment xff09 的一种 里面存放了用户的数据 xff0c 跟表一样需要占用磁盘空间 索引是一种允许直接访问数据表中某一数据行的树型结构 xff0c 为了提高查询效率而引入 xff0
  • 通过jad/mc/redefine命令,在docker容器中实现动态更新代码的功能:

    通过jad mc redefine命令 xff0c 在docker容器中实现动态更新代码的功能 xff1a demos dockerfile from openjdk 8u232 jdk maintainer czm lt chengzhi
  • 对抗攻击与防御(2022年顶会顶刊AAAI、ACM、 ECCV、NIPS、ICLR、CVPR)adversarial attack and defense汇总

    文章目录 AAAI 39 2022 论文汇总CVPR 2022论文汇总ACM 39 2022论文汇总ECCV 39 2022论文汇总ICLR 39 2022论文汇总NIPS 39 2022论文汇总后续 AAAI 2022 论文汇总 AAAI
  • 时间序列(time serie)分析系列之时间序列特征(feature)7

    文章目录 1 问题描述 2 特征构建 2 1时间特征 2 2平移特征 2 3窗口特征 3 总结 1 问题描述 时间序列数据作为一种典型的数据 常存在于各行各业 比如客流 车流 销量 KPI指标等等 如何对时序数据加以利用 比如做未来预测 交
  • 数论

    质数的定义 对于大于1的自然数 如果它的因子中只有1和它本身 则是一个质数也称素数 从定义可以看出质数的取值范围是从2开始的 小于2的数肯定不是质数 质数的判定 试除法 假设 d是n的一个因子 那么n d 也是n的一个因子 因此我们只需要枚
  • Linux yolov4配置运行

    1 下载yolov4 git clone https github com AlexeyAB darknet git 如果没有git sudo apt get install git 2 编译 进入darknet的目录下 执行下面的语句进行
  • 吐血分类整理 Windows 11的170个快捷键

    1 Windows 11 中新增的键盘快捷键 xff1a 作用快捷键打开小部件窗格 xff0c 提供天气预报 当地交通 新闻 xff0c 日历Win 43 W切换快速设置 控制音量 Wi Fi 蓝牙 亮度滑块 对焦辅助和其他设置Win 43
  • SLAM算法解析

    ref xff1a https www jianshu com p eb25bd481475 嵌牛导读 xff1a SLAM Simultaneous Localization and Mapping 是业界公认视觉领域空间定位技术的前沿方
  • mininet基本使用与操作方法

    启动Wireshark 要使用OpenFlow Wireshark解剖器查看控制流量 xff0c 请先在后台打开wireshark xff1a sudo wireshark amp do wireshark amp rk amp 每个主机进
  • ArUco Marker检测原理

    标记检测过程包括两个主要步骤 xff1a 检测候选marker 在该步骤中 xff0c 分析图像以找到作为标记的候选的正方形形状 它首先进行自适应阈值处理以对标记进行分割 xff0c 然后从阈值图像中提取轮廓 xff0c 并丢弃那些非凸起或
  • 深度学习中epoch、batch、batch size和iterations详解

    1 epoch 在训练一个模型时所用到的全部数据 xff1b 备注 xff1a 一般在训练时都要使用多于一个的epoch xff0c 因为在神经网络中传递完整的数据集仅仅一次是不够的 xff0c 只有将完整的数据集在同样的神经网络中传递多次
  • matlab如何将帮助变成简体中文

    仅作为尝试记录 xff0c 大佬请跳过
  • ubuntu安装px4

    无人机自动驾驶软件系列 网址 https gaas gitbook io guide software realization build your own autonomous drone wu ren ji zi dong jia sh
  • Optitrack与ROS详细教程以及Motive的使用

    一 软件安装 运行安装包安装 USB 驱动 第 一 次 安 装 Motive 时 xff0c 会 提 示 安 装 OptiTrack USB 驱 动 xff08 例 如 xff1a OptiTrack USB Driver x64 xff0
  • 解决Centos7无法通过Putty进行ssh连接的问题

    这问题搞了我一个晚上 xff0c 晕 1 首先查看自己的Centos7能不能连上网 xff0c 如果不能连上网 xff0c 这里我尝试了CSDN里的多种方法都无用 xff0c 最后这篇博客解决了我的问题 xff0c 原因是在于默认安装 2
  • 用Python实现归并排序算法

    本文是本人在学习左神的java代码后改写为的python代码 归并排序算法的步骤是 如 xff0c 对 1 2 4 9 3 55 25 64 对分 xff0c 对左半边和右半边进行递归 递归的终止条件是输入list的长度为1 如 xff0c
  • 风雨秋招路-CV太难了-记得复盘

    文章目录 字节跳动夏令营工商银行VIVO中移动信息技术面试海信文远知行六一教育格灵研究院字节 技术中台 已挂多益网络科大讯飞大疆笔试海康威视小米 打好基础 xff01 xff01 xff01 速腾聚创奇安信莉莉丝笔试阿里巴巴面试 很难美团面

随机推荐