能不能发我完整的工程文件看看?我怀疑是不是跟编译条件有关?
刚才实测了一下, 无论是立即数赋值还是变量赋值,编绎器都自动补全高位,编绎器没有问题。支持gent***的说法,检查其它方面原因
void test_x(void)
{
u8 xdata* pt = 0;
u16 addr =0x0206;
printf("立即\xCA\xFD赋值指针 pt=%lx\r\n",(u32)pt);
pt = (u8 xdata*)addr;
printf("16位变量赋值指针 pt=%lx\r\n",(u32)pt);
}
gentleman 发表于 2024-2-25 08:18
编译环境
xSmall -large
奇怪了,我这边确实不行。用的您的工程文件,一字未改
本帖最后由 programshao 于 2024-2-26 10:08 编辑
tzz1983 发表于 2024-2-26 09:17
刚才实测了一下, 无论是立即数赋值还是变量赋值,编绎器都自动补全高位,编绎器没有问题。支持gent***的 ...
还是有区别的。
在您的测试例程中,pt定义为(u8 xdata *),但我的test(uint8 *pt)函数入口是(uint8 *)。
programshao 发表于 2024-2-26 10:05
还是有区别的。
在您的测试例程中,pt定义为(u8 xdata *),但我的test(uint8 *pt)函数入口是(uint8 *) ...
你用仿真的吧,试试实测,配制一个串口,实读xdata后printf()看结果 本帖最后由 gentleman 于 2024-2-26 18:28 编辑
{:4_167:}第一次编译时是这样定义的
void test(uint8 xdata *pt)
值是正常的
修改后重新编译sram 未断电
还保存的第一次的值
你吧函数参数添加 xdata 限定一下,就没问题了
gentleman 发表于 2024-2-26 14:29
第一次编译时是这样定义的
void test(uint8 xdata *pt)
值是正常的
用xdata限定指针,是可以的。只是这样做就牺牲了灵活性,函数入口只能是xdata了,原本是想通用的(既可以xdata,也可以edata)。
至此应该可以得出结论了:
1、常量赋值指针时编绎自动处理类型,变量不处理。变量赋值指针指向xdata时,(uint8 xdata *)addr并没有指向xdata,仍然指向edata。
可用(uint8 xdata *)0+addr这种方式处理,或者干脆(uint8 *)(0x10000+addr),把地址值调到xdata区;
2、这个问题实际是C251的一个坑,作为使用者只能绕路避让。目前没找到完美填坑的方法。
programshao 发表于 2024-3-1 17:25
用xdata限定指针,是可以的。只是这样做就牺牲了灵活性,函数入口只能是xdata了,原本是想通用的(既可 ...
想灵活 就定义成far 指针啊{:4_165:}
void test(uint8 far *pt)
24位指针
本帖最后由 tzz1983 于 2024-3-5 08:27 编辑
programshao 发表于 2024-3-1 17:25
用xdata限定指针,是可以的。只是这样做就牺牲了灵活性,函数入口只能是xdata了,原本是想通用的(既可 ...
楼主说的是对的,这是个很有意思的事情,貌似 pt = (u8 xdata*)addr 中的强制转换(u8 xdata*)失效了一样{:lol:}
void test_x(void)
{
u8 *pt;
u16 addr =0x0206;
pt = (u8 xdata*)0;
printf("立即\xCA\xFD赋值指针 pt=%lx\r\n",(u32)pt);
pt = (u8 xdata*)addr;
printf("16位变量赋值指针 pt=%lx\r\n",(u32)pt);
}
看运行结果
只能说KEIL C251编译器是不是太多年没有升级了,不过还是挺好用的
不错,学习了
页:
1
[2]