Maker Pro
Maker Pro

smart watering controller

champ1

Jul 17, 2018
55
Joined
Jul 17, 2018
Messages
55
I don't understand assembly language. I have found assembly code. I'm looking someone to help me to understand assembly code.

Code for the smart watering controller. The comment in the code shows that the relay, real time clock are used in the controller. I have a doubt that LCD must have been used in it, but I 'm not confident.

The most important I want to understand what program supposed to do in controller.

Here is code
Code:
;
;
;    Code for the smart watering controller. We have a real time
;    clock that is periodically read and a list of actions stored
;    in EEprom that is compared with this time. If a match is found,
;    that action is activated. We have 7 relay outputs.
;
;
;
;
;
;
;
;
    chip    8051
;
;    port pin assignments
;
mux0        reg    P1.0        ;latch addr 0/bcd sw 0
mux1        reg    P1.1
mux2        reg    P1.2
mux_dat        reg    P1.3        ;latch data/bcd sw 3
mux_sel        reg    P1.4        ;latch strobe
wire1        reg    P1.5        ;Dallas 1 wire port
SCL        reg    P1.6        ;i2c port clock
SDA        reg    P1.7        ;i2c port data
sw_sel        reg    P3.5        ;bcd switch select
;
;    system equates
;
SOH        equ    1        ;ascii start of header char
eeprom_addr    equ    a4h        ;i2c addr for eeprom
rtc_addr    equ    a0h        ;i2c addr for 8583 rtc
baud        equ    3        ;19200 baud
time_tick    equ    9220        ;tick time =10mS
rom        equ    8000h        ;8000h for debug,0 for prom
;
;
;    op-code equates for the action stuff
;
;
op_on        equ    0        ;relay(s) on
op_off        equ    1        ;relay(s) off
op_ongt        equ    2        ;relay(s) on if var X > const
op_onlt        equ    3        ;relay(s) on if var X < const
op_offgt    equ    4        ;relay(s) off if var X > const
op_offlt    equ    5        ;relay(s) off if var X < const
;
;    Start of rom vectors
;
    org    rom
    ljmp    begin
    org    rom+3h
*    ljmp    int0_isr
    org    rom+bh
    ljmp    timer0_isr
    org    rom+13h
*    ljmp    int1_isr
    org    rom+1bh
*    ljmp    timer1_isr
    org    rom+23h
    ljmp    serial_isr
;
;
;    Start of code
;
;
    org    rom+28h
begin
;
;    init the serial port & timers
;
    mov    sp,#stack        ;load stack ptr
    mov    pcon,#80h        ;set SMOD
    mov    tmod,#00100001b        ;timer1 brg,timer0 16 bit
    mov    tl0,#<(1-time_tick)
    mov    th0,#>(1-time_tick)    ;reload the timer
    setb    tr0            ;and set it going again
    mov    th1,#-baud        ;load reload val
    mov    tl1,#-baud        ;load timer1
    mov    scon,#01010010b        ;mode 1 8 bit uart
    mov    tcon,#01010000b        ;timer 0,1 run
;
;    clear mem & init vars
;
    mov    r0,#01h            ;->ram
    clr    a               
mem_clr1
    mov    @r0,a            ;clear loc'n
    inc    r0            ;++->
    cjne    r0,#80h,mem_clr1    ;end?
    mov    task_bits,#40h        ;start with read clock task
    mov    ie,#10000010b        ;enable ints
    setb    task_bits.6
;----------------------------------------------------------------------------
;
;
;    Main dispatcher. To simulate a real-time task switch we fake things
;    a little by allowing each task time in 1mS chunks. If the task
;    finishes before time, we wait for the next 1mS tick. If the task runs
;    over time, the next task runs immediately after the previous has
;    finished. Each task has a priority, the highest priority task runs
;    first. The general idea is to have the highest priority tasks run
;    infrequently so that they don't hog the cpu
;
;
;----------------------------------------------------------------------------
dispatch
    jnb    task_bits.7,dispatch    ;wait for a tick
    clr    task_bits.7        ;reset the tick bit
    acall    update_relays       
    mov    r2,#0            ;start at task#0 -highest priority
    mov    a,task_bits        ;get the bits
find_task
    clr    c
    rrc    a            ;get task bit into carry
    jc    go_task            ;the bit is set,r2 has the task#
    inc    r2            ;try next
    cjne    r2,#7,find_task        ;7 tasks max!
    sjmp    dispatch        ;no tasks found! idle till next tick
;
;    task found! task# in R2
;       
go_task
    mov    a,r2            ;get task #
    rl    a            ;word index
    mov    dptr,#task_jt        ;->jump table
    jmp    @a+dptr            ;goto task
task_jt
    ajmp    decode_rx_packet    ;highest priority
    ajmp    dispatch
    ajmp    dispatch
    ajmp    dispatch
    ajmp    dispatch
    ajmp    scan_action        ;scan the action tables
    ajmp    read_clock        ;lowest priority   
;----------------------------------------------------------------------------
;
;
;    read the real time clock every 1/2 seconds & activate the action
;    scan routine when the minute ticks over
;
;
;----------------------------------------------------------------------------
read_clock
    clr    task_bits.6        ;reset the task request
    mov    clock_time,#50        ;restart this task in 500mS
    acall    read_rtc        ;get the current time
;
;    read the unit select switch
;
    orl    p1,#0fh            ;set p1.0..3 as inputs
    clr    sw_sel            ;select the address switch
    nop   
    nop
    nop
    mov    a,p1            ;read back the switch
    setb    sw_sel
    cpl    a            ;flip it
    anl    a,#0fh
    mov    unit_sw,a
    setb    es            ;allow serial ints

    mov    a,time_seconds        ;get the current seconds
    mov    b,prev_seconds        ;test with the previous
    mov    prev_seconds,a        ;update the previous
    cjne    a,b,rc_1
rc_1    jnc    rc_2            ;no minute tickover yet!
;
;    a minute has ticked over.activate the scan task
;
    setb    task_bits.5        ;activate
rc_2
    ajmp    dispatch        ;exit
;----------------------------------------------------------------------------
;
;
;    Scan the eeprom action tables for a time match & activate the action
;
;
;----------------------------------------------------------------------------
scan_action
    clr    task_bits.5        ;reset the task request
;
;    convert the day# into a bit field
;
    mov    a,time_wmonth
    rl    a
    rl    a
    rl    a
    anl    a,#7            ;get bits 5..7 to 0..2
    add    a,# const & turn relays on
;
    mov    a,act_cmd
    anl    a,#3            ;4 vars only
    add    a,#vars            ;add var base addr
    mov    r0,a
    mov    a,@r0            ;get the var
    mov    b,a            ;into B
    mov    a,#act_const        ;get the constant
    clr    c
    subb    a,b               ;const-var
    jnc    no_match
    sjmp    rly_on            ;if const < var
match_3
    cjne    a,#op_onlt,match_4
;
;    test for var < const & turn relays on
;
    mov    a,act_cmd
    anl    a,#3            ;4 vars only
    add    a,#vars            ;add var base addr
    mov    r0,a
    mov    a,@r0            ;get the var
    mov    b,#act_const        ;get the constant
    clr    c
    subb    a,b               ;var-const
    jnc    no_match
    sjmp    rly_on            ;if const < var
match_4
    cjne    a,#op_offgt,match_5
;
;    test for var > const & turn relays off
;   
    mov    a,act_cmd
    anl    a,#3            ;4 vars only
    add    a,#vars            ;add var base addr
    mov    r0,a
    mov    a,@r0            ;get the var
    mov    b,a            ;into B
    mov    a,#act_const        ;get the constant
    clr    c
    subb    a,b               ;const-var
    jnc    no_match
    sjmp    rly_off            ;if const < var
match_5
    cjne    a,#op_offlt,no_match
    mov    a,act_cmd
    anl    a,#3            ;4 vars only
    add    a,#vars            ;add var base addr
    mov    r0,a
    mov    a,@r0            ;get the var
    mov    b,#act_const        ;get the constant
    clr    c
    subb    a,b               ;var-const
    jnc    no_match
    sjmp    rly_on            ;if const < var
no_match
    inc    curr_action
    mov    a,curr_action
    cjne    a,#32,nm_1
nm_1    jnc    nm_2
    ajmp    do_it
nm_2
    mov    curr_action,#0        ;update the relays & exit
    acall    update_relays
    ajmp    dispatch
;----------------------------------------------------------------------------
;
;
;    Update the relay outputs
;
;
;----------------------------------------------------------------------------
update_relays
    mov    b,#0            ;start at bit 0
    mov    a,relays        ;get relay bits
ur_1
    rrc    a            ;get bit into carry
    mov    mux_dat,c        ;copy to latch
    mov    c,b.0
    mov    mux0,c
    mov    c,b.1
    mov    mux1,c
    mov    c,b.2
    mov    mux2,c
    clr    mux_sel            ;strobe data
    nop
    nop
    setb    mux_sel            ;set strobe hi
    inc    b            ;next..
    jnb    b.3,ur_1
    orl    p1,#0fh            ;set bits 0..3 high
    ret
;----------------------------------------------------------------------------
;
;    Read the Real Time Clock thru the i2c port.
;    returns time/date in structure 'time'
;    exit: carry clear if ok,else set if there was an error
;
;----------------------------------------------------------------------------
read_rtc
    mov    r0,#time        ;->time storage
    mov    r2,#7            ;7 regs
    mov    r1,#rtc_addr
    mov    a,#2            ;read from seconds reg onwards
    acall    read_block
    jc    rr_x            ;exit if error
;
;    test for year rollover
;
    mov    a,time_ydate        ;get year/date
    rl    a
    rl    a            ;get bits 7 & 6    into 1 & 0
    xrl    a,time_year        ;same as our year ram loc'n
    anl    a,#3            ;mask other bits
    jz    rr_x            ;jump if year hasn't ticked over
    inc    time_year        ;tick year count over
    mov    r0,#time_year        ;->time storage
    mov    r2,#1            ;1 byte
    mov    r1,#rtc_addr
    mov    a,#8            ;ram for year storage
    acall    write_block        ;update the year
rr_x
    ret
;----------------------------------------------------------------------------
;
;    Read the Real Time Clock thru the i2c port.
;    returns time/date in structure 'time'
;    exit: carry clear if ok,else set if there was an error
;   
;
;----------------------------------------------------------------------------
write_rtc
;
;    fix up the year stuff
;
    mov    a,time_ydate        ;get year/date
    anl    a,#3fh            ;clear year bits
    mov    time_ydate,a
    mov    a,time_year        ;get the year
    rr    a
    rr    a            ;get the tw olsb into the msbs
    anl    a,#c0h            ;bit 6 & 7 only
    orl    a,time_ydate
    mov    time_ydate,a        ;update the year/date value
;
;    stop the clock
;
    mov    r6,#80h            ;control reg..stop the clock
    mov    r7,#0
    mov    r0,#6            ;->R6
    mov    r2,#2            ;2 regs
    mov    r1,#rtc_addr
    mov    a,#0            ;read from seconds reg onwards
    acall    write_block
    jc    wrtc_x            ;exit of there was an error
;
;    write the time stuff
;
    mov    r0,#time        ;->time storage
    mov    r2,#7            ;7 regs
    mov    r1,#rtc_addr
    mov    a,#2            ;read from seconds reg onwards
    acall    write_block
    jc    wrtc_x            ;exit if error             
;
;    start the clock
;
    mov    r6,#00h            ;control reg..start the clock
    mov    r0,#6            ;->R6
    mov    r2,#1            ;1 reg
    mov    r1,#rtc_addr
    mov    a,#0            ;read from seconds reg onwards
    acall    write_block
wrtc_x
    ret
;----------------------------------------------------------------------------
;
;    Write from one byte to one page of data to an AT24Cxx.
;    Called with address of first byte in A,R0->data to write
;    byte count in register R2.
;    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, R0, R2.
;
;----------------------------------------------------------------------------
write_block
    push    b
    mov    b,a        ; save address
    acall    start
    jc    x38        ; abort if bus not available
;
    mov    a,R1        ; fixed address
    clr    acc.0        ; specify write operation
    acall    shout        ; send device address
    jc    x37        ; abort if no acknowledge
;
    mov    a,b
    acall    shout        ;
    jc    x37        ; abort if no acknowledge
;
x36
    mov    a,@r0        ; get data
    acall    shout        ; send data
    jc    x37        ; abort if no acknowledge
;
    inc    r0        ; advance buffer pointer
    djnz    r2, x36        ; next byte
    clr    c        ; clear error flag
x37
    acall    stop
x38
    pop    b
    ret
;----------------------------------------------------------------------------
;
;    Read from one byte to one page of data from an AT24Cxx.
;    Performs a Random Read which is extended into a Sequential Read
;    when more than one byte is read. Called with address of first
;    byte in A,byte count in register R2 and ->buffer in R0.
;    R1 has the i2c addr
;
;    Returns data in the buffer. Returns CY set to indicate that the bus is
;    not available or that the addressed device failed to acknowledge.
;    Destroys A, R0, R2.
;
;----------------------------------------------------------------------------
read_block
    push    b
    mov    b,a        ; save address into B   
    call    start
    jc    x35        ; abort if bus not available
;
    mov    a,R1        ; add fixed address
    clr    acc.0        ; specify write operation
    call    shout        ; send device address
    jc    x34        ; abort if no acknowledge
;
    mov    a,b         ; send address
    call    shout        ;
    jc    x34        ; abort if no acknowledge
;
;    Send read command and receive data.
;
    call    start        ; second start for read
    jc    x34        ; abort if bus not available
;
    mov    a,R1        ; get device address
    setb    acc.0        ; specify read operation
    call    shout        ; send device address
    jc    x34        ; abort if no acknowledge
;
x31
    call    shin        ; receive data byte
    mov    @r0, a        ; save data

    cjne    R2, #1, x32    ; jump if not last byte
    call    nak        ; do not acknowledge last byte
    jmp    x33        ; done
x32
     call    ack        ; acknowledge byte
     inc    r0        ; advance buffer pointer
    djnz    R2, x31        ; next byte
x33
    clr    c        ; clear error flag
x34
    call    stop
x35
    pop    b
    ret
;----------------------------------------------------------------------------
;
;    AT24Cxx Current Address Read function.
;    Returns data in A.
;    Returns CY set to indicate that the bus is not available
;    or that the addressed device failed to acknowledge.
;
;----------------------------------------------------------------------------
read_current:
    acall    start
    jc    x45        ; abort if bus not available
;
    mov    a, #eeprom_addr    ; add fixed address
    setb    acc.0        ; specify read operation
    acall    shout        ; send device address
    jc    x44        ; abort if no acknowledge
;
    acall    shin        ; receive data byte
    acall    nak        ; do not acknowledge byte
    clr    c        ; clear error flag
x44
    acall    stop
x45
    ret
;----------------------------------------------------------------------------
;
;    Send START, defined as high-to-low SDA with SCL high.
;    Return with SCL, SDA low.
;    Returns CY set if bus is not available.
;
;----------------------------------------------------------------------------
start
    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
;----------------------------------------------------------------------------
;
;    Send STOP, defined as low-to-high SDA with SCL high.
;    SCL expected low on entry. Return with SCL, SDA high.
;
;----------------------------------------------------------------------------
stop
    clr    SDA
    nop            ; enforce SCL low and data setup
    nop
    setb    SCL
    nop            ; enforce setup delay
    nop            ;
    nop            ;
    nop            ;
    nop            ;
    setb    SDA
    ret
;----------------------------------------------------------------------------
;
;    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.
;
;----------------------------------------------------------------------------
shout
    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
;----------------------------------------------------------------------------
;
;     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.
;
;----------------------------------------------------------------------------
shin
    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
;----------------------------------------------------------------------------
;
;     Clock out an acknowledge bit (low).
;     SCL expected low on entry. Return with SCL, SDA low.
;
;----------------------------------------------------------------------------
ack
    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
;----------------------------------------------------------------------------
;
;     Clock out a negative acknowledge bit (high).
;     SCL expected low on entry. Return with SCL low, SDA high.
;
;----------------------------------------------------------------------------
nak
    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
;-----------------------------------------------------------------------------
;
;
;    timer tick gets us here.
;
;
;-----------------------------------------------------------------------------
timer0_isr
    clr    tr0
    mov    tl0,#<(1-time_tick)
    mov    th0,#>(1-time_tick)    ;reload the timer
    setb    tr0            ;and set it going again
    push    psw
    push    a
    setb    task_bits.7        ;set the tick bit
;
;    re-enable the read_clock task if 500mS elapsed
;
    mov    a,clock_time        ;decrement the input scan timer
    jz    t0_1            ;already 0
    djnz    clock_time,t0_1        ;not 0..decrement it
    setb    task_bits.6
t0_1
;
;    eeprom write timer. If eeprom_time is 0, eeprom is free else write
;    cycle is in progress
;
    mov    a,eeprom_time        ;take care of the eeprom write timer
    jz    t0_2            ;already 0..leave it
    dec    a
    mov    eeprom_time,a        ;decrement it
t0_2
    pop    a
    pop    psw
    reti
;----------------------------------------------------------------------------
;
;    Decode the receive packets.
;    Commands supported are:
;    0 Read current inputs
;    1 Read raw channel & scale/offset
;    2 Set scale/offset
;    3 Dump the eeprom data (16 bytes at a time)
;    4 Set the channel display label
;
;----------------------------------------------------------------------------
decode_rx_packet
    clr    task_bits.0        ;clear our task request

    mov    unit_sw,#0        ;**diag

    mov    a,ppx_data        ;get the address
    xrl    a,unit_sw
    jz    addr_ok            ;if we're addressed
    ajmp    dispatch        ;else exit
addr_ok
    mov    a,ppx_data+1        ;get the cmd byte
    cjne    a,#max_cmd,drp_1
drp_1    jc    drp_2
    sjmp    cmd_error        ;illegal command
drp_2
    rl    a            ;make word index
    mov    dptr,#cmd_jump
    jmp    @a+dptr
max_cmd    equ    5            ;maximum cmd #
cmd_jump
    ajmp    cmd_read_inputs        ;cmd=0 reply with current relay state,time & vars
    ajmp    cmd_get_action        ;cmd=1 reply with action
    ajmp    cmd_set_action        ;cmd=2 reply with ok
    ajmp    cmd_set_time        ;cmd=3 reply with ok
    ajmp    cmd_set_relays        ;cmd=4 reply with ok
cmd_error
    mov    ppx_data,#ffh        ;destination=master
    mov    ppx_data+1,#ffh        ;cmd=ffh error
    mov    ppx_data+2,#'E'
    mov    ppx_data+3,#'r'
    mov    ppx_data+4,#'r'
    mov    ppx_lenl,#5        ;data packet length
    mov    ppx_lenh,#0        ;msb=0
    ajmp    create_tx        ;create packet & end
;----------------------------------------------------------------------------
;
;    Read input command. There is no parameters for this
;    We just reply with the time,the var values & the relay states
;    input packet:
;    addr
;    cmd
;    reply:
;    dest addr
;    cmd
;    time (7 bytes)
;    vars (4 bytes)
;    relays (1 byte)
;
;----------------------------------------------------------------------------
cmd_read_inputs
    mov    ppx_data,#ffh        ;destination=master
    mov    ppx_data+1,#80h        ;reply cmd
;
;    copy time
;
    mov    r0,#ppx_data+2        ;->destination
    mov    r1,#time        ;->source
    mov    r2,#7            ;7 bytes to the time structure
cri_1
    mov    a,@r1
    mov    @r0,a            ;copy byte
    inc    r0
    inc    r1
    djnz    r2,cri_1
;
;    copy vars
;
    mov    r1,#vars        ;->source
    mov    r2,#4            ;4 bytes to the time structure
cri_2
    mov    a,@r1
    mov    @r0,a            ;copy byte
    inc    r0
    inc    r1
    djnz    r2,cri_2
;
;    copy relay state
;
    mov    a,relays
    mov    @r0,a            ;copy relays
;
;    set packet length & send!
;
    mov    ppx_lenl,#2+7+4+1    ;data packet length
    mov    ppx_lenh,#0        ;msb=0
    ajmp    create_tx        ;create packet & end
;----------------------------------------------------------------------------
;
;    Read action from eeprom
;    input packet:
;    src addr
;    cmd
;    input #
;    reply:
;    dest addr
;    cmd
;    input#
;    action (8 bytes)
;
;----------------------------------------------------------------------------
cmd_get_action
    mov    ppx_data,#ffh        ;destination=master
    mov    ppx_data+1,#81h        ;reply cmd
    mov    a,ppx_data+2        ;get action #
    anl    a,#1fh            ;32 actions only!
    rl    a
    rl    a
    rl    a
    mov    r0,#ppx_data+3        ;->dest
    mov    r2,#8            ;8 bytes
    mov    r1,#eeprom_addr        ;from eeprom
    acall    read_block        ;get from the eeprom
    mov    ppx_lenh,#0
    mov    ppx_lenl,#2+1+8        ;set reply length
    ajmp    create_tx
;----------------------------------------------------------------------------
;
;    Write action to eeprom
;    input packet:
;    src addr
;    cmd
;    action #
;    action (8 bytes)
;    reply:
;    dest addr
;    cmd
;    action#
;    Ok
;
;----------------------------------------------------------------------------
cmd_set_action
    mov    ppx_data,#ffh        ;destination=master
    mov    ppx_data+1,#82h        ;reply cmd
    mov    a,ppx_data+2        ;get action#
    anl    a,#1fh            ;32 actions only!
    rl    a
    rl    a
    rl    a
    mov    r0,#ppx_data+3        ;where to copy the eeprom data from
    mov    r2,#8            ;8 bytes
    mov    r1,#eeprom_addr        ;to eeprom
    acall    write_block        ;write data to eeprom
    mov    eeprom_time,#2        ;load eeprom write timer
reply_ok
    mov    ppx_data+3,#'O'
    mov    ppx_data+4,#'k'        ;reply with Ok
    mov    ppx_lenl,#2+1+2
    mov    ppx_lenh,#0        ;set packet length
    ajmp    create_tx
;----------------------------------------------------------------------------
;
;    Read input command. There is no parameters for this
;    We just reply with all values for the 16 inputs.
;    input packet:
;    src addr
;    cmd
;    time (7 bytes)
;    reply:
;    dest addr
;    src addr
;    cmd
;    addr
;    eeprom data (16 bytes)
;
;----------------------------------------------------------------------------
cmd_set_time
    mov    ppx_data,#ffh        ;destination=master
    mov    ppx_data+1,#83h        ;reply cmd

    mov    r0,#ppx_data+2        ;->time
    mov    r1,#time
    mov    r2,#7            ;7 bytes
cst_1
    mov    a,@r0
    mov    @r1,a
    inc    r0
    inc    r1
    djnz    r2,cst_1
    acall    write_rtc        ;update the clock
    ajmp    reply_ok
;----------------------------------------------------------------------------
;
;    Set the relays
;    input packet:
;    src addr
;    cmd
;    relays
;
;    reply:
;    dest addr
;    cmd
;    Ok
;
;----------------------------------------------------------------------------
cmd_set_relays
    mov    ppx_data,#ffh        ;destination=master
    mov    ppx_data+1,#84h        ;reply cmd
    mov    a,ppx_data+2        ;get the new relay states
    mov    relays,a        ;copy
    ajmp    reply_ok
;----------------------------------------------------------------------------
;
;
;    Create a PPX-1  transmit data packet. Calc checksum and forward
;    the data onto the transmit interupt code. We assume the data
;    packet length has been previously set.
;    zaps A,B,R0
;    returns to the dispatch code
;
;----------------------------------------------------------------------------
create_tx
    mov    ppx_lenh,#0        ;we can't tx packets > 20 bytes
    mov    a,ppx_lenl
    add    a,#5            ;add ppx packet overhead
    mov    bank1+4,a        ;set length for tx code
;
;    calc the packet header check
;
    mov    a,ppx_lenh
    cpl    a              ;!length hi
    mov    r2,a            ;save into R2
    mov    a,ppx_lenl
    cpl    a              ;!length low
    add    a,r2
    mov    ppx_hchk,a        ;=!length hi + !length low
;
;    calc the checksum
;
    mov    b,ppx_lenl        ;get length
    mov    r0,#ppx_data        ;->data area
    mov    ppx_cksmh,#0
    mov    ppx_cksml,#0        ;init checksum
tx_cksm
    mov    a,@r0            ;get data
    inc    r0
    add    a,ppx_cksml
    mov    ppx_cksml,a
    jnc    tx_cksm1
    inc    ppx_cksmh
tx_cksm1
    djnz    b,tx_cksm        ;accumulate the checksum
;
;    append the checksum on the end of the data
;
    mov    a,ppx_cksmh
    mov    @r0,a
    inc    r0
    mov    a,ppx_cksml
    mov    @r0,a
    mov    bank1+1,#comms_buf    ;r1 bank1->comms buffer
    mov    sbuf,#SOH        ;start of packet
    clr    ti             ;activate the tx interupt code
    ajmp    dispatch
;----------------------------------------------------------------------------
;
;
;    serial port isr
;    we use register bank #1 exclusively
;    R0    rx ->
;    R1    tx ->
;    R2    rx state
;    R3
;    R4
;    R5    rx char
;    R6    packet length hi
;    R7    packet length low
;
;----------------------------------------------------------------------------
serial_isr
    jnb    ri,sint_1        ;if not rx int
    push    psw
    push    a
    push    dph
    push    dpl
    mov    psw,#08h        ;select register bank#1
    acall    rx_char
    pop    dpl
    pop    dph
    pop    a
    pop    psw
    reti
;
;    transmit code
;
sint_1
    jnb    ti,si_2            ;if not tx int
    clr    ti            ;reset the int flag
    push    psw
    push    a
    mov    psw,#08h        ;select register bank#1
    mov    a,r4
    jz    si_3            ;skip if ==0
    mov    a,@r1            ;get data
    mov    sbuf,a            ;send it
    inc    r1
    dec    r4
    sjmp    si_4
si_3
    mov    r2,#0            ;rx state=0
si_4
    pop    a
    pop    psw
si_2
    reti
;----------------------------------------------------------------------------
;
;    Receive char interupt routine. Attempt to assemble a rx packet
;    data packet. Reject bad headers
;
;----------------------------------------------------------------------------
rx_char
    mov    r5,sbuf            ;save char
    clr    ri            ;reset int flag
    mov    a,r2
    cjne    a,#max_rx_state,rx_1    ;test for valid state
rx_1    jnc    rx_jumptable        ;invalid state-goto state0
    rl    a
    mov    dptr,#rx_jumptable    ;->jump table
    jmp    @a+dptr            ;goto code
;
;
;
max_rx_state    equ    8        ;max state+1
rx_jumptable
    ajmp    rx_state0        ;wait for SOH
    ajmp    rx_state1        ;get packet length high
    ajmp    rx_state2        ;get packet length low
    ajmp    rx_state3        ;get header check
    ajmp    store_rx        ;get data
    ajmp    rx_state5        ;get checksum high
    ajmp    rx_state6        ;get checksum low
    ajmp    rx_state7        ;end idle state
;
;    look for a SOH for start of packet
;
rx_state0
    mov    a,r5            ;get the rx char
    cjne    a,#SOH,rx_st01        ;soh ?
    mov    r2,#1              ;yes! next state =1
    mov    r0,#ppx_data        ;reset the data ->
    mov    ppx_cksmh,#0
    mov    ppx_cksml,#0        ;clear the checksum
rx_st01
    ret   
;
;    we've got a SOH already,get the packet length high
;
rx_state1
    mov    a,r5
    mov    r7,a            ;into R7
    mov    ppx_lenh,a
    inc    r2
    ret
;
;    get the packet length low
;
rx_state2
    mov    a,r5
    mov    r6,a            ;into R6
    mov    ppx_lenl,a
    inc    r2
    ret
;
;    get the header check & check the header data
;
rx_state3
    mov    a,r7            ;get header length hi
    cpl    a            ;not
    mov    r7,a
    mov    a,r6
    cpl    a            ;not
    add    a,r7            ;!lenh + !lenl
    clr    c
    xrl    a,r5            ;test header check
    jnz    rx_st31            ;twas bad
;
;    header was good!
;
    mov    a,r7
    cpl    a
    mov    r7,a            ;flip the packet length hi back again
    orl    a,r6            ;test for packet size ==0
    jnz    rx_st33
;
;    packet size ==0 next state is checksum
;
    mov    r2,#5
    ret
;
;    packet size > 0
;
rx_st33
    inc    r2
    ret
;
;    header was bad!
;       
rx_st31
    mov    r2,#0
    ret
;
;    Rx char in R5
;    accumulate the checksum
;    decrement the byte count,if count==0 then next state=checksum
;
store_rx
;
;    test the rx data ->
;
    mov    a,r0            ;get the data ->
    cjne    a,#ppx_data+20,srx_4
srx_4    jnc    srx_1            ;-> too high! skip storing the data
;
;    store the rx data
;
    mov    a,r5            ;get rx char
    mov    @r0,a            ;store the rx char
    inc    r0            ;->++
;
;    accumulate the checksum
;
srx_3
    add    a,ppx_cksml
    mov    ppx_cksml,a
    mov    a,ppx_cksmh
    addc    a,#0
    mov    ppx_cksmh,a        ;accumulate the checksum
    xch    a,r6
    jnz    srx_1
    dec    r7
srx_1
    dec    a
    xch    a,r6            ;decrement the byte count
    mov    a,r6
    orl    a,r7            ;test byte count==0
    jnz    srx_2
;
;    byte count=0 next state = checksum
;
    mov    r2,#5
srx_2
    ret
;
;    we've got all the data,now check the checksum
;
rx_state5
    mov    a,r5            ;get the rx char
    xrl    a,ppx_cksmh        ;xor with our checksum hi
    mov    ppx_cksmh,a        ;store result back for later
    inc    r2
    ret
;
;    check the checksum low
;
rx_state6
    mov    a,r5
    xrl    a,ppx_cksml        ;xor checksum low
    orl    a,ppx_cksmh        ;check for good result==0
    jnz    rx_bad
;
;    receive packet was for us and was good. report completion
;    and next state=idle
;
    mov    r2,#7
    setb    task_bits.0        ;activate the serial comms task
    ret
;
;    checksum was bad...reject the packet
;
rx_bad
    mov    r2,#0
    ret
;
;    receive packet was good,stay in this state until we get released
;
rx_state7   
    ret
*****************************************************************************
*
*    print hex in A
*
phex    push    a
    swap    a
    acall    l_hex
    pop    a
l_hex
    anl    a,#0fh
    add    a,#30h
    cjne    a,#3Ah,lh_1
lh_1    jc    lh_2        ;if a<=$39
    add    a,#7
lh_2   
    acall    pchar       
    ret

*
*    send A out the serial port
*
pchar    clr    scon.1
    mov    sbuf,a
pc_1    jnb    scon.1,pc_1
    ret
;----------------------------------------------------------------------------
;
;    ram
;
;
;----------------------------------------------------------------------------
    RSECT
        org    0
bank0        ds    8
bank1        ds    8
bank2        ds    8
bank3        ds    8
relays        ds    1        ;relay states
task_bits    ds    1        ;task flags
unit_sw        ds    1        ;bcd switch value
eeprom_time    ds    1        ;eeprom write timer
prev_seconds    ds    1        ;previous seconds reading
clock_time    ds    1        ;time between rtc readings
;
;    real time clock structure for reading & writing to the rtc
;
time
time_seconds    ds    1
time_minutes    ds    1
time_hours    ds    1
time_ydate    ds    1
time_wmonth    ds    1
time_timer    ds    1
time_year    ds    1
;
;    action structure
;       
action
act_mins    ds    1        ;minutes in bcd
act_hrs        ds    1        ;hours in bcd
act_day        ds    1        ;days as a bit field
act_relay    ds    1        ;relays as a bit field
act_cmd        ds    1        ;command in hi nibble,var# in low
act_const    ds    1        ;constant for comparison operation
act_null1    ds    1
act_null2    ds    1
;
;
;
curr_action    ds    1        ;current action#
day_bits    ds    1        ;days as a bit field
vars        ds    4        ;storage for 4 input variables
ppx_cksml    ds    1        ;comms checksum low
ppx_cksmh    ds    1        ;comms checksum hi
comms_buf    equ    *        ;comms buffer
ppx_lenh    ds    1
ppx_lenl    ds    1
ppx_hchk    ds    1
ppx_data    ds    20

stack        equ    *
;----------------------------------------------------------------------------
;
;    EEprom
;
;----------------------------------------------------------------------------
eeprom    section
    org    0
actions    ds    32*8            ;action table
 

Harald Kapp

Moderator
Moderator
Nov 17, 2011
13,700
Joined
Nov 17, 2011
Messages
13,700
I don't understand assembly language.
Then you'll have to learn it. See for example here or look it up in your favorite search engine. Searching for "8051 assembly language tutorial" turned up over 500000 hits.
I doubt you'll find anyone walking you through over 1000 lines of assembler code.

Where did you get the code from? Usually I'd expect an explanation of the code on that website.
Alternatively find another source that offers code in a high level language such as e.g. "C" (a typical language used for microcontrollers). I found quite a few water controller projects.
 

bancroft

Apr 23, 2021
81
Joined
Apr 23, 2021
Messages
81
I think you can check out books on assembly language, it helps you understand better how the microcontroller works.
 
Top