⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flashprg.c

📁 以前做的一个仿PLC程序
💻 C
字号:
/***********************************************************************/
/*  This file is part of the uVision/ARM development tools             */
/*  Copyright (c) 2003-2009 Keil Software. All rights reserved.        */
/***********************************************************************/
/*                                                                     */
/*  FlashDev.C:  Flash Programming Functions adapted for               */
/*               NXP LPC11xx/13xx/LPC17xx Flash using IAP              */
/*                                                                     */
/***********************************************************************/

#include "FlashOS.H"        // FlashOS Structures
#include "..\Drive\PLC_PUBLIC.H"
extern void PLL0_INIT(void);
// Memory Mapping Control(存储器映射控制)
#define MEMMAP     (*((volatile unsigned char *) 0x400FC040))
// Phase Locked Loop (Main PLL)
#define PLL0CON    (*((volatile unsigned char *) 0x400FC080))
#define PLL0CFG    (*((volatile unsigned long *) 0x400FC084))
#define PLL0STAT   (*((volatile unsigned long *) 0x400FC088))
#define PLL0FEED   (*((volatile unsigned char *) 0x400FC08C))

#define END_SECTOR     29

unsigned long CCLK;            // CCLK in kHz

struct sIAP {                  // IAP Structure
  unsigned long cmd;           // Command
  unsigned long par[4];        // Parameters
  unsigned long stat;          // Status
  unsigned long res[2];        // Result
} IAP;


/* IAP Call */
typedef void (*IAP_Entry) (unsigned long *cmd, unsigned long *stat);
#define IAP_Call ((IAP_Entry) 0x1FFF1FF1)


/*
 * Get Sector Number  获取扇区编号
 *    Parameter:      adr:  Sector Address
 *    Return Value:   Sector Number
 */

unsigned long GetSecNum (unsigned long adr) {
  unsigned long n;

  n = adr >> 12;                               //  4kB Sector
  if (n >= 0x10) {
    n = 0x0E + (n >> 3);                       // 32kB Sector
  }

  return (n);                                  // Sector Number
}


/*
 *  Initialize Flash Programming Functions(初始化Flash编程功能)
 *    Parameter:      adr:  Device Base Address(地址:设备基址)
 *                    clk:  Clock Frequency (Hz)(时钟频率(Hz))
 *                    fnc:  Function Code (1 - Erase, 2 - Program, 3 - Verify)
 *    Return Value:   0 - OK,  1 - Failed
 */

int init (void)//int Init (unsigned long adr, unsigned long clk, unsigned long fnc) {
{ CCLK     = 4000;                             // 4MHz Internal RC Oscillator
  PLL0CON  = 0x00;                             // Disable PLL (use Oscillator)
  PLL0FEED = 0xAA;                             // Feed Sequence Part #1
  PLL0FEED = 0x55;                             // Feed Sequence Part #2
  MEMMAP   = 0x01;                             // User Flash Mode
  return (0);
}

/*
 *  Erase Sector in Flash Memory
 *    Parameter:      adr:  Sector Address
 *    Return Value:   0 - OK,  1 - Failed
 */
//擦除扇区
int EraseSector (unsigned long adr) {
  unsigned long n;

  n = GetSecNum(adr);                          // Get Sector Number

  IAP.cmd    = 50;                             // Prepare Sector for Erase
  IAP.par[0] = n;                              // Start Sector
  IAP.par[1] = n;                              // End Sector
  IAP_Call (&IAP.cmd, &IAP.stat);              // Call IAP Command
  if (IAP.stat) return (1);                    // Command Failed

  IAP.cmd    = 52;                             // Erase Sector
  IAP.par[0] = n;                              // Start Sector
  IAP.par[1] = n;                              // End Sector
  IAP.par[2] = CCLK;                           // CCLK in kHz
  IAP_Call (&IAP.cmd, &IAP.stat);              // Call IAP Command
  if (IAP.stat) return (1);                    // Command Failed

  return (0);                                  // Finished without Errors
}


int ProgramPage2 (unsigned long adr, unsigned long sz, unsigned long buf) {
  unsigned long n;

  n = GetSecNum(adr);                          // Get Sector Number

  IAP.cmd    = 50;                             // Prepare Sector for Write
  IAP.par[0] = n;                              // Start Sector
  IAP.par[1] = n;                              // End Sector
  IAP_Call (&IAP.cmd, &IAP.stat);              // Call IAP Command
  if (IAP.stat) return (1);                    // Command Failed

  IAP.cmd    = 51;                             // Copy RAM to Flash
  IAP.par[0] = adr;                            // Destination Flash Address
  IAP.par[1] = (unsigned long)buf;             // Source RAM Address
  IAP.par[2] = 4096;                           // Fixed Page Size
  IAP.par[3] = CCLK;                           // CCLK in kHz
  IAP_Call (&IAP.cmd, &IAP.stat);              // Call IAP Command
  if (IAP.stat) return (1);                    // Command Failed
  return (0);                                  // Finished without Errors
}

/*
 *  Program iap
 *   
 *   
 *   
 *    Return Value:   0 - OK,  1 - Failed
 */

void Plc_Program_iap(void) {
 disable_timer(0);
 init();//设置IAP时钟
 EraseSector(0x00040000);
 ProgramPage2(0x00040000,0x00040FFF,PLC_PROG_B_START_ADD);
 ProgramPage2(0x00041000,0x00041FFF,PLC_PROG_B_START_ADD+0x1000);
 ProgramPage2(0x00042000,0x00042FFF,PLC_PROG_B_START_ADD+0x2000);
 ProgramPage2(0x00043000,0x00043FFF,PLC_PROG_B_START_ADD+0x3000);
 PLL0_INIT();
 enable_timer(0);
}

void Plc_Data_Bod_iap(void) {
 init();//设置IAP时钟
 EraseSector(0x00050000);
 ProgramPage2(0x00050000,0x00050FFF,PLC_R_START_ADD);
 ProgramPage2(0x00051000,0x00051FFF,PLC_R_START_ADD+0x1000);
 ProgramPage2(0x00052000,0x00052FFF,PLC_R_START_ADD+0x2000);
 ProgramPage2(0x00053000,0x00053FFF,PLC_R_START_ADD+0x3000);
 ProgramPage2(0x00054000,0x00054FFF,PLC_R_START_ADD+0x4000);
 PLL0_INIT();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -