关于一个项目不定期死机问题的郁闷思考1

本文分享了一段导致系统每1个半月死机一次的程序片段,并详细记录了Bug定位的过程。作者通过不懈努力,最终定位到了问题所在——Timer1_Timer()主函数中的ComServer(1)函数。

原版程序(死机版)

ExpandedBlockStart.gifContractedBlock.gifPrivate Sub Timer1_Timer()Sub Timer1_Timer()
InBlock.gif
InBlock.gif    
Dim a
InBlock.gif    
Dim CheckValue As Integer
InBlock.gif    
InBlock.gif    Timer1.Enabled 
= False          '关闭定时器
InBlock.gif
    
InBlock.gif    
'**********************先检测通信是否正常
InBlock.gif
    '处理上下位机第一次通信就失败的情况
InBlock.gif
        If (FirstReceive = TrueThen '表明上下位机第一次通信,此时Rbyte()中为空
InBlock.gif
            FirstReceive = False
InBlock.gif            
Dim i As Integer
InBlock.gif            
'因为现在单机1号,所以可以这么写,并联运行则不能如此了!!!
InBlock.gif

InBlock.gif            
For ResetNum = 0 To 2
InBlock.gif
InBlock.gif                
For i = 0 To 10
InBlock.gif                    SendData1
InBlock.gif                    Delay (
0.015)
InBlock.gif                    
'将下位机发送来的数据收到Rbyte中,因为现在单机1号,所以可以这么写,并联运行则不能如此了!!!
InBlock.gif
                    ReceiveData1
InBlock.gif                    
If (Rlength = 26Then
InBlock.gif                            i 
= 0
InBlock.gif                            
Exit For
InBlock.gif                    
End If
InBlock.gif
InBlock.gif                
Next i
InBlock.gif
InBlock.gif                
If (i = 0Then  '说明接收到正确数据了
InBlock.gif
                    ResetNum = 0
InBlock.gif                    
Exit For
InBlock.gif                
End If
InBlock.gif                ResetLowerMachine (
1)
InBlock.gif            
Next ResetNum
InBlock.gif
InBlock.gif            
If (ResetNum <> 0Then '说明复位3次下位机都没有用!!!
InBlock.gif
                Timer4.Enabled = False
InBlock.gif                
MsgBox "下位机没有采到数据或通信模块出错!!"
InBlock.gif
'                App.End
InBlock.gif
            End If
InBlock.gif
InBlock.gif        
End If
InBlock.gif    
'******************************
InBlock.gif

InBlock.gif   
'指示下位机发送数据
InBlock.gif
   
InBlock.gif    ComServer (
1)
InBlock.gif        
InBlock.gif    Current_L_Level 
= Load_L_Level(11000'每次都刷新开关档位
InBlock.gif
    If Current_L_Level = 16 Then
InBlock.gif        
MsgBox "有载开关异常,请检查" '提示框的出现不影响Timer的运行,即,即使出来了提示框,照样进定时器中断!!!!!
InBlock.gif
        App.End
InBlock.gif    
End If
InBlock.gif    
InBlock.gif    init_level_1.Caption 
= Current_L_Level  '粗调档位
InBlock.gif
    now_middle_voltage_1.Caption = Round(MidV_Amplitude1(0))             '中性点电压
InBlock.gif
    Real_C_Level = Load_C_Level(11000)    '真实电容级数'
InBlock.gif

InBlock.gif    
If (LostSignal) Then        'receivedata1中的标志
InBlock.gif
        System_status_1.Caption = "信号输入不正确"  '这个优先级最高!!放在最前!!
InBlock.gif

InBlock.gif    
ElseIf (Ground_Status) Then                 '接地调节状态中
InBlock.gif
        GroundServer
InBlock.gif    
InBlock.gif    
ElseIf (Recalculation_Status) Then  '重新计算档位中
InBlock.gif
    
InBlock.gif        ReCalculationLevel
InBlock.gif    
InBlock.gif    
ElseIf (Change_L_Flag <> 0Then    '在投档调节状态中
InBlock.gif
    '在改变档位的过程中,有载开关要过很长的时间才能够调到下一档,这段时间不能死等,要判接地并动作
InBlock.gif
    '如果此间判到接地,那么马上运行GroundSever,GroundSever中置Ground_Status=true,直至接地解除,
InBlock.gif
    '否则会一直进入GroundSever,此时Change_L_Flag保持原来的值,接地解除后继续进入(Change_L_Flag <> 0)
InBlock.gif
    '的分支,接地处理就像51单片机中的中断一样,先中止当前运行的程序去处理中断,中断处理完毕后继续从断点处
InBlock.gif
    '往下运行
InBlock.gif
    '****************************
InBlock.gif
        If (CheckMiddleVoltageStatus = 1Then
InBlock.gif            GroundServer
InBlock.gif        
End If
InBlock.gif    
'****************************
InBlock.gif

InBlock.gif
InBlock.gif        Current_L_Level 
= Load_L_Level(11000)
InBlock.gif        
If Current_L_Level = 16 Then
InBlock.gif            
MsgBox "有载开关异常,请检查"
InBlock.gif            App.End
InBlock.gif        
End If
InBlock.gif        
InBlock.gif        
If (Current_L_Level > Next_L_Level) Then    '要下调
InBlock.gif
            a = Output_L_Level(12)
InBlock.gif        
InBlock.gif        
ElseIf (Current_L_Level < Next_L_Level) Then    '要上调
InBlock.gif
            a = Output_L_Level(11)
InBlock.gif        
InBlock.gif        
Else    '已经到达下一档,重算最优档位
InBlock.gif
        
InBlock.gif            
If (UpStatus) Then
InBlock.gif                UpStatus 
= False
InBlock.gif                a 
= Send_Current_Status(1000'调节完毕后通知主控台档位上调1档了
InBlock.gif
            End If
InBlock.gif            
If (DownStatus) Then
InBlock.gif                DownStatus 
= False
InBlock.gif                a 
= Send_Current_Status(0100'调节完毕后通知主控台档位下调1档了
InBlock.gif
            End If
InBlock.gif
InBlock.gif            init_level_1.Caption 
= Current_L_Level  '刷新电感档位显示
InBlock.gif
            Delay (0.1)                             '延时等待电感变化稳定下来
InBlock.gif

InBlock.gif            
'**************防止在两个档位之间来回调个不停*******************************
InBlock.gif
            If (SwitchFlag = FalseThen    '没有发生来回调个不停!!
InBlock.gif
                ReCalculationLevel          '重新计算最优档位
InBlock.gif
            Else                            '出现了来回调个不停的情况
InBlock.gif
                SwitchFlag = False
InBlock.gif
InBlock.gif                Change_L_Flag 
= 0  '不需调节
InBlock.gif
                Previous_L_Level = Current_L_Level
InBlock.gif                
'选择全投或全切方式
InBlock.gif
                If (Optimum_C_Level < 8Then   '全切
InBlock.gif
                    a = Output_C_Level(1, QUANTOU)
InBlock.gif                    QuanQieTou_Status 
= False
InBlock.gif                
Else                            '全投
InBlock.gif
                    a = Output_C_Level(1, QUANQIE)
InBlock.gif                     QuanQieTou_Status 
= True
InBlock.gif                    
'以全投时的电压为重计算的标准
InBlock.gif
                End If
InBlock.gif                Delay (
0.1'投切之后延时5周波,保证稳定!!!!!!
InBlock.gif

InBlock.gif                
'问下位机要数据!!
InBlock.gif
                 ComServer (1)
InBlock.gif                 MidV_Amplitude1(
1= MidV_Amplitude1(0)
InBlock.gif                 MidV_Phase1(
1= MidV_Phase1(0)     'Vca触发捕获的时候用到这个,因为此时中性点相位很大!!!!!
InBlock.gif
              InBlock.gif             End If
InBlock.gif        
'***********************************************************
InBlock.gif

InBlock.gif        
End If
InBlock.gif    
Else                                '一般状态下,开机启动首先进入该函数体
InBlock.gif
    
InBlock.gif        CheckValue 
= CheckMiddleVoltageStatus
InBlock.gif        
InBlock.gif        
Select Case (CheckValue) '检测中性点电压是否异常
InBlock.gif
        Case 0'稳定运行
InBlock.gif
                ExceedNum = 0       '中性点超界时给主控台发信息的次数清0
InBlock.gif
                SevereExceedNum = 0 '中性点严重超界时给主控台发信息的次数清0
InBlock.gif
                GroundNum = 0       '接地时给主控台发送信息的次数清0
InBlock.gif
                HighVQie = False
InBlock.gif                HighVTou 
= False
InBlock.gif                System_status_1.Caption 
= "正常运行"
InBlock.gif                
If (KaiJiStatus) Then
InBlock.gif                    KaiJiStatus 
= False
InBlock.gif                    Print_Page (
1)      '开机打印,每次开机只打印1次!!!
InBlock.gif
                End If
InBlock.gif                
InBlock.gif        
Case 1'发生接地
InBlock.gif
                ExceedNum = 0       '中性点超界次数清0
InBlock.gif
                SevereExceedNum = 0 '中性点严重超界次数清0
InBlock.gif
                HighVQie = False
InBlock.gif                HighVTou 
= False
InBlock.gif
InBlock.gif                System_status_1.Caption 
= "发生接地"
InBlock.gif                GroundServer
InBlock.gif
InBlock.gif        
Case 2'中性点电压>15%相电压,发生超界,往主控制台送状态
InBlock.gif
                SevereExceedNum = 0 '中性点严重超界次数清0
InBlock.gif
                GroundNum = 0       '接地时给主控台发送信息的次数清0
InBlock.gif

InBlock.gif                System_status_1.Caption 
= "中性点电压超界"
InBlock.gif                
If (ExceedNum = 0Then     '只往主控台发送1次!!!!!!
InBlock.gif
                    ExceedNum = 1
InBlock.gif                    a 
= Send_Current_Status(0010)
InBlock.gif                
End If
InBlock.gif                HighVoltageServer
InBlock.gif
InBlock.gif        
Case 3'需重新计算档位
InBlock.gif
                ExceedNum = 0       '中性点超界次数清0
InBlock.gif
                SevereExceedNum = 0 '中性点严重超界次数清0
InBlock.gif
                GroundNum = 0       '接地时给主控台发送信息的次数清0
InBlock.gif
                HighVQie = False
InBlock.gif                HighVTou 
= False
InBlock.gif
InBlock.gif                
If (Change_L_Flag = 0Then ReCalculationLevel
InBlock.gif
InBlock.gif        
Case 4'中性点电压>35%相电压但没有线路发生接地,发生严重超界,往主控制台送状态
InBlock.gif
                ExceedNum = 0   '中性点超界次数清0
InBlock.gif
                GroundNum = 0   '接地时给主控台发送信息的次数清0
InBlock.gif
                HighVQie = False
InBlock.gif                HighVTou 
= False
InBlock.gif
InBlock.gif                System_status_1.Caption 
= "中性点电压严重超界"
InBlock.gif                
If (SevereExceedNum = 0Then      '只往主控台发送1次!!!
InBlock.gif
                    SevereExceedNum = 1
InBlock.gif                    a 
= Send_Current_Status(0001)
InBlock.gif                
End If
InBlock.gif
InBlock.gif        
End Select
InBlock.gif 
InBlock.gif    
End If
InBlock.gif    Timer1.Enabled 
= True
InBlock.gif   
ExpandedBlockEnd.gif
End Sub

ExpandedBlockStart.gifContractedBlock.gif
Function ComServer()Function ComServer(ByVal devicenum As Integer)
InBlock.gif    
InBlock.gif    
Dim MidV_Level As Integer
InBlock.gif    
InBlock.gif    
If (devicenum = 1Then
InBlock.gif        SendData1
InBlock.gif        Delay (
0.015)    '延时10ms后收取下位机的数据
InBlock.gif
        ReceiveData1    '将下位机发送来的数据收到Rbyte中
InBlock.gif
    End If
InBlock.gif      
InBlock.gif    
InBlock.gif  
   If (Rbyte(1= &H11) Then    '说明数据正确!!!!
InBlock.gif
        lostnum = 0
InBlock.gif        MidV_Level 
= Rbyte(4)    '不同档位
InBlock.gif
        If (MidV_Level = 0Then
InBlock.gif   
            MidV_Amplitude1(0= CDbl(Rbyte(2+ Rbyte(3* 256* 0.36053
InBlock.gif        
ElseIf (MidV_Level = 1Then
InBlock.gif           
            MidV_Amplitude1(0= CDbl(Rbyte(2+ Rbyte(3* 256* 0.11493
InBlock.gif        
ElseIf (MidV_Level = 2Then
InBlock.gif            
           MidV_Amplitude1(0= CDbl(Rbyte(2+ Rbyte(3* 256* 0.0261045
InBlock.gif        
End If
InBlock.gif    
InBlock.gif
InBlock.gif        
'中性点电压频率
InBlock.gif
        If (Rbyte(6= 0 And Rbyte(7= 0Then
InBlock.gif            Rbyte(
7= &H12
InBlock.gif            Rbyte(
6= &H4F
InBlock.gif        
End If
InBlock.gif        MidV_Freq1(
0= Round(234375/ CDbl(Rbyte(6+ Rbyte(7* 256), 2)
InBlock.gif    
InBlock.gif        
'暂时用不到,所以先不用计算以节省时间
InBlock.gif
        '中性点电流幅值(有效值),电流互感器变比:250:5,未修正!!!!
InBlock.gif
        'MidC_Amplitude1(0) = CDbl(Rbyte(8) + Rbyte(9) * 256) * 1.41421 * 50 / 3830.112
InBlock.gif
        '投切电容总电流幅值(有效值),电流互感器变比:750:5
InBlock.gif
        'TotalCC_Amplitude1(0) = CDbl(Rbyte(10) + Rbyte(11) * 256) * 1.41421 * 150 / 5106.816
InBlock.gif

InBlock.gif    
InBlock.gif        
'三相线电压的幅值(有效值)和相位,10000:100,未修正!!!!约1.2左右,100/83=1.2
InBlock.gif
        'Vab_Amplitude1(0) = CDbl(Rbyte(12) + Rbyte(13) * 256) * 1.41421 * 100 / 223.872
InBlock.gif
        Vab_Amplitude1(0= CDbl(Rbyte(12+ Rbyte(13* 256* 0.6317
InBlock.gif        Vab_Phase1(
0= CDbl(Rbyte(14+ Rbyte(15* 256/ 100#
InBlock.gif        
'Vbc_Amplitude1(0) = CDbl(Rbyte(16) + Rbyte(17) * 256) * 1.41421 * 100 / 223.872
InBlock.gif
        Vbc_Amplitude1(0= CDbl(Rbyte(16+ Rbyte(17* 256* 0.6317
InBlock.gif        Vbc_Phase1(
0= CDbl(Rbyte(18+ Rbyte(19* 256/ 100#
InBlock.gif        
'Vca_Amplitude1(0) = CDbl(Rbyte(20) + Rbyte(21) * 256) * 1.41421 * 100 / 223.872
InBlock.gif
        Vca_Amplitude1(0= CDbl(Rbyte(20+ Rbyte(21* 256* 0.6317
InBlock.gif        Vca_Phase1(
0= CDbl(Rbyte(22+ Rbyte(23* 256/ 100#
InBlock.gif    
InBlock.gif        
'中性点电压相位
InBlock.gif
        MidV_Phase1(0= CDbl(Rbyte(24+ Rbyte(25* 256/ 100#
InBlock.gif                    
InBlock.gif    
ElseIf (Rbyte(1= 0Then '说明收到的数据都是零!!
InBlock.gif
        lostnum = lostnum + 1
InBlock.gif        
If (lostnum = 10Then
InBlock.gif            lostnum 
= 0
InBlock.gif            
InBlock.gif            Vab_Amplitude1(
0= CDbl(Rbyte(12+ Rbyte(13* 256* 0.6317
InBlock.gif            Vab_Phase1(
0= CDbl(Rbyte(14+ Rbyte(15* 256/ 100#
InBlock.gif            Vbc_Amplitude1(
0= CDbl(Rbyte(16+ Rbyte(17* 256* 0.6317
InBlock.gif            Vbc_Phase1(
0= CDbl(Rbyte(18+ Rbyte(19* 256/ 100#
InBlock.gif            Vca_Amplitude1(
0= CDbl(Rbyte(20+ Rbyte(21* 256* 0.6317
InBlock.gif            Vca_Phase1(
0= CDbl(Rbyte(22+ Rbyte(23* 256/ 100#
InBlock.gif    
InBlock.gif            
If ((Vab_Amplitude1(0< 4000Or (Vbc_Amplitude1(0< 4000Or (Vca_Amplitude1(0< 4000)) Then
InBlock.gif                LostSignal 
= True
InBlock.gif            
End If
InBlock.gif        
End If
InBlock.gif        
InBlock.gif    
End If
InBlock.gif    
ExpandedBlockEnd.gif
End Function
这个项目中的bug比较难找,这里只列出一些代码片断,其他省略。
反正总体说来本系统以10ms作一次循环,在每大概1个半月之后就会死机!
这段时期找bug就成了我的业余生活,在我坚持不懈的on error resume next下终于找到了错误的入口点-Timer1_Timer()主函数中的ComServer (1)函数出了问题!
于是进入ComServer ()函数体进行分析。
其实看看上面的ComServer()这个函数的程序就会发现程序很完美!

转载于:https://www.cnblogs.com/coffeeliu/archive/2006/04/19/379451.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值