Connect with us

indirect addressing problem on 16f628

Discussion in '8bit Microcontrollers' started by Sambo, Feb 11, 2005.

  1. Sambo

    Sambo Guest

    I thought I have alredy stepped through indirrect addressing code in MPLAB (unless it was flash rom code not sure), but as far as I canb determine, it should be emulated in the debugger.
    Unfortunately nothing is being stored in the buffer ( Status.7 = 0...???. )
    Although, RP0 is set INDF and FSR are in all banks.

    ;************************** DEBUG CODE ************************
    ; setup buffer pointers to point near the end of buffer
    movlw -5
    addwf buff_end, w
    movwf buff_head
    movwf buff_tail

    send_test_message: ; if baudrate changed, main loop starts here send 9-0 digits
    movlw 0x39 ; prepare ASCII of '9'
    movwf temp3
    send_next_byte:
    movfw temp3
    call place_byte_in_output_buffer
    movlw 0x30
    subwf temp3, w
    btfsc STATUS, Z
    goto main_loop
    decf temp3
    goto send_next_byte
    ..
    ..
    place_byte_in_output_buffer:
    ; pointers - test write/read advance

    movwf temp1
    ; test if head + 1 is equal tail , if so buffer is full!!!
    ; first test if it hits end of buffer
    movfw buff_head
    addlw 1
    movwf new_buff_head
    ; movwf temp2
    subwf buff_end, w
    btfsc STATUS, Z
    goto head_hit_end
    ; now test it against the tail pointer
    movfw new_buff_head
    subwf buff_tail, w
    btfsc STATUS, Z
    goto buffer_full
    goto place_character

    head_hit_end:
    ; head will be pointing to beginning - is tail currently pointing to the beginning?
    movfw buff_tail
    subwf buff_start, w
    btfsc STATUS, Z
    goto buffer_full
    movfw buff_start
    movwf new_buff_head
    place_character:
    movfw buff_head
    movwf FSR
    movfw temp1
    movwf INDF
    movfw new_buff_head
    movwf buff_head

    character_qued_for_output:
    bcf STATUS, C
    return

    buffer_full:
    bsf STATUS, C
    return


    Any thoughts?

    Sam.
     
  2. Yes, INDF and FSR are mapped to all banks. Are you sure *your* registers
    are in the correct bank?
    In the MPLAB, under Special Function Registers, you can't see the
    contents of INDF. You can see it if you load it into W and look at W.

    hjf

    --
     
  3. Sambo

    Sambo Guest

    As it turns out MPLAB seams to only work properly if you are addressing them (FSR and INDF)
    in bank 0 that means that I either have another problem in outputing logic or my internal OSC is too far off after 10 characters. ( my first test message from flash rom although not through the circular buffer )
    I'll try inserting one bit delay between chars untill it goes to circuit board where it is not going to be that much hassle to put crystal.

    All the storage in that piece of code is in the common memory(0x70-).

    cheers, Sam
     
  4. All the storage in that piece of code is in the common memory(0x70-).

    Have you tried adding dec 128 to the base address? In Bank 1, can't
    access 0x70, you have to access F0h, to read/write what's on 0x70h --the
    common memory.

    hjf
     
  5. Sambo

    Sambo Guest

    Is it april first already? You are joking right?
    it is a banked design, one can only address locations between 0 and 7f.
    The only (stupid) reason why registes outside of bank 0 are defined with
    more than 7 bits is so they can print warnings ( I guess), instead of having
    separate table indicating what registers are in what banks.
    Before I found the include files I started to write my own and later this was
    the first think that struck me.

    However I am still not having any luck even after adding a substantial delay.
    For a long time I was stuck, untill I realized the problem was with Hyperterm
    no longer working ( at 9600). When I finaly tried the serial sample
    'http://www.oz1bxm.dk/PIC/628uart.htm" worked fine even in Hyperterm.
    When I set it to 2400 last time I checked I got "?>>>READ" instead of
    "?>>>READY." in Hyperterm, what made me believe the frequency is off.
    With a MSC++ 5.0 sample terminal program I get the full first message but another
    message (9-0) placed in the circular buffer is not comming out.

    Here is the full code if anyone wants to try it.

    ----------------------------------------------------
    ;**********************************************************************
    ; This file is a basic code template for object module code *
    ; generation on the PICmicro PIC16F628A. This file contains the *
    ; basic code building blocks to build upon. As a project minimum *
    ; the 16F628A.lkr file will also be required for this file to *
    ; correctly build. The .lkr files are located in the MPLAB *
    ; directory. *
    ; *
    ; If interrupts are not used all code presented between the *
    ; code section "INT_VECTOR and code section "MAIN" can be removed. *
    ; In addition the variable assignments for 'w_temp' and *
    ; 'status_temp' can be removed. *
    ; *
    ; If interrupts are used, as in this template file, the 16F628A.lkr *
    ; file will need to be modified as follows: Remove the lines *
    ; CODEPAGE NAME=vectors START=0x0 END=0x4 PROTECTED *
    ; and *
    ; SECTION NAME=STARTUP ROM=vectors *
    ; and change the start address of the page0 section from 0x5 to 0x0 *
    ; *
    ; Refer to the MPASM User's Guide for additional information on *
    ; features of the assembler and linker (Document DS33014). *
    ; *
    ; Refer to the respective PICmicro data sheet for additional *
    ; information on the instruction set. *
    ; *
    ;**********************************************************************
    ; *
    ; Filename: xxx.asm *
    ; Date: *
    ; File Version: *
    ; *
    ; Author: *
    ; Company: *
    ; *
    ; *
    ;**********************************************************************
    ; *
    ; Files required: *
    ; 16F628A.lkr (modified) *
    ; *
    ; *
    ;**********************************************************************
    ; *
    ; Notes: *
    ; *
    ; *
    ; *
    ; *
    ;**********************************************************************

    list p=16F628A ; list directive to define processor
    #include <p16F628A.inc> ; processor specific variable definitions

    errorlevel -302 ; suppress message 302 from list file


    __CONFIG _CP_OFF & _DATA_CP_OFF & _LVP_OFF & _BOREN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT


    ; '__CONFIG' directive is used to embed configuration word within .asm file.
    ; The lables following the directive are located in the respective .inc file.
    ; See data sheet for additional information on configuration word settings.



    ;***** VARIABLE DEFINITIONS (examples)

    ; example of using Shared Uninitialized Data Section
    INT_VAR UDATA 0x20
    timer1_prescaler res 1 ; /start
    PB7_old_val res 1
    PB7_new_val res 1
    timer_lo res 1
    timer_hi res 1
    timer1_timeouts res 1
    ResultsA res 1 ; port A outputs
    ; 0 - 0, 1, 2, 3, 4, 6 characters in output buffer
    ; 1 -
    ; 2 -
    ; 3 -
    ; 4 -
    ; 5 - VPP/!MCLR always input
    ; 6 -
    ; 7 - baud rate input HI/LO (BRGH bit)

    ResultsB res 1 ; port B outputs
    ; 0 - timer read hickup indicator
    ; 1 - Async RX
    ; 2 - Async Tx
    ; 3 - ?IR output? not yet implemented
    ; 4 - PGM
    ; 5 - IR input
    ; 6 - PGC
    ; 7 - PGD
    DD_PA equ 0xa0
    DD_PB equ 0xf2

    ;###################################################################################
    ; Commands from the serial port precceded by 00 AA sync chars
    ; Read or write registers
    ; 101 00001 read register specified in following byte
    ; 101 00010 write register specified in following byte with data in next additional byte

    ;
    sync_OK res 1 ; set to 0 when 0 received incremented when AA received
    Last_command res 1 ; if sync is 1 store bytes
    Command_data1 res 1 ; usualy address
    Command_data2 res 1 ; usualy data value

    Free_ram:

    INT_VAR_SHR UDATA_SHR 0x71
    w_temp res 1 ; variable used for context saving
    status_temp res 1 ; variable used for context saving

    temp1 res 1 ; used by place_byte_in_output_buffer
    temp2 res 1 ; used by place_byte_in_output_buffer
    temp3 res 1
    buff_head res 1 ; points to where new data is stored
    buff_tail res 1 ; points to which byte is next to be transmited ( read advance )
    buff_start res 1 ;
    buff_end res 1
    new_buff_head res 1
    TX_char_count res 1
    TX_max_char_count res 1
    ;**********************************************************************
    RESET_VECTOR CODE 0x000 ; processor reset vector
    goto main ; go to beginning of program


    INT_VECTOR CODE 0x004 ; interrupt vector location
    movwf w_temp ; save off current W register contents
    swapf STATUS, w ; move status register into W register
    movwf status_temp ; save off contents of STATUS register

    ; isr code can go here or be located as a call subroutine elsewhere
    banksel INTCON
    btfss INTCON, 0
    goto portB_no_change
    movfw PORTB
    andlw 0x80
    movwf PB7_new_val
    subwf PB7_old_val, f
    btfsc STATUS, Z
    goto int_done
    movfw TMR1H
    movwf timer_hi
    movfw TMR1L
    movwf timer_lo
    movf TMR1H, w ; Read high byte
    SUBWF timer_hi, W ; Sub 1st read with
    ; 2nd read
    BTFSC STATUS, Z ; Is result = 0
    GOTO done_reading_timer ; Good 16-bit read
    bsf ResultsB, 0
    decf timer_hi
    done_reading_timer:
    clrf TMR1H
    clrf TMR1L
    clrf timer1_timeouts
    ; output the data to the Async output buffer
    ; test if change is L/H or H/L
    btfss PB7_new_val, 5
    goto bit_end
    bsf timer_hi, 7 ; slap the bit start indicator into the highest bit
    movfw timer_hi
    call place_byte_in_output_buffer
    movfw timer_lo
    call place_byte_in_output_buffer
    goto data_output_complete
    bit_end:
    bcf timer_hi, 7 ; slap the bit end indicator into the highest bit
    movfw timer_hi
    call place_byte_in_output_buffer
    movfw timer_lo
    call place_byte_in_output_buffer
    data_output_complete:

    portB_no_change:
    btfss PIR1, TMR1IF ; did timer 1 overflow?
    goto timer1_service_done
    bcf PIR1, TMR1IF
    ; clear a byte somewhere?
    incf timer1_timeouts
    movlw 14
    subwf timer1_timeouts, f
    btfss STATUS, C
    goto timer1_service_done
    clrf timer1_timeouts
    incf timer1_timeouts
    bcf ResultsB, 0 ; clear timer read faulup indicator

    timer1_service_done:

    int_done:
    swapf status_temp, w ; retrieve copy of STATUS register
    movwf STATUS ; restore pre-isr STATUS register contents
    swapf w_temp, f
    swapf w_temp, w ; restore pre-isr W register contents
    ; bsf ResultsB, 3
    retfie ; return from interrupt

    place_byte_in_output_buffer:
    ; pointers - test write/read advance

    movwf temp1
    ; test if head + 1 is equal tail , if so buffer is full!!!
    ; first test if it hits end of buffer
    movfw buff_head
    addlw 1
    movwf new_buff_head
    ; movwf temp2
    subwf buff_end, w
    btfsc STATUS, Z
    goto head_hit_end
    ; now test it against the tail pointer
    movfw new_buff_head
    subwf buff_tail, w
    btfsc STATUS, Z
    goto buffer_full
    goto place_character

    head_hit_end:
    ; head will be pointing to beginning - is tail currently pointing to the beginning?
    movfw buff_tail
    subwf buff_start, w
    btfsc STATUS, Z
    goto buffer_full
    movfw buff_start
    movwf new_buff_head
    place_character:
    movfw buff_head
    movwf FSR
    movfw temp1
    movwf INDF
    movfw new_buff_head
    movwf buff_head

    character_qued_for_output:
    bcf STATUS, C
    return

    buffer_full:
    bsf STATUS, C
    return

    main
    ; remaining code goes here
    bcf STATUS, RP0 ; RAM PAGE 0
    bcf STATUS, RP1 ; RAM PAGE 0

    movlw 7 ; turn comparator off
    movwf CMCON

    movlw 0x00
    movwf PORTA
    movlw 0x04
    movwf PORTB

    banksel OPTION_REG
    bcf OPTION_REG, NOT_RBPU
    bsf STATUS, RP0 ; RAM PAGE 1
    movlw 0x0f ; high speed int osc, POR and BOR
    movwf PCON
    movlw DD_PA
    movwf TRISA ; PA5, PA7 inputs

    movlw DD_PB ; RB7-RB4 and RB1(RX)=input, others output
    movwf TRISB
    banksel PORTB
    movlw 0x04
    movwf PORTB
    movwf ResultsB
    movwf PORTA
    movwf ResultsA
    banksel T1CON
    movlw 0x21 ; prescale /4, enable timer
    movwf T1CON
    clrf T1CON
    movwf timer1_prescaler
    movlw 0x30
    andwf timer1_prescaler
    ;;? movlw 0xc8 ; enable global interrupts, peripheral interrupts, interrupt on change of port B
    ;;? movwf INTCON
    bsf STATUS, RP0 ; RAM PAGE 1
    ;;? bsf PIE1, TMR1IE ; enable timer 1 interrupts, timeout clears any in-progrees IR character reception??

    ; ------------------------------------
    ; SET BAUD RATE TO COMMUNICATE WITH PC
    ; ------------------------------------
    ; Boot Baud Rate = 9600, No Parity, 1 Stop Bit
    ;
    banksel SPBRG
    movlw 0x19 ; 0x19=9600 bps (0x0C=19200 bps)
    movwf SPBRG
    movlw b'00100000' ; brgh(2) = high
    movwf TXSTA ; enable Async Transmission, set brgh

    bcf STATUS, RP0 ; RAM PAGE 0
    movlw b'10010000' ; enable Async Reception and continuous receive
    movwf RCSTA
    ; bsf PIR1, TXIF ; set tx reg empty interrupt flag

    bcf STATUS, RP0 ; RAM PAGE 0
    call check_baud_rate_input
    clrf temp1
    settle decfsz temp1,F
    goto settle


    ; setup the circular buffers
    movlw Free_ram
    addlw 10
    andlw 0f0
    movwf buff_start
    movwf buff_head
    movwf buff_tail
    movlw 70
    movwf buff_end

    bsf ResultsA, 3
    bsf PORTA, 3
    bcf STATUS, RP0 ; bank 0
    movlw 0x23
    movwf TXREG
    bsf STATUS, RP0 ; bank 1
    clrf EEADR
    get_next_char

    bsf STATUS, RP0 ; Bank1
    bsf EECON1, RD ; EE Read
    movfw EEDATA
    wait_trans_complete:
    bcf STATUS, RP0 ; bank 0
    btfss PIR1, TXIF ; (1) transmission is complete if hi
    goto wait_trans_complete
    movwf TXREG ; send data in W
    bsf ResultsA, 2
    bsf PORTA, 2
    sublw 0
    btfsc STATUS, Z
    goto ready_mess_done
    bsf STATUS, RP0 ; Bank1
    incf EEADR
    goto get_next_char
    ready_mess_done:
    bcf STATUS, RP0
    bcf ResultsA, 4
    bcf PORTA, 4


    ;************************** DEBUG CODE ************************
    ; setup buffer pointers to point near the end of buffer
    movlw -5
    addwf buff_end, w
    movwf buff_head
    movwf buff_tail
    send_test_message: ; if baudrate changed, main loop starts here send 9-0 digits
    movlw 0x39 ; prepare ASCII of '9'
    movwf temp3
    send_next_byte:
    movfw temp3
    call place_byte_in_output_buffer
    movlw 0x30
    subwf temp3, w
    btfsc STATUS, Z
    goto main_loop
    decf temp3
    goto send_next_byte

    clrf temp3
    ;************************ END DEBUG CODE **********************
    main_loop:
    ; first see if there is any data in the transmit buffer
    ; and calculate the number of bytes in there for performance monitoring
    ; otherwise it can be all dumped and transmit_data called blindly.

    movfw buff_tail
    subwf buff_head, w
    btfsc STATUS, Z
    goto check_for_incoming_data
    btfsc STATUS, C
    goto was_positive
    movwf TX_char_count
    movfw buff_end
    addwf TX_char_count
    movfw buff_start
    subwf TX_char_count
    goto calc_count_done
    was_positive:
    movwf TX_char_count
    calc_count_done:
    movfw TX_max_char_count
    subwf TX_char_count, w
    btfss STATUS, C
    goto new_char_count_max_done
    movfw TX_char_count
    movwf TX_max_char_count
    new_char_count_max_done:
    ; debug_code: generate inter character spacing
    incf temp3
    btfss STATUS, Z
    goto check_for_incoming_data
    movlw 0x80

    call transmit_data


    ; poll async receive for commands
    check_for_incoming_data:

    check_for_commands:


    ; if OK to change baudrate ie UART shift reg empty, timer 1 timed out ( at least once )
    ; command not being received (sync received)
    ; !!! CURRENTLY just DOIT !!!
    call check_baud_rate_input


    movfw ResultsB
    movwf PORTB

    goto main_loop ; loop forever, remove this instruction, for test only

    transmit_data:
    ;********************************************************************
    ; Transfer byte from cyrcular output buffer into transmit register
    ; if transmit register flag ( TXIF in PIR1 )indicates it is empty
    ; inputs: no direct input
    ; outputs: flag Z= 0 indicates byte was transfered
    ; 1 uart full/busy or no bytes in output buffer
    ;********************************************************************
    ; see if we can transmit
    bcf STATUS, RP0 ; RAM PAGE 0
    btfss PIR1, TXIF ; is transmit reg empty
    goto no_data_to_transmit ; check UART for data

    ; is there anything in the buffer?
    movfw buff_head
    subwf buff_tail, w
    btfsc STATUS, Z
    goto no_data_to_transmit
    place_in_TX_REG:
    movfw buff_tail
    incf buff_tail
    movwf FSR
    movfw INDF
    bsf STATUS, RP0 ; bank 1
    movwf TXREG
    bcf STATUS, RP0 ; bank 0
    movfw buff_end
    subwf buff_tail, w
    btfss STATUS, Z
    goto tail_pointer_OK
    movfw buff_start
    movwf buff_tail
    tail_pointer_OK:

    bcf STATUS, Z
    return
    no_data_to_transmit: ; or chanel not yet free
    bsf STATUS, Z
    return

    check_baud_rate_input:
    ;*****************************************************
    ; read external input and reflect it in TXSTA, BRGH
    ;*****************************************************

    bcf STATUS, RP0 ; RAM PAGE 0
    btfss PORTA, 7
    goto set_low_BRGH
    bsf STATUS, RP0 ; RAM PAGE 1
    bsf TXSTA, BRGH
    goto check_baud_rate_input_done
    set_low_BRGH:
    bsf STATUS, RP0 ; RAM PAGE 1
    bcf TXSTA, BRGH

    check_baud_rate_input_done:
    bcf STATUS, RP0 ; RAM PAGE 0
    return

    ; initialize eeprom locations
    EE CODE 0x2100
    DE ">>>READY."
    DE 0


    END ; directive 'end of program'
    -----------------------------------------------------------------

    The test circuit

    A0 - open
    A1 - open
    A2 - open
    A3 - open
    A4 - open
    A5 - 2.4K to Vdd
    A6 - open
    A7 - 20K to Vdd ( baud- select )
    B0 - open
    B1 - 1.6K to vdd ( AURT input )
    B2 - to ttl input of MAX232 CPE
    B3 - open
    B4 - to b5
    B5 - to B6
    B6 - to B7
    B7 - 10K to Vdd

    The only possibly out of spec thing (with the MAX232), I used 10uF caps.
    When I used this chip in a circuit over 10 years ago, a circuit I modelled on
    used 22uf, while checking recently, various models indicated 100nf or 1uf,
    but no specifics for MAX232CPE.

    ( I should realy hook up for in circuit programming I may even get better than 1 in 10
    success rate, lol)

    Cheers, Sam
     
  6. OK, you don't need to be an ass about it, you know? Remember: YOUR
    project is not working. You're the loser who can't send characters on
    the serial port of a 628. Anyway, **** you.

    hjf
     
Ask a Question
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.
Electronics Point Logo
Continue to site
Quote of the day

-