找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 835|回复: 9
收起左侧

51单片机函数结界,一旦进入某函数就会导致其它地方的代码失效

[复制链接]
ID:1078008 发表于 2025-5-5 15:48 | 显示全部楼层 |阅读模式
(我可能发错区了,能不能麻烦管理帮我移到问答区)

最近做项目,遇到了一个非常神奇的事情。ms_up_flag  在定时器中断中每1ms弹出一起,软件置0,然后执行下面的代码。

调式的时候发现,只要if(p1_w_cnt<p1_w_s1_v)这个判断的{}里面有任何内容,那么按键检测函数便会失效。

为了排除其它因素的影响,我重新声明了一个变量xxx,把所有无关代码删掉,这个变量在任何地方都是没有用到的,只在if(p1_w_cnt<p1_w_s1_v)判断内执行一个赋0操作。

现在的情况是,我只要把这一句备注了,按键检测正常,只要这一行不备注,按键检测就无法执行。但xxx=0这句代码和其它任何代码都没有任何关连。

百思不得其解,望各位提供思路、讨论排查原因,感激。

目前已知情况:
单片机没有死机,因为其它程序段的倒数能够正常进行。已测试过keil不同的代码优化级数无解


#define  p1_w_s1_v         p1_w[1]
u16 xdata jg1_cnt=0,p1_w_cnt=0;


void softtimer()
{
        if(ms_up_flag)
        {
                ms_up_flag=0;
               
                if(KV2_cnt_flag|KV4_cnt_flag|KV8_cnt_flag)
                {
                         KV_LP_counter++;
                }
               


                if(mode==m_zl&&gear>0)
                {
                        if(p1_w_cnt<p1_w_s1_v)
                        {
                                        xxx=0;        

}
}
}
回复

使用道具 举报

ID:1109793 发表于 2025-5-5 17:57 | 显示全部楼层
大概是变量地址冲突了吧。
回复

使用道具 举报

ID:1078008 发表于 2025-5-5 18:36 | 显示全部楼层
最新进展,把变量的声明的xdata去掉,程序就恢复正常了。
然后,把删掉的代码加回去,又发现了一个新的问题。

void jg(u16 jgv)
{
                        if(jg1_cnt<jgv)
                        {
                                jg1_cnt++;
                        }
                        else
                        {
                                jg1_cnt=0;
                                W_OP;
                                p1_w_cnt++;
                        }
}


void softtimer()
{
//        u16 i;
        if(ms_up_flag)
        {
                ms_up_flag=0;
               
                if(KV2_cnt_flag|KV4_cnt_flag|KV8_cnt_flag)
                {
                         KV_LP_counter++;
                }
               


                if(mode==m_zl&&gear>0)
                {
                        if(p1_w_cnt<p1_w_s1_v)
                        {
//                                  xxx=0;
//                                i=p1_jg1_v;

                               
                                        if(jg1_cnt<p1_jg1_v)
                                        {
                                                jg1_cnt++;
                                        }
                                        else
                                        {
                                                jg1_cnt=0;
                                                W_OP;
                                                p1_w_cnt++;
                                        }

//                                 jg(p1_jg1_v);

                        } else if(p1_w_cnt<p1_w_s1_v+p1_w_s2_v)
                        {
                                xxx=0;
                                jg(p1_jg2_v);
                        }
                        else
                        {
                                xxx=0;
                                p1_w_cnt=0;
                        }
                }
        }
}


以上代码
//                                 jg(p1_jg1_v);
上述代码这个备注掉的函数,如果引用,程序一样不正常。
如果不引用,直接把这个函数的内容放进来,程序就正常了。

但是可以看以看到,在程序的另一段else if(p1_w_cnt<p1_w_s1_v+p1_w_s2_v)代码里面,是可以正常引用这个函数的,代码可以正常运行。

但是这个函数其实和按键检测也是毫无关系的。

这个到底是keil的代码优化问题,还是有什么规则因为我基础功不够扎实而不知道导致的呢。

往哪个方向查资料学习,来在以后的开发中避免这样的奇怪问题,望各位大佬指教。
回复

使用道具 举报

ID:1078008 发表于 2025-5-5 18:36 | 显示全部楼层
xiaobendan001 发表于 2025-5-5 17:57
大概是变量地址冲突了吧。

谢谢指教。是的,我变量声明中的xdata去掉,程序就正常了。然后又有新的奇怪现象,详见另一条回复。
回复

使用道具 举报

ID:1133081 发表于 2025-5-6 06:15 | 显示全部楼层
wjccui 发表于 2025-5-5 18:36
谢谢指教。是的,我变量声明中的xdata去掉,程序就正常了。然后又有新的奇怪现象,详见另一条回复。

严重怀疑“#define  p1_w_s1_v         p1_w[1]”用法有问题。 p1_w是常量?
回复

使用道具 举报

ID:1109793 发表于 2025-5-6 08:22 | 显示全部楼层
wjccui 发表于 2025-5-5 18:36
谢谢指教。是的,我变量声明中的xdata去掉,程序就正常了。然后又有新的奇怪现象,详见另一条回复。

XDATA不是问题,地址冲突,5楼说的应该有可能
回复

使用道具 举报

ID:378108 发表于 2025-5-6 14:30 | 显示全部楼层
51 默认是不支持代码重入的,就是一个函数,不能保证在中断和非中断都调用的情况下都保证正确
回复

使用道具 举报

ID:192020 发表于 2025-5-6 15:53 | 显示全部楼层
有可能型号选错了,不知道什么单片机,但是之前也遇到过类似的,同一厂家型号不对也可以烧录,但是运行时会奇奇怪怪的
回复

使用道具 举报

ID:584814 发表于 2025-5-7 10:12 | 显示全部楼层
当年在玩编写程序时也遇到过类似问题,最后是在程序中加了个空行解决。
在硬件组装时也遇过类似问题,搞了两星期才解决,解决方法也是无法用科学原理解释但可重复。
所以搞成就行其他依兴趣而为罢。
回复

使用道具 举报

ID:1073939 发表于 2025-5-9 15:07 | 显示全部楼层
查看编译结果很重要:
1 警告不要忽略。
2 51的data用量要小于220,code不要超出芯片实际大小。

楼主做到了这些,就不会有奇怪问题了。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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