好吧,所以我写了一个.asm来操作3个LED,但是我很久以前就做过了,而且在命令/结构上非常生疏。我甚至无法弄清楚这个脚本究竟是做什么的!
据我所知,它以0-7(3个LED = 0-7?)的二进制计数。
我的问题是:如何在LED开启之间添加约1秒的延迟,以使其作为基本的可视二进制时钟?
非常感谢SO。
; 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
;*********************************************************************************
答案 0 :(得分:0)
是的,3个LED将从0到7计数。你需要做两件事之一。在那种pic上的指令时序是非常确定的(假设没有中断)所以如果你有一些嵌套的循环,它会烧掉一秒钟的执行时间。另一种选择是使用硬件定时器,定时器将以某种速率从系统(芯片/微控制器)时钟得到。了解时钟速率以及启用/设置的除数数量可以确定需要等待多少个时钟周期。例如,4mhz时钟是每秒400万个滴答。如果你有一个除以8的分数,你需要计算500,000个时钟滴答。例如,如果您只有一个16位计时器,则会以65536计数翻转,因此您需要等待7.629翻转。或使用不同的除数等。我将不得不重新阅读该部分的数据表,以了解您的选择。您可能希望计时器计数到50,000,然后观看它翻滚10次。最简单的是让计时器从最大计数翻到最小计数或最小计数到最大计数。例如,如果它是一个16位计数器并且它向上计数让它自由运行并自动加载以使其上升到0xFFFF,则下一个计数为0x0000。如果它倒计时然后是0x0000到0xFFFF。根据方向,如果它是16位计数器,您可以例如取一个定时器样本,称之为A,取另一个样本B,继续采样直到B-A(对于向上计数定时器)&gt; = 10,000(一些数量比计时器能力小一些。即使在翻转时,BA delta也能正常工作。当你达到10,000蜱,然后A = A + 10,000。再做一次。重复这个,直到得到你想要的蜱数。对于这个简单的例子说4mhz除以8个时钟,500,000个计数重复10,000次计数跳50次,这将是1秒。
不是在图片上,而是在其他微控制器上我有许多不同的例子http://github.com/dwelch67(在每个回购中寻找闪光灯示例)。