امروز برابر است با :10 فروردین 1403

درايور نويسنده پيام با 89C2051

  درايور نويسنده پيام با ۸۹C2051

horizontal

 

By using a Dontronics DT004 Simmbus mother board it is possible to use the micro-controller of your choice to drive equipment that is designed to be controlled by a PC via it’s parallel port. In this example the device to be controlled is a walking message display. In Silicon Chip magazine February 1997 edition there was an article on just such a device. The only modification required to drive this display from a micro-controller instead of the PC was the inclusion of a 330R resistor from pin8 to ground of the first 74LS164 (IC1). This was found to be necessary to eliminate rogue clock pulses being generated. The micro-controller I used is the 89C2051, mounted on a Dontronics DT104 board. The board also needs an eeprom and max232 on the board. The RS232 interface is used to download messages to be displayed from a PC and the eeprom is used to store the message after downloading. At power up, the software waits a few seconds for a key to be received on the RS232 port. If nothing is received the message is transferred from the eeprom into the 2051’s ram. This is because the eeprom is too slow to read from, because the display is multiplexed. The amount of ram in the 2051 limits the length of the message to be displayed to 60 characters.

 

photo of DT104 board

Photo of Dontronics DT104 board used for walking message display. Note the components in the top right hand prototype area are not needed for this project. However two of the yellow jumpers on the bottom of the board are required. The parallel port connections required are D0-D6, Strobe, Auto line feed and Select in. The D0-D6 and Strobe connections are connected to the 2051 port1.0 -port 1.6 and port 3.4 respectively. These connections are via the Dontronics DT004 motherboard and don’t require any additional wiring. However the Auto line feed and Select in signals are connected to the Simmbus pins 27 and 30 respectively. The Dontronics DT104 board does not have any connection to these pins. Therefore they need to be linked to a 2051 port. Auto line feed pin 27 should be linked to pin 23, 2051 port 3.2 and Select in pin 30 should be linked to pin 24, 2051 port 3.3. Note the extra jumper in the above picture is for another interfacing project.

 

photo showing the walking message display

Photo showing the walking message display being driven by a 2051 micro-controller. Note I chose to mount the walking message display board upside down compared to the original Silicon Chip article. The reason for this is that it simplified some of the coding.

 

photo showing the walking message display

 

Source code for walking message display written by Peter Averill

 

;Walking message display for 2051
;Written by Peter Averill
;version 2  Fix up 'S' display problems
;31-5-99
;
$mod2051                

CR              EQU     0dh             ; carriage return
LF              EQU     0ah             ; line feed


BAUD_9600       EQU     0fdh            ; 9600 baud


;eeprom equates
FADDR       EQU 0a0h        ; fixed address for AT24Cxx EEPROMs
PADDR       EQU 0       ; programmable address (0..7)

; Register definitions for serial eeprom

zdata       EQU r1      ; data register
addr_lo     EQU r2      ; 2-byte address register
addr_hi     EQU r3      ;

;register definitions for hex to dec routine

memptr      equ r0  ;ram memory pointer
col     equ r4  ;column increment
scans       equ r5  ;number of time the diplay is multiplexed
                ;before incrementing
count       equ r6  ;col count for each char displayed
char_count  equ r7  ;
;
; Microcontroller connections to AT24Cxx serial bus lines.

SCL     BIT p3.5        ; serial clock
SDA     BIT p3.7        ; serial data

;

clear       bit p3.4        ;master clear
clk     bit p3.2        ;clock
row     bit p3.3        ;row of display on

        DSEG AT 20H

delay_value:    ds  1
message:    ds  48      ;max lenght of string to display
        ORG 5fH     ; stack origin
stack:      DS  20H     ; stack depth



        CSEG

        ORG     0000H           ; power on/reset vector
        jmp     cold_start

        ORG     0003H           ; external interrupt 0 vector
        reti                    ; undefined

        ORG     000BH           ; timer 0 overflow vector
        reti

        ORG     0013H           ; external interrupt 1 vector
        reti                    ; undefined

        ORG     001BH           ; timer 1 overflow vector
        reti                    ; undefined

        ORG     0023H           ; serial I/O interrupt vector
        reti


        ORG     40H             ; begin constant data space

menu:           DB      CR,LF,LF,LF,LF,LF,LF,LF,LF,LF,LF,LF,LF,LF,LF,LF
        db  LF,LF,LF,LF,LF,LF,LF,LF,LF,LF
        db  'Walking led message display program',LF,CR
        db  '___________________________________',LF,CR
        db  'Written by Peter Averill',LF,LF,LF,CR
        db  'Press:-',LF,CR
        db  '        s to load the message from the PC terminated in a $',cr,lf
        db  '        d to display message',CR,LF,LF,LF,0

matrix:     db  00h,00h,00h,00h,00h ;space
        db  00h,00h,7dh,00h,00h ;!
        db  00h,60h,00h,60h,00h ;"
        db  14h,7fh,14h,7fh,14h ;#
        db  32h,49h,7fh,49h,26h ;$
        db  62h,64h,08h,13h,23h ;%
        db  36h,49h,35h,02h,05h ;&
        db  00h,00h,00h,50h,60h ;'
        db  1ch,22h,41h,00h,00h ;(
        db  00h,00h,41h,22h,1ch 
        db  2ah,1ch,3eh,1ch,2ah ;*
        db  08h,08h,3eh,08h,08h ;+
        db  00h,01h,02h,00h,00h ;,
        db  08h,08h,08h,08h,08h ;-
        db  00h,00h,01h,00h,00h ;.
        db  02h,04h,08h,10h,20h ;/
        db  3eh,45h,49h,51h,3eh ;0
        db  00h,21h,7fh,01h,00h ;1
        db  27h,49h,49h,49h,31h ;2
        db  22h,49h,49h,49h,36h ;3
        db  0ch,14h,24h,7fh,04h ;4
        db  7ah,49h,49h,49h,46h ;5
        db  3eh,49h,49h,49h,26h ;6
        db  41h,42h,44h,48h,70h ;7
        db  36h,49h,49h,49h,36h ;8
        db  32h,49h,49h,49h,3eh ;9
        db  00h,00h,22h,00h,00h ;:
        db  00h,01h,22h,00h,00h ;;
        db  08h,14h,22h,41h,00h ;<
        db  14h,14h,14h,14h,14h ;=
        db  00h,41h,22h,14h,08h ;>
        db  20h,40h,45h,48h,30h ;?
        db  3eh,41h,4dh,4dh,39h ;@
        db  1fh,24h,44h,24h,1fh ;A
        db  7fh,49h,49h,49h,36h ;B
        db  3eh,41h,41h,41h,22h ;C
        db  7fh,41h,41h,22h,1ch ;D
        db  7fh,49h,49h,49h,41h ;E
        db  7fh,48h,48h,48h,40h ;F
        db  3eh,41h,41h,45h,26h ;G
        db  7fh,08h,08h,08h,7fh ;H
        db  00h,41h,7fh,41h,00h ;I
        db  42h,41h,41h,7eh,40h ;J
        db  7fh,08h,14h,22h,41h ;K
        db  7fh,01h,01h,01h,01h ;L
        db  7fh,20h,18h,20h,7fh ;M
        db  7fh,10h,08h,04h,7fh ;N
        db  3eh,41h,41h,41h,3eh ;O
        db  7fh,48h,48h,48h,30h ;P
        db  3ch,42h,46h,42h,3dh ;Q
        db  7fh,48h,4ch,4ah,31h ;R
matrix1:    db  32h,49h,49h,49h,26h ;S
        db  40h,40h,7fh,40h,40h ;T
        db  7eh,01h,01h,01h,7eh ;U
        db  78h,06h,01h,06h,78h ;V
        db  7fh,02h,0ch,02h,7fh ;W
        db  63h,14h,08h,14h,63h ;X
        db  60h,10h,0fh,10h,60h ;Y
        db  43h,45h,49h,51h,61h ;Z

        USING   0               ; register bank zero
cold_start:
        mov     sp, #(stack-1)  ; initialize stack pointer
        call    initialize      ; initialize controller registers

        mov     p1, #0          ; write zeros to displays
        clr clear       ;clear display
        clr clk
        clr row 


        setb    TI
        setb    ES

        mov acc,#07fh
        call    delay_5mS

top:        jnb ri,m1
        clr es
        mov a,sbuf
        clr ri
        call    setup
        setb    es

m1:     call    get_mess    ;loads message from eeprom into ram
        
        setb    clear
m5:     mov char_count,#0

m3:         mov col,#6
m4:     mov scans,#10
m2:     mov memptr,#message
        mov a,memptr
        add a,char_count
        mov memptr,a
        call    char_cal
        call    scan_char1
        inc memptr
        call    char_cal
        mov count,#5
        call    scan_char
        inc memptr
        call    char_cal
        mov count,#5
        call    scan_char
        inc memptr
        mov a,@memptr
        cjne    a,#'$',m6
        jmp m5
m6:     call    char_cal
        mov count,#3
        cjne    col,#4,m7
m7:     jnc m8
        call    scan_char
m8:     djnz    scans,m2
        djnz    col,m4
        inc char_count
        jmp m3

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
char_cal:
        mov a,@memptr
        clr c
        subb    a,#20h
        mov b,#5
        mul ab
        mov b,a     
        mov c,ov
        jc  greater255
        mov dptr,#matrix
        jmp cc1
greater255: mov dptr,#matrix1
        inc dptr
cc1:        ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
scan_char1:     
        mov a,#6
        clr c
        subb    a,col

sd7:        jz  sd6
        inc dptr        ;inc dptr to start column
        dec a
        jmp sd7
sd6:
        mov a,col   
        mov count,a     ;load the number of columns to display
        dec count
        mov a,count
        jz  sd3     ;display space column only

        mov a,b
        movc    a, @a+dptr      ; get character
sd3:        mov p1,a
        setb    row
        setb    clk
        nop
        clr clk
        clr row
        inc dptr
        mov a,#60h
        call    delay
        mov a,count
        jz  sd2
sd1:        djnz    count,sd4
        jmp sd5     ;last column jmp to display space 
sd4:        mov a,b
        movc    a, @a+dptr
        mov p1,a
        setb    clk
        nop
        clr clk
        mov a,#60h
        call    delay
        inc dptr
        jmp sd1     ;jmp to check if last column        
sd5:        call    char_space
sd2:        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
char_space: clr a
        mov p1,a
        setb    clk
        nop
        clr clk
        mov a,#60h
        call    delay
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
scan_char:      
sc1:        mov a,b
        movc    a, @a+dptr
        mov p1,a
        setb    clk
        nop
        clr clk
        mov a,#60h
        call    delay
        inc dptr
        djnz    count,sc1       
        call    char_space
        ret

        
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
setup:


su1:        mov     dptr, #menu
        call    send_string
        call    getch
        call    send_char

su2:        cjne    a,#'s',su3
        call    store
su3:        cjne    a,#'d',su1

        ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
store:
        mov a,#0ah
        call    send_char
        mov a,#0dh
        call    send_char
        
        clr a
        mov ADDR_LO,a
get_next_char:  call    getch
        mov zdata,a
        call    send_char
        clr a
        call    write_byte
        inc ADDR_LO
        mov a,zdata
        cjne    a,#024h,get_next_char

        mov a,#0ah
        call    send_char   
        mov a,#0dh
        call    send_char

    
        ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
get_mess:
        mov memptr,#message
        clr a
        mov ADDR_LO,a
next_char:  clr a
        call    read_random
        mov @memptr,a
        inc ADDR_LO
        inc memptr
        cjne    a,#024h,next_char

        ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
getch:
        setb    es      ;enable reception
        jnb ri,$        ;wait for key press
        clr es
        mov a,sbuf
        clr ri
        ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

initialize:

    ; Initialize controller registers.

        mov     PCON, #0        ; initialize power control register
        mov     IE, #0          ; deactivate all interrupts


        mov     SCON, #01000000b        ; serial port mode one
        mov     TMOD, #00100001b        ; timer one 8-bit auto-reload,
                        ; timer zero 16-bit
        mov     TH1, #BAUD_9600         ; timer one reload value
        mov     TCON, #01010000b        ; start timer one & zero
        mov th0,#0b9h
        mov tl0,#0afh
        setb    et0
        setb    REN         ;enable rx int
        setb    EA          ;global int enable

        ret
         

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
send_string:

    ; Transmit string pointed to by DPTR.
    ; String may be of any length, but must be null-terminated.

        push    acc
        push    dpl
        push    dph
ss1:
        clr     a
        movc    a, @a+dptr      ; get character
        jz      ss2             ; check for terminator

        call    send_char       ; send character

        inc     dptr            ; point to next character
        jmp     ss1
ss2:
        pop     dph
        pop     dpl
        pop     acc
        ret


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
send_char:

    ; Wait for transmitter to clear, add even parity bit to character
    ; in accumulator and transmit it. Does not wait for transmitter
    ; to clear before returning.

        jnb     TI, $           ; wait here for transmitter to clear

        clr     TI              ; clear transmit flag
        push    acc             ; save char
        mov     SBUF, a         ; load character into transmitter
        pop     acc             ; restore char
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
delay:
        push    acc
        push    acc

        djnz    acc, $            ; 500 uS @ 12 MHz
        pop acc
        djnz    acc, $

        pop     acc
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
delay_5mS:

    ; Delay for 5mS times the value in the accumulator.

        push    acc
        push    b

        mov     b, a
ddd:
        mov     a, #0
        call    delay           ; 1mS
        call    delay           ; 2mS
        call    delay           ; 3mS
        call    delay           ; 4mS
        call    delay       ; 5mS
        djnz    b, ddd

        pop     b
        pop     acc
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
write_byte:

    ; AT24Cxx Byte Write function.
    ; Called with programmable address in A, byte address in
    ; register pair ADDR_HI:ADDR_LO, data in register XDATA.
    ; Does not wait for write cycle to complete.
    ; Returns CY set to indicate that the bus is not available
    ; or that the addressed device failed to acknowledge.
    ; Destroys A.

        call    start
        jc  x49     ; abort if bus not available

        rl  a       ; programmable address to bits 3:1
        orl a, #FADDR   ; add fixed address
        clr acc.0       ; specify write operation
        call    shout       ; send device address
        jc  x48     ; abort if no acknowledge

        mov a, addr_lo  ; send low byte of address
        call    shout       ;
        jc  x48     ; abort if no acknowledge

        mov a, zdata    ; get data
        call    shout       ; send data
        jc  x48     ; abort if no acknowledge

        clr c       ; clear error flag
    x48:
        call    stop
    x49:
        ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
read_current:

    ; AT24Cxx Current Address Read function.
    ; Called with programmable address in A. Returns data in A.
    ; Returns CY set to indicate that the bus is not available
    ; or that the addressed device failed to acknowledge.

        call    start
        jc  x45     ; abort if bus not available

        rl  a       ; programmable address to bits 3:1
        orl a, #FADDR   ; add fixed address
        setb    acc.0       ; specify read operation
        call    shout       ; send device address
        jc  x44     ; abort if no acknowledge

        call    shin        ; receive data byte
        call    NAK     ; do not acknowledge byte
        clr c       ; clear error flag
    x44:
        call    stop
    x45:
        ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
read_random:

    ; AT24Cxx Random Read function.
    ; Called with programmable address in A, byte address in
    ; register pair ADDR_HI:ADDR_LO. Returns data in A.
    ; Returns CY set to indicate that the bus is not available
    ; or that the addressed device failed to acknowledge.

        push    b
        mov b, a        ; save copy of programmable address

        ; Send dummy write command to set internal address.

        call    start
        jc  x47     ; abort if bus not available

        rl  a       ; programmable address to bits 3:1
        orl a, #FADDR   ; add fixed address
        clr acc.0       ; specify write operation
        call    shout       ; send device address
        jc  x46     ; abort if no acknowledge


        mov a, addr_lo  ; send low byte of address
        call    shout       ;
        jc  x46     ; abort if no acknowledge

        ; Call Current Address Read function.

        mov a, b        ; get programmable address
        call    read_current
        jmp x47     ; exit
    x46:
        call    stop
    x47:
        pop b
        ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
start:

    ; Send START, defined as high-to-low SDA with SCL high.
    ; Return with SCL, SDA low.
    ; Returns CY set if bus is not available.

        setb    SDA
        setb    SCL

        ; Verify bus available.

        jnb SDA, x40    ; jump if not high
        jnb SCL, x40    ; jump if not high

        nop         ; enforce setup delay and cycle delay
        clr SDA
        nop         ; enforce hold delay
        nop         ;
        nop         ;
        nop         ;
        nop         ;
        clr SCL

        clr c       ; clear error flag
        jmp x41
    x40:
        setb    c       ; set error flag
    x41:
        ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
stop:

    ; Send STOP, defined as low-to-high SDA with SCL high.
    ; SCL expected low on entry. Return with SCL, SDA high.

        clr SDA
        nop         ; enforce SCL low and data setup
        nop
        setb    SCL
        nop         ; enforce setup delay
        nop         ;
        nop         ;
        nop         ;
        nop         ;
        setb    SDA
        ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
shout:

    ; Shift out a byte to the AT24Cxx, most significant bit first.
    ; SCL, SDA expected low on entry. Return with SCL low.
    ; Called with data to send in A.
    ; Returns CY set to indicate failure by slave to acknowledge.
    ; Destroys A.

        push    b
        mov b, #8       ; bit counter
    x42:
        rlc a       ; move bit into CY
        mov SDA, c      ; output bit
        nop         ; enforce SCL low and data setup
        setb    SCL     ; raise clock
        nop         ; enforce SCL high
        nop         ;
        nop         ;
        nop         ;
        clr SCL     ; drop clock
        djnz    b, x42      ; next bit

        setb    SDA     ; release SDA for ACK
        nop         ; enforce SCL low and tAA
        nop         ;
        setb    SCL     ; raise ACK clock
        nop         ; enforce SCL high
        nop         ;
        nop         ;
        nop         ;
        mov c, SDA      ; get ACK bit
        clr SCL     ; drop ACK clock

        pop b
        ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
shin:

    ; Shift in a byte from the AT24Cxx, most significant bit first.
    ; SCL expected low on entry. Return with SCL low.
    ; Returns received data byte in A.

        setb    SDA     ; make SDA an input

        push    b
        mov b, #8       ; bit count
    x43:
        nop         ; enforce SCL low and data setup
        nop         ;
        nop         ;
        setb    SCL     ; raise clock
        nop         ; enforce SCL high
        nop         ;
        mov c, SDA      ; input bit
        rlc a       ; move bit into byte
        clr SCL     ; drop clock
        djnz    b, x43      ; next bit

        pop b
        ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ACK:

    ; Clock out an acknowledge bit (low).
    ; SCL expected low on entry. Return with SCL, SDA low.

        clr SDA     ; ACK bit
        nop         ; enforce SCL low and data setup
        nop         ;
        setb    SCL     ; raise clock
        nop         ; enforce SCL high
        nop         ;
        nop         ;
        nop         ;
        clr SCL     ; drop clock
        ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
NAK:

    ; Clock out a negative acknowledge bit (high).
    ; SCL expected low on entry. Return with SCL low, SDA high.

        setb    SDA     ; NAK bit
        nop         ; enforce SCL low and data setup
        nop         ;
        setb    SCL     ; raise clock
        nop         ; enforce SCL high
        nop         ;
        nop         ;
        nop         ;
        clr SCL     ; drop clock
        ret

        END

اشتراک گذاری