|
经过几天努力将C51的T9输入法移植到AVR上,C51的源代码:http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=629049&bbs_page_no=1&bbs_id=1000
编译环境avr-gcc-3.4.6
由于AVRGCC与C51在很多方面的差异,T9输入法的移植还是有些难度的,集中表现在如何把拼音索引表完整地存放在flash区,并能正确地检索与读取。
1.GCC访问flash有关内容
头文件:avr/pgmspace.h
数据类型:在基类型冠以“prog_”如char -->prog_char 等等
字符指针:PGM_P(const prog_char *)
空(void)指针:PGM_VOID_P(const prog_void *)指任意类型
数组定义:(常规)类型 数组名[下标常量]PROGMEM 或 (flash)类型 数组名[下标常量]
flash区常量的初始化:
prog_char c='A';
prog_int a=1234;
prog_char str[]="string";
PGM_P pstr;
pstr=PSTR("static strings");//字符串"static strings"在flash区,宏PSTR(获得静态字符串指针)只能在函数中使用。
flash区常量的读取:
读字符:pgm_read_byte(address_short)
读字:pgm_read_word(address_short)
读n个字符/字节:void *memcpy_P(void *, PGM_VOID_P, size_t) //void * 指目的指针(在SRAM)
读字符串:char *strcpy_P(char *, PGM_P)
其他内容参阅pgmspace.h和avr-libc用户手册
2.访问或定义flash区常量应注意的问题
flash区常量是不可见的,不能用常规 的方法来读取/定义,比如:
//拼音索引表结构定义
struct t9PY_index
{
PGM_P t9PY_T9;
PGM_P PY;
PGM_P PY_mb;
};
const prog_char PY_mb_space []PROGMEM={""};
const prog_char PY_mb_a []PROGMEM={"@啊阿"};
...
}
/*"拼音输入法查询码表,T9数字字母索引表(index)"*/
const struct t9PY_index t9PY_index2[]PROGMEM ={
{"","",PY_mb_space},
{"2","a",PY_mb_a},
..
}
结构定义中的所有域都定义成PGM_P,按理拼音输入法查询码表t9PY_index2所有数据都应放在flash区,但事实并不这样,“”、“2”、“a"
却放在.data段(SRAM),不管在字符串常量前加强制类型转换,这是因为GCC把全局或静态常量强制放在.data段(SRAM),解决的方法是
字符串常量换成常量标识符:
const prog_char digits_2[]="2";
..
const prog_char alpha_a[]="a";
..
const struct t9PY_index t9PY_index2[]PROGMEM ={
{PY_mb_space,PY_mb_space,PY_mb_space},
{digits_2,alpha_a,PY_mb_a},
..
}
PGM_VOID_P p_PY_CurrenIndex;//指向拼音输入法查询码表的指针
指向flash 结构指针或结构类型不能用指向符或域引用符获取结构的域成员,如(struct t9PY_index) p_PY_CurrenIndex->t9PY_T9。
正确方法:
struct t9PY_index PY_TempIndex;
char temp_t9PY_T9[8],*str;
memcpy_P(&PY_TempIndex,p_PY_CurrenIndex,sizeof(struct t9PY_index));
strcpy_P(temp_t9PY_T9,PY_TempIndex.t9PY_T9);
str=strstr(temp_t9PY_T9,p_PadInput);
点击此处下载源代码 |
|