IAP.C
/*
* 文 件 名:IAP.c
* 芯 片:STC12C5A60S2
* 晶 振:12MHz
* 创 建 者:冷月
* 创建日期:2010.8.23
* 修 改 者:
* 修改日期:
* 功能描述:STC内部1K(0x0000~0x3FFF)EEPROM读写
* 第一扇区0x0000~0x01FF
* 第二扇区0x0200~0x03FF
*/
#include <STC12C5A.H>
#include "IAP.h"
#define uchar unsigned char
#define uint unsigned int
/*
* 函 数 名:Open_IAP
* 功能描述:允许ISP/IAP
* 输入参数:无
* 返 回 值:无
*/
void Open_IAP(void)
{
//IAPEN SWBS SWRST CMD_FAIL - WT2 WT1 WT0
IAP_CONTR = 0x82; //充许ISP/IAP,系统时钟<20MHz时,设置等待时间WT2,WT1,WT0(010)
}
/*
* 函 数 名:Close_IAP
* 功能描述:禁止ISP/IAP
* 输入参数:无
* 返 回 值:无
*/
void Close_IAP(void)
{
IAP_CONTR = 0x00; //禁止ISP/IAP
IAP_ADDRH = 0xFF;
IAP_ADDRL = 0xFF;
}
/*
* 函 数 名:Read_IAP_Byte
* 功能描述:从EEPROM指定的单元读取一个字节数据
* 输入参数:addr:16bit地址
* 返 回 值:IAP_DATA:从指定的地址读取到的数据
*/
uchar Read_IAP_Byte(uint addr)
{
//- - - - - - MS1 MS0
IAP_CMD = 0x01;
IAP_ADDRH = (addr & 0xFF00)>>8;
IAP_ADDRL = addr & 0x00FF;
IAP_TRIG = 0x5A;
IAP_TRIG = 0xA5; //对IAP_TRIG先写0x5A再写0xA5,ISP/IAP命令才会生效
return IAP_DATA;
}
/*
* 函 数 名:Write_IAP_Byte
* 功能描述:把一个字节数据写入EEPROM指定的单元,写入数据前应先擦除扇区
* 输入参数:addr:16bit地址;writeVal:要写入的数据
* 返 回 值:无
*/
void Write_IAP_Byte(uint addr, uchar writeVal)
{
//- - - - - - MS1 MS0
IAP_CMD = 0x02;
IAP_ADDRH = (addr & 0xFF00)>>8;
IAP_ADDRL = addr & 0x00FF;
IAP_DATA = writeVal;
IAP_TRIG = 0x5A;
IAP_TRIG = 0xA5; //对IAP_TRIG先写0x5A再写0xA5,ISP/IAP命令才会生效
}
/*
* 函 数 名:Erase_IAP_Sector
* 功能描述:擦除扇区,没有字节擦除
* 输入参数:addr:扇区地址,扇区中任意一个字节地址都是该扇区地址
* 返 回 值:无
*/
void Erase_IAP_Sector(uint addr)
{
//- - - - - - MS1 MS0
IAP_CMD = 0x03;
IAP_ADDRH = (addr & 0xFF00)>>8;
IAP_ADDRL = addr & 0x00FF;
IAP_TRIG = 0x5A;
IAP_TRIG = 0xA5; //对IAP_TRIG先写0x5A再写0xA5,ISP/IAP命令才会生效
}
/*
* 函 数 名:Erase_IAP_Byte
* 功能描述:擦除指定单元内容
* 输入参数:addr:单元地址
* 返 回 值:无
*/
void Erase_IAP_Byte(uint addr)
{
//STC内部扩展1K(0x0000~0x03FF)ROM
//临时存放EEPROM一个扇区512Byte数据
uchar xdata EEPROM_sector[512] = {0};
uint sectorAddr; //扇区首地址
uint unit; //某个扇区的某个单元0~511
uint i;
sectorAddr = ((int)(addr / 512)) * 512;
unit = addr % 512;
for (i=0; i<512; i++)
{
EEPROM_sector = Read_IAP_Byte(sectorAddr+i); //读取扇区
}
Erase_IAP_Sector(sectorAddr); //擦除扇区
EEPROM_sector[unit] = 0xFF; //要擦除的单元置为0xFF
for (i=0; i<512; i++)
{
Write_IAP_Byte(sectorAddr+i, EEPROM_sector); //重新写入扇区
}
}
IAP.H
/*
* 文 件 名:IAP.h
* 芯 片:STC12C5A60S2
* 晶 振:12MHz
* 创 建 者:冷月
* 创建日期:2010.8.23
* 修 改 者:
* 修改日期:
* 功能描述:STC内部1K(0x0000~0x3FFF)EEPROM读写
* 第一扇区0x0000~0x01FF
* 第二扇区0x0200~0x03FF
*/
#ifndef _IAP_H_
#define _IAP_H_
#define uchar unsigned char
#define uint unsigned int
/*
* 函 数 名:Open_IAP
* 调 用:Open_IAP();
* 功能描述:允许ISP/IAP
*/
void Open_IAP(void);
/*
* 函 数 名:Close_IAP
* 调 用:Close_IAP();
* 功能描述:禁止ISP/IAP
*/
void Close_IAP(void);
/*
* 函 数 名:Read_IAP_Byte
* 调 用:val = Read_IAP_Byte(0x0000);
* 功能描述:从指定的EEPROM单元读取一个字节
*/
uchar Read_IAP_Byte(uint addr);
/*
* 函 数 名:Write_IAP_Byte
* 调 用:Write_IAP_Byte(0x0000, 0x12);
* 功能描述:向EEPROM指定的单元写入一个字节,写之前要先擦除
*/
void Write_IAP_Byte(uint addr, uchar writeVal);
/*
* 函 数 名:Erase_IAP_Sector
* 调 用:Erase_IAP_Sector(0x0000);
* 功能描述:擦除整个扇区,扇区中任意一个字节地址都是该扇区地址
*/
void Erase_IAP_Sector(uint addr);
/*
* 函 数 名:Erase_IAP_Byte
* 调 用:Erase_IAP_Byte(0x0000);
* 功能描述:擦除扇区中的一个单元
*/
void Erase_IAP_Byte(uint addr);
#endif
main.c
/*
* 文 件 名:main.c
* 芯 片:STC12C5A60S2
* 晶 振:12MHz
* 创 建 者:冷月
* 创建日期:2010.8.23
* 修 改 者:
* 修改日期:
* 功能描述:STC内部1K(0x0000~0x3FFF)EEPROM读写
*/
#include "IAP.h"
#include "UART.h"
#define uchar unsigned char
#define uint unsigned int
/*
* 函 数 名:main
* 功能描述:程序入口
* 输入参数:无
* 返 回 值:无
*/
void main(void)
{
uchar temp1 = 0, temp2 = 0;
UART1_Init(0xD9, 0, 1);
Open_IAP();
//Erase_IAP_Sector(0x0000);
Erase_IAP_Byte(0x0000);
Write_IAP_Byte(0x0000, 0x56);
Write_IAP_Byte(0x0001, 0x34);
temp1 = Read_IAP_Byte(0x0000);
temp2 = Read_IAP_Byte(0x0001);
Close_IAP();
UART1_SendOneChar(temp1);
UART1_SendOneChar(temp2);
while (1);
}
用户377235 2012-6-7 15:04
0k