0

好的,所以我写了一个 .asm 来操作 3 个 LED,但我很久以前就做过了,对命令/结构非常生疏。我什至无法弄清楚这个脚本到底是做什么的!

据我所知,它以 0-7 的二进制计数(3 个 LED = 0-7?)。

我的问题是:如何在 LED 开启之间添加约 1 秒的延迟,以使其充当基本的视觉二进制时钟?

非常感谢。

; WRITTEN BY            JL
; DATE                  28/03/05
; FILE SAVED AS         SAMPLE6.ASM
; DEVICE                PIC16F684
; OSCILLATOR            XT (4MHZ)
; WATCHDOG              DISABLED
; FUNCTION              LEDs are switched ON in a binary sequence 
    list      p=16f684            ; list directive to define processor
    #include <p16f684.inc>        ; processor specific variable definitions
__CONFIG  _CP_OFF & _WDT_OFF &_PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _CPD_OFF

;*******************************Equates****************************************
PORTA EQU 05h
COUNT1 EQU 20h; Set up two counters to count down a delay
COUNT2 EQU 21h

;*******************************Defines****************************************
; define input/output designation for LEDs (what TRISA will equal)

#define TRIS_D0_D1  B'00001111' ; TRISIO setting for D0 and D1
#define TRIS_D2_D3  B'00101011' ; TRISIO setting for D2 and D3
#define TRIS_D4_D5  B'00011011' ; TRISIO setting for D4 and D5

; define LED state (what PORTA will equal)

#define D0_ON   B'00010000'     ; D0 LED
#define D1_ON   B'00100000'     ; D1 LED
#define D2_ON   B'00010000'     ; D2 LED

;****************************** Start of Program ******************************

           org     0x000               ; processor reset vector

;************* Initialize PortA **********
           movlw    B'00111111'     ; Set all I/O pins of PORTA as inputs
           TRIS    PORTA                
           clrf    PORTA               ; clear all outputs

;************** LED0 ON *********************
START        movlw  TRIS_D0_D1      ; move predefined value to TRISA to switch ON LED0
           TRIS    PORTA
             movlw  D0_ON              ; move predefined value to PORTA TO switch ON LED0
           movwf    PORTA
           decfsz   COUNT1,1       ;Subtract 1 from 00h (this gives 255 or FFh)
          goto     START          ;If COUNT is zero, carry on.
          decfsz   COUNT2,1       ;Subtract 1 from 00h
          goto     START          ;Go back to the start of our loop
;************** LED1 ON *********************
LOOP2       movlw   D1_ON              ; move predefined value to PORTA TO switch ON LED1
           movwf    PORTA
             decfsz   COUNT1,1       ;Subtract 1 from 00h (this gives 255 or FFh)
          goto     LOOP2          ;If COUNT is zero, carry on.
          decfsz   COUNT2,1       ;Subtract 1 from 00h
          goto     LOOP2          ;Go back to the start of our loop
;************** LED0 and LED1 ON **************
LOOP3    movlw  D0_ON              ; move predefined value to PORTA TO switch ON LED0
           movwf    PORTA
             movlw  D1_ON              ; move predefined value to PORTA TO switch ON LED1
           movwf    PORTA
          decfsz  COUNT1,1        ;Subtract 1 from 00h (this gives 255 or FFh)
          goto    LOOP3           ;If COUNT is zero, carry on.
          decfsz  COUNT2,1        ;Subtract 1 from 00h
          goto    LOOP3           ;Go back to the start of our loop
;************** LED2 ON *********************   
LOOP4        movlw  TRIS_D2_D3      ; move predefined value to TRISA to switch ON LED2
           TRIS    PORTA
             movlw  D2_ON              ; move predefined value to PORTA TO switch ON LED2
           movwf    PORTA
          decfsz   COUNT1,1       ;Subtract 1 from 00h (this gives 255 or FFh)
          goto     LOOP4          ;If COUNT is zero, carry on.
          decfsz   COUNT2,1       ;Subtract 1 from 00h
          goto     LOOP4          ;Go back to the start of our loop
;************** LED0 and LED2 ON **************
LOOP5        movlw  TRIS_D0_D1       ; move predefined value to TRISA to switch ON LED0
           TRIS    PORTA
             movlw  D0_ON               ; move predefined value to PORTA TO switch ON LED0
           movwf    PORTA
             movlw  TRIS_D2_D3       ; move predefined value to TRISA to switch ON LED2
           TRIS    PORTA
             movlw  D2_ON               ; move predefined value to PORTA TO switch ON LED2
           movwf    PORTA
            decfsz  COUNT1,1        ;Subtract 1 from 00h (this gives 255 or FFh)
          goto    LOOP5           ;If COUNT is zero, carry on.
          decfsz  COUNT2,1        ;Subtract 1 from 00h
          goto    LOOP5           ;Go back to the start of our loop
;************** LED1 and LED2 ON **************
LOOP6        clrf      PORTA               ; clear all outputs
             movlw  TRIS_D0_D1       ; move predefined value to TRISA to switch ON LED1
           TRIS    PORTA
             movlw  D1_ON               ; move predefined value to PORTA TO switch ON LED1
           movwf    PORTA
             movlw  TRIS_D2_D3       ; move predefined value to TRISA to switch ON LED2
           TRIS    PORTA
             movlw  D2_ON               ; move predefined value to PORTA TO switch ON LED2
           movwf    PORTA
            decfsz  COUNT1,1        ;Subtract 1 from 00h (this gives 255 or FFh)
          goto    LOOP6           ;If COUNT is zero, carry on.
          decfsz  COUNT2,1        ;Subtract 1 from 00h
          goto    LOOP6           ;Go back to the start of our loop
;************** LED0,LED1 and LED2 ON **************
LOOP7        movlw  TRIS_D0_D1       ; move predefined value to TRISA to switch ON LED0 and LED1
           TRIS    PORTA
             movlw  D0_ON               ; move predefined value to PORTA TO switch ON LED0
           movwf    PORTA
             movlw  D1_ON               ; move predefined value to PORTA TO switch ON LED1
           movwf    PORTA
             movlw  TRIS_D2_D3       ; move predefined value to TRISA to switch ON LED2
           TRIS    PORTA
             movlw  D2_ON               ; move predefined value to PORTA TO switch ON LED2
           movwf    PORTA
            decfsz  COUNT1,1        ;Subtract 1 from 00h (this gives 255 or FFh)
          goto    LOOP7           ;If COUNT is zero, carry on.
          decfsz  COUNT2,1        ;Subtract 1 from 00h
          goto    LOOP7           ;Go back to the start of our loop

;**********End of program *****************

          goto    START           ; indefinite loop
           END                        ; End instruction is needed by some compilers and also useful in case we miss goto instruction

;*********************************************************************************
4

1 回答 1

1

是的,3 个 LED 将从 0 计数到 7。您需要做两件事之一。那种图片上的指令时序是相当确定的(假设没有中断),所以如果你有一些嵌套循环会消耗一秒钟的执行时间,那么它就可以做到。另一种选择是使用硬件定时器,定时器将以系统(芯片/微控制器)时钟的某个速率滴答作响。了解时钟的速率以及您启用/设置了多少除数,您可以确定需要等待多少时钟滴答。例如,一个 4mhz 时钟是每秒 400 万个滴答声。如果你有一个 8 分频,你需要计算 500,000 个时钟滴答。例如,如果您只有一个 16 位计时器,它会以 65536 计数翻转,因此您需要等待 7.629 翻转。或使用不同的除数等。我将不得不重新阅读该部分的数据表以了解您的选择。您可能希望将计时器计数为 50,000,然后观看它翻转 10 次。最简单的方法是让计时器从最大计数翻转到最小计数或从最小计数翻转到最大计数。例如,如果它是一个 16 位计数器并且它向上计数,让它自由运行并自动加载,以便它上升到 0xFFFF,那么下一个计数是 0x0000。如果它倒计时,则从 0x0000 到 0xFFFF。根据方向,如果它是一个 16 位计数器,例如,您可以对定时器进行采样,将其称为 A,再采样 B,继续采样直到 B - A(对于向上计数定时器)>= 10,000(有些数字比计时器的能力小很多。即使在翻转过程中,BA delta 也会起作用。当你达到 10,000 滴答时,然后 A = A + 10,000。再做一次。重复此操作,直到获得所需的刻度数。对于这个简单的例子,假设 4mhz 除以 8 时钟,500,000 计数重复 10,000 计数舞蹈 50 次,这将是一秒。

不是在图片上,而是在其他微控制器上,我有很多不同的示例http://github.com/dwelch67(在每个 repo 中查找闪烁器示例)。

于 2012-04-24T22:11:04.237 回答