Blink8LED

Blink8LED

When asked on the forum:- To do the equivalent of the code below with each LED blinking at a different rate - except that all 8 LEDs must blink concurrently.

    PORTB = 0
    TRISB = 0

    MAIN:

    LOOP1:
      TOGGLE PORTB.0
      PAUSE 500
    GOTO LOOP1

    LOOP2:
      TOGGLE PORTB.1
      PAUSE 220
    GOTO LOOP2

    LOOP3:
      TOGGLE PORTB.2
      PAUSE 380
    GOTO LOOP1

    LOOP4:
      TOGGLE PORTB.3
      PAUSE 750
    GOTO LOOP4

    LOOP5:
      TOGGLE PORTB.4
      PAUSE 170
    GOTO LOOP5

    LOOP6:
      TOGGLE PORTB.5
      PAUSE 400
    GOTO LOOP6

    LOOP7:
      TOGGLE PORTB.6
      PAUSE 620
    GOTO LOOP7

    LOOP8:
      TOGGLE PORTB.7
      PAUSE 130
    GOTO LOOP8

    GOTO MAIN

Darrel responded with this little Gem:

I've always said PAUSE is the worst statement in the BASIC language. It got me again.

Here's a version that should compensate ... It uses the CCP module in "Compare" mode to create a precise 10mS interval. So when you give a delay value of 50, it actually takes 500mS, on the nose.

DEFINE OSC 4
DEFINE BLINKYFREQ 100  ; 10mS periods

DATA 50,22,38,75,17,40,62,13  ; default periods for each Output
;----------------------------------------------------------------
CCPR1val  CON EXT      : @CCPR1val = (OSC*1000000/4)/ BLINKYFREQ
CCPR1     VAR WORD EXT : @CCPR1 = CCPR1L
Timer1    VAR WORD EXT : @Timer1 = TMR1L
CCPIF     VAR PIR1.2

LoopLED   VAR BYTE[8]
LoopCON   VAR BYTE[8]
x         VAR BYTE

;----[Initialize]------------------------------------------------
FOR x = 0 to 7         ; load the periods from EEPROM
    READ x, LoopCON(x)
NEXT X
;-- setup CCP1 and Start Timer1 --
CCPR1   = CCPR1val     ; set compare value
CCP1CON = %00001011    ; compare mode, special event 
Timer1  = 0            ; clear Timer1
T1CON.0 = 1            ; start Timer1

TRISB = 0              ; PORTB all OUTPUT

;----[Main Program Loop]----------------------------------------
Main: 
    x = (x + 1) // 8
    PORTB.0(x) = !(LoopLED(x) < LoopCON(x))
    LoopLED(x) = (LoopLED(x) + 1) // (LoopCON(x) << 1)
    IF x != 7 THEN Main
  Waiting: IF !CCPIF THEN Waiting
    CCPIF = 0
GOTO Main

Code:
'****************************************************************
'*  Name    : HWTX.BAS                                          *
'*  Author  : Henrik Olsson                                     *
'*  Notice  : Copyright (c) 2010 Henrik Olsson 2010             *
'*          : All Rights NOT Reserved - use as you see fit.     *
'*  Date    : 2010-11-16                                        *
'*  Version : 0.0                                               *
'*  Notes   : Test for interrupt based USART transmit using     *
'*          : DT_ints-18 on a 18F4520                           *
'****************************************************************
DEFINE LOADER_USED 1                ' We're using a bootloader
DEFINE OSC 20                       ' 20Mhz x-tal is used
DEFINE HSER_BAUD 38400              ' Baudrate is 38400
CMCON = 7                           ' Comparators OFF 
ADCON1 = %00001111                  ' No analog inputs
TRISC.7 = 1                         ' RxPin is input
TRISC.6 = 0                         ' TxPin is output
TRISB.0 = 1                         ' PortB.0 is input
TxBuffer VAR BYTE[128]              ' Transmit buffer array.
TxPointer VAR Byte                  ' Pointer into the above array
INCLUDE "DT_INTS-18.bas"            ' Include Darrels interrupt engine.
INCLUDE "ReEnterPBP-18.bas"         ' And the stub needed for interrupts in PBP 

ASM                                 ; Set up the USART transmit interrupt.
INT_LIST  macro     ; IntSource,   Label,    Type, ResetFlag?
        INT_Handler    TX_INT,   _USART_TX,   PBP,    no
    endm
    INT_CREATE                      ; Creates the interrupt processor
ENDASM
Boot:
  HSEROUT ["Program start",13]        ' A dummy HSEROUT here to init the USART and show we're alive.

  ' Now load the array with something we want to send. The string is, in this case, terminated with a CR (13).
  ArrayWrite TxBuffer,["This is the TX Array Buffer and we're sending it with an interupt based routine",13]

Main: 
  If PortB.0 = 0 then                 ' PortB.0 going low is what
    TxPointer = 0                     ' Initialize pointer to beginning of array
@   INT_ENABLE   TX_INT               ; Enable USART TX interrupt  
    Pause 100                         ' Simple debounce for the button
  ENDIF
  Goto Main                           ' And do it again.

USART_TX:
  TXREG = TxBuffer[TxPointer]       ' Load character from array into USART TX register
  If TxBuffer[TxPointer] = 13 then  ' If that character was a CR we're done so we.....
@   INT_DISABLE  TX_INT             ; ...disable the any further USART TX interrupts.
  ELSE                              ' If the character was not a CR we.....
    TxPointer = TxPointer + 1       ' ...increase prepare to send the next character.
  ENDIF
@ INT_RETURN     

Page last modified on March 24, 2018, at 11:38 PM