打印
[PIC®/AVR®/dsPIC®产品]

【CuriosityNano测评报告】+PIC16F15244 内部FLASH读写

[复制链接]
703|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 qjp1988113 于 2021-2-22 14:24 编辑

今天我们来做下PIC16F15244 内部FLASH读写。这个几乎没有什么配置.打开MCC,选上MEMORY功能。

生成对应的代码,下面我们直接调用代码即可:
/**
  MEMORY Generated Driver File

  @Company
    Microchip Technology Inc.

  [url=home.php?mod=space&uid=288409]@file[/url] Name
    memory.c

  @Summary
    This is the generated driver implementation file for the MEMORY driver using PIC10 / PIC12 / PIC16 / PIC18 MCUs

  @Description
    This file provides implementations of driver APIs for MEMORY.
    Generation Information :
        Product Revision  :  PIC10 / PIC12 / PIC16 / PIC18 MCUs - 1.81.5
        Device            :  PIC16F15244
        Driver Version    :  2.01
    The generated drivers are tested against the following:
        Compiler          :  XC8 2.20 and above
        MPLAB             :  MPLAB X 5.40
*/

/*
    (c) 2018 Microchip Technology Inc. and its subsidiaries.
   
    Subject to your compliance with these terms, you may use Microchip software and any
    derivatives exclusively with Microchip products. It is your responsibility to comply with third party
    license terms applicable to your use of third party software (including open source software) that
    may accompany Microchip software.
   
    THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER
    EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY
    IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS
    FOR A PARTICULAR PURPOSE.
   
    IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
    INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND
    WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP
    HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO
    THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL
    CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT
    OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS
    SOFTWARE.
*/

/**
  Section: Included Files
*/

#include <xc.h>
#include "memory.h"

/**
  Section: Flash Module APIs
*/

uint16_t FLASH_ReadWord(uint16_t flashAddr)
{
    uint8_t GIEBitValue = INTCONbits.GIE;   // Save interrupt enable
   
    INTCONbits.GIE = 0;     // Disable interrupts
    NVMADRL = (flashAddr & 0x00FF);
    NVMADRH = ((flashAddr & 0xFF00) >> 8);

    NVMCON1bits.NVMREGS = 0;    // Deselect Configuration space
    NVMCON1bits.RD = 1;      // Initiate Read
    NOP();
    NOP();
    INTCONbits.GIE = GIEBitValue;        // Restore interrupt enable

    return ((uint16_t)((NVMDATH << 8) | NVMDATL));
}

void FLASH_WriteWord(uint16_t flashAddr, uint16_t *ramBuf, uint16_t word)
{
    uint16_t blockStartAddr = (uint16_t)(flashAddr & ((END_FLASH-1) ^ (ERASE_FLASH_BLOCKSIZE-1)));
    uint8_t offset = (uint8_t)(flashAddr & (ERASE_FLASH_BLOCKSIZE-1));
    uint8_t i;

    // Entire row will be erased, read and save the existing data
    for (i=0; i<ERASE_FLASH_BLOCKSIZE; i++)
    {
        ramBuf[i] = FLASH_ReadWord((blockStartAddr+i));
    }

    // Write at offset
    ramBuf[offset] = word;

    // Writes ramBuf to current block
    FLASH_WriteBlock(blockStartAddr, ramBuf);
}

int8_t FLASH_WriteBlock(uint16_t writeAddr, uint16_t *flashWordArray)
{
    uint16_t    blockStartAddr  = (uint16_t )(writeAddr & ((END_FLASH-1) ^ (ERASE_FLASH_BLOCKSIZE-1)));
    uint8_t     GIEBitValue = INTCONbits.GIE;   // Save interrupt enable
    uint8_t i;

   
    // Flash write must start at the beginning of a row
    if( writeAddr != blockStartAddr )
    {
        return -1;
    }

    INTCONbits.GIE = 0;         // Disable interrupts

    // Block erase sequence
    FLASH_EraseBlock(writeAddr);

    // Block write sequence
    NVMCON1bits.NVMREGS = 0;    // Deselect Configuration space
    NVMCON1bits.WREN = 1;    // Enable wrties
    NVMCON1bits.LWLO = 1;    // Only load write latches

    for (i=0; i<WRITE_FLASH_BLOCKSIZE; i++)
    {
        // Load lower 8 bits of write address
        NVMADRL = (writeAddr & 0xFF);
        // Load upper 6 bits of write address
        NVMADRH = ((writeAddr & 0xFF00) >> 8);

        // Load data in current address
        NVMDATL = flashWordArray[i];
        NVMDATH = ((flashWordArray[i] & 0xFF00) >> 8);

        if(i == (WRITE_FLASH_BLOCKSIZE-1))
        {
            // Start Flash program memory write
            NVMCON1bits.LWLO = 0;
        }

        NVMCON2 = 0x55;
        NVMCON2 = 0xAA;
        NVMCON1bits.WR = 1;
        NOP();
        NOP();

        writeAddr++;
    }

    NVMCON1bits.WREN = 0;       // Disable writes
    INTCONbits.GIE = GIEBitValue;   // Restore interrupt enable

    return 0;
}

void FLASH_EraseBlock(uint16_t startAddr)
{
    uint8_t GIEBitValue = INTCONbits.GIE;   // Save interrupt enable
   

    INTCONbits.GIE = 0; // Disable interrupts
    // Load lower 8 bits of erase address boundary
    NVMADRL = (startAddr & 0xFF);
    // Load upper 6 bits of erase address boundary
    NVMADRH = ((startAddr & 0xFF00) >> 8);

    // Block erase sequence
    NVMCON1bits.NVMREGS = 0;    // Deselect Configuration space
    NVMCON1bits.FREE = 1;    // Specify an erase operation
    NVMCON1bits.WREN = 1;    // Allows erase cycles

    // Start of required sequence to initiate erase
    NVMCON2 = 0x55;
    NVMCON2 = 0xAA;
    NVMCON1bits.WR = 1;      // Set WR bit to begin erase
    NOP();
    NOP();

    NVMCON1bits.WREN = 0;       // Disable writes
    INTCONbits.GIE = GIEBitValue;        // Restore interrupt enable
}

/**
  Section: Data EEPROM Module APIs
*/

void DATAEE_WriteByte(uint16_t bAdd, uint8_t bData)
{
    uint8_t GIEBitValue = INTCONbits.GIE;

    NVMADRH = ((bAdd >> 8) & 0xFF);
    NVMADRL = (bAdd & 0xFF);
    NVMDATL = bData;   
    NVMCON1bits.NVMREGS = 1;
    NVMCON1bits.WREN = 1;
    INTCONbits.GIE = 0;     // Disable interrupts
    NVMCON2 = 0x55;
    NVMCON2 = 0xAA;
    NVMCON1bits.WR = 1;
    // Wait for write to complete
    while (NVMCON1bits.WR)
    {
    }

    NVMCON1bits.WREN = 0;
    INTCONbits.GIE = GIEBitValue;   // restore interrupt enable
}

uint8_t DATAEE_ReadByte(uint16_t bAdd)
{
    NVMADRH = ((bAdd >> 8) & 0xFF);
    NVMADRL = (bAdd & 0xFF);
    NVMCON1bits.NVMREGS = 1;   
    NVMCON1bits.RD = 1;
    NOP();  // NOPs may be required for latency at high frequencies
    NOP();

    return (NVMDATL);
}


/**
End of File
*/



这里要说明的是,我们用来作为存储一些设定数字的FLASH地址一定要大于程序本身生成的代码,最好用最后面几个地址。
同时要计时个数,不能超出范围,不然会死机。
我们的MCU对应的FLASH地址范围 0X000~0XFFF

FLASH具有划分及堆栈模式:

可以在IDE左下侧,查看当前使用情况。

我们这里向首地址为0XF00的位置写入"Hello,world!",然后再把它读出来,看是否正确!
main.c定义变量:
#define FLASH_ROW_ADDRESS     0x0F00

uint16_t wrBlockData[12] ={'H', 'e', 'l', 'l', 'o', ',', 'w', 'o', 'r','l','d','!'};
uint16_t receData[12]={0};
添加到main里面:
 for(i=0;i<12;i++)
    {
        receData[i]=0;
    }
    // write to Flash memory block
    FLASH_WriteBlock((uint16_t)FLASH_ROW_ADDRESS, (uint16_t*)wrBlockData);
    __delay_ms(500);
    for(i=0;i<12;i++)
    {
        receData[i]=FLASH_ReadWord((uint16_t)FLASH_ROW_ADDRESS+i);
        __delay_ms(2);
    }
    __delay_ms(500);   
    printf("\r\n the readata is:  %c%c%c%c%c%c%c%c%c%c%c%c \r\n",receData[0],receData[1],receData[2],receData[3],
            receData[4],receData[5],receData[6],receData[7],receData[8],receData[9],receData[10],receData[11]);
就不做数值转字符串的代码了,编译下载,直接显示:

使用起来还行,但奈何本身空间就很小,当程序代码多时,慎用,会出现莫名其妙的问题。
之前我在循环里面加了读取ADC,并串口输出,然后大数据的转换处理就出现问题了,出现一个不稳定的值~






使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

111

主题

627

帖子

2

粉丝