Pin won't stay high during Repeat...Until loop??

+ Reply to Thread
Results 1 to 2 of 2
  1. #1
    Join Date
    Mar 2009

    Question Pin won't stay high during Repeat...Until loop??

    My code is below for reference during this problem description. It has an alias called ext_pwr that is used to set PortC.3 high at the start of the Interrupt Service Routine (ISR) and is intended to stay high for the entire duration of the ISR, and then be set low when the ISR resumes the Main loop (ext_pwr = 0 is first statement in the Main Loop). The ext_pwr alias (PortC.3) is intended to be used to turn on or off a reed relay that is a control for external power delivery.
    Must be something I don't understand about the Repeat..Until loop, because the ext_pwr pin is being set low during the loop when not intended. I don't understand why, since no changes are made to PortC.3 or any of the PortC pins during the Repeat...Until loop. Could any of the register settings being made at the start of the Repeat...Until loop cause the PortC.3 pin to go low? Appears to me that the ext_pwr pin should stay high for the entire loop and only go low when the ISR is over and returns to the Main loop, but it doesn't. Can anyone tell me why this is happening???
    BTW, this code will run on a PICkit2 LPDB and the four LED's on the LPDB will light according to the PortC pin assignments in this code....purposely done so I can more easily trouble shoot the code before programming my custom board.

  2. #2
    Join Date
    Mar 2009

    Default This time with the code

    ' -----[ Device Declaration ]----------------------------------------------
    ' -----------------[ Declare Variables & Aliases ]
    ADINPUT VAR WORD      ' Stores VP6 value as sampled by the A/D 
    b0      VAr vdd.byte1 ' LSB of VDD when right justified
    b1      var VDD.Byte0 ' MSB of VDD when right justified
    dummy   VAR Byte      ' For read of on-interrupt port & clear mismatch condition
    ext_pwr VAR PORTC.3 ' Set RC3 to control RL2 as RL1 power control source
    flush   VAR PORTA.3   ' Set RA3 as input for sensing flush switch closure Int
    i       VAR Byte      ' Index used in Gallon counter loop
    LED_Grn VAR PORTC.0   ' Set RC0 (Green LED) for valve open..water flowing
    LED_Red VAR PORTC.1   ' Set RC1 (Red LED) for solenoid cmnd or low battery
    meter   VAR PORTA.2   ' Set RA2 as input for HS1 meter pulse Interrupt
    sol_valve VAR PORTC.2 ' Set RC2 as valve solenoid open/close command
    Vdd     VAR WORD      ' Stores Vdd value as converted from ADINPUT
    Vthr    CON 32        ' Set threshold (3.2v) to trigger low voltage warning
    ' -----[ Declare Constants ]
     k      CON 10   ' Calibration factor for flow meter...# pulses per gal
    ' -----[ Initialization ]  
    ' Setup Timer0 as an 8-bit counter with the clock input on RA2.
    ' 1:1 TMR0 prescaler
    ' TMR0 counts on high-to-low transitions
      OPTION_REG = %00111000   ' PORTA/B pullups enabled, Interrupt on falling
                               ' edge of RA2/INT, TMR0 clock source is RA2,
                               ' increment on high-to-low transitions, prescaler to 
                               ' TMR0, TMR0 Rate 1:2
      TMR0 = 256 - k           ' preload TMR0 to overflow after k counts
    ' Initialization of inputs/outputs
      flush = 1         ' Initialize RA3 (flush) at High value for flush interrupt
      meter = 1         ' Initialize RA2 (meter) at High for METER pulse inputs
                        ' RA2 = TMR0 clock input for simulated meter pulse inputs
      ext_pwr = 0       ' Intialize RC3 at low value to turn off external power
      sol_valve = 0     ' Initialize RC2 (sol_valve) at Low value 
      TRISA.2 = 1       ' Set RA2 as input port for clock to TMR0
      TRISA.3 = 1       ' Set RA3 as input port for sensing Flush switch closure
    ' Interrupts Settings
    TMR0_Enable VAR INTCON.5     ' Alias for On_Off switch of TMR0 counter
    FLUSH_INT_FLAG VAR INTCON.0  ' Alias RA3(FLUSH) On-change-interrupt flag bit
    TMR0_INT_FLAG VAR INTCON.2   ' Alias Timer0 overflow flag bit
    ' Set INT Handler
    ON INTERRUPT GOTO Int_handler   
    '-----[ Main Code Starts Here ]
      ' Perform following steps to save power during Sleep mode
        ext_pwr = 0         ' Turn off external power after interrupt is over
        OPTION_REG.7 = 1    ' Disable PortA/PortB pull-ups 
        OSCCON = %0100011   ' Switch to 1 MHz internal oscillator
        VRCON = %00100000   ' Set Voltage Reference for minimum power consumption
                            ' Disable CVref
        ANSEL= %11110011    ' Set PortA to Analog I/O to save power during Sleep but
                            ' leave Bits 2 & 3 as digital for RA2 pulse count
                            ' TMR0 overflow interrupt & RA3 On-Change intterupt.
        ANSELH= %11111111   ' Analog module enabled to save power during Sleep
        CM1CON0.7 = 0       ' Turn off comparators during Sleep
        CM2CON0.7 = 0
        PCON.4 = 0          ' Turn off BOR during Sleep
        WDTCON = %00010110  ' Turn WDT off to SLEEP indefinitely
        TRISA = %00001101   ' Set RA0, RA2 & RA3 as inputs
        TRISB = %11111111   ' Set all PORTB pins to inputs during Sleep
        TRISC = %11111111   ' Set all PORTC pins to input during Sleep
        PortA = %11111111   ' Write Port A all High to clear mismatch and save
                            ' power during SLEEP  
        PortB = %11111111   ' Set all Port B and C pins High to save power
        PortC = %11111111   ' in Sleep mode
        ' Interrupt Settings
        INTCON = %10001000  ' Enable interrupts: GIE & RABIE but TMR0 disabled
        IOCA = %00001000    ' before SLEEP.  Enable RA3 as RABIE on-change-INT
        @ sleep
        @ NOP              ' @ NOP statement here makes no difference               
        ' Microcontroller is in Sleep State waiting for external FLUSH Interrupt
            ' Valve should be closed at this point and no water flowing
       GOTO Main    ' Loop to Main to wait for next Flush interrupt on RA3 change
    '------{ Begin Interrupt Handler }
      DISABLE       ' Disable interrupts during interrupt handler
     'Initialize registers upon Interrupt wakeup from Sleep                    
        OPTION_REG.7 = 0    ' Enable PortA/PortB Pullups                   
        WDTCON = %0001000   ' Turn WDT on for ops
      ' A/D & Comparators disabled
        ANSEL=0             ' Set PortA to digital I/O for use with RA2 and RA3
        ANSELH=0            ' Analog module disabled
        CM1CON0=0           ' Disable comparators
      ' Port Settings
        'TRISA = %00001000   ' Per JoeS to save power
        TRISA = %11111111   ' Set all PORTA pins to inputs...RA0, RA2 & RA3 are used
        TRISB = %00000000   ' Set all PORTB pins to outputs
        'TRISC = %00000000
        TRISC = %11110000   ' Set lower 4 pins of PortC as outputs for LEDs
        PORTA = %00000000   ' PortA pins all set to Low
        PORTC = %00000000   ' LEDs off, PULSOUT RC3 provides a high-going pulse
        HIGH ext_pwr        ' Turn on power to RL1 and to external power during 
                            ' the Interrupt Service Routine            
        IF FLUSH_INT_FLAG = 1 Then  ' Interrupt was from RA3 on change
                ' Wait until the external Flush interrupt is at high level...limits
                ' interrupt to switch closure only and not also for switch opening 
            Until flush = 1
            PULSOUT sol_valve,2000*10  ' Generate 100 msec RC2 pulse to RL1 to
                                       ' open valve
            'Write  7, flush      ' Write FLUSH value..remove comment for test only  
            ' Put code here to start a timer to run for 50 secs as a fail safe 
            ' to prevent overflow of toilet tank in case of sensor failure.
                'PULSOUT relay_off,2000 ' Generate 20 msec
                                        ' pulse to RL2 to turn off power to RL1      
      TMR0_Enable = 1     ' Enable the TMR0 pulse counter for overflow interrupt
      ' Valve is open and water is flowing            
      REPEAT    ' Execute this loop while waiting for flow to reach 1.6 gallons.
      ' Set registers for using A/D converter
        ' Set ADCON registers for A/D converter
            ADCON0 = %10110101  
                ' ADCON0.7 = ADFM = 1          ' 10-bit result is right justified
                ' ADCON0.6 = VCFG = 0          ' Set VREF+ to Vdd 
                ' CHS<3:0> = 1101              ' Select 0.6V Ref channel                                                    
            ADCON1 = %00110000    ' Select FRC as A/D conversion clock source
      ' Set FOSC=1MHz to stay inside recommended TAD range when not in SLEEP mode
            OSCCON = %01000001
      ' Set ANSEL register to make RA1 analog input
        ANSEL= %11110011   ' Set PortA to Analog I/O to save power during Sleep but
                           ' leave Bits 2 & 3 as digital for RA2 and RA3 interrupts
        ANSELH= %11111111  ' Analog module enabled to save power during Sleep
        DEFine ADC_BITS 10
        ' Flash Green flow light while water flowing until pulse counter overflows.
            LED_Grn = 1
            Pause 125
            LED_Grn = 0
            Pause 500
        ' If Battery is low..flash low battery monitor light while water flowing
            VRCON.4 = 1        ' Turn 0.6V reference ON
            PAUSEUS 100        ' Allow VP6 to settle
            ADCIN 13,ADINPUT   ' Get VP6 analog reading (10-bit)
            VRCON.4 = 0        ' Turn 0.6V reference OFF
            WRITE 11,ADINPUT
            'A/D scale for 0.6 volts is 0.6 * 1024 Full Scale = 6138
            VDD = 6138/ADINPUT ' convert input reading to Vdd voltage
            ' Vdd now holds the measured Vdd voltage * 10 (i.e., 3.4V = 34)
            '   The formula is the same for any Vdd voltage.  Assume normal 
            '   Vdd = +3.95vdc direct from fully charged battery pack input.
            WRITE 13,b0        ' Remove comments on Write statements for test only
            WRITE 14,b1
            Write 17,Vthr      
            IF Vdd <= Vthr THEN  ' If Vdd less than or equal to 3.2v flash the
                LED_Red =1       ' Blink RED LED for warning to replace batteries.
                PAUSE 125        
                LED_Red = 0
                Pause 500       
      Until TMR0_INT_FLAG = 1    ' Loop ends w/ flow meter pulse counter overflows
        PULSOUT sol_valve,2000*10' Generate 100 msec pulse to RC2 & Blink LED_Red
        LED_Red = 1              ' Blink RED LED one time to indicate close command
        PAUSE 125        
        LED_Red = 0
        Pause 500    
        'WRITE 19, TMR0_INT_FLAG ' Write TMR0 value..remove comment for test only
        dummy = flush            ' Clear mismatch condition                   
        FLUSH_INT_FLAG = 0       ' Clear interrupt flag & enable RA3 on interrupt
        TMR0_INT_FLAG = 0        ' Clear overflow flag
        TMR0 = 256 - k           ' Reload TMR0 to overflow after k counts             
      RESUME                   ' Resume Main Program                 
      '-------{ End of Interrupt Handler }

Similar Threads

  1. SERIN MIDI out of Synch?
    By jncortes in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 9th June 2009, 20:08
  2. Old and beyond help ?
    By DavidFMarks in forum mel PIC BASIC Pro
    Replies: 46
    Last Post: - 11th December 2008, 16:23
  3. Microcontroller with 2 way paging application problem
    By oneohthree in forum mel PIC BASIC Pro
    Replies: 30
    Last Post: - 20th April 2007, 17:27
  4. sample code for M25P32
    By Pedro Santos in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 9th January 2007, 03:37
  5. Another RTC, DS1287
    By DavidK in forum Code Examples
    Replies: 0
    Last Post: - 12th December 2006, 18:07

Posting Permissions

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