搜索
bottom↓
回复: 36

PICC,竟然把 if(KeyTime==0) 编译成 RETURN,害我一个下午!把优化登记去掉还是不行!用的

[复制链接]

出0入0汤圆

发表于 2009-2-19 20:21:01 | 显示全部楼层 |阅读模式
169:                                  if(KeyTime==0)
   08E    0008     RETURN
170:                                  {
171:               
172:                                  KeyTask++;
   08F    0AA4     INCF 0x24, F
173:                                  }
174:                                 
175:                                  break;
   090    0008     RETURN

出0入0汤圆

发表于 2009-2-19 20:55:09 | 显示全部楼层
将KeyTime变量声明成volatile的。

出0入0汤圆

发表于 2009-2-19 20:56:56 | 显示全部楼层
将变量KeyTime声明成volatile的。

出0入0汤圆

 楼主| 发表于 2009-2-19 21:39:31 | 显示全部楼层
用了,还是不行,谢谢楼上的!

出0入0汤圆

发表于 2009-2-19 23:15:53 | 显示全部楼层
感觉PICC还是可以的啊!怎么会出这问题!?

出0入21汤圆

发表于 2009-2-20 01:04:21 | 显示全部楼层
我也用的是V9.60不会呀。把==0去掉试试,直接判断变量。

出0入0汤圆

 楼主| 发表于 2009-2-20 09:40:10 | 显示全部楼层
大家帮帮忙吧,怎么也不行,我都快放弃了!这是源文件!大家看看!不会是程序的问题吧?
点击此处下载 ourdev_420898.rar(文件大小:28K) (原文件名:pickey.rar)

出0入0汤圆

发表于 2009-2-20 10:06:23 | 显示全部楼层
楼主,好像有没指定单片机型号。文件工程打开失败。

出0入0汤圆

发表于 2009-2-20 10:10:38 | 显示全部楼层
看到里面的寄存器,只有PIC12F675相似。你所用的单片机是不是PIC12F675这型号。

出0入0汤圆

发表于 2009-2-20 10:14:22 | 显示全部楼层
;myled.c: 191: case 4:
   368                           ;myled.c: 192: KeyTime--;
   369  0387  03A3                       decf        F240        ;volatile
   370                           ;myled.c: 193: if(KeyTime==0)
   371  0388  0823                       movf        F240,w        ;volatile
   372  0389  1903                       btfsc        3,2
   373                           ;myled.c: 194: {
   374  038A  0AA4                       incf        F241        ;volatile
   375                           ;myled.c: 196: }
   376  038B  0008                       return
   377  038C                     l38

这是我从新编绎后的结果,没有出现楼主所说的问题。看来是你的编绎器的问题。

出0入0汤圆

 楼主| 发表于 2009-2-20 10:32:44 | 显示全部楼层
是675!编译器的问题,怎么办?楼上的用的是什么啊?能不能传一份啊?

出0入0汤圆

 楼主| 发表于 2009-2-20 10:36:40 | 显示全部楼层
ivws,你好,谢谢了!主要看看CASE2的if(KeyTime==0) ,是不是编译了?我怀疑是这样,是不是PICC认为(KeyTime==0)太多,所以不编译啊?

出0入0汤圆

发表于 2009-2-20 11:41:49 | 显示全部楼层
点击此处下载 ourdev_420972.rar(文件大小:28K) (原文件名:pickey.rar)

出0入0汤圆

发表于 2009-2-20 12:56:48 | 显示全部楼层
楼主,你把case 4的语句内容写成如下形式试试:
if( !(--KeyTime) )
{
        KeyTask++;
}
break;

出0入0汤圆

发表于 2009-2-20 13:14:51 | 显示全部楼层
甚至可以写成这样:
if( !(--KeyTime) )KeyTask++;
break;

理想情况下应该可以生成类似如下的汇编指令代码(4 word/5 cycle):
;   if( !(--KeyTime) )KeyTask++;
        DECFSZ  F240,   F
        GOTO    L123
        INCF    F241,   F
;   break;
L123:   RETURN

出0入0汤圆

发表于 2009-2-20 13:28:40 | 显示全部楼层
我想楼主问这个问题的原因肯定不是本身解决不了问题,也许换一种写法可能,问题是就算换种写法能正确,用这么个编译器也是不放心的.一个编译器应该在没有语法错误的情况,不管优不优化最起码应该能编译出完整且正确的代码.
    附:我以前用PICC8.05写低档的12位宽度指令的PIC单片机程序,也经常遇到这样的事,最后的结果是干脆不用C了,直接汇编

出0入0汤圆

发表于 2009-2-20 13:43:19 | 显示全部楼层
static  volatile unsigned char  KeyTime,KeyTask;    //定义任务时间参数、任务参数
给KeyTime赋一个值,如:  static  volatile unsigned char  KeyTime = 30;

我估计是因为static类型的变量初始值为0,所以 if(KeyTime==0) 总是true,直接就编译成RETURN了

出0入0汤圆

 楼主| 发表于 2009-2-20 15:29:56 | 显示全部楼层
这样解决了!下面是编译正确的程序。应该是编译器的问题!另外,我这个程序是按键扫描程序,每隔一毫秒调用一次!另外我想加上长按键检测,不知道怎么加!大家帮忙,成功后就是不错的按键扫描程序!
void scankey()
{
  static unsigned char KeyTime,KeyTask;    //定义任务时间参数、任务参数
  static unsigned char keycount;          //按键次数
  
   switch(KeyTask) {
        case 0:     if(KEY==0)
                     {
                    KeyTime=30;    //准备延时
                    KeyTask++;     //准备好下一个任务
                    //key_F=0;
                    }
                    break;
        case 1:    if( !(--KeyTime) )
                     KeyTask++;
                     break;
                  
                   break;
        case 2:    if(KEY==0)
           
                    {
                      keycount++;      //按键使用!
                      display(keycount);                                                        
                     if(keycount==9)
                             {
                         GPIO=0;
                             keycount=0;       
                              }
                  

                      KeyTask++;
                     
                      }
                   else KeyTask=0;   //退出任务
                   break;

         case 3:   //判断按键是否松开
              if(KEY)
              {

               KeyTime=30;
               KeyTask++;

               }
             break;
         case 4: //松开去抖29-30MS
               
                if(--KeyTime==0)
                 {
                   KeyTask++;
                 }
                break;
         case 5: //判断按键是否保持按下
           if(KEY)
              {
                     //可以加上按键抬起的判断 压入按键按下消息
                 KeyTask=0;
               }
           else KeyTask=3;     //继续检查
           break;
                  
            }
   }

出0入0汤圆

发表于 2009-2-20 16:00:02 | 显示全部楼层
大哥按键不应这样写得啊

出0入0汤圆

 楼主| 发表于 2009-2-20 16:07:25 | 显示全部楼层
楼上的,仔细看看,这是状态机。好好借鉴吧!
要不你写个好的!大家都看看!

出0入0汤圆

发表于 2009-2-20 16:49:46 | 显示全部楼层
楼上,你在17楼帖出的代码中,case 1和case 4是否都正常了?

出0入0汤圆

发表于 2009-2-20 16:54:42 | 显示全部楼层
你再把case 1和case 4的语句都改成如下的样子看结果如何:
KeyTime--;
if(KeyTime == 0)
{
        KeyTask++;
}
然后再把它们都改成这样呢:
KeyTime--;
if(0 == KeyTime)
{
        KeyTask++;
}

出0入0汤圆

 楼主| 发表于 2009-2-20 17:06:13 | 显示全部楼层
试了,不行!

出0入0汤圆

发表于 2009-2-20 17:37:38 | 显示全部楼层
是编绎器出的问题,在我的编绎器上得到的是正确的结果。

出0入0汤圆

 楼主| 发表于 2009-2-20 17:53:55 | 显示全部楼层
我两个电脑安装的不同的PICC版本,都是错的了?怪事

出0入0汤圆

发表于 2009-2-20 19:54:35 | 显示全部楼层
楼主改成这样试试:

static  volatile unsigned char  KeyTime = 30;
static  volatile unsigned char  KeyTask;

出0入0汤圆

发表于 2009-2-20 20:20:11 | 显示全部楼层
我用的是CCS-PICC,没有出现过类似的问题。

出0入0汤圆

发表于 2009-2-20 22:26:33 | 显示全部楼层
还是用汇编吧!

出0入0汤圆

发表于 2009-2-20 22:26:33 | 显示全部楼层
还是用汇编吧!

出0入0汤圆

发表于 2009-2-20 22:42:13 | 显示全部楼层
PICC有时候会把代码优化到别的地方去,你看看[View]->[Program Memory]的结果对不对
Disassembly Listing 中的汇编代码顺序是乱的

出0入0汤圆

发表于 2009-4-23 11:05:38 | 显示全部楼层
还状态机?还好好借鉴?坛子里不是有好多关于按键的写法吗,再去找找吧

出0入0汤圆

发表于 2009-4-23 11:30:37 | 显示全部楼层
PICC 9.6 如果打开优化,确实是经常出莫名其妙的问题的。我已经被它郁闷过N次了...

建议还是把优化完全关掉吧

出0入0汤圆

发表于 2009-4-25 08:22:40 | 显示全部楼层
状态机是FPGA中经常使用的一种手法,之一种很流行的手法呀。至于C语言里面我感觉写出来也不是不可以,因为这样编写程序非常的清晰,而且每种状态也非常好编写,是一种不错的编程风格。

出0入0汤圆

发表于 2009-8-14 12:42:38 | 显示全部楼层
为什么有的大侠帮忙解决问题的会有如下方式
将 if(KeyTime==0)描述换成其他的描述手段 if(0 == KeyTime)
真的有点搞不懂为什么会有这种想法,你明显的是怀疑PICC的智商嘛!哈哈.......

出0入0汤圆

发表于 2009-8-14 14:25:22 | 显示全部楼层
【33楼】 gaoqiru :
这种描述不是针对PICC,是针对所有的编译器。

如果你少写了一个=号,比如,if(0 = KeyTime),这样编译器会报错,而if(KeyTime=0)不会,最多给你个警告,甚至连警告都没有。

出0入0汤圆

发表于 2009-8-18 10:22:48 | 显示全部楼层
我也被PICC给郁闷了很久,PIC的C语言编译器用起来真的很不爽。

出0入0汤圆

发表于 2009-8-19 16:19:02 | 显示全部楼层
首先声明下 编译器并没有出错

我们看程序要结合上下语句一起来看,现在分两种情况:

第一种:我们结合 KeyTime--; 这个语句来看 编译的结果如下

196:                                KeyTime--;
   091    0BD6     DECFSZ 0x56, F
197:                               if(KeyTime == 0)
   092    0008     RETURN
198:                                {
199:                                  KeyTask++;
   093    0AD3     INCF 0x53, F
200:                                }
201:                               break;
   094    0008     RETURN

    在这里,我们看汇编语句,KeyTime-- 汇编后的语句应该是(DECF 0x56, F),但是这里却是(DECFSZ 0x56, F)。
这是编译器结合后面的语句进行了优化,因为后面紧跟着if(KeyTime == 0).
    现在来解释下:DECFSZ是减1后判断是否为0,如果是则跳过下个语句,如果不是则继续下个语句。当KeyTime减1后,如果为0则跳过了092行的return语句执行093行的语句,如果不为0则执行092行的return返回,这与C语言表达的一样。

第二种情况:我把KeyTime--这语句去掉后,在来看看编译后的结果

196:                    //            KeyTime--;
197:                               if(KeyTime == 0)
   091    08D6     MOVF 0x56, F
   092    1903     BTFSC 0x3, 0x2
198:                                {
199:                                  KeyTask++;
   093    0AD3     INCF 0x53, F
200:                                }
201:                               break;
   094    0008     RETURN
   
    可见if(KeyTime == 0)并没有编译成return

    所以我们看程序要结合上下来看 不能孤立的来对待
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-9 03:55

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表