ASM help


Closed Thread
Results 1 to 17 of 17

Thread: ASM help

Hybrid View

  1. #1
    Join Date
    Sep 2005
    Location
    Campbell, CA
    Posts
    1,107

    Default ASM help

    I'm trying to re-create a hardware serial port with pure software. I need a non-blocking RECEIVE port because I need to add a 3rd port to my 8723.

    Most of the interrupt-driven routines I have seen have a very large processor overhead because they sample all the time and because they sample often so as to get the bit timing right.

    I'm trying an approach that uses INT0. It watches for the first falling edge of the START bit, then starts a TMR4 interrupt to time the rest of the bits. Using this approach should use zero processing power when a byte isn't coming in, and not too many cycles when one is. INT0 is turned on only to detect the falling edge of the START bit. TMR4 int is turned on only when receiving bits.

    The trouble is - the following code always returns 0xff whenever I send it a character. Can someone tell me what I'm doing wrong? RxD is coming through a MAX232 and is fed to PORTB.0

    Code:
              T4CON = %00000110   ; T4 ON, /16 prescale, no postscalers
             INTCON = %11000000  ; Global Int enable, peripheral INT enable
             INTCON2 = %00000000
             
             PIE3.3 = 0 ;Turn off Int on tmr 4
             IPR3.3 =1           ; High priority for INT4
    
    
             bit_cntr  VAR BYTE
             rcv_byte  VAR BYTE
             byteready VAR BYTE
             rcv_buffer   VAR BYTE
    ;-----------------------------------------------------------------------
    
            INCLUDE "DT_INTS-18.bas"         ; Base Interrupt System
    
      
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
                  INT_Handler    INT0_INT,   GetStart,   ASM,  no 
                  INT_Handler    TMR4_INT,   BitTimer,   ASM,  no
    
              endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
                             
    Goto OverInt
    
    '---[INT - interrupt handler]---------------------------------------------------
       
    ASM
    GetStart  
          bcf T4CON,2   ; Turn off Timer 4
          movlw 0x97   ; w /16 prescaler gives 156uSec dly @ 40Mhz = 1.5 bit times
          movwf TMR4
          bsf T4CON,2     ; Turn timer 4 on
          bsf  PIE3,3     ; turn on the Timer4 INT
          movlw 0x08      ; load the bit counter  
          movwf _bit_cntr
          bcf INTCON,4   ; shut off the INT0 interrupt
          bcf  INTCON,1   ; clear INT0 int flag bit
          INT_RETURN
    ENDASM     
         
    ASM
    BitTimer
          bcf T4CON,2     ; Turn Timer4 off 
          movlw 0xBF      ; 104uSec   / 16, 40 Mhz  1 bit time
          movwf TMR4      ; load it
          bsf T4CON,2     ; Turn it back on
          btfss PORTB,0   ; check status of portB.0
          bcf   STATUS,C  ; move bit into carry
          btfsc PORTB,0   ; check status of portb.0
          bsf   STATUS,C   ; move bit into carry
          rrcf   _rcv_byte,f ; shift carry into rec'd byte
          decfsz _bit_cntr,f ; decrement the bit counter
          bra   Donebit      ; get out and wait for next int
          bra Donebyte       ; got 8  bits
          
    Donebit      
          bcf  PIR3,3        ; clear the int flag
          bsf  PIE3,3        ; start the TMR4 int again
          INT_RETURN
          
    Donebyte      
          movff _rcv_byte,_rcv_buffer
          movff _rcv_buffer,PORTD  ; this is a debug, just to see rec'd byte on LEDS
          bcf  PIR3,3       ; clear the int flag
          bsf INTCON,4   ; turn on the INT0 interrupt for next byte
          INT_RETURN
    ENDASM      
          
              
    OVERINT:
    
        TRISD = 0
        PORTD = 0
        TRISE = 0
        INTCON.1 = 0
        PIE3.3 = 0
        PIR3.3 = 0   
             
             PAUSE 100
        
    @    INT_ENABLE INT0_INT  
      
      
    WAITT:
    
        GOTO WAITT
    Charles Linquist

  2. #2
    Join Date
    Nov 2005
    Location
    Bombay, India
    Posts
    967


    Did you find this post helpful? Yes | No

    Default

    You need to consider the interrupt latency along with the bit time and adjust the timer accordingly. Look at the generated listing to know how much it is. Another improvement is here

    Code:
    BitTimer
          bcf T4CON,2     ; Turn Timer4 off 
          movlw 0xBF      ; 104uSec   / 16, 40 Mhz  1 bit time
          movwf TMR4      ; load it
          bsf T4CON,2     ; Turn it back on
          bsf   STATUS,C   ; move bit into carry
          btfss PORTB,0   ; check status of portB.0
          bcf   STATUS,C  ; move bit into carry
          rrcf   _rcv_byte,f ; shift carry into rec'd byte
          decfsz _bit_cntr,f ; decrement the bit counter
          bra   Donebit      ; get out and wait for next int
          bra Donebyte       ; got 8  bits

  3. #3
    Join Date
    Sep 2005
    Location
    Campbell, CA
    Posts
    1,107


    Did you find this post helpful? Yes | No

    Default

    I understand your improvement, and I realized that I hadn't considered latency, but at 40Mhz, it is only a few uSec.

    Even with a small timing error, it should get the first few bits right - but doesn't!
    Charles Linquist

  4. #4
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    In Donebyte, before re-enabling the INT0 interrupt, it clears the Timer4 flag.
    INT0IF will still be set and you'll get a false start when there's no data.
    Code:
          bcf  PIR3,3       ; clear the int flag
          bsf INTCON,4   ; turn on the INT0 interrupt for next byte
    And I think the 1-1/2 bit time is off.
    97 would be right if it were decimal, but it's hex.
    Try it with 0x61.


    Knowing you, this is probably part of a much bigger program with lots of variables ...
    You'll probably want to put the variables used in ASM into BANK0
    Code:
             bit_cntr  VAR BYTE BANK0
             rcv_byte  VAR BYTE BANK0
             rcv_buffer   VAR BYTE BANK0
    There's really no need to stop timer4 when reloading since it's an 8-bit timer.
    But adding the reload value to TMR4 instead of just loading it will cancel out any latencies.
    <br>
    DT

  5. #5
    Join Date
    Sep 2005
    Location
    Campbell, CA
    Posts
    1,107


    Did you find this post helpful? Yes | No

    Unhappy

    Yes, this *WILL* be part of a much bigger program!

    I made some changes -

    I cleared INTCON.1 before I re-enabled it in the
    Donebyte routine

    Code:
    Donebyte      
          movff _rcv_byte,_rcv_buffer
          movff _rcv_buffer,PORTD  ; this is a debug, just to see rec'd byte on LEDS
          bcf  PIR3,3       ; clear the int flag
          bcf INTCON,1
          bsf INTCON,4   ; turn on the INT0 interrupt for next byte
          INT_RETURN
    But that didn't help. It shouldn't have been set anyway, since I clear it
    after I shut off INT0 in the
    GetStart section.

    I changed the TMR4 reload value to 0x61

    I put the variables in BANK0

    I made the change recommend by Jerson to take one line out of the setb/clrb
    sequence.

    Still, when I hit ANY character, all the LEDs on PORTD light up (high).

    Something small still isn't right.
    Charles Linquist

  6. #6
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    I think you need to disable the TMR4 interrupts in Donebyte, instead of clearing the flag.

    I'll try to run it here on a 4520.

    No Timer4, but Timer2 should do the same thing for me.
    <br>
    DT

Similar Threads

  1. PBP, ASM and LST files
    By HenrikOlsson in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 12th January 2010, 13:43
  2. ASM or PBP First?
    By mackrackit in forum Off Topic
    Replies: 4
    Last Post: - 10th October 2009, 12:08
  3. Serial Output - for an ASM numb
    By scomi85 in forum Serial
    Replies: 0
    Last Post: - 1st March 2009, 10:13
  4. Problem using ASM instruction
    By ewandeur in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 3rd April 2008, 15:26
  5. Can an asm interrupt contain gosub to a picbasic routine?
    By sougata in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 21st April 2005, 19:49

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts