📄 flash.c
字号:
//[Flash.c]Flash擦写-------------------------------------------------------*
//本文件包含: *
// (1)Flash_Erase_Sector:擦除一个指定的扇区 *
// (2)Flash_Write_Nword:向一个指定的区域写入若干个字 *
//-------------------------------------------------------------------------*
//头文件
#include "Flash.h" //Flash擦写头文件
void Erase_Write_Pretreat(INT8U page); //擦写子函数内部调用的函数声明
//页所对应的块对照表
//两个flash块,每块4页 flash0 flash1
const INT8U pagetable[2][4] = {{0x3C,0x3D,0x3E,0x3F},{0x38,0x39,0x3A,0x3B}};
//Flash_Erase_Sector:擦除指定的扇区----------------------------------------*
//功 能:对页号为page,扇区首地址为addr的一个扇区进行擦除 *
//参 数:page--页号(0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F) *
// addr--扇区首地址(偶数) *
//返 回:无 *
//注 意:调用该函数之前,必须确定要擦除的区域可擦除 *
//-------------------------------------------------------------------------*
void Flash_Erase_Sector(INT8U page,INT16U addr)
{
//1 判断是否已分频、清相关错误标志、根据页号选择相应的flash块
Erase_Write_Pretreat(page); //擦写子函数共同调用的内部子函数
//2 向要擦除的扇区首地址写任意值(注意:经实验证实,不可以写0x0000)
*(INT16U *)addr = 0xFFFF;
//3 向命令寄存器写扇区擦除命令
FCMD = 0x40;
//4 在加高压期间,调用RAM区的机器码,相当于两条语句:
// FSTAT=0x80;
// while(!(FSTAT&0x40));
asm("JSR PrgOfRam");
}
//Flash_Write_Nword:向指定的扇区写入若干个字-------------------------------*
//功 能:将从address_source开始的len个字,写入页号为 page,起始地址为 *
// address_destination的扇区 *
//参 数:page--页映射地址(0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F) *
// address_destination--目标扇区首地址(偶数) *
// address_source--源地址 *
// len--字数(一次最多写入一行,即128个字) *
//返 回:无 *
//注 意:调用该函数之前,必须确定要写入的区域可写入 *
//-------------------------------------------------------------------------*
void Flash_Write_Nword(INT8U page,INT16U address_destination,
INT16U address_source,INT8U len)
{
INT8U m;
//1 判断是否已分频、清相关错误标志、根据页号选择相应的flash块
Erase_Write_Pretreat(page); //擦写子函数共同调用的内部子函数
//2 写入若干个字
for (m=0; m<len; m++)
{
//(1) 将源地址的一个字写入目标地址
*(INT16U *)address_destination = *(INT16U *)address_source;
//(2) 向命令寄存器写字写入命令
FCMD = 0x20;
//(3) 在加高压期间,调用RAM区的机器码,相当于两条语句:
// FSTAT=0x80;
// while(!(FSTAT&0x40));
asm("JSR PrgOfRam");
//(4) 源地址和目标地址同时向后移一个字
address_destination = address_destination+2;
address_source = address_source+2;
}
}
//Erase_Write_Pretreat:开始擦除或写入前的公共操作序列子函数----------------*
//功 能:判断是否已分频;清相关错误标志;根据页号选择相应的flash块;如果页号不*
// 为0,则设置PPAGE寄存器 *
//参 数:page--页映射地址(0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F) *
//返 回:无 *
//-------------------------------------------------------------------------*
void Erase_Write_Pretreat(INT8U page)
{
INT8U i,j;
//1 判断是否设置时钟分频,若无分频,则先分频
if ((FCLKDIV&0x80) == 0) FCLKDIV |= 0x03;
//2 清保护错误和访问错误标志位
FCNFG |= 0x01; //FCNFG的第0位置1,选择BLOCK1
FSTAT |= 0x30; //清保护错误和访问错误标志位
FCNFG &= 0xFE; //FCNFG的第0位置0,选择BLOCK0
FSTAT |= 0x30; //清保护错误和访问错误标志位
//3 查表、选择块号,如果页号不为0就设置页寄存器
if (page != 0)
{
for (i = 0;i < 2;i++)
{
for (j = 0;j < 4;j++)
{
if (page == pagetable[i][j])
break;
}
if (j < 4)
break;
}
if (i == 0) FCNFG &= 0xFE; //页号3C~3F,选择BLOCK0
if (i == 1) FCNFG |= 0x01; //页号38~3B,选择BLOCK1
PPAGE = page; //设置页寄存器
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -