中颖MCU专用《FLASH、类EEPROM 读写库》

[复制链接]
8798|40
手机看帖
扫描二维码
随时随地手机跟帖
Cortex-M0|  楼主 | 2011-10-19 06:53 | 显示全部楼层 |阅读模式
一、简介
自从上次编写了中颖单片机C51定点库、浮点库专用运算库函数,再接再励,完善中颖单片机通用库函数,特编写了《中颖FLASH、类EEPROM 专用读写库》,适于于中颖SH79/88/89系列对片内FLASH、类EEPROM 的读出和写入,完善对中颖单片机的技术支持。


二、中颖FLASH、类EEPROM 专用读写库 清单

/***************************************************************************************
Model  : flash-sh88f51.h
Description : Head file of defining global variable.
Author  : CLR
Create Time : 2011-10-19
Version ID  : 1.5
用  途      :中颖SH79/88/89F51系列MCU
作  者      :许意义
21ic  ID    :LAOXU
中颖论坛    : bbs.21ic.com   
****************************************************************************************/

#ifndef  _FLASH_SH88F51_H
#define  _FLASH_SH88F51_H

#pragma  MODDP2     // 打开中颖单片机双DPTR功能,加速数据传送
//#pragma  NOMODDP2    // 关闭中颖单片机双DPTR功能

/*--------------------------------------------------------------------------------------*/
/*      Resource - FLASH_SH88F51.asm            */
/*--------------------------------------------------------------------------------------*/

extern  uint8  read_eeprom_u8 (uint16 u16_addr, uint8 u8_FAC);     // 从指定的eeprom/flash地址中读出char型变量  
extern  uint16 read_eeprom_u16(uint16 u16_addr, uint8 u8_FAC);     // 从指定的eeprom/flash地址中读出int型变量  
extern  uint32 read_eeprom_u32(uint16 u16_addr, uint8 u8_FAC);     // 从指定的eeprom/flash地址中读出long型变量  
extern void read_eeprom_str(uint16 u16_addr, uint8 u8_len, uint8 *u8_data, uint8 u8_FAC); // 从eeprom/flash中读出字符串, 存储在char*指向的RAM中
extern void erase_eeprom(uint8 u8_XPAGE, uint8 u8_FAC);           // 擦除eeprom/flash的指定页
extern bit write_eeprom_u8 (uint8  u8_data,  uint16 u16_addr, uint8 u8_FAC);  // 将char型变量写入指定的eeprom/flash中  
extern bit write_eeprom_u16(uint16 u16_data, uint16 u16_addr, uint8 u8_FAC);  // 将int型变量写入指定的eeprom/flash中
extern  bit write_eeprom_u32(uint32 u32_data, uint16 u16_addr, uint8 u8_FAC);  // 将long型变量写入指定的eeprom/flash中  
extern  bit write_eeprom_str(uint16 u16_addr, uint8 u8_len, uint8 *u8_data, uint8 u8_FAC); // 将char*指向的字符串写入指定的eeprom/flash中  
extern bit  read_eeprom_like(uint8 u8_XPAGE, uint8 u8_len, uint8 *u8_data, uint8 u8_FAC); // 从指定页循环使用的eeprom/flash空间内,读出长度为u8_LEN的字符串  
extern bit write_eeprom_like(uint8 u8_XPAGE, uint8 u8_len, uint8 *u8_data, uint8 u8_FAC); // 从指定页循环使用的eeprom/flash空间内,读出长度为u8_LEN的字符串  
                                                // 入口要求: u8_FAC=1 指定eeprom时,u8_len > 1;u8_FAC=0 指定flash时,u8_len > 4
                                               // 返回:  C=0 --> 读写成功,C=1 --> u8_len长度不符规定或末成功写入

/* 中颖单片机EEPROM或FLASH数据读出/写入库内部调用函数
extern void read_rom_dptr1(int16 u16_DPTR1);        // 从@DPTR1中读出1byte EEPROM或FLASH数据(其FAC位已预设定)送ACC, DPTR1++
extern bit  cmp_eeprom_1(uint8  u8_data);            // 将@DPTR1指定的EEPROM或FLASH中内容读出, 和char型变量相比较,DPTR1++
extern bit  cmp_eeprom_2(uint16 u16_data);           // 将@DPTR1指定的EEPROM或FLASH中内容读出, 和 int型变量相比较,DPTR1++
extern bit  cmp_eeprom_4(uint32 u32_data);           // 将@DPTR1指定的EEPROM或FLASH中内容读出, 和long型变量相比较,DPTR1++
extern void write_rom_dptr1(int8 u8_ACC);          // 将ACC中数据写入@DPTR1指定的EEPROM或FLASH中(其FAC位已预设定),DPTR1++
extern void write_eeprom_1(uint8  u8_data)           // 将char型变量写入指定的eeprom/flash中
extern void write_eeprom_2(uint16 u16_data)          // 将 int型变量写入指定的eeprom/flash中
extern void write_eeprom_4(uint32 u32_data)          // 将long型变量写入指定的eeprom/flash中
extern bit check_eeprom_null(uint8 u8_len);          // 检查当前写入页中,len长度的空间是否为空 null
extern bit locate_eeprom(uint8 u8_eeprom_count_len); // 寻找index当前写入页中,是否有len长度的空间充许写入
*/

#endif


三、便用说明
只需要在编译程序过程中,加入《中颖FLASH、类EEPROM 专用读写库》----FLASH-SH88F51.LIB,其他什么事都不用干!在编译过程中实现自动插入,无缝嵌入。


四、友情提示
本《中颖FLASH、类EEPROM 专用读写库》,仅适用于中颖SH79/88/89系列单片机,其他51单片机并不适用,由于Keil C51不支持中颖51单片机的软件仿真,所以必须要用中颖51单片机的硬件仿真或依靠中颖51单片机的实时运行,读写结果才能正确。
Cortex-M0|  楼主 | 2011-10-19 06:53 | 显示全部楼层
FLASH-SH88F51.rar (5.2 KB)

使用特权

评论回复
neyo.zhong| | 2011-10-19 13:47 | 显示全部楼层
感谢许老兄为客户产品使用和中颖产品推广所做的努力,顶起~~~

使用特权

评论回复
huwr| | 2011-10-20 10:07 | 显示全部楼层
赞楼主一个

使用特权

评论回复
bananarer| | 2011-10-20 10:50 | 显示全部楼层
楼主,不好意思。你的程序我没有空看,但是烧写EEPROM和flash的程序需要加上抗干扰措施,否则很有可能跑飞掉然后误擦除eeprom和FLASH,所以说,这个库要谨慎使用,谨慎使用!!!!

使用特权

评论回复
huanghuac| | 2011-10-20 17:22 | 显示全部楼层
版主说的我毛骨悚然

使用特权

评论回复
tian111| | 2011-10-20 17:27 | 显示全部楼层
:L

使用特权

评论回复
Cortex-M0|  楼主 | 2011-10-20 19:18 | 显示全部楼层
楼主,不好意思。你的程序我没有空看,但是烧写EEPROM和flash的程序需要加上抗干扰措施,否则很有可能跑飞掉然后误擦除eeprom和FLASH,所以说,这个库要谨慎使用,谨慎使用!!!! ...
bananarer 发表于 2011-10-20 10:50



汗~~~  :L

假如严格按照中颖的技术要求读写FLASH, 类EEPROM,还会跑飞程序,然后误擦除eeprom和FLASH的话,只能说明中颖的芯片太山寨了~~~ :P

附,SSP编程注意事项:
为确保顺利完成SSP编程,用户软件必须按以下步骤设置。
A. 用于代码/数据编程:
1. 关闭中断;
2. 根据地址设置XPAGE、IB_OFFSET;
3. 按编程需要,设置IB_DATA;
4. 按照顺序设置IB_CON1~5;
5. 添加4个NOP指令;
6. 开始编程,CPU将进入IDLE模式;编程完成后自动退出IDLE模式;
7. 如需继续写入数据,跳转至第2步;
8. XPAGE寄存器清0;恢复中断设置。
B. 用于扇区擦除:
1. 关闭中断;
2. 按相应的扇区设置XPAGE;
3. 按照顺序设置IB_CON1~5;
4. 添加4个NOP指令;
5. 开始擦除,CPU将进入IDLE模式;擦除完成后自动退出IDLE模式;
6. 如需继续擦除数据,跳转至第2步;
7. XPAGE寄存器清0;恢复中断设置。
C.读取:
使用“MOVC A, @A+DPTR” 或者 “MOVC A, @A+PC”指令。

使用特权

评论回复
waszhang| | 2011-10-21 10:39 | 显示全部楼层
中颖建议加抗干扰措施,所以,能不能看一下你的部分源码呀,

使用特权

评论回复
bananarer| | 2011-10-21 12:34 | 显示全部楼层
汗~~~  :L

假如严格按照中颖的技术要求读写FLASH, 类EEPROM,还会跑飞程序,然后误擦除eeprom和FLASH的话,只能说明中颖的芯片太山寨了~~~ :P

附,SSP编程注意事项:
为确保顺利完成SSP编程,用户软件必须按 ...
Cortex-M0 发表于 2011-10-20 19:18

楼主的热情我很赞赏,但是spec上面的只是编程步骤,如果在强干扰情况下,PC指针跑飞掉,跑到烧写程序,但是没有做一些抗干扰措施,很有可能乱写的。
可以参考置顶的我的帖子,加上抗干扰措施会更好。

https://bbs.21ic.com/icview-245944-1-1.html

使用特权

评论回复
Cortex-M0|  楼主 | 2011-10-21 14:30 | 显示全部楼层
官方建议加抗干扰措施:
FLASH/类EEPROM 烧写/擦除的超级抗干扰措施
1)  在程序下载时,选择中代码选项中的“Enable LVR function”。
2)  上述程序示例中的步骤2 中,对XPAGE 写立即数。
3)  在调用烧写或擦除函数前,置一个标志,比如0EBH;在烧写或擦除函数中判断此
标志是否为0EBH,否则清零此标志,退出函数。示例如下:
… …
MOV      FlashFlag,#0EBH
LCALL   EreaseFlash
… …
… …
EreaseFlash:
      MOV      A, FlashFlag
      CJNZ     A,#0EBH, EreaseFlashExit
                     … …
                     … …
EreaseFlashExit:
                     MOV      FlashFlag,#0
                     RET
注意:以上三点非必须执行,可视干扰程度及程序结构等选用,建议“3)”必选。

///////////////////////////////////////////////////////////////////////////////////////////////////

个人意见:
官方的三点建议,除第一第二条俺赞同,第三条俺持保留意见,因为,要加一个全届变量,势必影响程序的可移植性,另外,程序乱写时,那么多RAM, 你设置的一个BYTE参照变量,也不一定会被改写,因此,起的作用极其有限。

在擦除子函数中,加入了必须传送两次PAGE页,以提高抗干扰性,其他的写入程序就不加了,你们自己用,愿意怎么改都行。


下面文件带源程序。

FLASH-SH88F51.rar (62.64 KB)

使用特权

评论回复
Cortex-M0|  楼主 | 2011-10-21 16:05 | 显示全部楼层
头文件清单:

/***************************************************************************************
        Model                : flash-sh88f51.h
        Description        : Head file of defining global variable.
        Author                : CLR
        Create Time        : 2011-10-19
        Version ID  : 1.5

        用  途      :中颖SH79/88/89F51系列MCU
        作  者      :许意义
        21ic  ID    :LAOXU
        中颖论坛    : bbs.21ic.com   
****************************************************************************************/
#ifndef                _FLASH_SH88F51_H
#define                _FLASH_SH88F51_H

#pragma  MODDP2                          // 打开中颖单片机双DPTR功能,加速数据传送
//#pragma  NOMODDP2                  // 关闭中颖单片机双DPTR功能

/*--------------------------------------------------------------------------------------*/
/*                                                Resource - FLASH_SH88F51.asm                                                                        */
/*--------------------------------------------------------------------------------------*/

extern  uint8  read_eeprom_u8 (uint16 u16_addr, uint8 u8_FAC);     // 从指定的eeprom/flash地址中读出char型变量  
extern  uint16 read_eeprom_u16(uint16 u16_addr, uint8 u8_FAC);     // 从指定的eeprom/flash地址中读出int型变量  
extern  uint32 read_eeprom_u32(uint16 u16_addr, uint8 u8_FAC);     // 从指定的eeprom/flash地址中读出long型变量  
extern        bit write_eeprom_u8 (uint8  u8_data,  uint16 u16_addr, uint8 u8_FAC);  // 将char型变量写入指定的eeprom/flash中  
extern        bit write_eeprom_u16(uint16 u16_data, uint16 u16_addr, uint8 u8_FAC);  // 将int型变量写入指定的eeprom/flash中
extern  bit write_eeprom_u32(uint32 u32_data, uint16 u16_addr, uint8 u8_FAC);  // 将long型变量写入指定的eeprom/flash中  
extern  bit write_eeprom_str(uint16 u16_addr, uint8 u8_len, uint8 *u8_data, uint8 u8_FAC); // 将char*指向的字符串写入指定的eeprom/flash中  
extern        void read_eeprom_str(uint16 u16_addr, uint8 u8_len, uint8 *u8_data, uint8 u8_FAC); // 从eeprom/flash中读出字符串, 存储在char*指向的RAM中

/*--------------------------------------------------------------------------------------*/
/*                                        下面为中颖标准型号FLASH(page=1k)读写专用                                                        */
/*--------------------------------------------------------------------------------------*/

extern        void erase_eeprom(uint8 u8_XPAGE, uint8 u8_XPAGE, uint8 u8_FAC);  // 擦除eeprom/flash的指定页,要求page连续送两遍,以提高抗干扰性(注:适用标准型号flash page=1k)

extern        bit  read_eeprom_like(uint8 u8_XPAGE, uint8 u8_len, uint8 *u8_data, uint8 u8_FAC); // 从指定页循环使用的eeprom/flash空间内,读出长度为u8_LEN的字符串  
extern        bit write_eeprom_like(uint8 u8_XPAGE, uint8 u8_len, uint8 *u8_data, uint8 u8_FAC); // 从指定页循环使用的eeprom/flash空间内,读出长度为u8_LEN的字符串  
                                                // 入口要求: u8_FAC=1 指定eeprom时,u8_len > 1;u8_FAC=0 指定flash时,u8_len > 4 (注:适用标准型号flash page=1k)
                                                                                        // 返回:  C=0 --> 读写成功,C=1 --> u8_len长度不符规定或末成功写入

/*--------------------------------------------------------------------------------------*/
/*                                        下面为中颖老型号FLASH(page=2k)读写专用                                                            */
/*--------------------------------------------------------------------------------------*/

extern        void erase_eeprom2(uint8 u8_XPAGE, uint8 u8_XPAGE, uint8 u8_FAC); // 擦除eeprom/flash的指定页,要求page连续送两遍,以提高抗干扰性(注:适用老型号flash page=2k)
extern        bit  read_eeprom_like2(uint8 u8_XPAGE, uint8 u8_len, uint8 *u8_data, uint8 u8_FAC); // 从指定页循环使用的eeprom/flash空间内,读出长度为u8_LEN的字符串  
extern        bit write_eeprom_like2(uint8 u8_XPAGE, uint8 u8_len, uint8 *u8_data, uint8 u8_FAC); // 从指定页循环使用的eeprom/flash空间内,读出长度为u8_LEN的字符串  
                                                // 入口要求: u8_FAC=1 指定eeprom时,u8_len > 1;u8_FAC=0 指定flash时,u8_len > 8 (注:适用老型号flash page=2k)
                                                                                        // 返回:  C=0 --> 读写成功,C=1 --> u8_len长度不符规定或末成功写入

/*        中颖单片机EEPROM或FLASH数据读出/写入库内部调用函数       
extern        void read_rom_dptr1(int16 u16_DPTR1);               // 从@DPTR1中读出1byte EEPROM或FLASH数据(其FAC位已预设定)送ACC, DPTR1++
extern        bit  cmp_eeprom_1(uint8  u8_data);            // 将@DPTR1指定的EEPROM或FLASH中内容读出, 和char型变量相比较,DPTR1++
extern        bit  cmp_eeprom_2(uint16 u16_data);           // 将@DPTR1指定的EEPROM或FLASH中内容读出, 和 int型变量相比较,DPTR1++
extern        bit  cmp_eeprom_4(uint32 u32_data);           // 将@DPTR1指定的EEPROM或FLASH中内容读出, 和long型变量相比较,DPTR1++
extern        void write_rom_dptr1(int8 u8_ACC);                 // 将ACC中数据写入@DPTR1指定的EEPROM或FLASH中(其FAC位已预设定),DPTR1++
extern        void write_eeprom_1(uint8  u8_data)           // 将char型变量写入指定的eeprom/flash中
extern        void write_eeprom_2(uint16 u16_data)          // 将 int型变量写入指定的eeprom/flash中
extern        void write_eeprom_4(uint32 u32_data)          // 将long型变量写入指定的eeprom/flash中
extern        bit check_eeprom_null(uint8 u8_len);          // 检查当前写入页中,len长度的空间是否为空 null
extern        bit locate_eeprom(uint8 u8_eeprom_count_len); // 寻找index当前写入页中,是否有len长度的空间充许写入
*/


#endif

使用特权

评论回复
冰清玉洁| | 2011-10-21 17:00 | 显示全部楼层
哇塞,好详细啊

使用特权

评论回复
lixupengarm| | 2011-11-20 13:59 | 显示全部楼层
谢谢了试试

使用特权

评论回复
hificwc| | 2011-11-29 21:10 | 显示全部楼层
留个脚印

使用特权

评论回复
callhgd| | 2011-12-6 13:09 | 显示全部楼层
也留个脚印,学习了。

使用特权

评论回复
hgnos| | 2011-12-7 15:41 | 显示全部楼层
Mark

使用特权

评论回复
hgnos| | 2011-12-7 16:44 | 显示全部楼层
请教一下LZ 本人刚接触中颖单片机,
对SSP 这个功能不太明白,  一般是什么情况使用,到底有什么作用?

使用特权

评论回复
不光写程序| | 2011-12-7 19:51 | 显示全部楼层
顶!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!:hug:

使用特权

评论回复
autopccopy| | 2011-12-9 23:03 | 显示全部楼层
现在才看到,顶老许!!!:victory:

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:学习chunyang和maychang两位老师,努力练好基本功。 学习HOT大叔,学好“Cortex-M0”,做“Cortex-M0”之菜鸟。

7

主题

4820

帖子

12

粉丝