Reputation: 7979
Okay, so I've written a .asm to manipulate 3 LEDS, but I did it a long time ago and am very rusty on the commands / structure. I can't even figure out what exactly this script does!
As far as I can tell, it counts in binary from 0-7 (3 LEDs = 0-7?).
My question is: How can I add a ~1 second delay between the LEDs turning on, in order for it to function as a basic visual binary clock?
Thanks very much 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
;*********************************************************************************
Upvotes: 0
Views: 1395
Reputation: 71536
yes, 3 leds will count from 0 to 7. you need to do one of two things. instruction timing on that kind of a pic is quite deterministic (assuming no interrupts) so if you have some nested loops that burn one seconds worth of execution time that will do it. the other option is to use a hardware timer, the timer will tick at some rate derived from the system (chip/microcontroller) clock. Knowing the rate of the clock and how many divisors you have enabled/set you can determine how many clock ticks you need to wait for. For example a 4mhz clock is 4 million ticks per second. if you had a single divide by 8 you would need to count 500,000 clock ticks. if you for example only have a 16 bit timer, that rolls over at 65536 counts, so you would want to wait for 7.629 roll overs. or use a different divisor, etc. I would have to re-read the datasheet for that part to know what your options are. you might want to have the timer count to 50,000 then watch it roll over 10 times. The simplest is letting the timer roll over from max count to min count or min count to max count. For example if it is a 16 bit counter and it counts up let it free run and autoload so that it goes up to 0xFFFF then the next count is 0x0000. if it counts down then 0x0000 to 0xFFFF. Depending on the direction, if it were a 16 bit counter, you could for example take a sample of the timer, call it A, take another sample B, keep sampling until B - A (for an upcounting timer) >= 10,000 (some number smaller by a fair amount than the timers abilities. Even across the rollover the B-A delta will work. When you reach 10,000 ticks, then A = A + 10,000. do it again. Repeat this until you get then number of ticks you want. for this trivial example say 4mhz witha divide by 8 clock, 500,000 counts repeat the 10,000 count dance 50 times and that will be one second.
Not on the pic but other microcontrollers I have many different examples of this http://github.com/dwelch67 (look for the blinker examples in each repo).
Upvotes: 1