laoxu 发表于 2016-6-16 14:35

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;
    }
}




Jim12345 发表于 2016-6-16 14:55

楼主,先给你一个非正式程序,读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);
}

Jim12345 发表于 2016-6-16 14:58

注意, KF8F335/312等后缀只有三个字母的请选择   FLASH_OP_VERSION      0

他们在返回值上是不一样的

Jim12345 发表于 2016-6-16 15:05

这个查表可以超过256字。

laoxu 发表于 2016-6-16 16:07

谢谢!

我改了一下,适合我从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);
}

Jim12345 发表于 2016-6-16 17:51

4158对应的 #define FLASH_OP_VERSION      1


不过这种方式只读了8位数据,      
      .db 0x01      //十六进制
      .db 1            //十进制
      .db 2
      .db 3
只能读奇字节或/偶字节?

laoxu 发表于 2016-6-16 18:21

Jim12345 发表于 2016-6-16 17:51
4158对应的 #define FLASH_OP_VERSION      1




是分高低字节读取的,偏移量地址右移一位(/2),再读ROM表,并且偏移量地址为偶数时只读高位,奇数时只读低位。

laoxu 发表于 2016-6-17 08:18

这个程序是利用 地址越界,对 仿 EEPROM(Flash) 的内容读出,实际地址指向 程序 Flash,不知内核是否支持?

特别对那些 片内不带仿 EEPROM(Flash)的单片机,本程序是否也支持?是否存在安全隐患?

laoxu 发表于 2016-6-17 08:24

说实话,没有 2楼的官方的例子,这种程序俺是一辈子都不敢编写的,谁知道是否存在安全隐患?

如没有官方的首肯,这种程序俺不敢用,因为什么时候死机都不知道。

Jim12345 发表于 2016-6-17 11:13

开发人员都有极客精神,我们的ICer也喜欢验证一些特别的东西,{:titter:}一旦成熟,就会开放出来的。

laoxu 发表于 2016-6-17 11:34

Jim12345 发表于 2016-6-17 11:13
开发人员都有极客精神,我们的ICer也喜欢验证一些特别的东西,一旦成熟,就会开放出来的。 ...

俺也喜欢极客精神,玩玩可以,但真的用到产品上,我是 稳定 压倒一切!

希望官方软硬件设计人员能充许沟通,确保硬件内核上能支持该损作,不留后遗症。

Jim12345 发表于 2016-6-17 11:39

这个硬件支持的
页: [1]
查看完整版本: KungFu8单片机 ROM查表 C程序