打印

KEIL C51中的STARTUP.A51有问题?

[复制链接]
7778|31
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ayongge|  楼主 | 2009-12-9 10:53 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我的一个项目,控制8个小继电器,因为输出是AC220V,怕小继电器带不动又接了8个13型中功率继电器,结果出问题了:
单个继电器吸起没有问题,但当有多个吸起时,死机。更有蹊跷的事:人工复位,一松开复位键马上又死机。
甩开中功率继电器,直接用小继电器控制输出接40W灯泡没有问题,但是接100W灯泡又出现同样的现象,用STC芯片和华邦的52芯片都如此。

相关帖子

沙发
chen3bing| | 2009-12-9 10:57 | 只看该作者
这根STARTUP.A51有什么关系?

使用特权

评论回复
板凳
xwj| | 2009-12-9 10:59 | 只看该作者
和电源、布线很大关系,几句话说不清楚的。

使用特权

评论回复
地板
xwj| | 2009-12-9 11:00 | 只看该作者
真不知道LZ是怎么把这个责任扯到Keil上去的

使用特权

评论回复
5
ayongge|  楼主 | 2009-12-9 11:42 | 只看该作者
本帖最后由 ayongge 于 2009-12-9 14:16 编辑

调试程序:
void main(void)
{
        WDT_CONTR = 0x3c; //片内看门狗
        AUXR = AUXR | 0x01; //禁止ALE信号输出

        serial();
        send_char(‘S’)
        OS_Start( ); //启动调度器(5ms时隙的周期调度器,用T2)
         
        SCH_Go_To_Sleep( ); //休眠
        WorkBegin();//工作变量初始化
        Input_INI();//输入端口初始化
        while(1)
        {
                WDT_CONTR = 0x3c; //喂片内看门狗
                Main_Work( ); //进入用户工作程序

                Send_char(‘W’);//发送字符“W”
                SCH_Go_To_Sleep( ); //休眠
        }
}

正常工作时能接收到:SWWWWWWW……
死机时可以看到:SWWWWW……WWSWSW
死机后再无法接收到任何字符。

while(1)
{
      Main_Work( ); //进入用户工作程序
     WDT_CONTR = 0x3c; //喂片内看门狗
   Send_char(‘W’);//发送字符“W”
   SCH_Go_To_Sleep( ); //休眠
}
结果相同,感觉进入工作程序内死机。
再改:
while(1)
{
     WDT_CONTR = 0x3c; //喂片内看门狗
     Send_char(‘W’);//发送字符“W”
      Main_Work( ); //进入用户工作程序
   SCH_Go_To_Sleep( ); //休眠
}
结果还是一样,最多是最后多接收到1、2个W
=>程序在进入工作程序之前就飞掉了?
"S"不再收到,说明在初始化串口之前程序就飞了。

使用特权

评论回复
6
原野之狼| | 2009-12-9 11:45 | 只看该作者
这是个问题

使用特权

评论回复
7
jerkoh| | 2009-12-9 12:22 | 只看该作者
题目和问题关系?

使用特权

评论回复
8
ayongge|  楼主 | 2009-12-9 14:55 | 只看该作者
本帖最后由 ayongge 于 2009-12-9 14:56 编辑

KEIL单步调试,发现从0000H进入STARTUP.A51部分后,看到的代码是
MOV R0,#0x7F
CLR A
MOV @R0,A
DJNZ R0,C:09C4
MOV  SP,#0x80
LJMP C:0A08
LJMP main
……
但是向下翻页,却没有发现在0A08处的指令,看见的是如下的2条指令:
0x0A07 8090   SJMP C:0999
0x0A09 0D     INC R5
但单步调试却可以到达0A08,指令改变为:
0x0A07 8090   SJMP C:0999
0x0A08 900D62 MOV DPTR,#0x0D62
为什么会这样?
难道这段程序有可能造成进入死循环的代码?

使用特权

评论回复
9
ayongge|  楼主 | 2009-12-9 14:57 | 只看该作者
注:我用的KEIL是V3.05C版

使用特权

评论回复
10
ayongge|  楼主 | 2009-12-9 15:10 | 只看该作者
再说调试:
在T2中断服务程序中令P10翻转,结果发现,死机后可以看到P10正常翻转。
猜想:也可能是进入工作程序之后的某处跳入死循环了。
测试工作程序的执行时间为1.4ms,可以放入T2中断服务程序中,程序修改后结果还是相同,死机后P10还是能正常翻转。
这时的主程序就很简单了:
while(1)
{
     WDT_CONTR = 0x3c; //喂片内看门狗
     Send_char(‘W’);//发送字符“W”

   SCH_Go_To_Sleep( ); //休眠
}
所以怀疑是STARTUP.A51有问题。

使用特权

评论回复
11
chunyisihai| | 2009-12-9 15:20 | 只看该作者
这肯定是程序写的有问题

使用特权

评论回复
12
ZRL700424| | 2009-12-9 15:23 | 只看该作者
电源有问题吧?

使用特权

评论回复
13
ayongge|  楼主 | 2009-12-9 15:35 | 只看该作者
本帖最后由 ayongge 于 2009-12-9 15:36 编辑

电源是12V开关电源供电,7805降压,12V给小继电器供电,没有隔离。中功率继电器无论是共用12V还是用另外的电源供电,都是相同结果。
曾经怀疑电源,更换过+5V、+12V两路输出的电源,没有改善。
52芯片是单芯片工作,干扰不可能从总线进入,这么娇嫩?郁闷。

使用特权

评论回复
14
ayongge|  楼主 | 2009-12-9 16:28 | 只看该作者
最后的解决是将小继电器改为双向可控硅(有光耦隔离,其他未变),但是一直对这事耿耿于怀,总觉得不应该这样。

使用特权

评论回复
15
ZRL700424| | 2009-12-9 16:41 | 只看该作者
电源如果没问题那就是PCB的问题了

使用特权

评论回复
16
ayongge|  楼主 | 2009-12-9 17:12 | 只看该作者
硬件构成是这样的:MCU板+输出扩展板
MCU板为89C52一片,MAXM232一片,P0口原用于无线遥控但在本应用中未使用,P1口用于输出接输出扩展板(连接用8芯线直接连接,未加屏蔽,也无间地)。输入仅用P3^5接一个按键,为1待命,检测到按键按下进入时序控制(控制5个灯光、一个100W的交流电机)。
输出扩展板接一片2803后再接2803(防止上电瞬间接通继电器)驱动继电器。
(最后重做了输出扩展板:P1口线接MOC3061隔离后触发BT138)

使用特权

评论回复
17
ayongge|  楼主 | 2009-12-9 17:17 | 只看该作者
注:程序一条语句都未变。

使用特权

评论回复
18
dlw2i| | 2009-12-9 17:20 | 只看该作者
继电器吸合时会对电源(可能会波及到MCU的工作电源)产生很大的影响,主要表现为一个低脉冲,此时会导致MCU进入复位状态,或其它不可靠状态,最好在MCU的电源及复位电路上做些处理,也包括固件的看门狗功能的实现。

使用特权

评论回复
19
ejack| | 2009-12-9 18:17 | 只看该作者
LZ大概没读过startup.a51的代码。
要是能跟它扯上关系,Keil早被人抹脖子了……

使用特权

评论回复
20
ejack| | 2009-12-9 18:20 | 只看该作者
但是向下翻页,却没有发现在0A08处的指令,看见的是如下的2条指令:


那是因为你的反汇编界面未区分程序段和数据段。举个简单的例子,随便找个图片,将其二进制码反汇编试试,看看软件生成了什么稀奇古怪的东西。:)

使用特权

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

本版积分规则

2

主题

14

帖子

0

粉丝