Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
???
05/27/07 09:03
Read: times


 
#139890 - Showing Vertical Couners
Responding to: ???'s previous message
To show an implementation of the vertical counters idea I decided to code this up. To demonstrate the performance possibilities lets say that you implemented an MCU that had 8 inputs on one byte wide port. If you polled the port repeatedly you could keep track of the pulse counts for all 8 of the inputs using code like that shown below. The sample code implements 8-bit counters for each of the inputs so that you can count up to 255 pulses before having to deal with overflow.

If this was implemented on an MCU such as a SiLabs C8051F226 part running at 25MHz you can detect properly for 8 inputs with high pulse widths up to 3.6usec wide and a period of 7.2usec. To leave a little margin estimate that this corresponds to detecting pulses for frequencies up to about 125 KHz @ 50% duty cycle. The 8-bit vertical counters implemented would be able to count pulses for up to 2 msec without overflow at this upper rate.

Included in the code is a short subroutine to fetch out any one of the 8 counters from the array of bytes that hold the vertical counter values. The extraction code has not been optimized and there are probably more time efficient ways to write that part.

Michael Karas

$XREF
$PL(78) PW(119)
$DEBUG
$SYMBOLS
$NOMOD51

#define CYGNAL_DEBUG  1             // set non-zero for enable of code mode for
                                    // cygnal debug platform.

#if CYGNAL_DEBUG
$include(c8051f200.inc)             ; register definitions compatible
                                    ; with Cygnal C8051F200
#else
$include(REG51FX.INC)               ; register definitions compatible 
                                    ; with standard Intel architecture FX cpu
#endif

;***************************************************
; SETUP THE NAMES OF THE SEGMENTS
;---------------------------------------------------

BITS_SEG    SEGMENT     BIT
DATA_SEG    SEGMENT     DATA
BUFF_SEG    SEGMENT     IDATA
CODE_SEG    SEGMENT     CODE

;***************************************************
; DATA ALLOCATIONS AND BUFFER SPACES
;---------------------------------------------------
;
;
; Variables and buffers
;
        RSEG    BITS_SEG        
TEST_BIT:
        DBIT    1                   ; sample bit declaration
;
        RSEG    DATA_SEG
PREV_VAL:
        DS      1                   ; previously sampled port value
;
BIT0_VAL:
        DS      1                   ; bit 0 of the counters (LSB)
BIT1_VAL:
        DS      1                   ; bit 1 of the counters
BIT2_VAL:
        DS      1                   ; bit 2 of the counters
BIT3_VAL:
        DS      1                   ; bit 3 of the counters
BIT4_VAL:
        DS      1                   ; bit 4 of the counters
BIT5_VAL:
        DS      1                   ; bit 5 of the counters
BIT6_VAL:
        DS      1                   ; bit 6 of the counters
BIT7_VAL:
        DS      1                   ; bit 7 of the counters
;
;
; stack support
;
        RSEG    BUFF_SEG
STACK:
        DS      10                  ; reserve 10 bytes of space

;***************************************************
; INTERRUPT VECTOR DEFINITIONS
;---------------------------------------------------

CSEG    AT      0000H               ; reset vector
        JMP     POWER_UP            ; power-on entry point

CSEG    AT      0003H               ; intr 0 vector
        CLR     EX0                 ; external int 0
        RETI                        ; not used

CSEG    AT      000BH               ; timer 0 vector
        RETI                        ; not used

CSEG    AT      0013H               ; intr 1 vector
        CLR     EX1                 ; external int 1
        RETI                        ; not used

CSEG    AT      001BH               ; timer 1 vector
        RETI                        ; not used

CSEG    AT      0023H               ; UART vector
        RETI                        ; not used

;***************************************************
; BASE OF CODE AREA
;---------------------------------------------------

        RSEG    CODE_SEG    

        USING   0                   ; use register block 0

;***************************************************
; MAIN PROGRAM INITIALIZATION
;---------------------------------------------------

POWER_UP:
        MOV     SP, #STACK          ; set stack pointer

#if CYGNAL_DEBUG
        ; disable watch dog timer
        MOV     WDTCN, #0DEh        ; Disable the WDT. 
        MOV     WDTCN, #0ADh        ; 2nd move to WDTCN must be within 
                                    ; 4 clocks of first so watch IRQs
        ; Configure the PRTnMX Registers
        MOV     PRT0MX, #005h       ; PRT0MX: Initial Reset Value
                                    ; bit 2="1" enables /INT0 pin
                                    ; bit 0="1" enables TxD and RxD pins
        MOV     PRT1MX, #000h       ; PRT1MX: Initial Reset Value
        MOV     PRT2MX, #000h       ; PRT2MX: Initial Reset Value

        ; Select Pin I/0
        ; Port configuration (1 = Push Pull Output)
        MOV     PRT0CF, #001h       ; Output configuration for P0
                                    ; bit 0="1" enables TxD pin as push pull output
        MOV     PRT1CF, #000h       ; Output configuration for P1 
        MOV     PRT2CF, #000h       ; Output configuration for P2 
        MOV     PRT3CF, #000h       ; Output configuration for P3 

        MOV     P0MODE, #0FFh       ; Input Configuration for P0
        MOV     P1MODE, #0FFh       ; Input Configuration for P1
        MOV     P2MODE, #0FFh       ; Input Configuration for P2
        MOV     P3MODE, #0FFh       ; Input Configuration for P3

        ; enable the external oscillator
        MOV     OSCXCN, #067h       ; External Oscillator Control Register  
        CLR     A
        DJNZ    ACC, $              ; wait for
        DJNZ    ACC, $              ; at least 1ms

OX_WAIT:
        MOV     A, OSCXCN
        JNB     ACC.7, OX_WAIT      ; poll XTLVLD
;
        MOV     A, OSCICN           ; Internal Oscillator Control Register
        SETB    ACC.3               ; set for external clock to be used
        MOV     OSCICN, A

        CLR     A
        MOV     CKCON, A            ; ensure timers T0, T1 & T2 run with /12 clocks

#endif
;
;
; main loop to poll 8 inouts from a port (P3) and increment counters for
; inputs that have a change in the input state. The counters are implemented
; as vertical bit slices in a series of 8 bytes.
;
; The main loop uses the B register to hold the edge detect and carry bits
; during the computational algorithm.
;
        MOV     A, P3               ; initialize the initial NOT prev_val
        CPL     A
        MOV     PREV_VAL, A     
MAIN_LOOP:                          ; main processing task
        ; edge detect logic
        MOV     B, P3               ; get the port value
        MOV     A, PREV_VAL
        ANL     A, B                ; edge bits
        XCH     A, B                ; save edge bits to B and get port_val to A
        CPL     A                   ; save NOT port bits to prev_val
        MOV     PREV_VAL, A
;
; perform bit serial increments into the vertical counters
;
        MOV     A, BIT0_VAL         ; compute the next stage carry bits
        ANL     A, B                ; ...CYout = BIT * CYin
        XCH     A, B                ; save the new carry and get previous 
        XRL     BIT0_VAL, A         ; compute XOR add for bits 0
;
        MOV     A, BIT1_VAL         ; compute the next stage carry bits
        ANL     A, B                ; ...CYout = BIT * CYin
        XCH     A, B                ; save the new carry and get previous 
        XRL     BIT1_VAL, A         ; compute XOR add for bits 1
;
        MOV     A, BIT2_VAL         ; compute the next stage carry bits
        ANL     A, B                ; ...CYout = BIT * CYin
        XCH     A, B                ; save the new carry and get previous 
        XRL     BIT2_VAL, A         ; compute XOR add for bits 2
;
        MOV     A, BIT3_VAL         ; compute the next stage carry bits
        ANL     A, B                ; ...CYout = BIT * CYin
        XCH     A, B                ; save the new carry and get previous 
        XRL     BIT3_VAL, A         ; compute XOR add for bits 3
;
        MOV     A, BIT4_VAL         ; compute the next stage carry bits
        ANL     A, B                ; ...CYout = BIT * CYin
        XCH     A, B                ; save the new carry and get previous 
        XRL     BIT4_VAL, A         ; compute XOR add for bits 4
;
        MOV     A, BIT5_VAL         ; compute the next stage carry bits
        ANL     A, B                ; ...CYout = BIT * CYin
        XCH     A, B                ; save the new carry and get previous 
        XRL     BIT5_VAL, A         ; compute XOR add for bits 5
;
        MOV     A, BIT6_VAL         ; compute the next stage carry bits
        ANL     A, B                ; ...CYout = BIT * CYin
        XCH     A, B                ; save the new carry and get previous 
        XRL     BIT6_VAL, A         ; compute XOR add for bits 6
;
        MOV     A, BIT7_VAL         ; compute the next stage carry bits
        ANL     A, B                ; ...CYout = BIT * CYin
        XCH     A, B                ; save the new carry and get previous 
        XRL     BIT7_VAL, A         ; compute XOR add for bits 7
;
        SJMP    MAIN_LOOP

;***************************************************
;NAME: BIT_MSK
;   Used to convert a bit number to a byte mask
;   Entry A is the 0-7 bit number
;   Exit A is the bit mask
;---------------------------------------------------

BIT_MSK:
        INC  A
        MOVC    A, @A+PC
        RET
;
        DB      00000001B           ; Bit 0    <-  0
        DB      00000010B           ; Bit 1    <-  1
        DB      00000100B           ; Bit 2    <-  2
        DB      00001000B           ; Bit 3    <-  3
        DB      00010000B           ; Bit 4    <-  4
        DB      00100000B           ; Bit 5    <-  5
        DB      01000000B           ; Bit 6    <-  6
        DB      10000000B           ; Bit 7    <-  7

;***************************************************
;NAME: GET_CNT
;   Used to extract a count value from the vertical
;   counter bytes. 
;   Entry A is the 0-7 counter number
;   Exit A is the counter value
;---------------------------------------------------

GET_CNT:
        CALL    BIT_MSK             ; get bit mask from counter #
        MOV     B, A                ; save mask in B
;
        CLR     A                   ; inital clear accumulate value
        PUSH    ACC     
        MOV     A, BIT0_VAL         
        ANL     A, B
        ADD     A, #0FFH            ; shift bit to carry
        POP     ACC
        RRC     A
;
        PUSH    ACC     
        MOV     A, BIT1_VAL         
        ANL     A, B
        ADD     A, #0FFH            ; shift bit to carry
        POP     ACC
        RRC     A
;
        PUSH    ACC     
        MOV     A, BIT2_VAL         
        ANL     A, B
        ADD     A, #0FFH            ; shift bit to carry
        POP     ACC
        RRC     A
;
        PUSH    ACC     
        MOV     A, BIT3_VAL         
        ANL     A, B
        ADD     A, #0FFH            ; shift bit to carry
        POP     ACC
        RRC     A
;
        PUSH    ACC     
        MOV     A, BIT4_VAL         
        ANL     A, B
        ADD     A, #0FFH            ; shift bit to carry
        POP     ACC
        RRC     A
;
        PUSH    ACC     
        MOV     A, BIT5_VAL         
        ANL     A, B
        ADD     A, #0FFH            ; shift bit to carry
        POP     ACC
        RRC     A
;
        PUSH    ACC     
        MOV     A, BIT6_VAL         
        ANL     A, B
        ADD     A, #0FFH            ; shift bit to carry
        POP     ACC
        RRC     A
;
        PUSH    ACC     
        MOV     A, BIT7_VAL         
        ANL     A, B
        ADD     A, #0FFH            ; shift bit to carry
        POP     ACC
        RRC     A
;
        RET                 
;
        END



List of 20 messages in thread
TopicAuthorDate
12 parallel pulses counting            01/01/70 00:00      
   How fast are these pulses?            01/01/70 00:00      
      pulses speed            01/01/70 00:00      
         More info            01/01/70 00:00      
         Pulse rate            01/01/70 00:00      
            Isn't it slightly more complicated?            01/01/70 00:00      
               Stretching pulses            01/01/70 00:00      
            Another Quick Way            01/01/70 00:00      
               Sampling timer with a buffer            01/01/70 00:00      
               Showing Vertical Couners            01/01/70 00:00      
            Yes other interrupt are also there            01/01/70 00:00      
               Avoid using interrupts where possible            01/01/70 00:00      
                  Run signals frequency...            01/01/70 00:00      
                     PLC can be dirt cheap            01/01/70 00:00      
                        PLCs            01/01/70 00:00      
                           an xcellent idea            01/01/70 00:00      
   Sample with 2 74LS165 parallel loadShiftRegisiters            01/01/70 00:00      
      would not the output pins drop...            01/01/70 00:00      
   No Extra Hardware Needed            01/01/70 00:00      
      No Extra Hardware Needed - I do not agree            01/01/70 00:00      

Back to Subject List