Lpc1788内置有eeprom
使用代码
#ifndef __E2PRONINCHIP_H_
#define __E2PROMINCHIP_H
#include "common.h"
#include "sys.h"
#include "debugserial.h"
#define EEPROM_CLOCK 375000
void e2prom_init(void);
u8 e2prom_write_8(u8 page,u8 addr,u8 value);
u8 e2prom_write_16(u8 page,u8 addr,u16 value);
u8 e2prom_write_32(u8 page,u8 addr,u32 value);
u8 e2prom_read_8(u8 page,u8 addr,u8* value);
u8 e2prom_read_16(u8 page,u8 addr,u16* value);
u8 e2prom_read_32(u8 page,u8 addr,u32* value);
u8 e2prom_program(u8 page);
u8 e2prom_test(void);
#endif
#include "e2prominchip.h"
//有一些寄存器只能写不能读,用起来的时候要小心& |子类的应用,如果发生总线中断可能是这些因素引起的
//eeprom有一个64的页缓存,写入的时候不需要页地址只需要页偏移地址先写到这个页里面
//然后写入页地址,也缓存直接写入整个页面(应该是匹配 不同 写入)
void e2prom_init(void)
{
u32 val;
LPC_EEPROM->PWRDWN = 0x00;//清除掉电
LPC_EEPROM->CLKDIV = ((u16)(SystemCoreClock/EEPROM_CLOCK))-1;//设置时钟
val = ((((SystemCoreClock / 1000000) * 15) / 1000) + 1);
val |= (((((SystemCoreClock / 1000000) * 55) / 1000) + 1) << 8);//设置等待时间 NS级别
val |= (((((SystemCoreClock / 1000000) * 35) / 1000) + 1) << 16);
LPC_EEPROM->WSTATE = val;
LPC_EEPROM->INT_CLR_STATUS = (1<<26)|(1<<28);//清除中断状态
// LPC_EEPROM->INT_CLR_ENABLE = (1<<26)|(1<<28);//关闭中断
}
static u8 write_8(u8 page,u8 addr,u8 value)
{
u16 dataddr = 0;
if(page>= 64 || addr >= 64)
{
return 1;
}
dataddr = (addr&0x3f);
LPC_EEPROM->ADDR = dataddr;//写入地址
LPC_EEPROM->CMD = 3;//非连续八位写入
LPC_EEPROM->INT_CLR_STATUS = (1<<26)|(1<<28);//清除中断状态
LPC_EEPROM->WDATA = value;
while(!(LPC_EEPROM->INT_STATUS &(1<<26)));//等待写入完成
LPC_EEPROM->INT_CLR_STATUS = (1<<26);//清除
return 0;
}
u8 e2prom_write_8(u8 page,u8 addr,u8 value)
{
if(write_8(page,addr,value))return 1;
return e2prom_program(page);
}
u8 e2prom_write_16(u8 page,u8 addr,u16 value)
{
u8 ret;
ret = write_8(page,addr,(u8)(value>>8));
if(ret)return ret;
ret = write_8(page,addr+1,(u8)value);
if(ret)return ret;
return e2prom_program(page);
}
u8 e2prom_write_32(u8 page,u8 addr,u32 value)
{
u8 ret;
ret = write_8(page,addr,(u8)(value>>24));
if(ret)return ret;
ret = write_8(page,addr+1,(u8)(value>>16));
if(ret)return ret;
ret = write_8(page,addr+2,(u8)(value>>8));
if(ret)return ret;
ret = write_8(page,addr+3,(u8)value);
if(ret)return ret;
return e2prom_program(page);
}
u8 e2prom_read_8(u8 page,u8 addr,u8* value)
{
u16 dataddr = 0;
LPC_EEPROM->INT_CLR_STATUS = (1<<26)|(1<<28);//清除中断状态
if(page>= 64 || addr >= 64)
{
return 1;
}
dataddr = page;
dataddr<<=6;
dataddr |= (addr&0x3f);
LPC_EEPROM->ADDR = dataddr;//写入地址
LPC_EEPROM->CMD = 0;//非连续八位读出
while(!(LPC_EEPROM->INT_STATUS &(1<<26)));//等待读出完成
*value = LPC_EEPROM->RDATA;
LPC_EEPROM->INT_CLR_STATUS = (1<<26);//清除
return 0;
}
u8 e2prom_read_16(u8 page,u8 addr,u16* value)
{
u8 a,b,ret;
ret = e2prom_read_8(page,addr,&a);
if(ret) return ret;
ret = e2prom_read_8(page,addr+1,&b);
if(ret) return ret;
*value = a;
*value<<=8;
*value += b;
return 0;
}
u8 e2prom_read_32(u8 page,u8 addr,u32* value)
{
u8 a,b,c,d,ret;
ret = e2prom_read_8(page,addr,&a);
if(ret) return ret;
ret = e2prom_read_8(page,addr+1,&b);
if(ret) return ret;
ret = e2prom_read_8(page,addr+2,&c);
if(ret) return ret;
ret = e2prom_read_8(page,addr+3,&d);
if(ret) return ret;
*value = a;
*value<<=8;
*value += b;
*value<<=8;
*value += c;
*value<<=8;
*value += d;
return 0;
}
u8 e2prom_program(u8 page)
{
u16 dataddr = 0;
LPC_EEPROM->INT_CLR_STATUS = (1 << 28);//清除编程中断
dataddr = (page&0x1f);
dataddr<<=6;
LPC_EEPROM->ADDR = dataddr;//写入地址
LPC_EEPROM->CMD = 6;//编程指令
while(!(LPC_EEPROM->INT_STATUS &(1<<28)));
return 0;
}
u8 e2prom_test(void)
{
u8 a ,b,c,d;
u32 read;
e2prom_write_32(1,0,0xaabbccdd);
e2prom_read_8(1,0,&a);
e2prom_read_8(1,1,&b);
e2prom_read_8(1,2,&c);
e2prom_read_8(1,3,&d);
printf("read a value is %2x\r\n",a);
printf("read b value is %2x\r\n",b);
printf("read c value is %2x\r\n",c);
printf("read d value is %2x\r\n",d);
e2prom_read_32(1,0,&read);
printf("read 32 value is %8x\r\n",read);
return 0;
}