打印
[STC单片机]

平时分析程序异常,有什么都是用的什么工具?

[复制链接]
982|18
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
linxi6414|  楼主 | 2022-9-9 09:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
写的一个控制主板程序,其中有一个变量,此变量初始化的时候为0,上电后,面板通过485把此变量设置为365,此后一直为365,程序中有其它的变量与它进行比较,可是运行一段时间后此变量居然变了,找遍整个程序,没有发现有任何的程序对它进行更改的,只有进行比较的,想破脑袋也想不出是怎么回事,找了两天都没有找出问题所在,本来之前运行的好好的,由于升级了晶振,升级的程序部分是18B20的部分,由于将晶振由原来的11.0592M升级为22.1184M后,需要对延迟的时间有所调整,因此升级了一下18B20的部分,其它的部分没有动过,不知道怎么回事,居然出现这样诡异的问题,像这样的问题该怎么找出来?
在程序中加入了大量的打印信息,写了一个判断子函数,一但发现此变量改变,立即打印输出,实际使用中,确实是能够监测出来问题,但是却找不到问题是出在哪里。


使用特权

评论回复

相关帖子

沙发
ayb_ice| | 2022-9-9 10:34 | 只看该作者
用代码比较软件比较一下代码,另外有可能是指针乱了

使用特权

评论回复
板凳
linxi6414|  楼主 | 2022-9-9 10:51 | 只看该作者
ayb_ice 发表于 2022-9-9 10:34
用代码比较软件比较一下代码,另外有可能是指针乱了

主板中没有用指针,大部分是逻辑判断,以及模拟量处理,模拟量处理部分有线性拟合计算,整个控制程序中,有485通讯,手动部分,自动部分,模拟量采集,温度传感,无线接收,这些内容,没有用到指针变量,面板里才有指针变量。

使用特权

评论回复
地板
dalarang| | 2022-9-9 10:55 | 只看该作者
不知道STC能不能在线仿真,碰到这种情况我会先进行在线仿真,然后看这个变量所在的内存地址,检查该地址前有哪些变量,代码中检查是否是对前面变量的写入发生了指针溢出。
或者你看一下这个变量被改写后,此地址前面的一些变量是否也被改写了,是的话八成是指针溢出了

使用特权

评论回复
5
ayb_ice| | 2022-9-9 11:15 | 只看该作者
linxi6414 发表于 2022-9-9 10:51
主板中没有用指针,大部分是逻辑判断,以及模拟量处理,模拟量处理部分有线性拟合计算,整个控制程序中, ...

可以先屏蔽部分程序再测试

使用特权

评论回复
6
玄德| | 2022-9-9 12:58 | 只看该作者

这种问题,发现的时候也没法判断原因。

1、可能有数组的指针越界,覆盖了不该去的地方。

2、同样的变量,在不同文件里定义了不同的宽度。


使用特权

评论回复
7
linxi6414|  楼主 | 2022-9-9 13:17 | 只看该作者
玄德 发表于 2022-9-9 12:58
这种问题,发现的时候也没法判断原因。

1、可能有数组的指针越界,覆盖了不该去的地方。

你说的这些问题我之前吃过亏,这次不是这个问题,所有的数据,都有预留,像485的收发缓冲,多预留了2个,ADC数据采样,多预留了5个,并且所有的数据操作,都有最大限制锁定,不可能越界,搞的头很大。整个程序好几千行,能够想到的地方全部加入了串口数据监控,可是依然找不出问题。

使用特权

评论回复
8
STCMCUNT018| | 2022-9-9 13:53 | 只看该作者
dalarang 发表于 2022-9-9 10:55
不知道STC能不能在线仿真,碰到这种情况我会先进行在线仿真,然后看这个变量所在的内存地址,检查该地址前 ...

STC可以仿真的。
打STC销售公司电话  0513-55012928  <9:00-12:00,13:00-17:30,  工作日的 周一到周五,其他时间是休息时间>   
让他们安排销售工程师给你,然后他们 拉技术 组个 QQ 群支持大家,会专人跟踪服务,一般的小问题,STC 销售工程师本群可以直接答复

使用特权

评论回复
9
linxi6414|  楼主 | 2022-9-9 14:13 | 只看该作者
STCMCUNT018 发表于 2022-9-9 13:53
STC可以仿真的。
打STC销售公司电话  0513-55012928     
让他们安排销售工程师给你,然后他们 拉技术 组 ...

玩意如何仿真,在实际运行的时候,需要不停的485通讯,模拟量不停的在变化,有各种动作,有很多的数据是变化的,真不知道怎么仿真。记得上次遇到类似的问题,坛友帮忙找出来了,是因为数组越界,所以后来所有的数据,都处理的特别小心。

使用特权

评论回复
评论
STCMCUNT018 2022-9-9 14:27 回复TA
19952583534 加我 我来两个技术群 支持你 
10
linxi6414|  楼主 | 2022-9-9 14:41 | 只看该作者
感觉找到问题了,可能问题还是出现在数组里,定义了一个ADC采集函数,需要连续采集6个数组的数据,每组最大不超过170个数据,里面定义了一个数据个数i,这个i并没有初始化,虽然限制了这个i的最大值,但是有可能因为这个i的值没有初始化,进入该函数的时候,如果这个值大于170,依然还会采集一次数据,那么这个数据指向的地址肯定是错误的,也许这个地址刚刚好指向了我所监测的这个变量,造成数据错误,准备去更新一下程序试试。

使用特权

评论回复
11
linxi6414|  楼主 | 2022-9-9 14:44 | 只看该作者
void SYS_Read_Elcnt(void)
{       
        unsigned char i;
        unsigned int  xdata a1[172],a2[172],a3[172],a4[172],a5[172],a6[172];
        ADC_CONTR = 0xc0;
        CLK_DIV=0x20;
        TF0 = 0;           //清除TF0标志
        ET0 = 0;       //关闭定时器0中断
    TR0 = 0;       //定时器0关闭计时   
    TH0 = 0x00;    //初始化计时值
        TH0 = 0x70;           //初始化计时值 定时20毫秒@22.1184M外置晶振
        TF0 = 0;           //清除TF0标志   
    ET0 = 1;       //使能定时器0中断
        TR0 = 1;       //定时器0开始计时
        READ_Elcnt_EN=1;//将定时时间到置1
        while(READ_Elcnt_EN)//到达20毫秒后,此变量通过定时器1中断置0,退出采样
        {               
                a1[i]=READ_ADC_Dat(0xc8);//P1.0
                a2[i]=READ_ADC_Dat(0xc9);//P1.1
                a3[i]=READ_ADC_Dat(0xca);//P1.2
                a4[i]=READ_ADC_Dat(0xcb);//P1.3
                a5[i]=READ_ADC_Dat(0xcc);//P1.4
                a6[i]=READ_ADC_Dat(0xcd);//P1.5                                                       
                if(i<169)//22.1184M 时钟,CLK_DIV=0x20;实际每通道采样次数为166次
                {
                        i++;
                }
        }
}
问题程序。

使用特权

评论回复
12
LLGTR| | 2022-9-9 16:08 | 只看该作者
你这种情况很有可能是数组越界修改到了你这个变量。

使用特权

评论回复
13
LLGTR| | 2022-9-9 16:09 | 只看该作者
你可以看一下,你这个变量的地址在哪,然后看一下在这地址附近的变量,怎么查看可以通过.map文件查看。

使用特权

评论回复
14
e_007| | 2022-9-9 17:10 | 只看该作者
本帖最后由 e_007 于 2022-9-9 18:11 编辑

...

使用特权

评论回复
15
guojin0273| | 2022-9-9 21:50 | 只看该作者
i未初始化,这个数组定义成全局吧,防止堆栈不够

使用特权

评论回复
16
linxi6414|  楼主 | 2022-9-9 22:01 | 只看该作者
设备经过几个小时的试用,没有再报错,问题总算解决了。

使用特权

评论回复
17
linxi6414|  楼主 | 2022-9-10 09:37 | 只看该作者
guojin0273 发表于 2022-9-9 21:50
i未初始化,这个数组定义成全局吧,防止堆栈不够

这个函数完整的有很长,贴上来的只是其中的一小段,这6个数组只在这个函数内部操作,没有在函数外部使用,不必要定义成全局的变量。

使用特权

评论回复
18
diweo| | 2022-9-13 14:53 | 只看该作者
局部变量一定要初始化。
全局变量可以不初始化,因为编译器会帮你初始化。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

57

主题

576

帖子

3

粉丝