首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用PIC18编写和读取内存?

如何使用PIC18编写和读取内存?
EN

Stack Overflow用户
提问于 2013-05-07 16:33:32
回答 7查看 10.9K关注 0票数 0

我想存储一个数字到PIC18,然后保留它,即使电源丢失或单元被重置。我认为我的写作代码部分看起来很好,只是它的阅读部分看上去很奇怪后,单位被重置。

我正在使用从微芯片获得的以下代码。

代码:

代码语言:javascript
复制
unsigned int value;
unsigned int DEEdata = 1;
unsigned int  DEEaddr = 0x04;

DataEEInit();
dataEEFlags.val = 0;

DataEEWrite(DEEdata,DEEaddr);
value = DataEERead(DEEaddr);
Nop();
printf("%d",value);

输出:1

然而,当我重置单元并且只使用读取代码时,我总是得到255。

代码读取

代码语言:javascript
复制
DataEEInit();
value = DataEERead(DEEaddr);
printf("%d",value);

输出:255

为什么会发生这种情况?我假设可能值没有被保存,或者读取部分不正确。谢谢!

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2013-05-15 15:05:05

一些PIC18微芯片除了内部闪光灯外,还有一个内部EEPROM。18F87J11没有这样的功能,所以您有两个选项:

1)写入闪存--这是存储程序的地方。确保您的应用程序的写入/读取周期的数量是可以的。

2)配置设置使用外部i2c或spi内存

您使用的DataEEWrite来自微芯片的“eeprom仿真”库(链接在下面的注释中)。有几件事要小心:

  • 当重新编程闪光灯时要小心!您可以覆盖您的设置。
  • 记住这不是真正的eeprom!写入周期是有限的,您必须删除内存的大部分-您不能删除一个字节。
票数 0
EN

Stack Overflow用户

发布于 2016-11-25 22:09:22

两个功能:使用64字节缓冲区@8字节块写入闪存和读取/比较闪存功能。

设备: PIC18F46K80

头文件的内容:

代码语言:javascript
复制
#define PRGM_BUFFER_SIZE 8
#define TABLE_WRITE_SIZE 64

#define LOAD_TBL_PTR(x) { TBLPTRU = ((((x)>>8)>>8)&0xff);\
                      TBLPTRH = (((x) >> 8) & 0xff);\
                      TBLPTRL = ((x) & 0xff);\
                    }

写入闪存功能:

代码语言:javascript
复制
/******************************************************
 * Function     : write_block
 * Input        : uint16_t position in destination flash
 * Global       : uint8_t buffer[64] - Location of source data
 * Output       : None
 * Description  : Writes the contents of the 64 byte
 * data buffer to program flash space.  Only 64 bytes
 * can be written at once.   The process of writing
 * to flash is: Erase->Write.
 ******************************************************/
static void write_block(uint16_t addr)
{
    int r, c;

    // Erase flash block first.  Erases a 64 byte block at a time.

    LOAD_TBL_PTR(addr);

    EECON1bits.EEPGD = 1;   // Point to flash program memory
    EECON1bits.CFGS = 0;    // Access flash memory
    EECON1bits.WREN = 1;    // Enable write to memory
    EECON1bits.FREE = 1;    // Enable Erase operation

    EECON2 = 0x55;
    EECON2 = 0xAA;

    EECON1bits.WR = 1;      // Clear the flash

    asm("NOP");             // Stall

    // Write buffer to internal buffer.  This process writes 8 bytes at a time
    // so we need to loop 8 times (8*8 = 64).)

    for (r = 0; r < 8; r++)
    {
        LOAD_TBL_PTR((addr + (r * 8)));

        for (c = 0; c < PRGM_BUFFER_SIZE; c++)
        {
            TABLAT = buffer[(r * 8) + c];

            asm("TBLWT*+");      // Push byte and then inc to next internal buffer cell
        }

        // Write the block to flash

        asm("TBLRD*-");         // Point back to original row

        // Write internal buffer to flash

        EECON1bits.EEPGD = 1;   // Point to flash program memory
        EECON1bits.CFGS = 0;    // Access flash program memory
        EECON1bits.WREN = 1;    // Enable write to memory
        INTCONbits.GIE = 0;     // Disable interrupts

        EECON2 = 0x55;
        EECON2 = 0xAA;

        EECON1bits.WR = 1;      // Start programming flash
        INTCONbits.GIE = 1;     // Re-enable interrupts
        EECON1bits.WREN = 0;    // Disable write to memory
    }
}

验证书面数据(演示闪存读取)

代码语言:javascript
复制
/******************************************************
 * Function     : compare_block
 * Input        : uint16_t position in destination flash
 * Global       : uint8_t buffer[64] - Location of previous written data
 * Output       : bool true=successful, false=did not match
 * Description  : Reads a 64 byte block of flash memory and
 * compares it to the data found in the global buffer.
 ******************************************************/
static bool compare_block(uint16_t addr)
{
    bool retVal = true; // succeeds
    uint8_t i = 0;

    INTCONbits.GIE = 0;     // Disable interrupts

    LOAD_TBL_PTR(addr);

    for (i = 0; i < TABLE_WRITE_SIZE && retVal == true; i++)
    {
        asm("TBLRD*+");

        if (buffer[i] != TABLAT)
            retVal = false;
    }

    INTCONbits.GIE = 1;     // Enable interrupts

    return retVal;
}

你的,布莱恩·威尔卡特

票数 2
EN

Stack Overflow用户

发布于 2013-05-14 12:42:15

您使用的设备除了其Flash之外没有内部的非易失性内存,后者通常用于存储代码。

我看到你有两个选择:

  1. 使用一些外部Flash或EEPROM,并将其与此PIC上可用的外部内存总线接口(参见家庭数据表第97页)。
  2. 重新映射内部Flash,以保留一小部分可用于存储数据(这样它不会干扰专门用于代码的内存区域),并将数据写入该区域(第87页)。

我已经多年没有使用过图片了,所以在实现细节方面不能给你太多的帮助,但我怀疑有很多例子可以从微芯片的网站上获得。

本质上,您的代码不能工作的原因是您试图访问不存在的内存。如果它在那里,那么接口是不正确的。

编辑:

我在微芯片的网站上查看了PIC18的代码示例页面,没有找到任何C示例来编写程序内存。不幸的是,看起来您必须在汇编程序中实现它。我不知道MPLAB编译器的语义,但是通常情况下,如果您要在内联中这样做的话:

代码语言:javascript
复制
void my_assembler_function(void)
{
    // Inline assembler code, actioned via C.
    asm("MOV x y");
    asm("MOV y z");
}

或者,微处理器的许多C编译器允许您使用C函数调用外部.s文件,从而避免了内联操作。

我认为您可以效仿我发现的这里来实现您所追求的功能。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16424157

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档