Menu

Counting square wave pulses with PIC 16F1829

Help
2022-12-31
2023-01-06
  • Terry Platt

    Terry Platt - 2022-12-31

    Hi All,
    I'm trying to count the number of cycles of a square wave (about 1 KHz) and decrement a word variable to zero. I have tried the following code (and small variants):

    Counter = 1000
    Pulsecount:
    Do While High PORTA.4
    Loop
    Counter = Counter - 1
    Do While Low PORTA.4
    Loop
    If Counter > 0 then goto Pulsecount

    However, it appears that it never exits. Is the input too fast, or is there an error in this code?
    Thanks for any ideas!
    Terry

     
  • mmotte

    mmotte - 2022-12-31

    I don't think it is recognizing the condition you are trying to create.

     Do [{While | Until} condition]
    
     loop
    
    Do While High PORTA.4
    Loop
    

    I think you need to form the condiont using an '=' sign.

    Do while PortA.4 = High
    Or
    Do while PortA.4 = 1

    I personally prefer the second one because it says what you are looking for. Where as 'high' is defined as 1 but as you change languages it may not be defined or be a keyword.

     
  • Anobium

    Anobium - 2023-01-01

    MMOTTE is spot on.

    Plus, if the program has #option explicit it would not have compiled.

    #chip mega328p, 20   'chosen as guess..
    #option Explicit
    
      Dim Counter as Word
    
     Dir PORTA.4 In
    
      Counter = 1000
      Pulsecount:
      Do While High PORTA.4
      Loop
      Counter = Counter - 1
      Do While Low PORTA.4
      Loop
      If Counter > 0 then goto Pulsecount
    

    This source failed to compile with the warning

    Variable HIGHPORTA was not explicitly declared
    Variable LOWPORTA was not explicitly declared
    
     

    Last edit: Anobium 2023-01-01
    • Anobium

      Anobium - 2023-01-01

      And, if you are looking for speed, consider the code below.

      #chip 16f886
      #option Explicit
      
        #DEFINE High 1
        #DEFINE Low  0
      
        Dir PORTA.4 In
      
        Repeat 1000
      
          Do While PORTA.4 = High
          Loop
      
          Do While PORTA.4 = Low
          Loop
      
        End Repeat
      

      The previous use of Counter = Counter - 1 and If Counter > 0 is logical code but will be slow. Adding the [WORD]Counter +1 and then checking the condition [WORD]Counter > 1 uses 26 words more and calls to subroutines.

      The Repeat loop simply sets a SysRepeatTemp variable and use DECrement to test it is not zero - a lot faster.

      Enjoy.

       

      Last edit: Anobium 2023-01-01
  • Terry Platt

    Terry Platt - 2023-01-01

    Hi mmote and Anobium, Many thanks for the suggestions. I'm pleased to report that using the faster loop has resolved the issue. The loop now exits correctly!

     
    • Anobium

      Anobium - 2023-01-01

      Pleasure. HNY.

       
  • stan cartwright

    stan cartwright - 2023-01-02

    Mr Kent posted a 328 frequencycounter years ago. I got the code.

     
  • William Roth

    William Roth - 2023-01-04

    Hi,

    Counting Pulses can also be done using a Timer. In this case Timer1 works nicely. The code below should be self-explantory. Timer1 is being used in Counter Mode ( default)

    #chip 16F1829 ,32
    #option Explicit
    ;  
    ;     Connect 1KHz square wave to PIC16F1829 Pin 2 (RA5)
    ;
    
    DIM COUNTER_16BIT ALIAS TMR1H,TMR1L as WORD
    
    // Enable & Clear Timer1/Counter
    T1CON.0 = 1    // Enable Timer1/Counter
    TMR1H = 0      // Clear High Byte
    TMR1L = 0      // Clear Low Byte
    
    // Timer1/Counter increments by 1 on every positive edge of 1 KHz Signal
    // So should flash LED for 100 ms every second.
    
    Do
           Wait Until COUNTER_16Bit >= 1000
           TMR1H = 0     // clear  to zero
           TMR1L = 0     // clear  to zero
    
           Pulseout PORTB.7, 100 ms
    
    Loop
    
     

    Last edit: William Roth 2023-01-05
    • Anobium

      Anobium - 2023-01-05

      A nice example,

      How could this be modified to use an interrupt to remove the wait until... blocking ? Then, the do loop could be free running.

       
  • Anobium

    Anobium - 2023-01-05

    Yes.

    Would the setup be the same for the 16F1829 ? As the 16f18026 requires PPS.

     
  • William Roth

    William Roth - 2023-01-05

    Same setup except there is No PPS for 16F1829.

    The T1CKI Pin is fixed at RA5 ( Pin2) on the 16F1829. So connect the 1KHz signal to Pin 2 ( RA5)

     #chip 16F1829, 16
    #option Explicit
    
    #DEFINE USART_BAUD_RATE 9600
    #DEFINE USART_TX_BLOCKING
    
    'Serial OUT on RB7/Pin10  (Use for debugging to terminal)
    SET PORTB.7 ON   'Serial Idle HIGH
    DIR PORTB.7 OUT
    
    #DEFINE LED PORTC.7
    DIR PORTC.7 OUT  'LED Indicator
    
    WAIT 500 ms      'Stabilize
    
    'Setup Timer1 as Counter
    TMR1CS1 = 1      ' Configures Clock Source as Ext pulse on RA2
    TIMER1 = 64535   ' PreLoad (65535 - 1000 = 64535)
    TMR1ON  = 1      ' Enable Timer/Counter
    
    ON INTERRUPT TIMER1Overflow  Call ISR1
    
    ' ----- MainLoop -----
    Do
            'Do Stuff Here
    Loop
    ' ---------------------
    
    Sub ISR1
            TIMER1 = 64535  ' PreLoad (65535 - 1000 = 64535)
            PulseOut LED, 50 ms
    End Sub
    
     

    Last edit: William Roth 2023-01-05

Log in to post a comment.