PIC16F877A - Object Detection and Rejection - Timer Interrupt

Discussion in 'Embedded Systems and Microcontrollers' started by daljeet795, Mar 24, 2019.

  1. daljeet795

    Thread Starter Member

    Jul 2, 2018
    241
    3
    I am using PIC16F877A and Compiler MPLABX XC8

    I want to turn on LED on timer interrupt When a switch is pressed Counter goes from 0 to 22000 and when It reaches 22000 turns LED on

    When switch would be pressed Timer would be load with 22000 counts when It would overflow Led would be turned ON in ISR


    upload_2019-3-24_16-13-24.png

    How to configure timer control Register?

    T1SYNC = 1;
    T1OSCEN = 1;
    TMR1ON = 1;
    TMR1CS = 1;
    T1CKPS0 = 0;
    T1CKPS1 = 0;

    Is it a correct configuration?
     
  2. shteii01

    AAC Fanatic!

    Feb 19, 2010
    4,617
    730
  3. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    7,815
    3,663

    Check out the MCC feature in MPLab X. It will guide you though all of the configuration. Assuming PIC16F877A is supported. Not all chips are supported.
     
    Travm likes this.
  4. daljeet795

    Thread Starter Member

    Jul 2, 2018
    241
    3
    I have seen some good information here https://exploreembedded.com/wiki/PIC16f877a_Timer
    Code (C):
    1.  
    2. #include<pic16f877a.h>
    3.  
    4. char value = 0;
    5. #define SBIT_PS1  5
    6. #define SBIT_PS0  4
    7.  
    8. void interrupt timer_isr()
    9. {
    10.     if(TMR1IF==1)
    11.     {
    12.         value=~value;   // complement the value for blinking the LEDs
    13.         TMR1H=0x0B;     // Load the time value(0xBDC) for 100ms delay
    14.         TMR1L=0xDC;
    15.         TMR1IF=0;       // Clear timer interrupt flag
    16.     }
    17. }
    18.  
    19.  
    20. void main()
    21. {  
    22.     TRISD=0x00;    //COnfigure PORTD as output to blink the LEDs
    23.  
    24.     T1CON = (1<<SBIT_PS1) | (1<<SBIT_PS0); // Timer0 with external freq and 8 as prescalar
    25.     TMR1H=0x0B;     // Load the time value(0xBDC) for 100ms delay
    26.     TMR1L=0xDC;    
    27.     TMR1IE=1;       //Enable timer interrupt bit in PIE1 register
    28.     GIE=1;          //Enable Global Interrupt
    29.     PEIE=1;         //Enable the Peripheral Interrupt
    30.     TMR1ON = 1;     //Start Timer1  
    31.  
    32.     while(1)
    33.     {
    34.         PORTD = value;
    35.     }
    36. }

    I didn't understand this line T1CON = (1<<SBIT_PS1) | (1<<SBIT_PS0); // Timer0 with external freq and 8 as prescalar ?

    I am just looking simple way to configure T1CON register
     
  5. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    7,815
    3,663

    I already gave you a simple way. Did you try it?
     
  6. AlbertHall

    AAC Fanatic!

    Jun 4, 2014
    7,578
    1,836
    No you didn't. MCC is good but there is a new learning curve for it to add to understanding the PIC.
     
  7. AlbertHall

    AAC Fanatic!

    Jun 4, 2014
    7,578
    1,836
    Your original code is running from an external crystal connected to T1OSI and T1OSO.
    The second code you show is running from the PIC clock ( Fosc/4).
    Which do you want to run from - do you have that second crystal connected?
     
  8. MaxHeadRoom

    Expert

    Jul 18, 2013
    17,903
    5,476
    I thought the original intention was to input an encoder pulse into the TMT1 CLK input pin and load a preset value so TMR1 rolls over in a predetermined time and provides an interrupt?.
    Max.
     
    daljeet795 likes this.
  9. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    7,815
    3,663

    I don't even understand your statement. What learning curve?? To add what? The code? MCC?


    And it is completely your opinion if MCC is isn't a useful tool. I happen to think MCC is a very useful to understand how to setup a peripheral. It has turned the light on for me a number of times.

    If you mean there is a learning curve to setup MCC, then you have to be kidding me. It takes 5 ot 10 minutes to figure out how to add it and maybe another 10 or 20 minutes on figuring out how to use it.
     
    Travm likes this.
  10. Ian Rogers

    Well-Known Member

    Dec 12, 2012
    608
    162
    Whilst I agree to a point... I think MCC is turning Pic programming into Arduino style programming...Turning a port pin on and off now has a wrapper function, delays that I really never need...Far too much overhead... But!! For learning, yes!I think it works.. Even the diehard AVR freaks don't use Arduino..
     
  11. daljeet795

    Thread Starter Member

    Jul 2, 2018
    241
    3
    yes I am trying to use a timer to load pre determine count and when it over trigger output load
     
  12. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    7,815
    3,663

    You sound like one of the assembler zealots. ;)

    While I COMPLETELY agree, it is always best to know the chip a well as possible. And that includes knowing how to program in assembler. What good is it going to do to the hobbyist when they are bogged down in all the details of hos the chip works? If it get the job done then who cares how it did it? You get the project working.

    That said, when something does go wrong with the tools. the person that has a full understanding of how the chip works at an enormous advantage. So there is value in learning.

    I would also expect the professional to know the chip all the way down to the register and assembler level but for the hobbyist it is your choice. I say get the job done using tools available but pay attention to what is going on.
     
  13. Ian Rogers

    Well-Known Member

    Dec 12, 2012
    608
    162
    Horses for courses as they say.... No I hardly ever use ASM, but I have always been able to do what I need in C.. The only time assembler is used is to get things like graphical screens updated as quickly as humanly possible..
     
  14. LesJones

    Well-Known Member

    Jan 8, 2017
    2,059
    609
    Here is a program that does what you want. (Assuming my understanding of your requirements is correct.) It is written in assembler as I don't know how to do it in "C". The comments may give you enough of an idea about how it works which may help you to write it in "C"

    Code (Text):
    1.  
    2. ;*****************************************************************************  
    3. ;
    4. ;  Module:  TM1divide
    5. ;  
    6. ;  Version:02  
    7. ;
    8. ;
    9. ;
    10. ;*****************************************************************************  
    11.  
    12. ;I/O port useage
    13.  
    14. ;Port A
    15. ;   RA0   (Pin 2)
    16. ;   RA1   (Pin 3)
    17. ;   RA2   (Pin 4)
    18. ;   RA3   (Pin 5)
    19. ;   RA4   (Pin 6)   NOTE this is an open drain output so a pullup resistor must be used.
    20. ;   RA5   (Pin 7)
    21. ;   RA6
    22. ;   RA7
    23.  
    24. ;Port B
    25. ;   RB0t     (Pin 33)
    26. ;   RB1     (Pin 34)
    27. ;   RB2     (Pin 35)
    28. ;   RB3     (Pin 36)
    29. ;   RB4     (Pin 37)
    30. ;   RB5     (Pin 38)
    31. ;   RB6     (Pin 39)
    32. ;   RB7     (Pin 40)
    33.  
    34. ;Port C
    35.  
    36. ;   RC0   Encoder input pulse.     (Pin 15)
    37. ;   RC1   Use for sensor input.     (Pin 16) (Active low.)
    38. ;   RC2   used for pulse output     (Pin 17)
    39. ;   RC3   (Pin 18)
    40. ;   RC4   (Pin 23)
    41. ;   RC5   (Pin 24)
    42. ;   RC6   TX data       (Pin 25)
    43. ;   RC7   RX data       (Pin 26)
    44.  
    45. ;Port D
    46.  
    47. ;   RD0     (Pin 19)
    48. ;   RD1     (Pin 20)
    49. ;   RD2     (Pin 21)
    50. ;   RD3     (Pin 22)
    51. ;   RD4     (Pin 27)
    52. ;   RD5     (Pin 28)
    53. ;   RD6     (Pin 29)
    54. ;   RD7     (Pin 30)
    55.  
    56.  
    57. ;Port E
    58.  
    59. ;   RE0      (Pin 8)
    60. ;   RE1     (Pin 9)
    61. ;   RE2     (Pin 10)
    62.  
    63. ;*****************************************************************************  
    64.   list p=16f877A, st=OFF, x=OFF, n=0
    65.   errorlevel -302
    66.   errorlevel -306
    67.  
    68.   #include <p16f877A.inc>
    69.  
    70.    __CONFIG   _HS_OSC & _WDT_OFF & _PWRTE_ON & _BODEN_ON & _LVP_OFF & _CPD_OFF & _CP_OFF
    71.  
    72. ;  ******** RAM Locations ***********
    73. ;Bank 0
    74.    CBLOCK   0x20   ;GPR' starts at 0x20
    75.  
    76.  
    77.  
    78.    ENDC       ;Must end at 07F
    79. ; CBLOCK not used as no register variables are needed
    80.  
    81.      ORG  0
    82.  
    83. RESET:  GOTO  Start
    84.  
    85.  
    86.  
    87. ;Interrupt vector  
    88.      ORG  4     ;Should not get here as interrupts are not being used
    89.      retfie       ;Return from interrupt
    90. ;*****************************************************************************  
    91. ;
    92. ;  Function :  Main
    93. ;  Main application loop
    94. ;
    95. ;  Input:  None.
    96. ;
    97. ;  Output:  N/A
    98. ;
    99. ;*****************************************************************************  
    100. Start:
    101.      clrf  STATUS  ; Select bank 0
    102.      clrf  INTCON  ; No interrupts
    103.      clrf  PCLATH  ; Code is in first bank
    104.  
    105. ;         Now setup I/O ports
    106.      bsf     STATUS, RP0       ;Select bank 1 registers
    107.      movlw  0x03     ;Bits 0,1 inputs.
    108.      movwf  TRISC
    109.      bcf  STATUS, RP0  ;back to bank 0 registers
    110.  
    111. Wait_trigger_L:       ;Loop waiting for trigger pulse from sensor to go low  (Button pressed.)
    112.    btfsc   PORTC,1
    113.    goto   Wait_trigger_L
    114.  
    115. Wait_trigger_H:       ;Loop waiting for trigger pulse from sensor to go high (Button released.)
    116.    btfss   PORTC,1
    117.    goto   Wait_trigger_H
    118.  
    119. ;Init TMR1
    120.  
    121. ;   Prescale 1:1           (Bits 4 & 5 = 0)
    122. ;   T1OSCEN Timer1 Oscillator Enable Control bit    (Bit 3 = 0)
    123. ;   T1SYNC             (Bit 2  = 0  )
    124. ;   TMR1CS            (Bit 1  = 1  )
    125. ;   TMR1ON             (Bit 0 = 0 )
    126.      movlw  B'00000010'
    127.      movwf  T1CON
    128.  
    129. Start_counter:
    130.    movlw   0x0B
    131.    movwf   TMR1H
    132.    movlw   0xDC
    133.    movwf   TMR1L
    134.    bcf   PIR1,TMR1IF   ;Clear interrupt flag
    135.    bsf    T1CON,TMR1ON   ;Start TMR1
    136.  
    137.  
    138. Count_Loop:     ;Wait for TMR1 overflow bit
    139.    btfss    PIR1,TMR1IF   ;Test interrupt flag
    140.    goto   Count_Loop
    141.  
    142.    bsf   PORTC,2       ; set output pulse high
    143.    call    Delay100ms
    144.    bcf   PORTC,2       ; set output pulse low
    145.  
    146.    goto   Start
    147.  
    148.  
    149.  
    150.  
    151. ;Subroutines.
    152.  
    153.  
    154.  
    155. ;*****************************************************************************  
    156. ;
    157. ;  Function :  Delay 100 mS  
    158. ;  
    159. ;  
    160. ;  Input:  None
    161. ;
    162. ;  Output:  None
    163. ;
    164. ;*****************************************************************************
    165.  
    166. Delay100ms:
    167.      clrf  INTCON  ; No interrupts
    168.  
    169. ;   Prescale 1:8           (Bits 4 & 5 = 1)
    170. ;   T1OSCEN Timer1 Oscillator Enable Control bit    (Bit 3 = 0)
    171. ;   T1SYNC             (Bit 2  = 0 )
    172. ;   TMR1CS            (Bit 1  = 0  )
    173. ;   TMR1ON             (Bit 0 = 0 )
    174.  
    175.      movlw  B'00110000'
    176.      movwf  T1CON
    177.  
    178.    bcf   PIR1,TMR1IF   ;Clear interrupt flag
    179.  
    180.    movlw   0x0B
    181.    movwf   TMR1H
    182.    movlw   0xDC
    183.    movwf   TMR1L
    184.    bsf    T1CON,TMR1ON   ;Start TMR1
    185.  
    186. D_Loop:
    187.    btfss    PIR1,TMR1IF   ;Test interrupt flag
    188.    goto   D_Loop
    189.  
    190.    bcf    T1CON,TMR1ON   ;Stop TMR1  
    191.  
    192.    return  
    193. ;*****************************************************************************
    194.  
    195.  
    196.   END  ; End of program
    197.  
    198.  
    It turned out it could be done without using interrupts which save quite a few lines of code.
    I used a push button to simulate the input that sensed the object.
    The encoder output of the encoder was simulated with a signal generator running at a 100 Khz.
    at the end of counting the pulses (62500 from the values that you used in post #4) it generates a 100 mS output pulse on port C bit 2.
    A far as I could measure the delay between releasing the push button and the start of the 100 mS output was a bit over 620 mS which is close to the calculated time of 625 mS.
    I think this could be done with an 8 pin PIC such as a PIC12F1840. The internal oscillator could be used on this which would save a crystal and two capacitors.

    Les.
     
    daljeet795 likes this.
  15. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    7,815
    3,663
    TS is programming in C.
     
  16. MaxHeadRoom

    Expert

    Jul 18, 2013
    17,903
    5,476
    Les did acknowledge that in his thread.;)
    Max.
     
    daljeet795 and spinnaker like this.
  17. daljeet795

    Thread Starter Member

    Jul 2, 2018
    241
    3
    Thank you Les

    I tried to convert code into c programming as possible but I couldn't complete all because I don't understand assembly.

    refrence link https://exploreembedded.com/wiki/PIC16f877a_Timer

    I have compiled code successfully

    Code (C):
    1. // CONFIG
    2. #pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
    3. #pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
    4. #pragma config PWRTE = ON      //
    5. #pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR enabled)
    6. #pragma config LVP = OFF        // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
    7. #pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
    8. #pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
    9. #pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)
    10.  
    11. #define _XTAL_FREQ 8000000 //Specify the XTAL crystal FREQ
    12. #include <xc.h>
    13.  
    14. void main(void)
    15. {
    16.     TRISC0=1;     // Make RC0 pin as input encoder
    17.     TRISC1= 1;    // Make RC1 pin as input sensor
    18.     TRISC1= 0;    // Make RC2 pin as output
    19.  
    20.  
    21.     TMR1ON = 0; // Stops Timer1
    22.     TMR1CS = 1; // External clock from pin RC0/T1OSO/T1CKI (on the rising edge)
    23.     T1SYNC = 0; // Synchronize external clock input
    24.     T1OSCEN = 0; //Oscillator is shut-off
    25.     T1CKPS1 = T1CKPS0 = 0; // Assigned prescaler rate is 1:1
    26.  
    27.     TMR1IF = 0; // TMR1 register overflow is cleared
    28.     TMR1H=0x82; // initial count values in timer1 register
    29.     TMR1L=0xff;
    30.     TMR1ON = 1;     //Start Timer1
    31.  
    32. while(1)
    33. {
    34.  
    35.     if ( TMR1IF==1)
    36.     {
    37.       RC0 = 1;  // LED on
    38.       __delay_ms(100);
    39.      RC0 = 0;  // LED off
    40.     }
    41. }
    42. }
     
    Last edited: Mar 27, 2019
  18. LesJones

    Well-Known Member

    Jan 8, 2017
    2,059
    609
    I don't really understand how "C" works. I was under the impression the "C" normally uses timer1 for timing functions (For example delay) If I am correct then we would need to find out how to prevent C from using timer 1 so we have full control over it.

    If you have managed to get control of timer 1 then you have got as far as starting the timer. Now you have to keep checking for bit zero of register PIR1 changing from a zero to a one. This indicates that TMR1 has overflowed. If I had used interrupts the program could carry on doing something else useful until the interrupt occurred. There is nothing else for the program to do until it needs to generate the output pulse. I have also used timer 1 to generate the 100 mS output pulse.

    Les.
     
    daljeet795 likes this.
  19. Ian Rogers

    Well-Known Member

    Dec 12, 2012
    608
    162
    Here's the defines.. They are just macro's
     
  20. MaxHeadRoom

    Expert

    Jul 18, 2013
    17,903
    5,476
    If you are looking to learn C, there is the trial version of MikroC and the instruction manual PDF shows all the examples of code.
    I only use assembler, but have used the mikroC manual in order to convert and decipher the different instructions to assembler.
    Max.
     
    daljeet795 likes this.
Loading...