mmswza 发表于 2011-9-27 21:29:01

汇编中断程序遇到问题,请教马老师

开始学下汇编,这是一个MEGA32 Timer2异步时钟中断测试程序在中断里翻转PORTD~0,1,
异步时钟频率:32.768K。
AVR Studio 4.18
现在程序可以正常跑,但初始化似乎出现未知情况,上电后要等待两到三秒(感觉)才开始正常执行。劳您指教。
.CSEG

.include "m32def.inc"   

.org 0x0000            

   rjmp RESET         
       
.org 0x008

       rjmp Timer

.org 0x0030

Timer:

        ldi r17,0x01

        sub r27,r17

        cpi r27,0x00

        brne GO_back

        ldi r27,0x1f

        in r16, PORTD

        swapr16

    out PORTD, r16

GO_back:

        reti


.org 0x0039

RESET:

    ldi        r28,0x5f

    ldi        r29,0x1f

    out        SPL,r28

    out        SPH,r29

        ldi r27,0x08
                         
    ldi r16, 0xff

    out DDRD, r16

    ldi r16, 0xde

    out PORTD, r16
       
    ldi r16, 0x00

    out TIMSK, r16              
       
    ldi r16, 0x08

        in r17, ASSR

        orr16,r17

    out ASSR, r16

    ldi r16, 0x00

    out TCNT2, r16
       
    ldi r16, 0x00

    out OCR2, r16
               
    ldi r16, 0x0f

    out TCCR2, r16
       
Status:

        inr16,ASSR

        cpi r16,0x08

        brne Status

    ldi r16, 0xc0

        in r17, TIFR

        orr16,r17

    out TIFR, r16

    ldi r16, 0x80

    out TIMSK, r16

    sei

Loop:

    rjmp Loop

machao 发表于 2011-9-28 23:43:10

如果汇编再没有注释的话,别人就根本不想看了,请先把必要注释加上。

mmswza 发表于 2011-9-29 15:55:23

呵呵,谢谢马老师,目前正努力改善自己的注释习惯,要不时间长了,自己都不清楚。

目前问题得到解决,问题在我把TCNT2和OCR2写入0,而错过了首次比较必须等计数溢出一次才会正常,而此时异步时钟频率较低,
所以我在上电后要等待(等待计数溢出),大概掐了下表,远不止2-3秒。目前将TCNT2初始化为255,问题得以解决。

继续加上注释:
.CSEG

.include "m32def.inc"   

.org 0x0000            

    rjmp RESET         
       
.org 0x008

    rjmp Timer

.org 0x0030

Timer:

    ldi r17,0x01

    sub r27,r17         ;计数值减一

    cpi r27,0x00      ;计数值为0则LED状态交换

    brne GO_back      ;否则直接返回

    ldi r27,0x1f

    in r16, PORTD

    swapr16

    out PORTD, r16

GO_back:

    reti


.org 0x0039

RESET:

    ldi        r28,0x5f      ;堆栈初始化

    ldi        r29,0x1f      ;

    out        SPL,r28         ;

    out        SPH,r29         ;

    ldi r27,0x08      ;R27作为中断计数值,装入8,大约每秒否则LED4次
                         
    ldi r16, 0xff       ;简单设置PORTD口全为输出

    out DDRD, r16

    ldi r16, 0xde       ;初始化PORTD为0xde,可通过swap指令实现PORTD~0、1的轮流翻转点亮。

    out PORTD, r16
       
    ldi r16, 0x00       ;按要求初始化TIMER2

    out TIMSK, r16              ;TIMSK写入0,清零 OCIE2 和 TOIE2 ,       
       
    ldi r16, 0x08

    in r17, ASSR      ;置位AS2选择异步时钟,//ASSR|=0X08

    orr16,r17

    out ASSR, r16

    ldi r16, 0x00       ;TCNT2、 OCR2 、TCCR2 写入数据

    out TCNT2, r16
       
    ldi r16, 0x00

    out OCR2, r16
               
    ldi r16, 0x0f       ;CTC模式,1024分频

    out TCCR2, r16
       
Status:               ;等待 TCN2UB、 OCR2UB 和 TCR2UB 为0

    inr16,ASSR

    cpi r16,0x08

    brne Status

    ldi r16, 0xc0       ;清除中断标志//TIFR|=0XC0

    in r17, TIFR

    orr16,r17

    out TIFR, r16

    ldi r16, 0x80       ;使能比较匹配中断

    out TIMSK, r16

    sei               ;使能全局中断

Loop:

    rjmp Loop

http://cache.amobbs.com/bbs_upload782111/files_46/ourdev_680748BXCGNK.JPG
(原文件名:1.JPG)
页: [1]
查看完整版本: 汇编中断程序遇到问题,请教马老师