#define EEPMASS2 0x56 //密码钥匙2
#define EEPADDR 0x4000 //eep地址起始
void eeprom_read(U16 u16Addr, U8 *pdatas, U8 len)
{
U8 *eep=(U8 *)u16Addr
U8 j
for(j=0j<lenj++)
{
pdatas[j]=eep[j]
}
}
void eep_word_write(U16 u16Addr, U8 *pdatas, U8 len)
{
U8 *eep=(U8*)u16Addr
U8 j
FLASH_DUKR=EEPMASS1 //锁埋饥铅1密钥
FLASH_DUKR=EEPMASS2 //锁2密钥
while(!(FLASH_IAPSR&0x08))//等待解密就绪
DISABLE_MAC_INTERRUPTS()
FLASH_CR2 |= 0x40//
FLASH_NCR2 &= ~0x40 //设置字弯好编程
for(j=0j<lenj++)
{
eep[j] = pdatas[j]
}
while(!(FLASH_IAPSR&0x04))
FLASH_IAPSR &=0xf7 // off the eeprom program
ENABLE_MAC_INTERRUPTS()
}
很多工艺过程需要对一些变量做长久保存。比如某些控制参数,在程序运行过程中可能会被修改,在改变后必须再一次永久保存以防掉电丢失。自然,这些参数不能由数据块或初始化予以预置。因此,S7-200提供了将数据写入EEPROM的功能。由于写EEPROM是在每个扫描周期的尾部执行的,我的理解是一次扫描只能写一个数据。这就带来一个问题,如果有多个数据需改森埋要同时写入这么办?按照手册上提供的方法,重复多写几个Network、多用几个使能标识位可以吗?这样简单的重复显然会有问题:由于使用上升沿触发写EEPROM程序,完成了第一个写入后程序将进入下一个扫描周期,尽管SM31.7已经被释放,但后几个使能位的上升沿已经不存在了;因此还是只能写一个数据。 为了保证所有数据都能写入EEPROM,我对手册上的范例做了一些改动,相关程序请看附件。详细说明如下: 1、为了将多个数据写入EEPROM,就必须用多个扫描周期,而且保证每个扫描周期依次写入一个数据,直到全部写完。这样,每个数据写入的使能标识位在数据尚未写入时必须处在使能状态。而在写入完成后必须退出使能状态。 2、由于写入程序的触发还有一个SM31.7作为判断条件,按照程序的时序关系,前一个写入程序被使能后,后面的写入程序核蚂必然会被屏蔽,因此无需担心写入条件发生改变。 3、在数据写入被使能后及时退出本数据的写入使能,避免下一个扫描周期被再次触发。同时释放写入请求以使下一个数据的写入请求能被响应。 4、一般来说,写EEPROM不是一件经常发生的事件,因此不必担心两个相邻扫描周期内同一个写入使能位被再次触发。除非程序本身的编写有误。 5、实例程序中用M0.0使能VD100的写入,用M0.1使能VD104的写入,M0.2同时使能上述两个标识位(也可以在监控状态下单独使能某个位)。这里我们讨论两个标识位同时被使能的情况。 6、M0.0置位后,SM31.7=0,执行VD100的写入程序;然后置位SM31.7,并立即复位M0.0。由于SM31.7被置位,即使M0.1也处于被使能状态,在本次扫描周期内VD104的写入请求被忽略,而M0.1还保持使能状态。 7、在下一个扫描周期内,由于M0.0已经退出使能状态,因此VD104的写入请求将被响应。与M0.0一样,写入请求被响应后M0.1也立即退出使能状态。 8、这样,在两个扫描周期内两个数据被写入EEPROM。如果有更多的数据需要保存,可以以此类推。 9、检验本程序的方法:在系统块中将V寄存器的掉电保持全部取消,可以看到重新上电后前一次写入V寄存器的数据会丢失。此时用本程序保存VD100和VD104,重新上电后可以看到这两个寄存器内的数据依然存在。 10、两个被写入的寄存器地址可以随意改变,无所谓是否连续。 这个程序是我自己琢磨出来的,贴出来供大伙儿拍拍砖。 西门子官方网站提供了一个免费的库程序,可以一次写入多个数春运据。网址是 “ http://support.automation.siemens.com/CN/llisapi.dll/17471561?func=ll&objId=17471561&objAction=csView&nodeid0=10805150&lang=zh&siteid=cseus&aktprim=0&extranet=standard&viewreg=CN&load=content ”。void EEPROM_erasure(UINT16 number) //清除 *** 作函数{
UINT16 *erase
//erase = (unsigned char*)(0x400+number)
erase = (UINT16*)(number)
*erase = 0xff
DisableInterrupts
while(!(ECLKDIV & 0x80))
{}
while(!(ESTAT & 0x80))
{}
while(!(EPROT & 0x80))
{}
ECMD = 0x40
ESTAT |= 0x80
while(!(ESTAT & 0x40))
{}
EnableInterrupts
}
void EEPROM_write(UINT16 code,UINT16 number) //写 *** 作
{
纯销
UINT16 *eeaddr //对EEPROM进行写 *** 作时的地址
/*
allow_calibration = 0
calibration = 1
*/
DisableInterrupts
eeaddr = (UINT16*)(number)
while(!(ECLKDIV & 0x80)) 烂物 //判断ECLKDIV是否被写入,是向下进行,否原地等待?
{}
while(!(ESTAT & 0x80)) //判断缓冲区是否准备好,准备好则饥裤液向下进行,没有准备好则原地等待?
{}
while(!(EPROT & 0x80)) //判断EEPROM是否允许被写入,允许向下进行,不允许则原地等待?
{}
*eeaddr= code
ECMD = 0x20
ESTAT |= 0x80
while(!(ESTAT & 0x40)) //判断EEPROM是否被写入,是向下进行,否原地等待;
{}
EnableInterrupts
return
}
*/
UINT16 EEPROM_read(UINT16 add) //读 *** 作
{
UINT16 *erase
UINT16 m
calibration = 0
DisableInterrupts
erase = (UINT16*)(add)
m = *erase
EnableInterrupts
return m
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)