KungFu8单片机 ROM查表 C程序
KungFu8是一种功耗极低,高性能单时钟周期的8位单片机,结构简洁,有利于提高代码密度并简化程序设计。
KungFu8 使用 ChipOn-IDE 编译器,但目前编译器只支持通过在RAM中建立表格,当表格略为大一点时,占据过多的RAM空间 以及初始化执行程序空间,因此,想了一个办法,利用嵌入式汇编,搞了一个小程序,把表格建立在ROM中,直接查询ROM中表格数据,大大减少了RAM占用空间。
本程序封装成函数,方便C语言直接调用。
查询最大 256字节的 C程序:
// a为入口参数,范围:0-255, 返回查表值
char table_256(unsigned char a)
{ __asm // 查 256字节表
ADD PCL,R0
.DT '1','2','3',0; // 最大256字节数据
__endasm;
}
如果查询字节数大于256,可自行扩展,下面例举了一个查询 512字节的 C程序:
// a为入口参数,范围:0-511, 返回查表值
char table_512(unsigned int a)
{ if (a>>8)
{ __asm // 查高 256字节表
ADD PCL,R0
.DT 'A','B','C',0; // 高256字节数据
__endasm;
}
else
{ __asm // 查低 256字节表
ADD PCL,R0
.DT '1','2','3',0; // 低256字节数据
__endasm;
}
}
楼主,先给你一个非正式程序,读16位的,请参考
/****************************************************************************************
*
* 文件名: main.c
* 项目名: 20160308
* 版 本: v1.0
* 日 期:
*
****************************************************************************************/
#include<KF8F335.h>
/*
* KF8FXXX 对应 FLASH_OP_VERSION 0
* KF8FXXXX/KF8V/KF8TS/KF8L FLASH_OP_VERSION 1
* KF8S系列请咨询技术支持
*
*
*
*
*
*
* */
#define FLASH_OP_VERSION 0
//数组
void array_0()
{
__asm
.dw 0x0123 //十六进制
.dw 1 //十进制
.dw 2
.dw 3
__endasm;
}
#pragma save
#pragma disable_warning 59
#pragma disable_warning 85
unsigned int readflash(void *p,unsigned int i)
{
__asm
BANKSEL STK00
MOV R0,STK01
MOV R1,STK00
ADD R0,STK03
JNB 0x03, 0
INC R1
ADD R1,STK02
BANKSEL 0x3A
MOV 0x3A, R1
MOV 0x3B, R0
MOV R0,#0x81
MOV 0x3C,R0
NOPZ
NOPZ
NOPZ
NOPZ
#if FLASH_OP_VERSION == 0
BANKSEL STK00
MOV STK00,R6
MOV R0,R7
#elif FLASH_OP_VERSION == 1
BANKSEL 0x39
MOV R0,0x39
BANKSEL STK00
MOV STK00,R0
BANKSEL 0x38
MOV R0,0x38
#else
#error "unknow FLASH_OP_VERSION"
#endif
__endasm;
}
#pragma restore
unsigned int i;
void main()
{
i = readflash(array_0,0);
}
注意, KF8F335/312等后缀只有三个字母的请选择 FLASH_OP_VERSION 0
他们在返回值上是不一样的 这个查表可以超过256字。 谢谢!
我改了一下,适合我从ROM中,读8位的数据
/****************************************************************************************
*
* 文件名: main.c
* 项目名: 20160308
* 版 本: v1.0
* 日 期:
*
****************************************************************************************/
#include<KF8F4158.h>
/*
* KF8FXXX 对应 FLASH_OP_VERSION 0
* KF8FXXXX/KF8V/KF8TS/KF8L FLASH_OP_VERSION 1
* KF8S系列请咨询技术支持
* */
#define FLASH_OP_VERSION 0
//数组
void array_0()
{ __asm
.db 0x01 //十六进制
.db 1 //十进制
.db 2
.db 3
__endasm;
}
#pragma save
#pragma disable_warning 59
#pragma disable_warning 85
unsigned char readflash(void *p,unsigned int i)
{ //*p高8位:STK00 ,*p低8位:STK01
// i高8位:STK02 ,i低8位:STK03
__asm
BANKSEL STK00
MOV R0,STK01
MOV R1,STK00
CLR PSW, 0
RRC STK02
RRC STK03
MOV R7, PSW
ADD R0,STK03
JNB PSW, 0
INC R1
ADD R1,STK02
BANKSEL NVMADDRH
MOV NVMADDRH, R1
MOV NVMADDRL, R0
MOV R1, R7
MOV R0,#0x81// 读BLOCK EEPROM命令
MOV NVMCTL0,R0
NOPZ
NOPZ
NOPZ
NOPZ
#if FLASH_OP_VERSION == 0
MOV R0,R7
JNB R1, 0
MOV R0,R6
#elif FLASH_OP_VERSION == 1
MOV R0,#NVMDATAH
JNB R1, 0
INC R0
LD R0,
#else
#error "unknow FLASH_OP_VERSION"
#endif
__endasm;
}
#pragma restore
unsigned char i;
void main()
{
i = readflash(array_0,0);
}
4158对应的 #define FLASH_OP_VERSION 1
不过这种方式只读了8位数据,
.db 0x01 //十六进制
.db 1 //十进制
.db 2
.db 3
只能读奇字节或/偶字节? Jim12345 发表于 2016-6-16 17:51
4158对应的 #define FLASH_OP_VERSION 1
是分高低字节读取的,偏移量地址右移一位(/2),再读ROM表,并且偏移量地址为偶数时只读高位,奇数时只读低位。 这个程序是利用 地址越界,对 仿 EEPROM(Flash) 的内容读出,实际地址指向 程序 Flash,不知内核是否支持?
特别对那些 片内不带仿 EEPROM(Flash)的单片机,本程序是否也支持?是否存在安全隐患? 说实话,没有 2楼的官方的例子,这种程序俺是一辈子都不敢编写的,谁知道是否存在安全隐患?
如没有官方的首肯,这种程序俺不敢用,因为什么时候死机都不知道。 开发人员都有极客精神,我们的ICer也喜欢验证一些特别的东西,{:titter:}一旦成熟,就会开放出来的。 Jim12345 发表于 2016-6-17 11:13
开发人员都有极客精神,我们的ICer也喜欢验证一些特别的东西,一旦成熟,就会开放出来的。 ...
俺也喜欢极客精神,玩玩可以,但真的用到产品上,我是 稳定 压倒一切!
希望官方软硬件设计人员能充许沟通,确保硬件内核上能支持该损作,不留后遗症。 这个硬件支持的
页:
[1]