Freescale 9S12 系列单片机应用笔记(EETS4K模块) 1

EETS4K 模块应用笔记(1

9S12 系列单片机的通常包含4KB EEPROMFreescale EEPROM 模块称之为 EETS4K。实际上,这里所谓的 EEPROM 其实是FLASH,只不过Freescale 特意将这里Flash 的 sector 做的很小(4Bytes),使得用户用起来像是在用 EEPROM

EEPROM 是直接映射到9S12 单片机的地址空间的,如果程序中只是读取 EEPROM 中的内容,而不涉及到对 EEPROM 中数据的修改。那就不需要特殊的编程。就像读取RAM数据那样直接访问就可以了。

只有当需要在程序中更新EEPROM 中内容时,才需要学习下面的内容。

初始化EETS4K

在向EETS4K写入数据或擦除数据前要先配置EETS4K的时钟。EETS4K的时钟频率必须在150KHz——200KHz之间,为此需要配置 ECLKDIV 寄存器。

ECLKDIV 寄存器(EEPROM Clock Divider Register)

Freescale 9S12 系列单片机应用笔记(EETS4K模块) 1_第1张图片

图 1ECLKDIV 寄存器

PRDIV8是预分频位:当PRDIV8=1时输入时钟被预分频为1/8

EDIV5——EDIV8为分频除数寄存器,最多可以产生1/64 的分频比。简单的计算可知,当输入时钟大于12.8MHz 时需要将 PRDIV8 置位。

经过PRDIV8EDIV两级分频最多可将时钟频率分为1/512

擦除和写入和读取

这里不详细介绍每一个寄存器的用法。只对需要注意的地方加以说明。

EETS4K 模块的最小擦除单位是4BytesEETS4K 模块提供了两条相关命令,一条是擦除一个 sector,也就是 字节,并且要求是字节对其的双字。另一条命令擦除全部EEPROM 空间。

每次编程(写入)单位为两个字节。并且这两个字节要是对其字。

EETS4K 模块正在进行擦除或编程操作时是不能同时读取EEPROM中内容的。

有了这些介绍就够了。下面给出一个具体的例子。

 

/*EETS4K.h*/
#ifndef  NVM_H
#define  NVM_H

/*
 *                                       CONSTANTS
 */

#define  NVM_NO_ERR                (1)
#define  NVM_ODD_ACCESS_ERR       (-1)
#define  NVM_ACCESS_ERR           (-2)
#define  NVM_PROTECTION_ERR       (-3)

/*
 *                                           FUNCTION PROTOTYPES
 */

void  EEPROM_Init(unsigned long sysclk);
char  EEPROM_Write_Word(unsigned int address, unsigned int data);
char  EEPROM_Erase_Sector(unsigned int address);
char  EEPROM_Erase_All (void);
unsigned int EEPROM_Read_Word(unsigned int address);

#endif                    /* End of file */
/*EETS4K.C*/
#include <hidef.h>      /* common defines and macros */
#include "derivative.h"      /* derivative-specific definitions */
#include "eets4k.h"


/**  @brief This function initializes the Non Volatile EEPROM control registers 
 *            and must be called before attempting to write or erase an EEPROM sector.
 *  
 *   @para sysclk the CPU clock frequency (SYSCLK) driven by the onboard oscillator or the PLL if enabled.
 */
void  EEPROM_Init (unsigned long sysclk)
{
    unsigned char  eclk_val;
	
	
    if (sysclk >= 12000) {                /* If the SYSCLK is > 12MHz, then set FDIV8 bit */          
        eclk_val  =  (sysclk  / (8*200)) - 1;    /* Compute the correct divider value */
        ECLKDIV  |=   ECLKDIV_PRDIV8_MASK | eclk_val;   /* Write the ECLKDIV register with the correct settings */
    } else {
        eclk_val  =  (sysclk / 200) - 1;         /* Compute the correct divider value */
        ECLKDIV  |=   eclk_val;                  /* Write the ECLKDIV register with the correct settings */
    }

    ESTAT        |=  (ESTAT_PVIOL_MASK | ESTAT_ACCERR_MASK); /* Clear any error flags  */
}

/**  @brief This function writes a 16-bit word to EEPROM
 *   @param  address, the destination EEPROM address to write the data
 *   @param  data,    the data to write to argument address.
 *   @return 
 *               NVM_NO_ERR           - EEPROM Write Success
 *               NVM_ODD_ACCESS_ERR   - EEPROM Write Error, Address not on an even address boundry
 *               NVM_ACCESS_ERR       - EEPROM Write Error, Access Violation
 *               NVM_PROTECTION_ERR   - EEPROM Write Error, Attempted to write a protected sector
 */
char  EEPROM_Write_Word (unsigned int address, unsigned int data)
{
    while (!ESTAT_CBEIF) {    /* Wait for EEPROM access controller to become ready */
        ;
    }
    
    ESTAT = (ESTAT_ACCERR_MASK | ESTAT_PVIOL_MASK); /* Clear existing error flags */
    
    if (address & 0x0001) {
        return (NVM_ODD_ACCESS_ERR);                /* Address is NOT aligned on an even boundry? */
    }
    
    (*(unsigned int *)address) = data;              /* Write the data to the specified address */

    ECMD = ECMD_CMDB5_MASK;	                         /* Store programming command in FCMD */
    ESTAT_CBEIF = 1;                                /* Execute the command */

    if (ESTAT_ACCERR) {                             /* Check if there has been an access error */
        return (NVM_ACCESS_ERR);                    /* Return an Access Error code */
    }
    
    if (ESTAT_PVIOL) {                              /* Check if there has been a protection error  */
        return (NVM_PROTECTION_ERR);                /* Return a Protection Error code */
    }
    
    return (NVM_NO_ERR);                            /* Return No Error */
}

/**  @brief This function erases a 4-byte sector of EEPROM
 *   @param address, the start of the 4-byte sector to address
 *   @return  
 *          NVM_NO_ERR           - EEPROM Write Success
 *          NVM_ODD_ACCESS_ERR   - EEPROM Write Error, Address not on an even address boundry
 *          NVM_ACCESS_ERR       - EEPROM Write Error, Access Violation
 *          NVM_PROTECTION_ERR   - EEPROM Write Error, Attempted to write a protected sector
 */
char  EEPROM_Erase_Sector (unsigned int address)
{
    while (!ESTAT_CBEIF) {                            /* Wait for EEPROM access controller to become ready */
        ;
    }
    
    ESTAT = (ESTAT_ACCERR_MASK | ESTAT_PVIOL_MASK);   /* Clear existing error flags  */
    
    if (address & 0x0001) {
        return (NVM_ODD_ACCESS_ERR);                  /* Address is NOT aligned on an even boundry? */
    }
    
    (*(unsigned int *)address) = 0xFFFF;              /* Write the data to the specified address */

    ECMD = ECMD_CMDB6_MASK;	                          /* Store programming command in FCMD */
    ESTAT_CBEIF = 1;                                  /* Execute the command  */

    if (ESTAT_ACCERR) {                               /* Check if there has been an access error */
        return (NVM_ACCESS_ERR);                      /* Return an Access Error code */
    }
    
    if (ESTAT_PVIOL) {                                /* Check if there has been a protection error */
        return (NVM_PROTECTION_ERR);                  /* Return a Protection Error code */
    }
    
    return (NVM_NO_ERR);                              /* Return No Error */
}
char  EEPROM_Erase_All (void)
{
    while (!ESTAT_CBEIF) {                            /* Wait for EEPROM access controller to become ready */
        ;
    }
    
    ESTAT = (ESTAT_ACCERR_MASK | ESTAT_PVIOL_MASK);   /* Clear existing error flags */
    
    
    (*(unsigned int *)0x0400) = 0xFFFF;               /* Write the data to the specified address */

    ECMD = 0x41;          	                          /* Store programming command in FCMD */
    ESTAT_CBEIF = 1;                                  /* Execute the command  */

    if (ESTAT_ACCERR) {                               /* Check if there has been an access error */
        return (NVM_ACCESS_ERR);                      /* Return an Access Error code */
    }
    
    if (ESTAT_PVIOL) {                                /* Check if there has been a protection error */
        return (NVM_PROTECTION_ERR);                  /* Return a Protection Error code */
    }
    
    return (NVM_NO_ERR);                              /* Return No Error */
}

/** @brief This function reads a 16-bit word from the specified address in EEPROM
 *  @param address, the start of the 16-bit data to read
 *  @return The 16-bit word stored in location 'address'
 */
unsigned int  EEPROM_Read_Word (unsigned int address)
{
    unsigned int  data;
    
    
    while (!ESTAT_CBEIF) {    /* Wait for EEPROM access controller to become ready */
        ;
    }
	
	data = (*(unsigned int *)address); /* Read the data at location 'address'  */
	return (data);  /* Return the data*/
}


 

#include <hidef.h>      /* common defines and macros */
#include "derivative.h"      /* derivative-specific definitions */
#include "sci.h"
#include "eets4k.h"

void main(void) 
{
    unsigned int data;
     EEPROM_Init(16384);
    EnableInterrupts;
    
    EEPROM_Erase_All ();
    EEPROM_Write_Word(0x400, 1234);
    data = EEPROM_Read_Word(0x400);
    for(;;) 
    {
        _FEED_COP(); /* feeds the dog */
    } /* loop forever */
}


 

你可能感兴趣的:(编程,function,command,Access,macros,Constants)