在ZLG的书上有一个LPC2131下的例子,是Thumb指令下的,为什么我放在一个用ARM指令的工程就不能了? 源程序如下 /****************************************Copyright (c)************************************************** ** Guangzou ZLG-MCU Development Co.,LTD. ** graduate school ** http://www.zlgmcu.com ** **--------------File Info------------------------------------------------------------------------------- ** File name: main.c ** Last modified Date: 2004-09-16 ** Last Version: 1.0 ** Descriptions: The main() function example template ** **------------------------------------------------------------------------------------------------------ ** Created by: Chenmingji ** Created date: 2004-09-16 ** Version: 1.0 ** Descriptions: The original version ** **------------------------------------------------------------------------------------------------------ ** Modified by: Chenxibing ** Modified date: 2005-02-16 ** Version: ** Descriptions: ** ******************************************************************************************************* */ #include "config.h"
#define BEEP (1 << 7)
#define IAP_ENTER_ADR 0x7FFFFFF1 // IAP入口地址定义
/* 定义IAP命令字 */ // 命令 参数 #define IAP_SELECTOR 50 // 选择扇区 【起始扇区号、结束扇区号】 #define IAP_RAMTOFLASH 51 // 拷贝数据 【FLASH目标地址、RAM源地址、写入字节数、系统时钟频率】 #define IAP_ERASESECTOR 52 // 擦除扇区 【起始扇区号、结束扇区号、系统时钟频率】 #define IAP_BLANKCHK 53 // 查空扇区 【起始扇区号、结束扇区号】 #define IAP_READPARTID 54 // 读器件ID 【无】 #define IAP_BOOTCODEID 55 // 读Boot版本号 【无】 #define IAP_COMPARE 56 // 比较命令 【Flash起始地址、RAM起始地址、需要比较的字节数】
/* 定义IAP返回状态字 */ #define CMD_SUCCESS 0 #define INVALID_COMMAND 1 #define SRC_ADDR_ERROR 2 #define DST_ADDR_ERROR 3 #define SRC_ADDR_NOT_MAPPED 4 #define DST_ADDR_NOT_MAPPED 5 #define COUNT_ERROR 6 #define INVALID_SECTOR 7 #define SECTOR_NOT_BLANK 8 #define SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION 9 #define COMPARE_ERROR 10 #define BUSY 11
/* 定义CCLK值大小,单位为KHz */ #define IAP_FCCLK 11059
/* 定义函数指针 */ void (*IAP_Entry)(uint32 param_tab[], uint32 result_tab[]);
uint32 paramin[8]; // IAP入口参数缓冲区 uint32 paramout[8]; // IAP出口参数缓冲区
/* ********************************************************************************************************* ** 函数名称:SelSector() ** 函数功能:IAP操作扇区选择,命令代码50。 ** 入口参数:sec1 起始扇区 ** sec2 终止扇区 ** 出口参数:IAP操作状态码 ** IAP返回值(paramout缓冲区) ******************************************************************************************************* */ uint32 SelSector(uint8 sec1, uint8 sec2) { paramin[0] = IAP_SELECTOR; // 设置命令字 paramin[1] = sec1; // 设置参数 paramin[2] = sec2; (*IAP_Entry)(paramin, paramout); // 调用IAP服务程序 return(paramout[0]); // 返回状态码 }
/* ******************************************************************************************************* ** 函数名称:RamToFlash() ** 函数功能:复制RAM的数据到FLASH,命令代码51。 ** 入口参数:dst 目标地址,即FLASH起始地址。以512字节为分界 ** src 源地址,即RAM地址。地址必须字对齐 ** no 复制字节个数,为512/1024/4096/8192 ** 出口参数:IAP操作状态码 ** IAP返回值(paramout缓冲区) ******************************************************************************************************* */ uint32 RamToFlash(uint32 dst, uint32 src, uint32 no) { paramin[0] = IAP_RAMTOFLASH; // 设置命令字 paramin[1] = dst; // 设置参数 paramin[2] = src; paramin[3] = no; paramin[4] = IAP_FCCLK; (*IAP_Entry)(paramin, paramout); // 调用IAP服务程序 return(paramout[0]); // 返回状态码 }
/* ******************************************************************************************************* ** 函数名称:EraseSector() ** 函数功能:扇区擦除,命令代码52。 ** 入口参数:sec1 起始扇区 ** sec2 终止扇区 ** 出口参数:IAP操作状态码 ** IAP返回值(paramout缓冲区) ******************************************************************************************************* */ uint32 EraseSector(uint8 sec1, uint8 sec2) { paramin[0] = IAP_ERASESECTOR; // 设置命令字 paramin[1] = sec1; // 设置参数 paramin[2] = sec2; paramin[3] = IAP_FCCLK; (*IAP_Entry)(paramin, paramout); // 调用IAP服务程序 return(paramout[0]); // 返回状态码 }
/* ******************************************************************************************************* ** 函数名称:BlankCHK() ** 函数功能:扇区查空,命令代码53。 ** 入口参数:sec1 起始扇区 ** sec2 终止扇区 ** 出口参数:IAP操作状态码 ** IAP返回值(paramout缓冲区) ******************************************************************************************************* */ uint32 BlankCHK(uint8 sec1, uint8 sec2) { paramin[0] = IAP_BLANKCHK; // 设置命令字 paramin[1] = sec1; // 设置参数 paramin[2] = sec2; (*IAP_Entry)(paramin, paramout); // 调用IAP服务程序
return(paramout[0]); // 返回状态码 }
/* ******************************************************************************************************* ** 函数名称:ReadParID() ** 函数功能:扇区查空,命令代码53。 ** 入口参数:无 ** 出口参数:IAP操作状态码 ** IAP返回值(paramout缓冲区) ******************************************************************************************************* */ uint32 ReadParID(void) { paramin[0] = IAP_READPARTID; // 设置命令字 (*IAP_Entry)(paramin, paramout); // 调用IAP服务程序
return(paramout[0]); // 返回状态码 }
/* ******************************************************************************************************* ** 函数名称:BootCodeID() ** 函数功能:读取boot代码版本号,命令代码55。 ** 入口参数:无 ** 出口参数:IAP操作状态码 ** IAP返回值(paramout缓冲区) ******************************************************************************************************* */ uint32 BootCodeID(void) { paramin[0] = IAP_BOOTCODEID; // 设置命令字 (*IAP_Entry)(paramin, paramout); // 调用IAP服务程序
return(paramout[0]); // 返回状态码 }
/* ******************************************************************************************************* ** 函数名称:Compare() ** 函数功能:校验数据,命令代码56。 ** 入口参数:dst 目标地址,即RAM/FLASH起始地址。地址必须字对齐 ** src 源地址,即FLASH/RAM地址。地址必须字对齐 ** no 复制字节个数,必须能被4整除 ** 出口参数:IAP操作状态码 ** IAP返回值(paramout缓冲区) ******************************************************************************************************* */ uint32 Compare(uint32 dst, uint32 src, uint32 no) { paramin[0] = IAP_COMPARE; // 设置命令字 paramin[1] = dst; // 设置参数 paramin[2] = src; paramin[3] = no; (*IAP_Entry)(paramin, paramout); // 调用IAP服务程序
return(paramout[0]); // 返回状态码 }
/* ******************************************************************************************************* ** 函数名称:main() ** 函数功能:IAP函数调用,测试 ******************************************************************************************************* */ int main(void) { uint8 err; uint32 i; PINSEL0 = 0x00000000; // 管脚连接GPIO IO0DIR = BEEP; IO0SET = BEEP; IAP_Entry = (void(*)())IAP_ENTER_ADR; // 初始化函数指针IAP_Entry ReadParID(); // 读器件ID BootCodeID(); // 读Boot版本号 SelSector(1,1); // 选择扇区1 EraseSector(1,1); // 擦除扇区1 BlankCHK(1,1) ; // 查空扇区1 SelSector(1,1); // 选择扇区1 RamToFlash(0x00001000, 0x40001000, 256); // 写数据到扇区1 err = Compare(0x00001000, 0x40001000, 256); // 比较数据 if(err == CMD_SUCCESS) { /* 成功,蜂鸣一声 */ IO0CLR = BEEP; for (i=0; i<0x3FFFFF; i++); IO0SET = BEEP; } else { /* 失败,一直蜂鸣 */ IO0CLR = BEEP; } while(1); return(0); }
|