打印

为什么我的程序跑表时间远大于我的预定时间

[复制链接]
2315|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
aihe|  楼主 | 2007-5-8 09:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
;***********************************************************
;Aihe            于2007年五一假期中断续写成
;4MHz晶振,1微秒每个指令周期
;内部定时器256×16=4.096mS查询
;主要功能定时控制电动阀开关
;起始延时由四个拨动开关设定,全关为5分钟
;多任务同时执行
;***********************************************************
        list        p=16c54
#INCLUDE         P16C5X.INC
;字节定义    
#DEFINE        MS500            08H                ;分秒
#DEFINE        S1                09H                ;秒
#DEFINE        S30                0AH                ;30秒
#DEFINE        M                0BH                ;分
#DEFINE        H                0CH                ;
#DEFINE        START_YS        0DH
#DEFINE        FLAG1            0EH                ;
;A口输出位    
#DEFINE        CLOSE_OUT        00H                ;开阀
#DEFINE        OPEN_OUT        01H                ;关阀
#DEFINE        CLOSE_LED        02H                ;开
#DEFINE        OPEN_LED        03H                ;关
;B口输入定义
#DEFINE        S1_1                00H                ;启动
#DEFINE        S1_2                01H                ;延时
#DEFINE        S1_3                02H                ;选择
#DEFINE        S1_4                03H                ;开关
#DEFINE        OPEN            04H                ;开按钮
#DEFINE        CLOSE            05H                ;关按钮
#DEFINE        OPEN_CILCK        06H                ;开到位
#DEFINE        CLOSE_CILCK        07H                ;关到位
;标帜FLAG1位定义
#DEFINE        ST_YS_FG        00H
#DEFINE        OPEN_FG            01H                ;
#DEFINE        VT_FG            02H                ;阀门延时标帜
#DEFINE        BB                03H                ;关标帜
#DEFINE        O_FG            04H                ;开按钮标帜
#DEFINE        C_FG            05H                ;关按钮标帜
#DEFINE        OC_FG            06H                ;开到位标帜
#DEFINE        CC_FG            07H                ;关到位标帜
;        
        
            ORG            00H
                
            BTFSS        STATUS,NOT_PD
            GOTO        WAIT
            BTFSS        STATUS,NOT_TO
            GOTO        DOG

START        MOVLW        08H                    ;w=08h
            MOVWF        FSR                    ;FSR=08H
XH1            CLRF        INDF                    ;08单元处被清零
            INCF            FSR,F                ;FSR=FSR+1,指向下一单元
            MOVLW        1FH                    ;准备检查FSR是否为1FH
            XORWF        FSR,W                ;FSR和W异或,FSR保持不变
            BTFSS        STATUS,Z            ;检测Z标志是否为1,是则循环结束
            GOTO        XH1                    ;继续循环

DOG            MOVLW        00H                    ;PA为输出
            TRIS            PORTA                ;
            CLRF        PORTA                ;PA为低电平
            MOVLW        0FFH                ;PB为输入
            TRIS            PORTB

SET_ST        BSF            FLAG1,ST_YS_FG        ;置开机延时标志
            MOVF        PORTB,0                ;读开机延时状态
            MOVWF        START_YS            ;
            MOVLW        B'00001111'
            ANDWF        START_YS,1            ;
            INCF            START_YS,1            ;开机延时加1
            MOVF        START_YS,0            ;延时分钟数n×5
            ADDWF        START_YS,1
            ADDWF        START_YS,1
            ADDWF        START_YS,1
            ADDWF        START_YS,1
                                    
SET_RTCC    CLRF        TMR0                ;
            MOVLW        B'00001011'            ;定义1/16,RTCC为内部计数方式
            OPTION                            ;
            MOVLW        10H                    ;0.5秒
            MOVWF        MS500
            MOVLW        02H                    ;1秒
            MOVWF        S1
            MOVLW        1EH                    ;30秒
            MOVWF        S30    
            MOVLW        02H                    ;1分钟
            MOVWF        M
            MOVLW        3CH                    ;1小时
            MOVWF        H
                    
WAIT        MOVLW        03H                    ;31.25mS处理一次外部事务
            SUBWF        TMR0,0
            SKPNC        
            GOTO        WAIT                
            CLRWDT                            ;清看门狗
                
B1            BTFSS        PORTB,OPEN            ;开按键检测
            GOTO        B2                    ;
            BTFSC        FLAG1,O_FG            ;延时确认
            GOTO        B3                    ;
            BSF            FLAG1,O_FG            ;    
B2            BTFSS        PORTB,CLOSE            ;关按键检测
            GOTO        A1                    ;
            BTFSC        FLAG1,C_FG            ;延时确认
            GOTO        B4                    ;关
            BSF            FLAG1,C_FG            ;
            GOTO        A1                    ;

B3            BTFSS        FLAG1,C_FG            ;同时按下停止
            GOTO        B5                    ;
            BCF            PORTA,OPEN_OUT        ;
            BCF            PORTA,CLOSE_OUT        ;
            GOTO        A1                    ;
B4            BCF            FLAG1,OPEN_FG            ;关
            BCF            PORTA,OPEN_OUT        ;
            GOTO        A3                    
B5            BSF            FLAG1,OPEN_FG            ;开
            BCF            PORTA,CLOSE_OUT        ;
            GOTO        A2
                
A1            BTFSS        FLAG1,ST_YS_FG        ;是否开机延时开通
            GOTO        A2                
            BSF            PORTA,CLOSE_OUT
            
            DECFSZ        MS500,1
            GOTO        WAIT                    
            MOVLW        10H                    ;0.5秒
            MOVWF        MS500
            
            BTFSC        FLAG1,VT_FG            ;
            GOTO        C3                    ;
            BTFSS        PORTB,CLOSE_CILCK    ;
            GOTO        C1                    ;
            BTFSC        FLAG1,CC_FG            ;延时确认
            GOTO        C2                    ;
C1            BTFSS        PORTA,CLOSE_LED        ;关闭灯闪烁
            GOTO        C2
            BCF            PORTA,CLOSE_LED
            GOTO        C3
C2            BSF            PORTA,CLOSE_LED
C3            DECFSZ        S1,1
            GOTO        WAIT                    
            MOVLW        02H                    ;1秒
            MOVWF        S1
            DECFSZ        S30,1
            GOTO        WAIT                    
            MOVLW        1EH                    ;30秒
            MOVWF        S30
            BTFSC        FLAG1,VT_FG            ;
            GOTO        $+3
            BSF            PORTA,CLOSE_LED
            BSF            FLAG1,VT_FG            ;
            DECFSZ        M,1
            GOTO        WAIT
            MOVLW        02H                    ;1分钟
            MOVWF        M
            DECFSZ        START_YS,1            ;5分钟×n
            GOTO        WAIT
            BCF            PORTA,CLOSE_OUT
            BCF            PORTA,CLOSE_LED
            BSF            FLAG1,OPEN_FG
            BCF            FLAG1,ST_YS_FG
            BCF            FLAG1,VT_FG            ;
            GOTO        WAIT
                
A2            BTFSS        FLAG1,OPEN_FG
            GOTO        A3
            BSF            PORTA,OPEN_OUT
            DECFSZ        MS500,1
            GOTO        WAIT                    
            MOVLW        10H                    ;0.5秒
            MOVWF        MS500
            
            BTFSC        FLAG1,VT_FG            ;
            GOTO        D3                    ;
            BTFSS        PORTB,OPEN_CILCK    ;
            GOTO        D1                    ;
            BTFSC        FLAG1,OC_FG            ;延时确认
            GOTO        D2                    ;
D1            BTFSS        PORTA,OPEN_LED        ;关闭灯闪烁
            GOTO        D2
            BCF            PORTA,OPEN_LED
            GOTO        D3
D2            BSF            PORTA,OPEN_LED

D3            DECFSZ        S1,1
            GOTO        WAIT                    
            MOVLW        02H                    ;1秒
            MOVWF        S1
            DECFSZ        S30,1
            GOTO        WAIT                    
            MOVLW        1EH                    ;30秒
            MOVWF        S30

            BTFSC        FLAG1,VT_FG            ;
            GOTO        $+3
            BSF            PORTA,OPEN_LED
            BSF            FLAG1,VT_FG            ;

            DECFSZ        M,1
            GOTO        WAIT
            MOVLW        02H                    ;1分钟
            MOVWF        M
            BCF            PORTA,OPEN_LED
            BCF            PORTA,OPEN_OUT
            BCF            FLAG1,OPEN_FG                
            BCF            FLAG1,VT_FG            ;
            GOTO        WAIT
                
A3            BTFSC        FLAG1,OPEN_FG
            GOTO        A2
            BSF            PORTA,CLOSE_OUT
            DECFSZ        MS500,1
            GOTO        WAIT                    
            MOVLW        10H                    ;0.5秒
            MOVWF        MS500
            
            BTFSC        FLAG1,VT_FG            ;
            GOTO        E3                    ;
            BTFSS        PORTB,CLOSE_CILCK    ;
            GOTO        E1                    ;
            BTFSC        FLAG1,CC_FG            ;延时确认
            GOTO        E2                    ;
E1            BTFSS        PORTA,CLOSE_LED        ;关闭灯闪烁
            GOTO        E2
            BCF            PORTA,CLOSE_LED
            GOTO        E3
E2            BSF            PORTA,CLOSE_LED

E3            DECFSZ        S1,1
            GOTO        WAIT                    
            MOVLW        02H                    ;1秒
            MOVWF        S1
            DECFSZ        S30,1
            GOTO        WAIT                    
            MOVLW        1EH                    ;30秒
            MOVWF        S30

            BTFSC        FLAG1,VT_FG            ;
            GOTO        $+3
            BSF            PORTA,CLOSE_LED
            BSF            FLAG1,VT_FG            ;

            DECFSZ        M,1
            GOTO        WAIT
            MOVLW        02H                    ;1分钟
            MOVWF        M
            DECFSZ        H,1
            GOTO        WAIT
            MOVLW        3CH                    ;1小时
            MOVWF        H
            BCF            PORTA,CLOSE_OUT
            BCF            PORTA,CLOSE_LED
            BSF            FLAG1,OPEN_FG
            BCF            FLAG1,VT_FG            ;
            GOTO        WAIT
                    
            END
沙发
兰天白云| | 2007-5-8 09:22 | 只看该作者

这个感觉不对

WAIT        MOVLW        03H         ;31.25mS处理一次外部事务
            SUBWF        TMR0,0
            SKPNC        
            GOTO        WAIT                
            CLRWDT         

使用特权

评论回复
板凳
aihe|  楼主 | 2007-5-8 12:25 | 只看该作者

我看到中档单片机参考手册上写的

11.7 设计技巧
问1: 在我的计数器/ 时钟应用中,为什么时钟会丢失时间或不准确?
答1:
如果您通过查询TMR0 来查看它是否计满回零,可以执行:
wait MOVF TMR0,W ; read the timer into W
BTFSS STATUS,Z ; see if it was zero, if so,
; break from loop
GOTO wait ; if not zero yet, keep waiting
丢失时钟周期的两种可能的情况为:
1. 当TMR0 的递增计数是来自内部指令时钟,或与内部时钟几乎同样快的外部时钟源时,那
么在执行两周期的GOTO 指令时,可能会发生溢出,使您的时钟周期丢失。在这种情况下,
应将TMR0 进行预分频。
或者您也可做一个测试,通过检测小于标称值的值来查看TMR0 是否计满回零:
Wait movlw 3
subwf TMR0,W
btfsc STATUS,C
goto Wait
2. 当向TMR0 写入数据时,会丢失两个时钟周期。通常您希望对一个特定的时间段计数,如
十进制数100。此时您会将156 写入TMR0(256-100 = 156)。然而,由于向TMR0 写入数
据时会丢失两个指令周期( 用于内部逻辑电路的同步),因此实际上应向定时器写入158。


WAIT        MOVLW        03H         ;31.25mS处理一次外部事务
            SUBWF        TMR0,0
            SKPC        
            GOTO        WAIT                
            CLRWDT         

使用特权

评论回复
地板
xieyuanbin| | 2007-5-9 09:08 | 只看该作者

这种时间问题,用SIM仿真很容易找出问题所在.

MPLAB中有个叫做软件仿真的东西,在DEBUGER中选择SIM,里面有跑表可以看你程序所用时间,精确到指令周期,而且超快,比硬件实际执行时间都快.如果SIM中是对的,那么就是晶振不对了.

使用特权

评论回复
5
aihe|  楼主 | 2007-5-9 14:34 | 只看该作者

就是在SIM中跑出来不对

我用TMRO计数查询,TMR0过零时执行其他任务,TMRO照样计数
但好像SIM把执行其他任务的时间也计算进去了,其实我执行
其他任务达不到256时钟周期的

使用特权

评论回复
6
aihe|  楼主 | 2007-5-10 10:02 | 只看该作者

重新改过,现在正确了全部重发

;***********************************************************
;AIHE            于2007年五一假期中断续写成
;4MHz晶振,1微秒每个指令周期
;内部定时器256×16=4.096mS查询
;主要功能定时控制电动阀开关
;起始延时由四个拨动开关设定,全关为5分钟
;多任务同时执行
;***********************************************************
        list        p=16c54
#INCLUDE         P16C5X.INC
;字节定义    
#DEFINE        MS500            08H                ;分秒
#DEFINE        S1                09H                ;秒
#DEFINE        S30                0AH                ;30秒
#DEFINE        M                0BH                ;分
#DEFINE        START_YS        0CH
#DEFINE        FLAG1            0DH                ;
;A口输出位    
#DEFINE        CLOSE_OUT        00H                ;开阀
#DEFINE        OPEN_OUT        01H                ;关阀
#DEFINE        CLOSE_LED        02H                ;开
#DEFINE        OPEN_LED        03H                ;关
;B口输入定义
#DEFINE        S1_1            00H                ;启动
#DEFINE        S1_2            01H                ;延时
#DEFINE        S1_3            02H                ;选择
#DEFINE        S1_4            03H                ;开关
#DEFINE        OPEN            04H                ;开按钮
#DEFINE        CLOSE            05H                ;关按钮
#DEFINE        OPEN_CILCK        06H                ;开到位
#DEFINE        CLOSE_CILCK        07H                ;关到位
;标帜FLAG1位定义
#DEFINE        ST_YS_FG        00H
#DEFINE        OPEN_FG            01H                ;
#DEFINE        VT_FG            02H                ;阀门延时标帜
#DEFINE        BB                03H                ;关标帜
#DEFINE        O_FG            04H                ;开按钮标帜
#DEFINE        C_FG            05H                ;关按钮标帜
#DEFINE        OC_FG            06H                ;开到位标帜
#DEFINE        CC_FG            07H                ;关到位标帜
;        
        
            ORG            00H
                
            BTFSS        STATUS,NOT_PD
            GOTO        WAIT
            BTFSS        STATUS,NOT_TO
            GOTO        DOG

START        MOVLW        08H                    ;w=08h
            MOVWF        FSR                    ;FSR=08H
XH1            CLRF        INDF                    ;08单元处被清零
            INCF        FSR,F                ;FSR=FSR+1,指向下一单元
            MOVLW        1FH                    ;准备检查FSR是否为1FH
            XORWF        FSR,W                ;FSR和W异或,FSR保持不变
            BTFSS        STATUS,Z            ;检测Z标志是否为1,是则循环结束
            GOTO        XH1                    ;继续循环

SET_ST        MOVF        PORTB,0                ;读开机延时状态
            MOVWF        START_YS            ;
            MOVLW        B'00001111'
            ANDWF        START_YS,1            ;
            INCF        START_YS,1            ;开机延时加1
            MOVF        START_YS,0            ;延时分钟数n×5
            ADDWF        START_YS,1
            ADDWF        START_YS,1
            ADDWF        START_YS,1
            ADDWF        START_YS,1
                                    
DOG            MOVLW        00H                    ;PA为输出
            TRIS        PORTA                ;
            CLRF        PORTA                ;PA为低电平
            MOVLW        0FFH                ;PB为输入
            TRIS        PORTB

SET_RTCC    MOVLW        10H                    ;0.5秒
            MOVWF        MS500
            MOVLW        02H                    ;1秒
            MOVWF        S1
            MOVLW        1EH                    ;30秒
            MOVWF        S30    
            MOVLW        02H                    ;1分钟
            MOVWF        M
            CLRF        TMR0                ;
            MOVLW        B'00001011'            ;定义1/16,RTCC为内部计数方式
            OPTION                            ;
            BCF            FLAG1,OPEN_FG
            BSF            PORTA,CLOSE_OUT
            BSF            FLAG1,VT_FG

WAIT        MOVLW        05H                    ;31.25mS处理一次外部事务
            SUBWF        TMR0,0
            BTFSC        STATUS,C        
            GOTO        WAIT                
            CLRWDT                            ;清看门狗
            BSF            STATUS,C
                
B1            BTFSS        PORTB,OPEN            ;开按键检测
            GOTO        B2                    ;
            BTFSC        FLAG1,O_FG            ;延时确认
            GOTO        B3                    ;
            BSF            FLAG1,O_FG            ;

B2            BTFSS        PORTB,CLOSE            ;关按键检测
            GOTO        A1                    ;
            BTFSC        FLAG1,C_FG            ;延时确认
            GOTO        B4                    ;关
            BSF            FLAG1,C_FG            ;
            GOTO        A1                    ;

B3            BTFSS        FLAG1,C_FG            ;同时按下停止
            GOTO        B5                    ;
            BCF            PORTA,OPEN_OUT        ;
            BCF            PORTA,OPEN_LED
            BCF            PORTA,CLOSE_OUT        ;
            BCF            PORTA,CLOSE_LED
            GOTO        A1                    ;

B4            BCF            FLAG1,OPEN_FG        ;关
            BCF            PORTA,OPEN_OUT        ;
            BCF            PORTA,OPEN_LED
            BSF            PORTA,CLOSE_OUT
            GOTO        A3                    

B5            BSF            FLAG1,OPEN_FG        ;开
            BCF            PORTA,CLOSE_OUT        ;
            BCF            PORTA,CLOSE_LED
            BSF            PORTA,OPEN_OUT
            GOTO        A2
                
A1            BTFSS        FLAG1,OPEN_FG        ;
            GOTO        A2                
            GOTO        A3
            
A2            DECFSZ        MS500,1
            GOTO        WAIT                    
            MOVLW        10H                    ;0.5秒
            MOVWF        MS500
            
            BTFSS        FLAG1,VT_FG            ;
            GOTO        C3                    ;
            BTFSS        PORTB,CLOSE_CILCK    ;
            GOTO        C1                    ;
            BTFSC        FLAG1,CC_FG            ;延时确认
            GOTO        C1                    ;
            BCF            FLAG1,VT_FG            ;关到位
            BCF            PORTA,CLOSE_OUT
            BSF            PORTA,CLOSE_LED
            GOTO        C3

C1            BTFSS        PORTA,CLOSE_LED        ;关闭灯 闪烁
            GOTO        C2
            BCF            PORTA,CLOSE_LED
            GOTO        C3
C2            BSF            PORTA,CLOSE_LED

C3            DECFSZ        S1,1
            GOTO        WAIT                    
            MOVLW        02H                    ;1秒
            MOVWF        S1
            DECFSZ        S30,1
            GOTO        WAIT                    
            MOVLW        1EH                    ;30秒
            MOVWF        S30

            BTFSS        FLAG1,VT_FG            ;
            GOTO        $+4
            BSF            PORTA,CLOSE_LED
            BCF            PORTA,CLOSE_OUT
            BCF            FLAG1,VT_FG            ;

            DECFSZ        M,1
            GOTO        WAIT
            MOVLW        02H                    ;1分钟
            MOVWF        M

            DECFSZ        START_YS,1            ;5分钟×n
            GOTO        WAIT
            MOVLW        3CH                    ;1小时
            MOVWF        START_YS
            
            BCF            PORTA,CLOSE_LED
            BSF            PORTA,OPEN_OUT
            BSF            FLAG1,OPEN_FG
            BSF            FLAG1,VT_FG            ;
            GOTO        WAIT
                
A3            DECFSZ        MS500,1
            GOTO        WAIT                    
            MOVLW        10H                    ;0.5秒
            MOVWF        MS500
            
            BTFSS        FLAG1,VT_FG            ;
            GOTO        D3                    ;
            BTFSS        PORTB,OPEN_CILCK    ;
            GOTO        D1                    ;
            BTFSC        FLAG1,OC_FG            ;延时确认
            GOTO        D1                    ;
            BCF            FLAG1,VT_FG            ;开关到位
            BCF            PORTA,OPEN_OUT
            BSF            PORTA,OPEN_LED
            GOTO        D3

D1            BTFSS        PORTA,OPEN_LED        ;开启灯 闪烁
            GOTO        D2
            BCF            PORTA,OPEN_LED
            GOTO        D3
D2            BSF            PORTA,OPEN_LED

D3            DECFSZ        S1,1
            GOTO        WAIT                    
            MOVLW        02H                    ;1秒
            MOVWF        S1
            DECFSZ        S30,1
            GOTO        WAIT                    
            MOVLW        1EH                    ;30秒
            MOVWF        S30

            BTFSS        FLAG1,VT_FG            ;
            GOTO        $+4
            BSF            PORTA,OPEN_LED
            BCF            PORTA,OPEN_OUT
            BCF            FLAG1,VT_FG            ;

            DECFSZ        M,1
            GOTO        WAIT
            MOVLW        02H                    ;1分钟
            MOVWF        M

            BCF            PORTA,OPEN_LED
            BSF            PORTA,CLOSE_OUT
            BCF            FLAG1,OPEN_FG                
            BSF            FLAG1,VT_FG            ;
            GOTO        WAIT
                
            END

使用特权

评论回复
7
stghl| | 2007-5-12 14:26 | 只看该作者

你写的也太长吧

TMRO寄存器不要修改其值,需要时只对TMR0读取,这样的话时间的误差就不会太大
PIC内部时钟也不是很准,有10%的误差....

使用特权

评论回复
8
Aihe| | 2007-5-14 11:14 | 只看该作者

谢谢楼上

我没有修改TMR0的值,只是,读其值与5相减,得到的数字放入W,看手册上的例子有问题,这样改后跑表就能达到预定值了
我是用32768Hz的外接晶振,应该比较精确
检查过了,还要修改,按键后处理还有问题,这两天还要改改

使用特权

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

本版积分规则

26

主题

1258

帖子

1

粉丝