Loading ...
Sorry, an error occurred while loading the content.

Dual-Digit Binary-to-Hexadecimal Decoder IC

Expand Messages
  • mikemclaren6502
    Someone on another forum mentioned having difficulty finding binary-to-hexadecimal decoder ICs which reminded me of a solution I came up with several years ago
    Message 1 of 11 , Mar 31, 2014
    Someone on another forum mentioned having difficulty finding binary-to-hexadecimal decoder ICs which reminded me of a solution I came up with several years ago that used an 18-pin PIC.  I thought I'd post it here in the hope that someone may find it useful.  I would probably use a more recent and less expensive PIC like an 18-pin 16F1527 ($1.73) or a 20-pin 16F1507 ($1.53) instead of the 16F628A.  Please note that you would still need a latch IC of some kind for each decoder IC.

    Cheerful regards, Mike


    ;******************************************************************
    ;                                                                 *
    ;   Filename: Forum 4477 IC v1.asm                                *
    ;     Author: Mike McLaren, K8LH                                  *
    ;       Date: 14-Sep-07  (rev 29-Sep-07)                          *
    ;                                                                 *
    ;   8-bit Hex to Dual 7-Segment LED Decoder/Driver IC Firmware    *
    ;                                                                 *
    ;   Uses a 16F628A with a 4-MHz INTOSC and Eric Gibbs standard    *
    ;   multiplexed dual-digit common cathode display circuit         *
    ;                                                                 *
    ;   Digit 1 (left) inputs are RA7..RA4 (msb..lsb)                 *
    ;   Digit 2 (right) inputs are RA3..RA0 (msb..lsb)                *
    ;   Segments A..G connected to RB0..RB6 via 330 ohm resistors     *
    ;   Common cathodes connect to RB7 via a 2 transistor circuit     *
    ;                                                                 *
    ;      MPLab: 7.40    (tabs=8)                                    *
    ;      MPAsm: 5.03                                                *
    ;                                                                 *
    ;******************************************************************

            #include        <p16f628a.inc>
            errorlevel      -302

            radix   dec

      __config  _MCLRE_OFF & _LVP_OFF & _WDT_OFF & _INTOSC_OSC_NOCLKOUT

    ;
    ;  variables
    ;
    digsel  equ     0x21            ; digit select bit b7
    delayhi equ     0x22            ; DelayCy() subsystem var'

    ;==================================================================
    ;  K8LH DelayCy() subsystem macro generates four instructions  =
    ;==================================================================
            radix   dec
    clock   equ     4               ; 4, 8, 12, 16, 20 (MHz), etc.
    usecs   equ     clock/4         ; cycles/microsecond multiplier
    msecs   equ     clock/4*1000    ; cycles/millisecond multiplier

    DelayCy macro   delay           ; 11..327690 cycle range
            movlw   high((delay-11)/5)+1
            movwf   delayhi
            movlw   low ((delay-11)/5)
            call    uDelay-((delay-11)%5)
            endm

    ;******************************************************************
    ;  Reset vector                                                   *
    ;******************************************************************

            org     0x0000
    v_reset
            clrf    STATUS          ; force bank 0                    |B0
    ;
    ;  // psuedo C code program example
    ;
    ;  char segdata [] = { 0b00111111,      // "0"   -|-|F|E|D|C|B|A
    ;                      0b00000110,      // "1"   -|-|-|-|-|C|B|-
    ;                      0b01011011,      // "2"   -|G|-|E|D|-|B|A
    ;                      0b01001111,      // "3"   -|G|-|-|D|C|B|A
    ;                      0b01100110,      // "4"   -|G|F|-|-|C|B|-
    ;                      0b01101101,      // "5"   -|G|F|-|D|C|-|A
    ;                      0b01111101,      // "6"   -|G|F|E|D|C|-|A
    ;                      0b00000111,      // "7"   -|-|-|-|-|C|B|A
    ;                      0b01111111,      // "8"   -|G|F|E|D|C|B|A
    ;                      0b01101111,      // "9"   -|G|F|-|D|C|B|A
    ;                      0b01110111,      // "A"   -|G|F|E|-|C|B|A
    ;                      0b01111100,      // "b"   -|G|F|E|D|C|-|-
    ;                      0b00111001,      // "C"   -|-|F|E|D|-|-|A
    ;                      0b01011110,      // "d"   -|G|-|E|D|C|B|-
    ;                      0b01111001,      // "E"   -|G|F|E|D|-|-|A
    ;                      0b01110001 };    // "F"   -|G|F|E|-|-|-|A
    ;
    ;  void Main()
    ;  { static unsigned char digsel = 0;   // digit select, 0 or 128
    ;    cmcon = 7;                         // turn comparator off
    ;    trisa = 255;                       // Port A all inputs
    ;    trisb = 0;                         // Port B all outputs
    ;    while(1)                           // loop forever
    ;    { unsigned char work = porta;      // sample inputs
    ;      if(digsel)                       // if left (hi) digit
    ;        work /= 16;                    // use hi nibble, 0..F
    ;      else                             // otherwise
    ;        work &= 15;                    // use lo nibble, 0..F
    ;      work = segdata[work];            // get segment data
    ;      work |= digsel;                  // pick up digit select bit
    ;      portb = work;                    // update display
    ;      DelayMS(8);                      // ~60 Hz refresh rate
    ;      digsel ^= 128;                   // toggle digit select bit
    ;    }                                  //
    ;  }                                    //
    ;
            movlw   h'07'           ; turn comparator off             |B0
            movwf   CMCON           ; for digital I/O                 |B0
    ;
    ;  setup ports and display sub-system variables
    ;
            bsf     STATUS,RP0      ; bank 1                          |B1
            movlw   h'FF'           ;                                 |B1
            movwf   TRISA           ; make Port A all inputs          |B1
            clrf    TRISB           ; make Port B all outputs         |B1
            bcf     STATUS,RP0      ; bank 0                          |B0
            clrf    digsel          ; init b7 digit select bit        |B0
    ;
    ;  isochronous loop (8-mS, 50% duty cycle, 62.5 Hz refresh rate)
    ;
    Display
            swapf   PORTA,W         ; W = hi nybble in b3..b0 bits    |B0
            btfss   digsel,7        ; left digit? yes, skip, else     |B0
            movf    PORTA,W         ; W = lo nybble in b3..b0 bits    |B0
            andlw   b'00001111'     ; mask off upper 4 bits           |B0
            call    SegData         ; get segment data in W           |B0
            iorwf   digsel,W        ; add digit select bit in b7      |B0
            movwf   PORTB           ; display new digit               |B0
            DelayCy(8*msecs-16)     ; 8-msecs minus 16 cycles         |B0
            movlw   b'10000000'     ; mask for digit select bit       |B0
            xorwf   digsel,F        ; toggle b7 digit select bit      |B0
            goto    Display         ; loop forever                    |B0

    ;******************************************************************
    ;  Subroutines                                                    *
    ;******************************************************************

    SegData
            addwf   PCL,F           ;                                 |B0
            retlw   b'00111111'     ; "0"   -|-|F|E|D|C|B|A
            retlw   b'00000110'     ; "1"   -|-|-|-|-|C|B|-
            retlw   b'01011011'     ; "2"   -|G|-|E|D|-|B|A
            retlw   b'01001111'     ; "3"   -|G|-|-|D|C|B|A
            retlw   b'01100110'     ; "4"   -|G|F|-|-|C|B|-
            retlw   b'01101101'     ; "5"   -|G|F|-|D|C|-|A
            retlw   b'01111101'     ; "6"   -|G|F|E|D|C|-|A
            retlw   b'00000111'     ; "7"   -|-|-|-|-|C|B|A
            retlw   b'01111111'     ; "8"   -|G|F|E|D|C|B|A
            retlw   b'01101111'     ; "9"   -|G|F|-|D|C|B|A
            retlw   b'01110111'     ; "A"   -|G|F|E|-|C|B|A
            retlw   b'01111100'     ; "b"   -|G|F|E|D|C|-|-
            retlw   b'00111001'     ; "C"   -|-|F|E|D|-|-|A
            retlw   b'01011110'     ; "d"   -|G|-|E|D|C|B|-
            retlw   b'01111001'     ; "E"   -|G|F|E|D|-|-|A
            retlw   b'01110001'     ; "F"   -|G|F|E|-|-|-|A

    ;******************************************************************
    ;  K8LH DelayCy() subsystem 16-bit uDelay subroutine              *
    ;******************************************************************

            nop                     ; entry for (delay-11)%5 == 4     |B0
            nop                     ; entry for (delay-11)%5 == 3     |B0
            nop                     ; entry for (delay-11)%5 == 2     |B0
            nop                     ; entry for (delay-11)%5 == 1     |B0
    uDelay  addlw   -1              ; subtract 5 cycle loop time      |B0
            skpc                    ; borrow? no, skip, else          |B0
            decfsz  delayhi,F       ; done?  yes, skip, else          |B0
            goto    uDelay          ; do another loop                 |B0
            return                  ;                                 |B0

    ;******************************************************************
            end

  • Raymond Siminas
    There is also a pic varsion at picprojects.org that can use either common anode or common cathode displays.  Here is a link to the page.
    Message 2 of 11 , Mar 31, 2014
    • 0 Attachment
      There is also a pic varsion at picprojects.org that can use either common anode or common cathode displays.  Here is a link to the page.

      http://picprojects.org/projects/decoder7/

      This seems to be a really cool place.  I bought and built one of their 5 x 5 x 5 LED cubes.
       
       


      From: "mikemclaren6502@..." <mikemclaren6502@...>
      To: cosmacelf@yahoogroups.com
      Sent: Monday, March 31, 2014 9:31 AM
      Subject: [cosmacelf] Dual-Digit Binary-to-Hexadecimal Decoder IC [2 Attachments]

       
      Someone on another forum mentioned having difficulty finding binary-to-hexadecimal decoder ICs which reminded me of a solution I came up with several years ago that used an 18-pin PIC.  I thought I'd post it here in the hope that someone may find it useful.  I would probably use a more recent and less expensive PIC like an 18-pin 16F1527 ($1.73) or a 20-pin 16F1507 ($1.53) instead of the 16F628A.  Please note that you would still need a latch IC of some kind for each decoder IC.

      Cheerful regards, Mike


      ;******************************************************************
      ;                                                                 *
      ;   Filename: Forum 4477 IC v1.asm                                *
      ;     Author: Mike McLaren, K8LH                                  *
      ;       Date: 14-Sep-07  (rev 29-Sep-07)                          *
      ;                                                                 *
      ;   8-bit Hex to Dual 7-Segment LED Decoder/Driver IC Firmware    *
      ;                                                                 *
      ;   Uses a 16F628A with a 4-MHz INTOSC and Eric Gibbs standard    *
      ;   multiplexed dual-digit common cathode display circuit         *
      ;                                                                 *
      ;   Digit 1 (left) inputs are RA7..RA4 (msb..lsb)                 *
      ;   Digit 2 (right) inputs are RA3..RA0 (msb..lsb)                *
      ;   Segments A..G connected to RB0..RB6 via 330 ohm resistors     *
      ;   Common cathodes connect to RB7 via a 2 transistor circuit     *
      ;                                                                 *
      ;      MPLab: 7.40    (tabs=8)                                    *
      ;      MPAsm: 5.03                                                *
      ;                                                                 *
      ;******************************************************************

              #include        <p16f628a.inc>
              errorlevel      -302

              radix   dec

        __config  _MCLRE_OFF & _LVP_OFF & _WDT_OFF & _INTOSC_OSC_NOCLKOUT

      ;
      ;  variables
      ;
      digsel  equ     0x21            ; digit select bit b7
      delayhi equ     0x22            ; DelayCy() subsystem var'

      ;==================================================================
      ;  K8LH DelayCy() subsystem macro generates four instructions  =
      ;==================================================================
              radix   dec
      clock   equ     4               ; 4, 8, 12, 16, 20 (MHz), etc.
      usecs   equ     clock/4         ; cycles/microsecond multiplier
      msecs   equ     clock/4*1000    ; cycles/millisecond multiplier

      DelayCy macro   delay           ; 11..327690 cycle range
              movlw   high((delay-11)/5)+1
              movwf   delayhi
              movlw   low ((delay-11)/5)
              call    uDelay-((delay-11)%5)
              endm

      ;******************************************************************
      ;  Reset vector                                                   *
      ;******************************************************************

              org     0x0000
      v_reset
              clrf    STATUS          ; force bank 0                    |B0
      ;
      ;  // psuedo C code program example
      ;
      ;  char segdata [] = { 0b00111111,      // "0"   -|-|F|E|D|C|B|A
      ;                      0b00000110,      // "1"   -|-|-|-|-|C|B|-
      ;                      0b01011011,      // "2"   -|G|-|E|D|-|B|A
      ;                      0b01001111,      // "3"   -|G|-|-|D|C|B|A
      ;                      0b01100110,      // "4"   -|G|F|-|-|C|B|-
      ;                      0b01101101,      // "5"   -|G|F|-|D|C|-|A
      ;                      0b01111101,      // "6"   -|G|F|E|D|C|-|A
      ;                      0b00000111,      // "7"   -|-|-|-|-|C|B|A
      ;                      0b01111111,      // "8"   -|G|F|E|D|C|B|A
      ;                      0b01101111,      // "9"   -|G|F|-|D|C|B|A
      ;                      0b01110111,      // "A"   -|G|F|E|-|C|B|A
      ;                      0b01111100,      // "b"   -|G|F|E|D|C|-|-
      ;                      0b00111001,      // "C"   -|-|F|E|D|-|-|A
      ;                      0b01011110,      // "d"   -|G|-|E|D|C|B|-
      ;                      0b01111001,      // "E"   -|G|F|E|D|-|-|A
      ;                      0b01110001 };    // "F"   -|G|F|E|-|-|-|A
      ;
      ;  void Main()
      ;  { static unsigned char digsel = 0;   // digit select, 0 or 128
      ;    cmcon = 7;                         // turn comparator off
      ;    trisa = 255;                       // Port A all inputs
      ;    trisb = 0;                         // Port B all outputs
      ;    while(1)                           // loop forever
      ;    { unsigned char work = porta;      // sample inputs
      ;      if(digsel)                       // if left (hi) digit
      ;        work /= 16;                    // use hi nibble, 0..F
      ;      else                             // otherwise
      ;        work &= 15;                    // use lo nibble, 0..F
      ;      work = segdata[work];            // get segment data
      ;      work |= digsel;                  // pick up digit select bit
      ;      portb = work;                    // update display
      ;      DelayMS(8);                      // ~60 Hz refresh rate
      ;      digsel ^= 128;                   // toggle digit select bit
      ;    }                                  //
      ;  }                                    //
      ;
              movlw   h'07'           ; turn comparator off             |B0
              movwf   CMCON           ; for digital I/O                 |B0
      ;
      ;  setup ports and display sub-system variables
      ;
              bsf     STATUS,RP0      ; bank 1                          |B1
              movlw   h'FF'           ;                                 |B1
              movwf   TRISA           ; make Port A all inputs          |B1
              clrf    TRISB           ; make Port B all outputs         |B1
              bcf     STATUS,RP0      ; bank 0                          |B0
              clrf    digsel          ; init b7 digit select bit        |B0
      ;
      ;  isochronous loop (8-mS, 50% duty cycle, 62.5 Hz refresh rate)
      ;
      Display
              swapf   PORTA,W         ; W = hi nybble in b3..b0 bits    |B0
              btfss   digsel,7        ; left digit? yes, skip, else     |B0
              movf    PORTA,W         ; W = lo nybble in b3..b0 bits    |B0
              andlw   b'00001111'     ; mask off upper 4 bits           |B0
              call    SegData         ; get segment data in W           |B0
              iorwf   digsel,W        ; add digit select bit in b7      |B0
              movwf   PORTB           ; display new digit               |B0
              DelayCy(8*msecs-16)     ; 8-msecs minus 16 cycles         |B0
              movlw   b'10000000'     ; mask for digit select bit       |B0
              xorwf   digsel,F        ; toggle b7 digit select bit      |B0
              goto    Display         ; loop forever                    |B0

      ;******************************************************************
      ;  Subroutines                                                    *
      ;******************************************************************

      SegData
              addwf   PCL,F           ;                                 |B0
              retlw   b'00111111'     ; "0"   -|-|F|E|D|C|B|A
              retlw   b'00000110'     ; "1"   -|-|-|-|-|C|B|-
              retlw   b'01011011'     ; "2"   -|G|-|E|D|-|B|A
              retlw   b'01001111'     ; "3"   -|G|-|-|D|C|B|A
              retlw   b'01100110'     ; "4"   -|G|F|-|-|C|B|-
              retlw   b'01101101'     ; "5"   -|G|F|-|D|C|-|A
              retlw   b'01111101'     ; "6"   -|G|F|E|D|C|-|A
              retlw   b'00000111'     ; "7"   -|-|-|-|-|C|B|A
              retlw   b'01111111'     ; "8"   -|G|F|E|D|C|B|A
              retlw   b'01101111'     ; "9"   -|G|F|-|D|C|B|A
              retlw   b'01110111'     ; "A"   -|G|F|E|-|C|B|A
              retlw   b'01111100'     ; "b"   -|G|F|E|D|C|-|-
              retlw   b'00111001'     ; "C"   -|-|F|E|D|-|-|A
              retlw   b'01011110'     ; "d"   -|G|-|E|D|C|B|-
              retlw   b'01111001'     ; "E"   -|G|F|E|D|-|-|A
              retlw   b'01110001'     ; "F"   -|G|F|E|-|-|-|A

      ;******************************************************************
      ;  K8LH DelayCy() subsystem 16-bit uDelay subroutine              *
      ;******************************************************************

              nop                     ; entry for (delay-11)%5 == 4     |B0
              nop                     ; entry for (delay-11)%5 == 3     |B0
              nop                     ; entry for (delay-11)%5 == 2     |B0
              nop                     ; entry for (delay-11)%5 == 1     |B0
      uDelay  addlw   -1              ; subtract 5 cycle loop time      |B0
              skpc                    ; borrow? no, skip, else          |B0
              decfsz  delayhi,F       ; done?  yes, skip, else          |B0
              goto    uDelay          ; do another loop                 |B0
              return                  ;                                 |B0

      ;******************************************************************
              end



    • Mark Graybill
      And if AVR is simpler than PIC for someone s specific circumstances, there s this: http://saundby.com/electronics/AVR/ Both single and dual digit drivers, CA
      Message 3 of 11 , Apr 2 5:13 PM
      • 0 Attachment
        And if AVR is simpler than PIC for someone's specific circumstances, there's this:

        Both single and dual digit drivers, CA or CC selectable, your choice of duty cycles, the dual digit driver will do either 7 segment or 10/14 segment displays.

        Mark Graybill
        ---------------------------------------------------------------
        Electronics, Books, Video Games, etc.

        On Mar 31, 2014, at 9:31 AM, <mikemclaren6502@...> <mikemclaren6502@...> wrote:

         

        Someone on another forum mentioned having difficulty finding binary-to-hexadecimal decoder ICs which reminded me of a solution I came up with several years ago that used an 18-pin PIC.  I thought I'd post it here in the hope that someone may find it useful.  I would probably use a more recent and less expensive PIC like an 18-pin 16F1527 ($1.73) or a 20-pin 16F1507 ($1.53) instead of the 16F628A.  Please note that you would still need a latch IC of some kind for each decoder IC.


        Cheerful regards, Mike


        ;******************************************************************
        ;                                                                 *
        ;   Filename: Forum 4477 IC v1.asm                                *
        ;     Author: Mike McLaren, K8LH                                  *
        ;       Date: 14-Sep-07  (rev 29-Sep-07)                          *
        ;                                                                 *
        ;   8-bit Hex to Dual 7-Segment LED Decoder/Driver IC Firmware    *
        ;                                                                 *
        ;   Uses a 16F628A with a 4-MHz INTOSC and Eric Gibbs standard    *
        ;   multiplexed dual-digit common cathode display circuit         *
        ;                                                                 *
        ;   Digit 1 (left) inputs are RA7..RA4 (msb..lsb)                 *
        ;   Digit 2 (right) inputs are RA3..RA0 (msb..lsb)                *
        ;   Segments A..G connected to RB0..RB6 via 330 ohm resistors     *
        ;   Common cathodes connect to RB7 via a 2 transistor circuit     *
        ;                                                                 *
        ;      MPLab: 7.40    (tabs=8)                                    *
        ;      MPAsm: 5.03                                                *
        ;                                                                 *
        ;******************************************************************

                #include        <p16f628a.inc>
                errorlevel      -302

                radix   dec

          __config  _MCLRE_OFF & _LVP_OFF & _WDT_OFF & _INTOSC_OSC_NOCLKOUT

        ;
        ;  variables
        ;
        digsel  equ     0x21            ; digit select bit b7
        delayhi equ     0x22            ; DelayCy() subsystem var'

        ;==================================================================
        ;  K8LH DelayCy() subsystem macro generates four instructions  =
        ;==================================================================
                radix   dec
        clock   equ     4               ; 4, 8, 12, 16, 20 (MHz), etc.
        usecs   equ     clock/4         ; cycles/microsecond multiplier
        msecs   equ     clock/4*1000    ; cycles/millisecond multiplier

        DelayCy macro   delay           ; 11..327690 cycle range
                movlw   high((delay-11)/5)+1
                movwf   delayhi
                movlw   low ((delay-11)/5)
                call    uDelay-((delay-11)%5)
                endm

        ;******************************************************************
        ;  Reset vector                                                   *
        ;******************************************************************

                org     0x0000
        v_reset
                clrf    STATUS          ; force bank 0                    |B0
        ;
        ;  // psuedo C code program example
        ;
        ;  char segdata [] = { 0b00111111,      // "0"   -|-|F|E|D|C|B|A
        ;                      0b00000110,      // "1"   -|-|-|-|-|C|B|-
        ;                      0b01011011,      // "2"   -|G|-|E|D|-|B|A
        ;                      0b01001111,      // "3"   -|G|-|-|D|C|B|A
        ;                      0b01100110,      // "4"   -|G|F|-|-|C|B|-
        ;                      0b01101101,      // "5"   -|G|F|-|D|C|-|A
        ;                      0b01111101,      // "6"   -|G|F|E|D|C|-|A
        ;                      0b00000111,      // "7"   -|-|-|-|-|C|B|A
        ;                      0b01111111,      // "8"   -|G|F|E|D|C|B|A
        ;                      0b01101111,      // "9"   -|G|F|-|D|C|B|A
        ;                      0b01110111,      // "A"   -|G|F|E|-|C|B|A
        ;                      0b01111100,      // "b"   -|G|F|E|D|C|-|-
        ;                      0b00111001,      // "C"   -|-|F|E|D|-|-|A
        ;                      0b01011110,      // "d"   -|G|-|E|D|C|B|-
        ;                      0b01111001,      // "E"   -|G|F|E|D|-|-|A
        ;                      0b01110001 };    // "F"   -|G|F|E|-|-|-|A
        ;
        ;  void Main()
        ;  { static unsigned char digsel = 0;   // digit select, 0 or 128
        ;    cmcon = 7;                         // turn comparator off
        ;    trisa = 255;                       // Port A all inputs
        ;    trisb = 0;                         // Port B all outputs
        ;    while(1)                           // loop forever
        ;    { unsigned char work = porta;      // sample inputs
        ;      if(digsel)                       // if left (hi) digit
        ;        work /= 16;                    // use hi nibble, 0..F
        ;      else                             // otherwise
        ;        work &= 15;                    // use lo nibble, 0..F
        ;      work = segdata[work];            // get segment data
        ;      work |= digsel;                  // pick up digit select bit
        ;      portb = work;                    // update display
        ;      DelayMS(8);                      // ~60 Hz refresh rate
        ;      digsel ^= 128;                   // toggle digit select bit
        ;    }                                  //
        ;  }                                    //
        ;
                movlw   h'07'           ; turn comparator off             |B0
                movwf   CMCON           ; for digital I/O                 |B0
        ;
        ;  setup ports and display sub-system variables
        ;
                bsf     STATUS,RP0      ; bank 1                          |B1
                movlw   h'FF'           ;                                 |B1
                movwf   TRISA           ; make Port A all inputs          |B1
                clrf    TRISB           ; make Port B all outputs         |B1
                bcf     STATUS,RP0      ; bank 0                          |B0
                clrf    digsel          ; init b7 digit select bit        |B0
        ;
        ;  isochronous loop (8-mS, 50% duty cycle, 62.5 Hz refresh rate)
        ;
        Display
                swapf   PORTA,W         ; W = hi nybble in b3..b0 bits    |B0
                btfss   digsel,7        ; left digit? yes, skip, else     |B0
                movf    PORTA,W         ; W = lo nybble in b3..b0 bits    |B0
                andlw   b'00001111'     ; mask off upper 4 bits           |B0
                call    SegData         ; get segment data in W           |B0
                iorwf   digsel,W        ; add digit select bit in b7      |B0
                movwf   PORTB           ; display new digit               |B0
                DelayCy(8*msecs-16)     ; 8-msecs minus 16 cycles         |B0
                movlw   b'10000000'     ; mask for digit select bit       |B0
                xorwf   digsel,F        ; toggle b7 digit select bit      |B0
                goto    Display         ; loop forever                    |B0

        ;******************************************************************
        ;  Subroutines                                                    *
        ;******************************************************************

        SegData
                addwf   PCL,F           ;                                 |B0
                retlw   b'00111111'     ; "0"   -|-|F|E|D|C|B|A
                retlw   b'00000110'     ; "1"   -|-|-|-|-|C|B|-
                retlw   b'01011011'     ; "2"   -|G|-|E|D|-|B|A
                retlw   b'01001111'     ; "3"   -|G|-|-|D|C|B|A
                retlw   b'01100110'     ; "4"   -|G|F|-|-|C|B|-
                retlw   b'01101101'     ; "5"   -|G|F|-|D|C|-|A
                retlw   b'01111101'     ; "6"   -|G|F|E|D|C|-|A
                retlw   b'00000111'     ; "7"   -|-|-|-|-|C|B|A
                retlw   b'01111111'     ; "8"   -|G|F|E|D|C|B|A
                retlw   b'01101111'     ; "9"   -|G|F|-|D|C|B|A
                retlw   b'01110111'     ; "A"   -|G|F|E|-|C|B|A
                retlw   b'01111100'     ; "b"   -|G|F|E|D|C|-|-
                retlw   b'00111001'     ; "C"   -|-|F|E|D|-|-|A
                retlw   b'01011110'     ; "d"   -|G|-|E|D|C|B|-
                retlw   b'01111001'     ; "E"   -|G|F|E|D|-|-|A
                retlw   b'01110001'     ; "F"   -|G|F|E|-|-|-|A

        ;******************************************************************
        ;  K8LH DelayCy() subsystem 16-bit uDelay subroutine              *
        ;******************************************************************

                nop                     ; entry for (delay-11)%5 == 4     |B0
                nop                     ; entry for (delay-11)%5 == 3     |B0
                nop                     ; entry for (delay-11)%5 == 2     |B0
                nop                     ; entry for (delay-11)%5 == 1     |B0
        uDelay  addlw   -1              ; subtract 5 cycle loop time      |B0
                skpc                    ; borrow? no, skip, else          |B0
                decfsz  delayhi,F       ; done?  yes, skip, else          |B0
                goto    uDelay          ; do another loop                 |B0
                return                  ;                                 |B0

        ;******************************************************************
                end



      • mikemclaren6502
        ... Very nice, Mark... Now you have me wondering if I could use a 28-pin PIC for a 4-digit 1802 address display? If so, could it do double duty as the high
        Message 4 of 11 , Apr 3 4:23 AM
        • 1 Attachment
        • 252 KB
        >Mark wrote:
        >And if AVR is simpler than PIC for someone's specific circumstances, there's 
        >
        >Both single and dual digit drivers, CA or CC selectable, your choice of duty cycles, the 
        >dual digit driver will do either 7 segment or 10/14 segment displays.

        Very nice, Mark... Now you have me wondering if I could use a 28-pin PIC for a 4-digit '1802 address display?  If so, could it do double duty as the high address latch?  Where in the timing diagram would I capture the low address for the display?  At the rising edge of TPB, perhaps?

        Regards, Mike

      • ted_rossin
        I played some of these games with my 1802 and 1861 emulators using PIC processors: http://www.tedrossin.net46.net/Electronics/Pic/Pic.html#ElfClone
        Message 5 of 11 , Apr 3 1:48 PM
        • 0 Attachment

          I played some of these games with my 1802 and 1861 emulators using PIC processors:

           

              http://www.tedrossin.net46.net/Electronics/Pic/Pic.html#ElfClone

           

          The problem is that using a 16F series PICs the instructions take 200ns each.  With the 18F series PICs the instructions take 100ns each.  With an 1802 running at 2 MHz, timing pulse A is just a clock cycle long which is 500ns.  To detect TPA you need a loop reading the port (1 instruction), then a test and branch (2 instruction cycles).  For a 16F series PIC, that is 600ns so you might miss TPA.  For the 18F series PIC, that is only 300ns so you should be set.  You should be able to use the 8MHz internal OSC with 4x PLL multiplier to run at 32MHz which (4 clocks per instruction cycle) gives a 125ns/instruction.  Multiply by 3 for the loop and you get 375ns which should work out without an external clock.

           

          I think there is some hardware in the PIC that I used for the 1861 emulator (it has been a while now) to detect a rising edge in the capture/compare peripheral.  I think this is also in the 16F series parts and if so, that will allow you to detect a "quick" pulse and use the part as an address latch.

           

          The 18F2620 that I used for the 1861 should do the trick.  You could use one with less code and data space but usually, they cost about the same due to volumes.  So with no clock and if you configure the pins for the OSC to be I/O you get a total of 21 I/Os:

              8 bit input multiplexed address input

              1 bit input TPA

              7 bit multiplexed segment driver

              4 bit digit driver

          Total of 20 pins.  So, this should work.

          If you can't get a handle on the capture compare logic, your polling loop would have to have another check to refresh the display which would make timing a bit tight.  I took a loop at the 18F2620 spec and the capture compare module will do the trick.  It has a rising or falling edge detector that will set a bit.  You don't have long to capture the high order address (maybe 1/2 to 1 1802 clock cycle) but this should allow a little more time to handle refreshing the multiplexed display.  I don't think you can use interrupts as the enter/exit time will eat up too many cycles.

           

          Sorry for all the words.

        • John Porubek
          No problem when they re such insightful words! -John
          Message 6 of 11 , Apr 3 2:18 PM
          • 0 Attachment
            No problem when they're such insightful words!

            -John


            On Thu, Apr 3, 2014 at 4:48 PM, <ted_rossin@...> wrote:

            <snip>

            Sorry for all the words.

          • bill rowe
            Another way to go would be to generate the 1802 s clock yourself so you could stretch the particular cycles you needed to check something on. To:
            Message 7 of 11 , Apr 3 2:24 PM
            • 0 Attachment

              Another way to go would be to generate the 1802's clock yourself so you could stretch the particular cycles you needed to check something on.


              To: cosmacelf@yahoogroups.com
              From: ted_rossin@...
              Date: Thu, 3 Apr 2014 13:48:14 -0700
              Subject: Re: [cosmacelf] Dual-Digit Binary-to-Hexadecimal Decoder IC

               

              I played some of these games with my 1802 and 1861 emulators using PIC processors:
               
                  http://www.tedrossin.net46.net/Electronics/Pic/Pic.html#ElfClone
               
              The problem is that using a 16F series PICs the instructions take 200ns each.  With the 18F series PICs the instructions take 100ns each.  With an 1802 running at 2 MHz, timing pulse A is just a clock cycle long which is 500ns.  To detect TPA you need a loop reading the port (1 instruction), then a test and branch (2 instruction cycles).  For a 16F series PIC, that is 600ns so you might miss TPA.  For the 18F series PIC, that is only 300ns so you should be set.  You should be able to use the 8MHz internal OSC with 4x PLL multiplier to run at 32MHz which (4 clocks per instruction cycle) gives a 125ns/instruction.  Multiply by 3 for the loop and you get 375ns which should work out without an external clock.
               
              I think there is some hardware in the PIC that I used for the 1861 emulator (it has been a while now) to detect a rising edge in the capture/compare peripheral.  I think this is also in the 16F series parts and if so, that will allow you to detect a "quick" pulse and use the part as an address latch.
               
              The 18F2620 that I used for the 1861 should do the trick.  You could use one with less code and data space but usually, they cost about the same due to volumes.  So with no clock and if you configure the pins for the OSC to be I/O you get a total of 21 I/Os:
                  8 bit input multiplexed address input
                  1 bit input TPA
                  7 bit multiplexed segment driver
                  4 bit digit driver
              Total of 20 pins.  So, this should work.
              If you can't get a handle on the capture compare logic, your polling loop would have to have another check to refresh the display which would make timing a bit tight.  I took a loop at the 18F2620 spec and the capture compare module will do the trick.  It has a rising or falling edge detector that will set a bit.  You don't have long to capture the high order address (maybe 1/2 to 1 1802 clock cycle) but this should allow a little more time to handle refreshing the multiplexed display.  I don't think you can use interrupts as the enter/exit time will eat up too many cycles.
               
              Sorry for all the words.


            • Michael McLaren
              ... Hi Ted. Nice to see you here on the group (I m the guy who sent you an email a couple months back to comment on the genius of your Elf Clone). Some more
              Message 8 of 11 , Apr 3 6:51 PM
              • 0 Attachment
                On 4/3/2014 4:48 PM, ted_rossin@... wrote:
                 

                I played some of these games with my 1802 and 1861 emulators using PIC processors:

                 

                    http://www.tedrossin.net46.net/Electronics/Pic/Pic.html#ElfClone

                 

                The problem is that using a 16F series PICs the instructions take 200ns each.  With the 18F series PICs the instructions take 100ns each.  With an 1802 running at 2 MHz, timing pulse A is just a clock cycle long which is 500ns.  To detect TPA you need a loop reading the port (1 instruction), then a test and branch (2 instruction cycles).  For a 16F series PIC, that is 600ns so you might miss TPA.  For the 18F series PIC, that is only 300ns so you should be set.  You should be able to use the 8MHz internal OSC with 4x PLL multiplier to run at 32MHz which (4 clocks per instruction cycle) gives a 125ns/instruction.  Multiply by 3 for the loop and you get 375ns which should work out without an external clock.

                Hi Ted.  Nice to see you here on the group (I'm the guy who sent you an email a couple months back to comment on the genius of your Elf Clone).

                Some more recent 16F devices have a 32-MHz clock so Tcy = 125-ns, but that's still not very fast.  The 18F26K22 and 18F46K22 devices I've been using run at 64-MHz with Tcy = 62.5-ns so that gives me a little more head room with 64 PIC instruction cycles per 1802 machine cycle (2-MHz 1802 clock). 
                 

                I think there is some hardware in the PIC that I used for the 1861 emulator (it has been a while now) to detect a rising edge in the capture/compare peripheral.  I think this is also in the 16F series parts and if so, that will allow you to detect a "quick" pulse and use the part as an address latch.

                 

                I saw that in your 1861 emulator code.  Very clever! 

                I'm not sure I'd have enough pins on a 28-pin PIC to replace the 74HC373 address latch IC, unless I can reduce the number of pins required to drive the 4-digit display by adding a TPIC6C595 or similar 8-bit serial-to-parallel driver IC.  That would require a little more overhead to drive the display but with a relatively low refresh rate (~200 Hz), it should be relatively easy to spread out the task of loading the driver IC shift register bit-by-bit over several 1802 machine cycles without affecting performance.

                The 18F2620 that I used for the 1861 should do the trick.  You could use one with less code and data space but usually, they cost about the same due to volumes.  So with no clock and if you configure the pins for the OSC to be I/O you get a total of 21 I/Os:

                    8 bit input multiplexed address input

                    1 bit input TPA

                    7 bit multiplexed segment driver

                    4 bit digit driver

                Total of 20 pins.  So, this should work.

                That looks about right.  I believe I have 24 pins to work with on an 18F26K22 device. 

                If you can't get a handle on the capture compare logic, your polling loop would have to have another check to refresh the display which would make timing a bit tight.  I took a look at the 18F2620 spec and the capture compare module will do the trick.  It has a rising or falling edge detector that will set a bit.  You don't have long to capture the high order address (maybe 1/2 to 1 1802 clock cycle) but this should allow a little more time to handle refreshing the multiplexed display.  I don't think you can use interrupts as the enter/exit time will eat up too many cycles.

                Is there any reason why I couldn't use the TPB signal for synchronization?  That is, use TPB rising edge as my trigger then capture address high data some 2.5 or 3.0 clock cycles later?

                Sorry for all the words.

                Not at all.  I really appreciate your input.  Thank you...

                Cheerful regards, Mike
              • mikemclaren6502
                ... Hi, Bill. You re absolutely correct. Controlling the 1802 clock opens up tremendous capabilities. Cheerful regards, Mike
                Message 9 of 11 , Apr 3 7:05 PM
                • 0 Attachment
                  >Bill wrote:
                  >Another way to go would be to generate the 1802's clock yourself so you could stretch the
                  >particular cycles you needed to check something on.

                  Hi, Bill.  You're absolutely correct.  Controlling the 1802 clock opens up tremendous capabilities.

                  Cheerful regards, Mike
                • Andrew Wasson
                  Yup, when I was building a 2 digit, 7-seg driver for the 1802 with a uController, I thought about adding a clock output from my circuit to make sure that the
                  Message 10 of 11 , Apr 3 9:08 PM
                  • 0 Attachment
                    Yup, when I was building a 2 digit, 7-seg driver for the 1802 with a uController, I thought about adding a clock output from my circuit to make sure that the 1802 didn't get ahead of my circuit. It never became an issue for what I was doing but it's a great idea none-the-less. 

                    How's your project coming along Mike?

                    Andrew 



                    On 2014-04-03, at 7:05 PM, <mikemclaren6502@...> wrote:

                     

                    >Bill wrote:

                    >Another way to go would be to generate the 1802's clock yourself so you could stretch the
                    >particular cycles you needed to check something on.

                    Hi, Bill.  You're absolutely correct.  Controlling the 1802 clock opens up tremendous capabilities.

                    Cheerful regards, Mike


                  • mikemclaren6502
                    ... Hi Andrew, Work is progressing slowly, mostly because I m wiring up a prototype board instead of using a solderless breadboard. I decided to do it this
                    Message 11 of 11 , Apr 4 6:49 PM
                    • 0 Attachment
                      >Andrew wrote;
                      >How's your project coming along Mike?

                      Hi Andrew,

                      Work is progressing slowly, mostly because I'm wiring up a prototype board instead of using a solderless breadboard.  I decided to do it this way to make the switches and LEDs more solid and reliable.  

                      Once everything is wired up I'll verify timing for all of the 1802 signals on a clock-to-clock basis via PIC serial connection and try to work out what I need to be able to "push" and "pull" data to/from the 1802.  After that I'll try to make the PIC look like 32-48 kB of ROM and ~4 kB of RAM.  Hopefully I'll learn enough from this 2 chip design to build a smaller and more fully featured 64-kB design.

                      Later.  Cheerful regards, Mike
                    Your message has been successfully submitted and would be delivered to recipients shortly.