Hserin with Instant Interrupts.


Closed Thread
Results 1 to 18 of 18
  1. #1
    Join Date
    Dec 2003
    Location
    Storrs, Ct.
    Posts
    91

    Default Hserin with Instant Interrupts.

    My goal is to connect 2 pics together with Zigbee. I bought a Dev. kit from http://www.digi.com/ for $99.00. I'd like to use the Hardware serial port in the pic (18f2525) to communicate with the Zigbees so I'm trying to learn the ins and outs of Hserin, Hserout.

    I put together this little collection of snippetts to echo characters back to Hyperterminal. The echo seems to work fine when I send one character or 20. The part that has me stumped is:
    1) the Mainloop doesn't run. No Heartbeat.
    2) The echo part of the ISR seems to work as expected but the Led2 doesn't toggle as expected. (on with the first byte sent, off with the second on with the third etc....).

    I've been thru "TFM" on the Eusart and tried many different register settings many times but the solution hasn't jumped out at me yet.
    I've Hserin with and without timeouts.
    I've tried a pullup on RC7.
    I've tried a pulldown on RC7.

    So, as always, I would greatly appreciate a little nudge in the right direction. Not spoon feeding, just a nudge.
    Code:
     '::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
                         'Hserin with Darryl Taylor's Instant Interrupts
     '::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
       '   Program to echo incoming serial data 
        '   Baudrate : 9600 Baud
           ' MCSP and MPASM, LabX-2, Microcodeloader, PBP2.50
             ' Using PIC 18F2525 @ 4MHZ and bootloader
               ' Using internal USART and MAX232 to interface to Hyperterminal on PC
    
            
            DEFINE LOADER_USED 1
            DEFINE OSC 4
            DEFINE HSER_RCSTA 90h ' enable serial port, 
            define HSER_TXSTA 24h ' enable transmit, 
            define HSER_SPBRG 25 ' set baudrate to 9600                   
            DEFINE HSER_CLOERR  1 ' automatic clear overrun error  
            
            TRISC  = %10000000    ' PORTC.7 is the RX input, PORTC.6 is the TX output
                                  
        
        '   Serial communication definition
        '   ===============================
            '
            
    '::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    
    INCLUDE "MODEDEFS.BAS"       ' Include Shiftin/out modes
    INCLUDE "DT_INTS-18.bas"     ' Base Interrupt System
    INCLUDE "ReEnterPBP-18.bas"  ' Include if using PBP interrupts
    '::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
        '   Variable definition
    '::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
            
    RCIF       VAR     PIR1.5     ' Receive  interrupt flag (1=full , 0=empty)
    TXIF       VAR     PIR1.4     ' Transmit interrupt flag (1=empty, 0=full)
    led        var     PORTB.0
    led1       var     PORTB.1
    led2       var     PORTB.2
    holdoff    var     word
    SerialData var     byte
    
    clear
    
            '((((((((((((((((((((((((((((((((((((((()))))))))))))))))))))))))))))))))))))))
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   RX_INT,    _Getbytes,    PBP,  no
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
    
    @   INT_ENABLE  RX_INT     ; enable RX_INT interrupts
    
    
            '((((((((((((((((((((((((((((((((((((((()))))))))))))))))))))))))))))))))))))))
                       ' Subroutine to slow loop down some and toggle heartbeat
            '((((((((((((((((((((((((((((((((((((((()))))))))))))))))))))))))))))))))))))))
    Mainloop:
            for holdoff = 1 to 1000
            pause 1
            next holdoff
            toggle led           'toggle led every loop for heartbeat  
            goto Mainloop
    
    
            '((((((((((((((((((((((((((((((((((((((()))))))))))))))))))))))))))))))))))))))
               'ISR for RX_int interrupt 
            '((((((((((((((((((((((((((((((((((((((()))))))))))))))))))))))))))))))))))))))
    
    Getbytes:
            
           While RCIF = 1     ' clear the buffer
           HSERIN 100,error,[Serialdata] ' take it
           hserout [serialdata] ' send it
           Wend
           toggle led2       'led to confirm program went to RX ISR
    
    @ INT_RETURN
    
    
    error:
          Toggle led1
    @ INT_RETURN
     end
    "It will never happen here!" just happened here.
    My thoughts and prayers for Sandy Hook victims and families.

  2. #2
    skimask's Avatar
    skimask Guest

    Default

    For grins, try this instead of TOGGLE...
    Code:
     '::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
                         'Hserin with Darryl Taylor's Instant Interrupts
     '::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
       '   Program to echo incoming serial data 
        '   Baudrate : 9600 Baud
           ' MCSP and MPASM, LabX-2, Microcodeloader, PBP2.50
             ' Using PIC 18F2525 @ 4MHZ and bootloader
               ' Using internal USART and MAX232 to interface to Hyperterminal on PC
    
            
            DEFINE LOADER_USED 1
            DEFINE OSC 4
            DEFINE HSER_RCSTA 90h ' enable serial port, 
            define HSER_TXSTA 24h ' enable transmit, 
            define HSER_SPBRG 25 ' set baudrate to 9600                   
            DEFINE HSER_CLOERR  1 ' automatic clear overrun error  
            
            TRISC  = %10000000    ' PORTC.7 is the RX input, PORTC.6 is the TX output
                                  
        
        '   Serial communication definition
        '   ===============================
            '
            
    '::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    
    INCLUDE "MODEDEFS.BAS"       ' Include Shiftin/out modes
    INCLUDE "DT_INTS-18.bas"     ' Base Interrupt System
    INCLUDE "ReEnterPBP-18.bas"  ' Include if using PBP interrupts
    '::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
        '   Variable definition
    '::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
            
    RCIF       VAR     PIR1.5     ' Receive  interrupt flag (1=full , 0=empty)
    TXIF       VAR     PIR1.4     ' Transmit interrupt flag (1=empty, 0=full)
    led        var     PORTB.0
    led1count var byte
    led2count var byte
    led1       var     PORTB.1
    led2       var     PORTB.2
    holdoff    var     word
    SerialData var     byte
    
    clear
    
            '((((((((((((((((((((((((((((((((((((((()))))))))))))))))))))))))))))))))))))))
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   RX_INT,    _Getbytes,    PBP,  no
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
    
    @   INT_ENABLE  RX_INT     ; enable RX_INT interrupts
    
    
            '((((((((((((((((((((((((((((((((((((((()))))))))))))))))))))))))))))))))))))))
                       ' Subroutine to slow loop down some and toggle heartbeat
            '((((((((((((((((((((((((((((((((((((((()))))))))))))))))))))))))))))))))))))))
    Mainloop:
            for holdoff = 1 to 1000
            pause 1
            next holdoff
            led1count = led1count + 1
            led = led1count.0     'toggle led every loop for heartbeat  
            goto Mainloop
    
    
            '((((((((((((((((((((((((((((((((((((((()))))))))))))))))))))))))))))))))))))))
               'ISR for RX_int interrupt 
            '((((((((((((((((((((((((((((((((((((((()))))))))))))))))))))))))))))))))))))))
    
    Getbytes:
            
           While RCIF = 1     ' clear the buffer
           HSERIN 100,error,[Serialdata] ' take it
           hserout [serialdata] ' send it
           Wend
           led2count = led2count + 1
           led2 = led2count.0     'led to confirm program went to RX ISR
    
    @ INT_RETURN
    
    
    error:
          Toggle led1
    @ INT_RETURN
     end
    Using that method to set the LEDs, you can dispense with the pause loop and select a higher bit in the ledxcount variable to slow down the blinking.
    Last edited by skimask; - 14th September 2008 at 00:50.

  3. #3
    Join Date
    Jul 2003
    Posts
    2,405

    Default

    Nudge: Disable A/D....;o}
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  4. #4
    skimask's Avatar
    skimask Guest

    Default

    Quote Originally Posted by Bruce View Post
    Nudge: Disable A/D....;o}
    Doh! PortB...A/D...no kidding...

  5. #5
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924

    Default

    Looks like this needs re-named? If PORTS A through Z do not work
    http://www.picbasic.co.uk/forum/showthread.php?t=561
    Dave
    Always wear safety glasses while programming.

  6. #6
    Join Date
    Dec 2003
    Location
    Storrs, Ct.
    Posts
    91

    Default Never crossed my mind!

    I never thought I'd need to set ADCON1 since I'm not using any of PortA.
    Learning something new every day. As always, thanks for the help.

    I'm going to try your method of toggling the LED's Skimask, never seen it done like that, Thanks.

    New working code with one minor change. (Thanks Bruce.)

    Code:
     '::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
                         'Hserin with Darryl Taylor's Instant Interrupts
     '::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
       '   Program to echo incoming serial data 
        '   Baudrate : 9600 Baud
           ' MCSP and MPASM, LabX-2, Microcodeloader, PBP2.50
             ' Using PIC 18F2525 @ 4MHZ and bootloader
               ' Using internal USART and MAX232 to interface to Hyperterminal on PC
    
            
            DEFINE LOADER_USED 1
            DEFINE OSC 4
            DEFINE HSER_RCSTA 90h ' enable serial port, 
            define HSER_TXSTA 24h ' enable transmit, 
            define HSER_SPBRG 25 ' set baudrate to 9600                   
            DEFINE HSER_CLOERR  1 ' automatic clear overrun error  
            
            TRISC  = %10000000    ' PORTC.7 is the RX input, PORTC.6 is the TX output
                                  
        
        '   Serial communication definition
        '   ===============================
            '
      ADCON1 = %00001111      'Set up ADCON1 register no matter what you're doing!!!!!!
    '::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    
    INCLUDE "MODEDEFS.BAS"       ' Include Shiftin/out modes
    INCLUDE "DT_INTS-18.bas"     ' Base Interrupt System
    INCLUDE "ReEnterPBP-18.bas"  ' Include if using PBP interrupts
    '::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
        '   Variable definition
    '::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
            
    RCIF       VAR     PIR1.5     ' Receive  interrupt flag (1=full , 0=empty)
    TXIF       VAR     PIR1.4     ' Transmit interrupt flag (1=empty, 0=full)
    led        var     PORTB.0
    led1       var     PORTB.1
    led2       var     PORTB.2
    holdoff    var     word
    SerialData var     byte
    
    clear
    
            '((((((((((((((((((((((((((((((((((((((()))))))))))))))))))))))))))))))))))))))
    ASM
    INT_LIST  macro    ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler   RX_INT,    _Getbytes,    PBP,  no
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
    
    @   INT_ENABLE  RX_INT     ; enable RX_INT interrupts
    
    
            '((((((((((((((((((((((((((((((((((((((()))))))))))))))))))))))))))))))))))))))
                       ' Subroutine to slow loop down some and toggle heartbeat
            '((((((((((((((((((((((((((((((((((((((()))))))))))))))))))))))))))))))))))))))
    Mainloop:
            for holdoff = 1 to 1000
            pause 1
            next holdoff
            toggle led           'toggle led every loop for heartbeat  
            goto Mainloop
    
    
            '((((((((((((((((((((((((((((((((((((((()))))))))))))))))))))))))))))))))))))))
               'ISR for RX_int interrupt 
            '((((((((((((((((((((((((((((((((((((((()))))))))))))))))))))))))))))))))))))))
    
    Getbytes:
            
           While RCIF = 1     ' clear the buffer
           HSERIN 100,error,[Serialdata] ' take it
           hserout [serialdata] ' send it
           Wend
           toggle led2       'led to confirm program went to RX ISR
    
    @ INT_RETURN
    
    
    error:
          Toggle led1
    @ INT_RETURN
     end
    "It will never happen here!" just happened here.
    My thoughts and prayers for Sandy Hook victims and families.

  7. #7
    skimask's Avatar
    skimask Guest

    Default

    Quote Originally Posted by ronjodu View Post
    I'm going to try your method of toggling the LED's Skimask, never seen it done like that, Thanks.
    I like that method of using the heartbeat because it allows for an easy change of blink frequency. The LED 'attached' to a timer works also, but it only tells you that the timer is running and an interrupt is working. Generally, I use 2 heartbeats, one for a mainloop, and one for a timer. Mainloop says the program is looping, timer says the PIC is actually running.

  8. #8

    Default

    From what I see it's mostly a matter of setting up the defines and running getbytes?

    Is this the barebones of what I need to get data in/out of serialdata?

    As long as data is at portc.7 it continuously runs in the background as an input, loading serialdata while any other code is executing?

    I can then sample serialdata when I need to in my code?


    DEFINE LOADER_USED 1
    DEFINE OSC 4
    DEFINE HSER_RCSTA 90h ' enable serial port,
    define HSER_TXSTA 24h ' enable transmit,
    define HSER_SPBRG 25 ' set baudrate to 9600
    DEFINE HSER_CLOERR 1 ' automatic clear overrun error

    TRISC = %10000000 ' PORTC.7 is the RX input, PORTC.6 is the TX output


    ' Serial communication definition


    Getbytes:

    While RCIF = 1 ' clear the buffer
    HSERIN 100,error,[Serialdata] ' take it
    hserout [serialdata] ' send it
    Wend

  9. #9
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,588

    Default Re: Hserin with Instant Interrupts.

    To start,

    Set a new flag in interrupt, check that flag in main, do processing there and reset your flag.

    Keep isr as small as possible.

    Robert

  10. #10
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,588

    Default Re: Hserin with Instant Interrupts.

    Have you tried DT USART INTERRUPT?

    It works great, don't have to play with flags.

    Robert

  11. #11
    Join Date
    Feb 2013
    Location
    Quebec, Canada
    Posts
    67

    Default Re: Hserin with Instant Interrupts.

    This is what I do with DT_Interrupts on a serial stream of 115kBps on a PIC18F25k22 @44.2368MHz.

    "Buffer" is a circular buffer of 256 bytes. When BufferReady = 1, I use another pointer (ParsePtr) to parse the data.


    Code:
    '----[interrupts Handlers]-------------------------------------------------------
    RX_IntHandler:
        IF (RCSTA1.2 = 1) THEN
            ' A framing error occurred.
            ' Read RCREG to clear the error but don't use the data.
            CharBuff = RCREG1
    
        ELSE
           ' No framing error occurred. Get caracter.
           CharBuff = RCREG1
    
            If CharBuff <= 10 Then
                Buffer(BuffPtr) = 0
                BuffPtr = BuffPtr + 1
                BufferReady = 1
    
            Else
                If CharBuff >= 32 Then
                    Buffer(BuffPtr) = CharBuff
                    BuffPtr = BuffPtr + 1
                ENDIF
            ENDIF
        ENDIF
    
        @ INT_RETURN

  12. #12
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,517

    Default Re: Hserin with Instant Interrupts.

    Hi Andy,

    Looking at the original code I think at least one problem is the presense of the PAUSE in main routine.

    When using ON INTERRUPT the interrupt flag is checked in between each PBP statement. If characters start to come in while the PIC is exectuing a PAUSE 150 satements you're going to flood the USART buffer since the interrupt isn't serviced untill after the PAUSE 150 finishes.

    Same thing with the LCDOUT and PAUSE statements and in the master. They takes some time to execute and the interrupt flag is checked ONLY in between each statement so if the slave starts responding while the master is in the middle of printing to the LCD or executing a PAUSE the slave is going to flood the buffer of the master.

    That's the downside of ON INTERRUPT.

    /Henrik.

  13. #13
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,517

    Default Re: Hserin with Instant Interrupts.

    Hi Andy,
    I don't have the time to rig something up here at the moment but I took a look at your code again and here are a couple of suggestions.
    For the master you don't need interrupts at all. Since it's querying the slave for data it already knows when data is supposed to come in. What you may want to do is add a timeout to the HSERIN though in case something goes wrong. The defines for the LCD, at the top of the program, needs to be UPPER CASE or they won't have any effect. So, for the master, remove the interrupt stuff then go directly from HSEROUT to HSERIN, something like this:
    Code:
    Main:
    	lcdout $fe,1
    	lcdout $fe,128,"Test RX-Tx"
    	lcdout $fe,192,"Reading"
    	
    	pause 1000
    	
    	lcdout $fe,1
    	lcdout $fe,128,#m[0],#M[1],#M[2],#M[3]
    	lcdout $fe,192,"Transmitting!"
    
    	High en
    	high led
    	
    	hserout ["P",$88]
    	
    	' Wait for the data to go out before pulling the EN signal to
    	' the tranceiver - IF that's what the EN-signal is doing.....
    	While TXSTA.1 = 0 : WEND
    	
    	low en
    	low led
    	
    	Hserin [wait("S0"),m[0], wait("S1"),m[1], wait("S2"),M[2], wait("S3"),m[3]]
    
    
    	toggle led
    
    
    	lcdout $fe,1
    	lcdout $fe,128,"Received!"
    	LCDOUT $fe,192,#m[0],"*",#M[1],"*",#M[2],"*",#M[3]
    	pause 1000
    goto main
    For the slave, what you can do if you want to keep the ON INTERRUPT and still have your blinking LED in the main is to replace the long PAUSE with loop consisting of many short pauses instead. That way the interrupt flag will be polled after each of those short pauses instead of after the single long one. Much less risk of flooding the buffer. Something like this perhaps:
    Code:
    i VAR WORD
    main:
    	toggle led
    	low en        'My stuff 
    	For i = 0 to 299
    		PAUSEUS 500		' Pause for 150ms
    	NEXT	
    goto main
    
    Disable	interrupt		' Don't check for interrupts in this section
    
    serialin:						
    
    ' Read USART and store character to next empty location  
        	Hserin [wait("P"),start]
        	high en
    	if start =$88 then
        		for j=0 to 3            ' Producing ODD numbers (Just for checking of continuous communication) 
        			i=i+1
        			m[j]=(2*i)+1
            		if m[j]>100 then
            			i=0
            			m[j]=j+1
            		endif
        		next j
    		
    		hserout ["S0",m[0],"S1",m[1],"S2",M[2],"S3",m[3]]
    
    		' Wait for the data to go out before pulling the EN signal to
    		' the tranceiver.
    		While TXSTA.1 = 0 : WEND
    
    		low en
    	endif
    
    enable interrupt
    Resume							' Return to program
    goto main
    Please note that I have not tested it but it is what I would do given the circumstances. As for DT-INTS what he claimed really is true, once you've used it you'll never want to use ON INTERRUPT again. Yes, it's little bit trickier to use but really not that much. I suggest you look around the forum, there are plenty of examples of how to use it.

    /Henrik.

  14. #14
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,588

    Default Re: Hserin with Instant Interrupts.

    Andy,

    Do you have a particular need for USART? Or is this just to start getting familiar with DT Interrupts for whenever you may need them?

    Have you been able to get something working?

    Robert

  15. #15
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,588

    Default Re: Hserin with Instant Interrupts.

    Andy,

    I've been pulling out my hair since last night trying to get a simple USART communication between 2 PICs (I needed to add it to my current project anyways).

    Check this thread I found on Google and who started it:
    http://www.picbasic.co.uk/forum/showthread.php?t=17282

    I remember things forever, I just have problems recalling the information!

    Robert

  16. #16
    Join Date
    Aug 2006
    Location
    Look, behind you.
    Posts
    2,818

    Default Re: Hserin with Instant Interrupts.

    Speaking from a position of ignorance, as I have NOT studied the above. This link to serial backpack uses DT_Ints & HSERIN together:
    http://www.picbasic.co.uk/forum/cont...rial-backpacks
    If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
    .
    Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
    .
    There simply is no "Happy Spam" If you do it you will disappear from this forum.

  17. #17
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,588

    Default Re: Hserin with Instant Interrupts.

    Andy,

    Here's a little something to transmit. I left all the comments in it since I don't know your level of knowledge. I keep these in my programs since I often forget, or leave code on the shelf for year(s).

    Code:
    '--------------------------------------------------------------------'
    ' Author:  Demon                                                     '
    ' Date:    Dec 29th, 2014                                            '
    ' Project: RESIDENTIAL ALARM SYSTEM                                  '
    ' Circuit: Master                                                    '
    '                                                                    '
    ' PIC:            18F44K22 @ 64MHz                                   '
    ' Language:       PIC Basic Pro v2.60c                               '
    ' Assembler:      MPASM v6.49                                        '
    ' IDE:            MicroCode Studio Plus from Mecanique v2.1.0.7      '
    ' Programmer:     MeLabs USB Programmer v4.32                        '
    ' LCD:            CASIL CCM-2040CSL v2.0 (HD44780 parallel interface)'
    '                                                                    '
    ' All rights reserved.                                               '
    '                                                                    '
    ' Use of parts of code is permitted as long as credit is given       '
    ' to the author.  Code may or may not work, use at your own risk     '
    ' including but not limitted to financial loss, heartbreak and       ' 
    ' loss of an eye.                                                    '
    '--------------------------------------------------------------------'
    
    'DEFINE  LOADER_USED 1
    clear
    
    ' ---------------------------- Configuration Fuses -----------------------------
    asm
     __CONFIG    _CONFIG1H, _FOSC_INTIO67_1H & _PLLCFG_ON_1H & _PRICLKEN_OFF_1H & _FCMEN_ON_1H & _IESO_OFF_1H
     __CONFIG    _CONFIG2L, _PWRTEN_ON_2L & _BOREN_SBORDIS_2L & _BORV_285_2L
     __CONFIG    _CONFIG2H, _WDTEN_OFF_2H
     __CONFIG    _CONFIG3H, _CCP2MX_PORTC1_3H & _PBADEN_OFF_3H & _CCP3MX_PORTE0_3H & _HFOFST_OFF_3H & _T3CMX_PORTB5_3H & _P2BMX_PORTC0_3H & _MCLRE_EXTMCLR_3H
     __CONFIG    _CONFIG4L, _STVREN_OFF_4L & _LVP_OFF_4L & _XINST_OFF_4L & _DEBUG_OFF_4L
    endasm
    
    ' -------------------------------- Oscillator ----------------------------------
    DEFINE OSC 64
    
    ' --------------------------------- Includes -----------------------------------
    'INCLUDE "DT_INTS-18.bas"
    'INCLUDE "ReEnterPBP-18.bas"
    'INCLUDE "ReEnterPBP-18LP.bas"      ; PBP Re-entry for low priority external interrupt
    'INCLUDE "Elapsed_INT-18_64MHz.bas"
    
    ' -------------------------------- Interrupts ----------------------------------
    
    'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    '                      RX must be done manually on Master                      x
    'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    ;ASM
    ;----[High Priority Interrupts] ------------------------------------------------
    ;INT_LIST  macro    ; IntSource,        Label,           Type,   ResetFlag?
    ;        INT_Handler   TMR1_INT,   _ClockCount,   PBP,  yes
    ;    endm
    ;    INT_CREATE              ; Creates the High Priority interrupt processor
    
    ;----[Low Priority Interrupts] -------------------------------------------------
    ;INT_LIST_L  macro  ; IntSource,        Label,           Type,   ResetFlag?
    
    ;        INT_Handler   TMR3_INT,   _T3handler,   PBP,  yes
    ;    endm
    ;    INT_CREATE_L           ; Creates the Low Priority interrupt processor
    ;ENDASM
    
    ;DEFINE USE_LOWPRIORITY 1            ' Low priority interrupts
    
    ' ------------------------------------ USB -------------------------------------
    
    ' --------------------------------- Registers ----------------------------------
    OSCCON  = %01110000                 ' OSCILLATOR CONTROL REGISTER
    ' bit 7 IDLEN: Idle Enable bit
    '     R/W       1 = Device enters Idle mode on SLEEP instruction
    '               0 = Device enters Sleep mode on SLEEP instruction
    ' bit 6-4 IRCF<2:0>: Internal RC Oscillator Frequency Select bits(2)
    '     R/W       111 = HFINTOSC – (16 MHz)
    '               110 = HFINTOSC/2 – (8 MHz)
    '               101 = HFINTOSC/4 – (4 MHz)
    '               100 = HFINTOSC/8 – (2 MHz)
    '               011 = HFINTOSC/16 – (1 MHz)(3)
    '           If INTSRC = 0 and MFIOSEL = 0:
    '               010 = HFINTOSC/32 – (500 kHz)
    '               001 = HFINTOSC/64 – (250 kHz)
    '               000 = LFINTOSC – (31.25 kHz)
    '           If INTSRC = 1 and MFIOSEL = 0:
    '               010 = HFINTOSC/32 – (500 kHz)
    '               001 = HFINTOSC/64 – (250 kHz)
    '               000 = HFINTOSC/512 – (31.25 kHz)
    '           If INTSRC = 0 and MFIOSEL = 1:
    '               010 = MFINTOSC – (500 kHz)
    '               001 = MFINTOSC/2 – (250 kHz)
    '               000 = LFINTOSC – (31.25 kHz)
    '           If INTSRC = 1 and MFIOSEL = 1:
    '               010 = MFINTOSC – (500 kHz)
    '               001 = MFINTOSC/2 – (250 kHz)
    '               000 = MFINTOSC/16 – (31.25 kHz)
    ' bit 3 OSTS: Oscillator Start-up Time-out Status bit
    '       R       1 = Device is running from the clock DEFINEd by FOSC<3:0> of the CONFIG1H register
    '               0 = Device is running from the internal oscillator (HFINTOSC, MFINTOSC or LFINTOSC)
    ' bit 2 HFIOFS: HFINTOSC Frequency Stable bit
    '       R       1 = HFINTOSC frequency is stable
    '               0 = HFINTOSC frequency is not stable
    ' bit 1-0 SCS<1:0>: System Clock Select bit
    '       R/W     1x = Internal oscillator block
    '               01 = Secondary (SOSC) oscillator
    '               00 = Primary clock (determined by FOSC<3:0> in CONFIG1H).
    
    OSCCON2 = %00000100                 ' OSCILLATOR CONTROL REGISTER 2
    ' bit 7 PLLRDY: PLL Run Status bit
    '     R         1 = System clock comes from 4xPLL
    '               0 = System clock comes from an oscillator, other than 4xPLL
    ' bit 6 SOSCRUN: SOSC Run Status bit
    '     R         1 = System clock comes from secondary SOSC
    '               0 = System clock comes from an oscillator, other than SOSC
    ' bit 5 Unimplemented: Read as ‘0’.
    ' bit 4 MFIOSEL: MFINTOSC Select bit
    '     R/W=0     1 = MFINTOSC is used in place of HFINTOSC frequencies of 500 kHz, 250 kHz and 31.25 kHz
    '               0 = MFINTOSC is not used
    ' bit 3 SOSCGO(1): Secondary Oscillator Start Control bit
    '     R/W=0     1 = Secondary oscillator is enabled.
    '               0 = Secondary oscillator is shut off if no other sources are requesting it.
    ' bit 2 PRISD: Primary Oscillator Drive Circuit Shutdown bit
    '     R/W=1     1 = Oscillator drive circuit on
    '               0 = Oscillator drive circuit off (zero power)
    ' bit 1 MFIOFS: MFINTOSC Frequency Stable bit
    '     R         1 = MFINTOSC is stable
    '               0 = MFINTOSC is not stable
    ' bit 0 LFIOFS: LFINTOSC Frequency Stable bit
    '     R         1 = LFINTOSC is stable
    '               0 = LFINTOSC is not stable
    
    OSCTUNE = %11000000                 ' OSCILLATOR TUNING REGISTER
    ' bit 7 INTSRC: Internal Oscillator Low-Frequency Source Select bit
    '     R/W       1 = 31.25 kHz device clock derived from the MFINTOSC or HFINTOSC source
    '               0 = 31.25 kHz device clock derived directly from LFINTOSC internal oscillator
    ' bit 6 PLLEN: Frequency Multiplier 4xPLL for HFINTOSC Enable bit(1)
    '     R/W       1 = PLL enabled
    '               0 = PLL disabled
    ' bit 5-0 TUN<5:0>: Frequency Tuning bits – use to adjust MFINTOSC and HFINTOSC frequencies
    '     R/W       011111 = Maximum frequency
    '               011110 =
    '               • • •
    '               000001 =
    '               000000 = Oscillator module (HFINTOSC and MFINTOSC) are running at the factory calibrated frequency.
    '               111111 =
    '               • • •
    '               100000 = Minimum frequency
    
    PMD0 = %10111111                    ' PERIPHERAL MODULE DISABLE REGISTER 0
    ' bit 7 UART2MD: UART2 Peripheral Module Disable Control bit
    '               1 = Module is disabled, Clock Source is disconnected, module does not draw digital power
    '               0 = Module is enabled, Clock Source is connected, module draws digital power
    ' bit 6 UART1MD: UART1 Peripheral Module Disable Control bit
    '               1 = Module is disabled, Clock Source is disconnected, module does not draw digital power
    '               0 = Module is enabled, Clock Source is connected, module draws digital power
    ' bit 5 TMR6MD: Timer6 Peripheral Module Disable Control bit
    '               1 = Module is disabled, Clock Source is disconnected, module does not draw digital power
    '               0 = Module is enabled, Clock Source is connected, module draws digital power
    ' bit 4 TMR5MD: Timer5 Peripheral Module Disable Control bit
    '               1 = Module is disabled, Clock Source is disconnected, module does not draw digital power
    '               0 = Module is enabled, Clock Source is connected, module draws digital power
    ' bit 3 TMR4MD: Timer4 Peripheral Module Disable Control bit
    '               1 = Module is disabled, Clock Source is disconnected, module does not draw digital power
    '               0 = Module is enabled, Clock Source is connected, module draws digital power
    ' bit 2 TMR3MD: Timer3 Peripheral Module Disable Control bit
    '               1 = Module is disabled, Clock Source is disconnected, module does not draw digital power
    '               0 = Module is enabled, Clock Source is connected, module draws digital power
    ' bit 1 TMR2MD: Timer2 Peripheral Module Disable Control bit
    '               1 = Module is disabled, Clock Source is disconnected, module does not draw digital power
    '               0 = Module is enabled, Clock Source is connected, module draws digital power
    ' bit 0 TMR1MD: Timer1 Peripheral Module Disable Control bit
    '               1 = Module is disabled, Clock Source is disconnected, module does not draw digital power
    '               0 = Module is enabled, Clock Source is connected, module draws digital power
    
    PMD1 = %11011111                    ' PERIPHERAL MODULE DISABLE REGISTER 1
    ' bit 7 MSSP2MD: MSSP2 Peripheral Module Disable Control bit
    '               1 = Module is disabled, Clock Source is disconnected, module does not draw digital power
    '               0 = Module is enabled, Clock Source is connected, module draws digital power
    ' bit 6 MSSP1MD: MSSP1 Peripheral Module Disable Control bit
    '               1 = Module is disabled, Clock Source is disconnected, module does not draw digital power
    '               0 = Module is enabled, Clock Source is connected, module draws digital power
    ' bit 5 Unimplemented: Read as ‘0’
    ' bit 4 CCP5MD: CCP5 Peripheral Module Disable Control bit
    '               1 = Module is disabled, Clock Source is disconnected, module does not draw digital power
    '               0 = Module is enabled, Clock Source is connected, module draws digital power
    ' bit 3 CCP4MD: CCP4 Peripheral Module Disable Control bit
    '               1 = Module is disabled, Clock Source is disconnected, module does not draw digital power
    '               0 = Module is enabled, Clock Source is connected, module draws digital power
    ' bit 2 CCP3MD: CCP3 Peripheral Module Disable Control bit
    '               1 = Module is disabled, Clock Source is disconnected, module does not draw digital power
    '               0 = Module is enabled, Clock Source is connected, module draws digital power
    ' bit 1 CCP2MD: CCP2 Peripheral Module Disable Control bit
    '               1 = Module is disabled, Clock Source is disconnected, module does not draw digital power
    '               0 = Module is enabled, Clock Source is connected, module draws digital power
    ' bit 0 CCP1MD: CCP1 Peripheral Module Disable Control bit
    '               1 = Module is disabled, Clock Source is disconnected, module does not draw digital power
    '               0 = Module is enabled, Clock Source is connected, module draws digital power
    
    PMD2 = %00001111                    ' PERIPHERAL MODULE DISABLE REGISTER 2
    ' bit 7-4 Unimplemented: Read as ‘0’
    ' bit 3 CTMUMD: CTMU Peripheral Module Disable Control bit
    '               1 = Module is disabled, Clock Source is disconnected, module does not draw digital power
    '               0 = Module is enabled, Clock Source is connected, module draws digital power
    ' bit 2 CMP2MD: Comparator C2 Peripheral Module Disable Control bit
    '               1 = Module is disabled, Clock Source is disconnected, module does not draw digital power
    '               0 = Module is enabled, Clock Source is connected, module draws digital power
    ' bit 1 CMP1MD: Comparator C1 Peripheral Module Disable Control bit
    '               1 = Module is disabled, Clock Source is disconnected, module does not draw digital power
    '               0 = Module is enabled, Clock Source is connected, module draws digital power
    ' bit 0 ADCMD: ADC Peripheral Module Disable Control bit
    '               1 = Module is disabled, Clock Source is disconnected, module does not draw digital power
    '               0 = Module is enabled, Clock Source is connected, module draws digital power
    
    ANSELA = %00000000                  ' Set ports to digital
    ANSELB = %00000000
    ANSELC = %00000000
    ANSELD = %00000000
    ANSELE = %00000000
    
    ADCON0 = %00000000                  ' Disable ADC
    
    ' ---------------------------------- EUSART ------------------------------------
    'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    '                             For MULTIPLE Slaves                              x
    '                                                                              x
    '                 Do not use USART TX pin for HSEROUT on Slave                 x
    '                   Use SEROUT at 115200 baud open collector                   x
    '                                                                              x
    '                                   - or -                                     x
    '                                                                              x
    '                   Enable USART TX pin for HSEROUT on Slave                   x
    '                              Transmit to Master                              x
    '                                Disable TX pin                                x
    '                            (my preferred method)                             x
    'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    
    'DEFINE CHAR_PACING 1000 
    DEFINE HSER_RCSTA 90h               ' Enable serial port & continuous receive
    DEFINE HSER_TXSTA 24h               ' Enable transmit, BRGH = 1
    DEFINE HSER_CLROERR 1               ' Clear overflow automatically
    DEFINE HSER_SPBRG 138               ' 115200 Baud @ 64MHz, -0,08%
    
    RCSTA = $90                         ' Enable serial port & continuous receive
    TXSTA = $24                         ' Enable transmit, BRGH = 1
    SPBRG = 138                         ' 115200 Baud @ 64MHz, -0.08%
    SPBRGH = 0                          ' Baud Rate Generator high byte
    BAUDCON.3 = 1                       ' Enable 16 bit Baud Rate Generator
    
    '                                       Override switches
    'RCSTA1.4 = 0                        ' Disable USART RX1 function
    'RCSTA2.4 = 0                        ' Disable USART RX2 function
    'TXSTA1.5 = 0                        ' Disable USART TX1 function
    'TXSTA2.5 = 0                        ' Disable USART TX2 function
    
    ' ------------------------------------ LCD -------------------------------------
    DEFINE  LCD_DREG        PORTA
    DEFINE  LCD_DBIT        0
    DEFINE  LCD_RSREG       PORTE   ' Register Select
    DEFINE  LCD_RSBIT       0
    DEFINE  LCD_EREG        PORTE   ' Enable
    DEFINE  LCD_EBIT        1
    DEFINE  LCD_BITS        4
    DEFINE  LCD_LINES       4
    'DEFINE  LCD_COMMANDUS 1500          ' Set command delay time in microseconds
    'DEFINE  LCD_DATAUS    50            ' Set data delay time in microseconds
    
    ' ------------------------------ Port directions -------------------------------
    'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    '             - From Microchip PIC datasheet in EUSART section -               x
    ' For all modes of EUSART operation, the TRIS control bits corresponding to    x
    ' the RXx/DTx and TXx/CKx pins should be set to ‘1’. The EUSART control will   x
    ' automatically reconfigure the pin from input to output, as needed.           x
    'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    TRISA = %00000000                   ' 0 = output 
    TRISB = %00000000                   ' 1 = input
    TRISC = %11000000
    TRISD = %00000000
    TRISE = %00000000
    
    ' ----------------------------------- Ports ------------------------------------
    PORTA = %00000000                   ' 0 = low  (GND)
    PORTB = %00000000                   ' 1 = high (5V)
    PORTC = %00000000
    PORTD = %00000000
    PORTE = %00000000
    
    ' --------------------------------- Constants ----------------------------------
    conSlave1   CON 1                   ' Slave address
    conSlave2   CON 2
    conEcho     con 69                  ' Slave Echo command (Dec 69 = ASCII "E")
    
    ' --------------------------------- Variables ----------------------------------
    pinTX       var PortC.4             ' This pin is used for debugging only
    
    bytLoop     var byte                ' Loop control
    bytAddress  var byte                ' Slave address
    bytCommand  var byte                ' Slave command
    
    wrdCS       var word                ' CheckSum
    
    bytBuffer1  var byte[8]             ' Data buffers sent to Slave
    bytBuffer2  var byte[8]
    
    ' ------------------------------- Program start --------------------------------
        for bytLoop = 0 to 7            ' Initialize arrays with "fake data"
          bytBuffer1[bytLoop] = bytLoop
          bytBuffer2[bytLoop] = bytLoop
        next bytLoop
    
        pause 500
    
    '@ INT_ENABLE  TMR1_INT 
    
        goto MainProgram
    
    ' -------------------------------- Subroutines ---------------------------------
    'T1handler:
    '    T1CON.0 = 0                     ' Stop timer
    '@ INT_RETURN
    
    ' -------------------------------- Main Program --------------------------------
    MainProgram:
        
        Lcdout $fe, 1, "USART sample program"
    
        bytAddress  = conSlave1         ' Slave system address
        bytCommand  = conEcho           ' Slave echo command
        wrdCS = bytAddress + bytCommand ' Checksum = Address + Command
        for bytLoop = 0 to 7            ' Checksum = Checksum + Buffer1 + Buffer2
          wrdCS = wrdCS + bytBuffer1[bytLoop]
          wrdCS = wrdCS + bytBuffer2[bytLoop]
        next bytLoop
    
        pinTX = 1                       ' Signal the start of Transmit to Slave PIC
        hserout [dec3 bytAddress, dec2 bytCommand,   _
                 str bytBuffer1\8, str bytBuffer2\8, _
                 dec5 wrdCS.byte1, dec5 wrdCS.byte0]
        pinTX = 0                       ' Signal the end
        
        Lcdout $fe, $c0, "Addr:", dec3 bytAddress, "  Cmd:", dec2 bytCommand
        Lcdout $fe, $94, "Buf:", dec1 bytBuffer1[0], dec1 bytBuffer1[1], dec1 bytBuffer1[2], _
                                 dec1 bytBuffer1[3], dec1 bytBuffer1[4], dec1 bytBuffer1[5], _
                                 dec1 bytBuffer1[6], dec1 bytBuffer1[7],                     _
                                 dec1 bytBuffer2[0], dec1 bytBuffer2[1], dec1 bytBuffer2[2], _
                                 dec1 bytBuffer2[3], dec1 bytBuffer2[4], dec1 bytBuffer2[5], _
                                 dec1 bytBuffer2[6], dec1 bytBuffer2[7]
        Lcdout $fe, $D4, "Checksum:", dec5 wrdCS.byte1, dec5 wrdCS.byte0
    
    '    goto MainProgram
    end
    You can comment out the LCD stuff if you don't need it. I use a Saleae probe to see the data on the TX pin. The normal method is to connect to a PC using MAX232 chip (search forum for circuit).

    The interrupt is commented out because it is just a placeholder. It is not in working order, it's just there so I remember where I put stuff in my program. I adjust it to my needs when I need it. In this case, we don't need one in the Master.

    This shows how the data is sent across the TX line (display is too narrow on laptop).
    Name:  Saleae USART XMIT a.PNG
Views: 1792
Size:  45.1 KB
    Name:  Saleae USART XMIT b.PNG
Views: 1807
Size:  45.8 KB

    Robert
    Last edited by Demon; - 4th October 2016 at 16:55.

  18. #18
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,588

    Default Re: Hserin with Instant Interrupts.

    The checksum method above is just a basic one, there are many formulas, this was good enough for me.

    The code above is a basic structured approach. I try to keep all my "stuff" in the same order, makes it easier for me to find stuff (to copy&paste into new programs). Nothing is forcing you to organize your code, but there are some exceptions (DT_INT must be the first of DT includes). There is also paging issues, but that's advanced stuff. Generally; config fuses at top, then defines, registers, ports, variables, code and then data (it can be anywhere, it's just easier when it's at the bottom of the scroll range - especially when you have LOTS of data statements).

    Comments are your friend and take no space.

    I don't know how complex your PIC network will be, but the code above gives you a basic design. The Address can be for a single PIC, or a Call-All-PICs address (999 or whatever you want). The Command gives you flexibility in telling the slave what code to execute. The Buffers can be whatever you want (within PBP/PIC limits), mine will be at least 55 bytes. Same with the address and command; they can be whatever format you want.

    There are many ways to handle the actual message size. Some send one byte at a time, some send the longest record and let the slave figure out what it needs. Another way is to send a command first, the slave determines which size wil be sent, signals the master to send the data and then waits for it. You transfer less bytes but you do more data transfers; if my buffer lengths vary little, I send it all, if there's a HUGE difference in size, it's worth telling the slave what to wait for.

    There's no limit to how complex you can handle communications. I suggest you stick with whatever makes you happy.

    (have to get back to my PC, wife doesn't like having parts in the kitchen)

    Robert
    My Creality Ender 3 S1 Plus is a giant paperweight that can't even be used as a boat anchor, cause I'd be fined for polluting our waterways with electronic devices.

    Not as dumb as yesterday, but stupider than tomorrow!

Similar Threads

  1. Instant Interrupts - Revisited
    By Darrel Taylor in forum Code Examples
    Replies: 772
    Last Post: - 17th February 2016, 23:14
  2. Clock using Instant Interrupts
    By PICpocket in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 16th February 2009, 22:43
  3. Instant Interrupts and HSERIN
    By Rob in forum mel PIC BASIC Pro
    Replies: 26
    Last Post: - 31st January 2009, 06:13
  4. DT instant interrupts with mister_e keypad
    By Tomexx in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 26th November 2008, 21:02
  5. DT's Instant Interrupts trouble
    By Tomexx in forum mel PIC BASIC Pro
    Replies: 7
    Last Post: - 24th November 2008, 21:48

Members who have read this thread : 2

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