循环直接跳过,貌似溢出了,但是我用的是32bit类型啊!

2009年07月15日 16:50    发布者:wangkj
#define     WIDTH       1024
#define     HIGH        768

void clr_scr(void)
{
   unsigned long int i;
   for (i=0;i<(unsigned long int)(WIDTH*HIGH*8*2);i++)
   {
         MOSI=0;
      SPCK=1;
      SPCK=0;
   }
}

循环直接跳过,貌似溢出了,但是我用的是32bit类型啊!
该文章有附件资料,如需下载请访问 电脑版

网友评论

wangkj 2009年07月15日
难道每个数字后面都跟个L?但是,非32bit类型咋办?
定义两个?
宇宙飞船 2009年07月15日
可用sizeof ( unsigned long int) 测试编译器对unsigned long int支持的长度。
wangkj 2009年07月15日
这个倒是没问题,应该是32bit的。
wangkj 2009年07月15日
(WIDTH*HIGH*8*2) 强制成32bit才是关键。
宇宙飞船 2009年07月15日
老王别教坏小朋友了。
wangkj 2009年07月15日
版主跑哪里去了,香肠呢?这都是51高手啊。
wangkj 2009年07月15日
程序源码
wangkj 2009年07月15日
昨天是 for(i=0;i<97;i++) for(j<0;j<255;j++) for(k<0;k<255;k++) 这样清屏的
这样速度最快!
但是,最开始用的就是32bit int,是正常的。
这个俺想不起来咋办了。

难道都需要增加  L  标志符?

模拟执行,鼠标右键,选择显示汇编代码。
Netjob 2009年07月15日
哈哈,估计楼主用ADS吧?  ADS有这个稀里糊涂的毛病。
wangkj 2009年07月15日
addr的值是0!!!!
wangkj 2009年07月15日
不用宏,照样!
Netjob 2009年07月15日
帮楼主在 ADS1.2 下 软件仿真,没问题。 图:
wangkj 2009年07月15日
俺这个是keil c,51的软件。
你用arm的系统,纯32位的,当然没问题了。

或许,换个别的版本的编译器,也没准正常,俺这个是keil c 8.18的。
Netjob 2009年07月15日
这个 摆明就是数据溢出了, 对 数据异常的 判断 编译器都作  FALSE 处理!?
本分书生 2009年07月15日
来顺(31726560) 17:43:38
我想应该是编译是解释的次序问题
来顺(31726560) 17:54:50
已经找到错误了,是宏定义的问题
应该写为#defined WITH 1024L
注意L必须加
来顺(31726560) 17:55:30
应为keil是先算1024*768*8*2,然后才转换为long,所以编译出了问题



问题可以终结了
本分书生 2009年07月15日
也就是说要keil要写成1024L*768L*8*2
phoenixmy 2009年07月15日
学习了

很有价值,顶
wangkj 2009年07月15日
或许,写成8L * 2 * 1024 * 768也没准可以。
wangkj 2009年07月15日
另外,谁有简单的图形测试程序,51下的,给我一份。
类似turbo c的bgi demo就行。或者更简单也好。
例如画线,园,三角方块等等的。
phoenixmy 2009年07月15日
可以多试试

加了L应该就没有问题
wangkj 2009年07月16日
果然可以了,只需要最前面,加上 1L * 就可以!
phoenixmy 2009年07月16日
看来keil会把define中的内容默认为最匹配的数据类型,挺节约的,呵呵
一朝成名 2009年07月16日
看来以后宏定义也要注明类型:lol
太繁琐了~
phoenixmy 2009年07月16日
其实这样做并不是繁琐,呵呵,看来keil还是很聪明的,为了帮助节省资源,会自动选择数据类型,只是用的时候要小心
phoenixmy 2009年07月16日
这几天看了21上单片机版面的置顶贴,讲程序优化的,感觉前人总结的
高内聚,低耦合,模块功能要单纯
真是经典


呵呵,跑题了
一朝成名 2009年07月16日
建议ls读一下《Unix编程艺术》
你就知道那些东西不过尔尔~

做硬件的跟纯做软件的专业水准是比不了的  哈哈~
wangkj 2009年07月16日
有出错了,还是int 32的问题,高16bit丢了!

void cursor(unsigned int x,y)  //设置显存地址 8M 寻址空间。
{
   //int i;
   union
   {
      unsigned long int addr;
          unsigned int addr_HL;
   } addr_union;
   addr_union.addr=1L*y*WIDTH+x;
   EA0=1;//set cmd status
   //addr=272*y+x;
   spi_write16(addr_union.addr_HL);  
   spi_write16(addr_union.addr_HL);  

   EA0=0;//set data status        PutCmd(0);//reset display ram pointer to 0
}
wangkj 2009年07月16日
>>> hex(0x201*1024+0x201)='0x80601'

把0x80丢了!
wangkj 2009年07月16日
结果输出的图。
Netjob 2009年07月16日
应该还是 那类问题吧~?  8位机确实比较费劲~
machunshui 2009年07月16日
这是一个很好讨论,

请问一下wangkj,编译器难道没有警告吗?

要是没有警告的话,

应该就算编译器的BUG了吧?
wangkj 2009年07月16日
51 vga的图片,vga部分的接口引出,可以不用板载的51
wangkj 2009年07月16日
Build target 'Target 1'
compiling serial.c...
compiling vga51.c...
linking...
*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
    SEGMENT: ?PR?GET_CHAR?SERIAL
*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
    SEGMENT: ?CO?SERIAL
*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
    SEGMENT: ?PR?NOP?VGA51
*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
    SEGMENT: ?PR?UDELAY?VGA51
Program Size: data=213.1 xdata=0 code=985
creating hex file from "vga51"...
"vga51" - 0 Error(s), 4 Warning(s).
wangkj 2009年07月16日
这几个警告没用,都是我注释掉的函数。
wangkj 2009年07月16日
keil c51真的很垃圾,int32 不让用,纯粹是想断单片机的后路。
machunshui 2009年07月16日
有没有设置成最严格的警告方式?
machunshui 2009年07月16日
瞎猜的,不知道KEIL有没有这样的设置
wangkj 2009年07月16日
源码在附件中。
wangkj 2009年07月16日
void cursor(unsigned int x,y)  //设置显存地址 8M 寻址空间。
{
   //int i;
   union
   {
      unsigned long int addr;
          unsigned int addr_HL;
   } addr_union;
   addr_union.addr=1L*(long)y*WIDTH+(long)x;
   EA0=1;//set cmd status
   //addr=272*y+x;
   spi_write16(addr_union.addr_HL);  
   spi_write16(addr_union.addr_HL);  

   EA0=0;//set data status        PutCmd(0);//reset display ram pointer to 0
}
wangkj 2009年07月16日
addr_union.addr=1L*(long)y*WIDTH+(long)x;

加上 long 强制转换就能搞定!
wangkj 2009年07月16日
:L keil c 用 long类型得十分注意才行啊。
李冬发 2009年07月20日
右式第一个参数为long型就可以了。
wangkj 2009年07月20日
必须都加long才行。