注:芯片内部FLASH读写操作时,烧录工具上一定要选择 Option 设置->IAP Range ->Code:ALL选项,否则程序无法进行,芯片内部FLASH读写操作。
#include "sc92f8003_iap.h"
#include "sc92f8003_gpio.h"
#include "sc92f8003_option.h"
void main(void)
{
uint8_t i;
uint16_t j;
GPIO_Init(GPIO2,GPIO_PIN_0,GPIO_MODE_OUT_PP); //将P20设置为强推挽模式
IAP_SetHoldTime(IAP_HOLDTIME_1500US); //HoldTime时间为1MS
OPTION_IAP_SetOperateRange(IAP_OPERATERANGE_ONLY_EEPROM); //只允许EEPROM进行IAP操作
while(1)
{
for(i=0;i<10;i++)
{
IAP_ProgramByte(i, 0xaa, IAP_MEMTYPE_EEPROM, 0xf0); //往EEPROM区i地址写值0xaa,操作时限0xf0
if(IAP_ReadByte(i, IAP_MEMTYPE_EEPROM) == 0xaa) //读EEPROM区i地址的值
{
if(GPIO_ReadPin(GPIO2,GPIO_PIN_0)) //相等翻转IO
{
GPIO_WriteLow(GPIO2,GPIO_PIN_0);
}
else
{
GPIO_WriteHigh(GPIO2,GPIO_PIN_0);
}
}
else
{
GPIO_Init(GPIO2,GPIO_PIN_0,GPIO_MODE_IN_HI); //不等则将P20设置为高阻输入模式
}
for(j=0;j<50000;j++);
}
}
}
#include "sc92f8003_iap.h"
#include <intrins.h>
/**************************************************
*函数名称:void IAP_DeInit(void)
*函数功能:IAP相关寄存器复位至缺省值
*入口参数:void
*出口参数:void
**************************************************/
void IAP_DeInit(void)
{
IAPKEY = 0X00;
IAPADL = 0X00;
IAPADH = 0X00;
IAPADE = 0X00;
IAPDAT = 0X00;
IAPCTL = 0X00;
}
/**************************************************
*函数名称:void IAP_SetHoldTime(IAP_HoldTime_TypeDef IAP_HoldTime)
*函数功能:IAP操作CPU Hold Time配置函数
*入口参数:IAP_HoldTime CPU Hold Time选择
*出口参数:void
**************************************************/
void IAP_SetHoldTime(IAP_HoldTime_TypeDef IAP_HoldTime)
{
IAPCTL = (IAPCTL & 0xF3) | IAP_HoldTime;
}
/**************************************************
*函数名称:void IAP_ProgramByte(uint16_t Address, uint8_t Data, IAP_MemType_TypeDef IAP_MemType, uint8_t WriteTimeLimit)
*函数功能:IAP写入一个字节
*入口参数:Address IAP操作地址
Data 写入的数据
IAP_MemType IAP操作对象(ROM、IFB、EEPROM)
WriteTimeLimit IAP操作时限 (非零值)
*出口参数:void
**************************************************/
void IAP_ProgramByte(uint16_t Address, uint8_t Data, IAP_MemType_TypeDef IAP_MemType, uint8_t WriteTimeLimit)
{
BitStatus tmpbit;
tmpbit = (BitStatus)EA;
if(tmpbit)
{
disableInterrupts();
}
IAPADE = IAP_MemType;
IAPDAT = Data;
IAPADH = (uint8_t)(Address >> 8);
IAPADL = (uint8_t)Address;
IAPKEY = WriteTimeLimit; //必须为非零值
IAPCTL |= 0x02;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
IAPADE = IAP_MEMTYPE_ROM;
if(tmpbit)
{
enableInterrupts();
}
}
/**************************************************
*函数名称:uint8_t IAP_ReadByte(uint16_t Address, IAP_MemType_TypeDef IAP_MemType)
*函数功能:IAP读一个字节
*入口参数:Address IAP操作地址
FLASH_MemType IAP操作对象(ROM、IFB、EEPROM)
*出口参数:uint8_t 读到的字节数据
**************************************************/
uint8_t IAP_ReadByte(uint16_t Address, IAP_MemType_TypeDef IAP_MemType)
{
uint8_t tmpbyte;
BitStatus tmpbit;
tmpbit = (BitStatus)EA;
if(tmpbit)
{
disableInterrupts();
}
IAPADE = IAP_MemType;
tmpbyte = *((uint8_t code*)Address);
IAPADE = IAP_MEMTYPE_ROM;
if(tmpbit)
{
enableInterrupts();
}
return tmpbyte;
}
#ifndef _SC92F8003_IAP_H_
#define _SC92F8003_IAP_H_
#include "sc92f8003.h"
typedef enum {
IAP_MEMTYPE_ROM = (uint8_t)0x00, //IAP操作区域为ROM
IAP_MEMTYPE_IFB = (uint8_t)0x01, //IAP操作区域为IFB
IAP_MEMTYPE_EEPROM = (uint8_t)0x02 //IAP操作区域为EEPROM
} IAP_MemType_TypeDef;
typedef enum {
IAP_HOLDTIME_6000US = (uint8_t)0x00, //设定CPU Hold Time为6MS
IAP_HOLDTIME_3000US = (uint8_t)0x04, //设定CPU Hold Time为3MS
IAP_HOLDTIME_1500US = (uint8_t)0x08 //设定CPU Hold Time为1.5MS
} IAP_HoldTime_TypeDef;
void IAP_DeInit(void);
void IAP_SetHoldTime(IAP_HoldTime_TypeDef IAP_HoldTime);
void IAP_ProgramByte(uint16_t Address,uint8_t Data,IAP_MemType_TypeDef IAP_MemType,uint8_t WriteTimeLimit);
uint8_t IAP_ReadByte(uint16_t Address,IAP_MemType_TypeDef IAP_MemType);
#endif
#include "sc92f8003_option.h"
/*****************************************************
*函数名称:void OPTION_WDT_Cmd(FunctionalState NewState)
*函数功能:WDT功能开关函数
*入口参数:FunctionalState NewState 功能启动/关闭选择
*出口参数:void
*****************************************************/
void OPTION_WDT_Cmd(FunctionalState NewState)
{
OPINX = 0XC1;
if(NewState == DISABLE)
{
OPREG &= 0X7F;
}
else
{
OPREG |= 0X80;
}
}
/*****************************************************
*函数名称:void OPTION_XTIPLL_Cmd(FunctionalState NewState)
*函数功能:外部高频晶振使能
*入口参数:FunctionalState NewState 启动/关闭选择
*出口参数:void
*****************************************************/
void OPTION_XTIPLL_Cmd(FunctionalState NewState)
{
OPINX = 0XC1;
if(NewState == DISABLE)
{
OPREG &= 0XBF;
}
else
{
OPREG |= 0X40;
}
}
/*****************************************************
*函数名称:void OPTION_XTIPLL_SetRange(XTIPLL_Range_TypeDef XTIPLL_Range)
*函数功能:外部高频晶振频率范围
*入口参数:XTIPLL_Range 外部晶振频率选择
*出口参数:void
*****************************************************/
void OPTION_XTIPLL_SetRange(XTIPLL_Range_TypeDef XTIPLL_Range)
{
OPINX = 0XC2;
OPREG = OPREG & 0XBF | XTIPLL_Range;
}
/*****************************************************
*函数名称:void OPTION_SYSCLK_Init(SYSCLK_PresSel_TypeDef SYSCLK_PresSel)
*函数功能:系统时钟分频初始化
*入口参数:SYSCLK_PresSel 选择系统时钟分频
*出口参数:void
*****************************************************/
void OPTION_SYSCLK_Init(SYSCLK_PresSel_TypeDef SYSCLK_PresSel)
{
OPINX = 0XC1;
OPREG = OPREG & 0XCF | SYSCLK_PresSel;
}
/*****************************************************
*函数名称:void OPTION_RST_PIN_Cmd(FunctionalState NewState)
*函数功能:外部复位管脚(P17)使能
*入口参数:FunctionalState NewState 使能/关闭选择
*出口参数:void
*****************************************************/
void OPTION_RST_PIN_Cmd(FunctionalState NewState)
{
OPINX = 0XC1;
if(NewState == DISABLE)
{
OPREG |= 0X08;
}
else
{
OPREG &= 0XF7;
}
}
/*****************************************************
*函数名称:void OPTION_LVR_Init(LVR_Config_TypeDef LVR_Config)
*函数功能:LVR 电压选择
*入口参数:LVR_Config 选择LVR电压
*出口参数:void
*****************************************************/
void OPTION_LVR_Init(LVR_Config_TypeDef LVR_Config)
{
OPINX = 0XC1;
OPREG = OPREG & 0XF8 | LVR_Config;
}
/*****************************************************
*函数名称:void OPTION_ADC_VrefConfig(ADC_Vref_TypeDef ADC_Vref)
*函数功能:ADC 参考电压选择
*入口参数:ADC_Vref 选择ADC参考电压
*出口参数:void
*****************************************************/
void OPTION_ADC_VrefConfig(ADC_Vref_TypeDef ADC_Vref)
{
OPINX = 0xC2;
OPREG = OPREG & 0X7F | ADC_Vref;
}
/**************************************************
*函数名称:void OPTION_IAP_SetOperateRange(IAP_OperateRange_TypeDef IAP_OperateRange)
*函数功能:允许IAP操作的范围设置
*入口参数:IAP_OperateRange IAP操作范围
*出口参数:void
**************************************************/
void OPTION_IAP_SetOperateRange(IAP_OperateRange_TypeDef IAP_OperateRange)
{
OPINX = 0xC2;
OPREG = (OPREG & 0xF3) | IAP_OperateRange;
}
#ifndef _SC92F8003_OPTION_H_
#define _SC92F8003_OPTION_H_
#include "sc92f8003.h"
typedef enum {
SYSCLK_PRESSEL_FOSC_D1 = (uint8_t)0x00, //预分频 Fsys = Fosc/1
SYSCLK_PRESSEL_FOSC_D2 = (uint8_t)0x10, //预分频 Fsys = Fosc/2
SYSCLK_PRESSEL_FOSC_D4 = (uint8_t)0x20, //预分频 Fsys = Fosc/4
SYSCLK_PRESSEL_FOSC_D12 = (uint8_t)0x30 //预分频 Fsys = Fosc/12
} SYSCLK_PresSel_TypeDef;
typedef enum {
LVR_INVALID = (uint8_t)0x04, //LVR无效
LVR_2_3V = (uint8_t)0x00, //LVR 2.3V复位
LVR_2_9V = (uint8_t)0x01, //LVR 2.9V复位
LVR_3_7V = (uint8_t)0x02, //LVR 3.7V复位
LVR_4_3V = (uint8_t)0x03 //LVR 4.3V复位
} LVR_Config_TypeDef;
typedef enum {
IAP_OPERATERANGE_ONLY_EEPROM = (uint8_t)0x00, //只允许EEPROM进行IAP操作
IAP_OPERATERANGE__LAST_0_5K_CODEREGION = (uint8_t)0x04, //允许ROM最后0.5k和EEPROM进行IAP操作
IAP_OPERATERANGE__LAST_1K_CODEREGION = (uint8_t)0x08, //允许ROM最后1k和EEPROM进行IAP操作
IAP_OPERATERANGE__ALL_CODEREGION = (uint8_t)0x0c //允许ROM和EEPROM所有区域进行IAP操作
} IAP_OperateRange_TypeDef;
typedef enum {
XTIPLL_HIGHER_THAN_12M = (uint8_t)0x40, //外接晶振振荡频率大于等于12M
XTIPLL_UNDER_12M = (uint8_t)0x00 //外接晶振振荡频率小于12M
} XTIPLL_Range_TypeDef;
typedef enum {
ADC_VREF_VDD = 0x00, //选择VDD做ADC参考电压
ADC_VREF_2_4V = 0x80 //选择内部2.4V做ADC参考电压
} ADC_Vref_TypeDef;
void OPTION_WDT_Cmd(FunctionalState NewState);
void OPTION_XTIPLL_Cmd(FunctionalState NewState);
void OPTION_XTIPLL_SetRange(XTIPLL_Range_TypeDef XTIPLL_Range);
void OPTION_SYSCLK_Init(SYSCLK_PresSel_TypeDef SYSCLK_PresSel);
void OPTION_RST_PIN_Cmd(FunctionalState NewState);
void OPTION_LVR_Init(LVR_Config_TypeDef LVR_Config);
void OPTION_ADC_VrefConfig(ADC_Vref_TypeDef ADC_Vref);
void OPTION_IAP_SetOperateRange(IAP_OperateRange_TypeDef IAP_OperateRange);
#endif