Incoming Pulse Monitoring code - comments and suggestions welcome


Closed Thread
Results 1 to 4 of 4
  1. #1
    Join Date
    Aug 2005
    Posts
    44

    Default Incoming Pulse Monitoring code - comments and suggestions welcome

    Hi,

    I've been working on a project that looks at an incoming pulse which is a 50% duty cycle and varying between 0 to 400hz.

    This project is using the instant interrupts routines to do all its work.

    The pic basically needs to invert the incoming pulse and put it back out of a port, however, If theres no incoming pulse for around 1.5 or more seconds, then the pic needs to generate approx 15 Hz on the same output port, until the incoming pulse is restored, then it will output the inverted incoming pulse back on the output.

    On the scope it seems to work upto about 2kHz which is more than enough speed for my purpose.

    Anyway here is my code, any comments or suggestions are welcome (sorry about the formatting, it did look ok in MPLAB)

    Code:
    '------------------------------------------------
    '  	Pulse Monitor
    '  	PIC16F628A @ 4mhz
    '
    '
    '	Input Signal Port B.3
    '	Output Signal Port B.5
    '------------------------------------------------
    
    
    INCLUDE "DT_INTS-14.bas"     ' Base Interrupt System
    INCLUDE "ReEnterPBP.bas"     ' Include if using PBP interrupts
    
    
    CMCON = 7						' set portA to digital
    TRISA = %00100000				' Port A all output but MCLR
    TRISB = %00001000				' Port B all output but 3 (CCP)
    T1CON = %00110000				' Set Timer 1, Off and 1/8 prescale (fire every 520ms)
    T2CON = %00000011				' Set Timer 2, Off and 1/16 prescae (fire every 4ms)
    Symbol  Capture = PIR1.2 		' CCP1 capture flag
    T1count		VAR BYTE			' Timer 1 count (1 count = 0.52 sec)
    i			VAR BYTE			' i is the incrementer for the pulse generator
    
    ASM
    INT_LIST  macro    	 ; IntSource,   Label,  	Type, ResetFlag?
            INT_Handler	   CCP1_INT,  _gotpulse,	PBP, 	yes
    		INT_Handler    TMR1_INT,  _nospeed,		PBP,  	yes
    		INT_Handler    TMR2_INT,  _generate,   	PBP,  	yes
    			
        endm
        INT_CREATE               	; Creates the interrupt processor
    
        INT_ENABLE   TMR1_INT     	; enable timer1 interrupts (CCP timer)
    	INT_ENABLE 	 CCP1_INT	  	; enable CCP port change interrupt
    	INT_DISABLE  TMR2_INT     	; enable timer2 interrupts (pulse generator)
    ENDASM
    
    
    
    	Low portb.5					' start with Portb.5 low
    	T1count = 0					' set variable	
    	i		= 0					' set variable
    
        CCP1CON = %00000100  		' Capture mode, capture on falling
        T1CON.0 = 1          		' Turn TMR1 on here
    
       
    MainLoop:
    	
    	pauseus 20
        GOTO MainLoop
        
        END
    
    
    '=======================================================================================
    
    '---[CCP1 - interrupt handler - We got an input Pulse] ---------------------------------
    
    gotpulse:
    
    		If CCP1CON.0 = 0 then			' if we captured a falling edge, switch to rising edge
    		CCP1CON.0 = 1
    		else
    		if CCP1CON.0 = 1 then			' if we captured a rising edge, switch to a falling edge
    		CCP1CON.0 = 0
    		endif
    		endif
    
    		Portb.5 = Portb.3 ^ $0F			' Output PortB.5 = inverted state of Portb.3
    
    		TMR1H = 0            			' Clear high byte of TMR1 counter
        	TMR1L = 0            			' Clear low byte
    		@ INT_DISABLE  TMR2_INT     	' disable timer0 interrupts (pulse generator)
    	    T2CON = %00000011				' Set Timer 2 Off prescale 1/16
    	
    @ INT_RETURN
    
    
    
    '=======================================================================================
    
    '---[TMR1 - interrupt handler - Called when CCP Timer Overflows @ 520ms] ---------------
    nospeed:
    
    	 T1count = T1count + 1				' increment every 520ms
    
    	 If T1count >= 3 then				' no pulses for 1560ms, start generating them
    	 T2CON = %00000111					' Set Timer 2 prescale 1/16 and on
    	 Low portb.5						' start with portb.5 low
    	 @ INT_ENABLE  TMR2_INT    			' enables timer0 interrupts (TMR0 fires on Overflow)
    	 T1count = 0						' reset the TMR1 count
    	 endif
    	
    	 TMR1H = 0            				' Clear high byte of TMR1 counter
         TMR1L = 0            				' Clear low byte
    
    	
    @ INT_RETURN
    
    
    '==========================================================================================
    
    '---[TMR2 - interrupt handler - This will fire every 4ms]----------------------------------
    ' send a 20ms pulse every  (12 *4ms) 48ms, gives a frequency of ~ 15hz
    generate:
    
    i = i + 1								' increment tmr2 count
    
    if i => 12 then							' equal to or more than 12, send a pulse
    pulsout portb.5,2000					' 20ms pulse out
    i = 0									' wait another 12+ cycles
    endif
    
    	
    @ INT_RETURN

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


    Did you find this post helpful? Yes | No

    Default

    Hi jamie,

    It's nice to see more examples with Instant Interrupts popping up.

    I think using the CCP to generate an interrupt on every transition of the Input is slowing things down.

    If you handle the "Input to Inverted Output" in the main loop, It should go alot faster than 2khz.
    Then the interrupts can just handle the timer overflows.

    Here's a possibility ...
    Code:
    '------------------------------------------------
    '  	Pulse Monitor
    '  	PIC16F628A @ 4mhz
    '
    '
    '	Input Signal Port B.3
    '	Output Signal Port B.5
    '------------------------------------------------
    
    
    INCLUDE "DT_INTS-14.bas"        ' Base Interrupt System
    INCLUDE "ReEnterPBP.bas"        ' Include if using PBP interrupts
    
    
    CMCON = 7                       ' set portA to digital
    TRISA = %00100000               ' Port A all output but MCLR
    TRISB = %00001000               ' Port B all output but 3 (CCP)
    T1CON = %00110000               ' Set Timer 1, Off and 1/8 prescale (fire every 520ms)
    T2CON = %00000011               ' Set Timer 2, Off and 1/16 prescae (fire every 4ms)
    T1count     VAR BYTE            ' Timer 1 count (1 count = 0.52 sec)
    i           VAR BYTE            ' i is the incrementer for the pulse generator
    
    InPIN       VAR PORTB.3         ' Input Pin
    OutPIN      VAR PORTB.5         ' Output Pin
    TMR1ON      VAR T1CON.0
    TMR2ON      VAR T2CON.2
    LastState   VAR BIT
    
    ASM
    INT_LIST  macro     ; IntSource,      Label,   Type, ResetFlag?
            INT_Handler    TMR1_INT,   _nospeed,    PBP,    yes
            INT_Handler    TMR2_INT,  _generate,   	PBP,    yes
        endm
        INT_CREATE                  ; Creates the interrupt processor
    
        INT_ENABLE   TMR1_INT       ; enable timer1 interrupts (CCP timer)
        INT_ENABLE   TMR2_INT       ; enable timer2 interrupts (pulse generator)
    ENDASM
    
    
    Low OutPIN                      ' start with Output LOW
    T1count = 0                     ' set variable	
    TMR1H   = 0                     ' Clear high byte of TMR1 counter
    TMR1L   = 0                     ' Clear low byte
    i       = 0                     ' set variable
    TMR1ON  = 1                     ' Turn TMR1 on here
    
       
    '=======================================================================================
    '---[MainLoop handles the Inverted transfer From InPIN to OutPIN] ----------------------
    MainLoop:
        if InPIN <> LastState then  ' If Input State Changed 
            LastState = InPIN
            TMR2ON = 0              ' Stop Timer 2
            OutPIN = LastState ^ 1  ' Output = inverted state of Input
            TMR1H = 0               ' Clear high byte of TMR1 counter
            TMR1L = 0               ' Clear low byte
            T1count = 0
        endif
    GOTO MainLoop
        
    '=======================================================================================
    '---[TMR1 - interrupt handler - Called when Timer1 Overflows @ 520ms] ------------------
    nospeed:
        T1count = T1count + 1       ' increment every 520ms
    
        If T1count >= 3 then        ' no pulses for 1560ms, start generating them
            TMR2ON = 1              ' Set Timer 2 on
            T1count = 0             ' reset the TMR1 count
        endif
    @ INT_RETURN
    
    '==========================================================================================
    '---[TMR2 - interrupt handler - This will fire every 4.103ms]------------------------------
    ' send a 20ms pulse every  (12 * 4ms) 48ms, gives a frequency of ~ 15hz
    generate:
        i = i + 1                   ' increment tmr2 count
    
        if i < 12 then              ' Pin is low for 1-11
            OUTPIN = 0
        else
            OutPin = 1              ' Pin is high for 5 ints  (20ms)
        endif
        If i = 17 then i = 0        ' restart cycle, total = 69.751ms = 14.3hz 
    @ INT_RETURN
    Last edited by Darrel Taylor; - 4th March 2007 at 07:58. Reason: Changed INT_DISABLE TMR2_INT - to - INT_ENABLE
    DT

  3. #3
    Join Date
    Aug 2007
    Posts
    15


    Did you find this post helpful? Yes | No

    Default 18f4431 try to use three-input capture mode with hall-effect senor state transitoin d

    capture
    ansel0=%00000000 'all digital
    trisa=%11111111 'set all port a pins to input cap1,cap2,cap3
    trisb=%00000000 'set all port b pins as output

    t1 var word
    t2 var word
    t3 var word

    Capture1 var pir3.1 ' tmr5 value was capture by the active edga on capl input
    Capture2 var pir3.2 'interrupt flag for pin cap2
    Capture3 var pir3.3 'interrupt flag for pin cap3

    ' auto time base reset, capture on rising to falling edge
    RiseToFall CON %01000111
    ' auto time base reset, capture on falling to rising edge
    FallToRise CON %01000110
    false con 0
    true con 1

    'capture mode
    intcon =0 'interrupts off
    tmr5h = 0 'clean high byte of tm5 counter
    tmr5l = 0 'clean low byte
    t5con = %00000001 ' prescale 1:1, int clock, tmr5 =on


    cap1con=%01000111 ' enable caputure,pulse width measurement mode,
    'every rising o falling edge
    cap2con=%01000101
    cap3con=%01000101

    Capture1 = false 'rest caputer flag
    Capture2 = false
    Capture3 = false
    main :
    if (Capture1=true)and(capture2=true)and(capture3 = true) then
    high portb.7
    endif


    end
    if (Capture1=true)and(capture2=false)and(capture3 = true) then
    high portb.6
    endif
    goto main

  4. #4
    Join Date
    Aug 2007
    Posts
    15


    Did you find this post helpful? Yes | No

    Default need help with 3-input caputer transtion detector

    need help with 3-input caputer transtion detector

Similar Threads

  1. Pushbutton code routine suggestions?
    By jessey in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 3rd September 2005, 02:02

Members who have read this thread : 1

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