PIC16F877A - Object Detection and Rejection - Timer Interrupt

LesJones

Joined Jan 8, 2017
4,511
Hi joey,
I did think about suggesting the above methods to let the assembler do the work but decided it was probably better for the TS to do these things himself to get him to understand what is going on. As he has a background in programming in "C" he may be happier with the options that you suggested. Myself I find "C" very difficult as I don't understand exactly how it works. With assembler all the information I need is in the data sheet for the chip I am using. When I started programming I used to do the assembly part by hand converting the instructions one at a time into machine codes.

Les.
 

joeyd999

Joined Jun 6, 2011
6,300
When I started programming I used to do the assembly part by hand converting the instructions one at a time into machine codes.
I did the same (Z80). But, additionally, I had to simulate the code in my head since I couldn't afford actual hardware to run the code on.
 

LesJones

Joined Jan 8, 2017
4,511
I did quite a lot with Z80s I built a copy of an Nascom 2 on strip board But by that time I was using the Zeep assembler. I wrote a very basic disk operating system for it using first 8" then 5.25" and finally 3.5" floppy drives.

Les.
 

Thread Starter

daljeet795

Joined Jul 2, 2018
295
Hi joey,
I did think about suggesting the above methods to let the assembler do the work but decided it was probably better for the TS to do these things himself to get him to understand what is going on. As he has a background in programming in "C" he may be happier with the options that you suggested. Myself I find "C" very difficult as I don't understand exactly how it works.

Les.
Les you helped me a lot. I was struggling with logic millions of thanks to you for helping with your program

the code in assembly but I can attempt to convert in c language and now I am sure I will do it
 

Thread Starter

daljeet795

Joined Jul 2, 2018
295
Hi joey,
I did think about suggesting the above methods to let the assembler do the work but decided it was probably better for the TS to do these things himself to get him to understand what is going on. As he has a background in programming in "C" he may be happier with the options that you suggested. Myself I find "C" very difficult as I don't understand exactly how it works. With assembler all the information I need is in the data sheet for the chip I am using. When I started programming I used to do the assembly part by hand converting the instructions one at a time into machine codes.

Les.
Hello Les

you explained in reply, If there are a number of object between the scanner and the rejection point. We need to have a counter running for each object. consider the number of object is five then we should have counter more than five

if you don't mind @les. Can you write code in assembly for five-timer I feel it's more difficult
 

LesJones

Joined Jan 8, 2017
4,511
The delay routine also uses TMR1 but is counting timing pulses derived from the CPU clock. The CPU clock is one quarter of the crystal frequency (20 Mhz) so the CPU clock is 5 Mhz. If you look at the comments at the start of the delay subroutine you will see that the prescaler is set to 1:8. This means that the actual input to TMR1 is 5Mhz/8 = 625 Khz So the period of that is 1000000/625000 = 1.6 uS As we wanted a delay of 100 mS (100000 uS) we need to count 100000/1.6 = 62500 of these pulses. As I reminded you yesterday if we want the counter to overflow after 62500 pulses we must preset it to 65536 - 62500 = 3036 which is 0x0BDC. To load TMR1 with this value we st TMR1H to 0x0B and TMR1L to 0xDC ( Which are the values we used in the delay subroutine.) The delay subroutine will actually be a few microseconds longer than 100 mS as I have ignored the time taken to execute the instructions in the subroutine.(You could get the delay to be more accurate by adjusting the number of pulses counted to compensate. This method cannot give delay of much more than 100 mS (Maximum would be 65536 x 1.6 uS = 104857.6 uS = 104.8576 mS) If you want a delay of 250 mS you could call the 100 mS delay routine twice then call a 50 mS delay routine once. (You would have to write the 50 mS delay routine.) Note there are many alternative way to delay 250 mS.

Les.
 

Thread Starter

daljeet795

Joined Jul 2, 2018
295
This method cannot give delay of much more than 100 mS (Maximum would be 65536 x 1.6 uS = 104857.6 uS = 104.8576 mS) If you want a delay of 250 mS you could call the 100 mS delay routine twice then call a 50 mS delay routine once. (You would have to write the 50 mS delay routine.) Note there are many alternative way to delay 250 mS.

Les.
the air jet is connected to output pin RD4 and the 100ms response time (turn 0n/off) is very less so it doesn't collect object if I will set it to 200ms to 250m it can be a collect object. that's why need to change delay time

before asked you to change delay time I spent some time to understand loop in assembly language but I didn't see any registers where you have load value and then incrementing value for the delay
 

MaxHeadRoom

Joined Jul 18, 2013
30,663
I have both the Picmicro Universal Picdem-2 boards, also a couple I put together.
I also have the Mechatronics and the BLDC picmicro development boards.
All are universal to 16f - 18f series.
I primarily use the 18f2221/4221 series and the 18f23K22/44K22, they cover most of what I need.
I am wondering if you can use some kind of rotating buffer for the potential 5 positions, any or all would be reject stored values of the counter.
Max.
 

Ian Rogers

Joined Dec 12, 2012
1,136
I use the pic18f4520.. BUT!! the footprint fits all of these 40 pin pics..

I used the pic16f877a as you do, but the later pic16f887 is the new kid on the block.. But I can use the pic18's for more ram and faster clocking speeds.. The pic18f4620 has oodles of ram.. The pic18f4522 has two USARTS.. All the new K and J series are pin compatible and run up to 64MHz as well..
 

Thread Starter

daljeet795

Joined Jul 2, 2018
295
Hello All

I am trying to convert assembly code post #56 into c language I would need someone's help understand both c and assembly code

I don't know the assembly but tried reading comments

C:
/*
* File:   main.c
* Author: Daljeet
*/
#pragma config FOSC = HS  
#pragma config WDTE = OFF 
#pragma config PWRTE = OFF 
#pragma config BOREN = ON 
#pragma config LVP = OFF   
#pragma config CPD = OFF   
#pragma config WRT = OFF   
#pragma config CP = OFF    
#include <xc.h>

#define _XTAL_FREQ 20000000 // XTAL crystal FREQ

void Init_TMR1 (void)

    {
       TMR1ON = 0;  //Stops Timer1
       TMR1CS = 1;  //External clock from pin RC0/T1OSO/T1CKI (on the rising edge) bit1
       T1SYNC = 0;  //Synchronize external clock input bit2
       T1OSCEN = 0; //Oscillator is shut-off
       T1CKPS0 = 0;
       T1CKPS1 = 0;
    }

    void Start_counter (void)
    {
         TMR1H =  0x8E;  //65536 - 29001 = 36535 = 0x8EB7
         TMR1L = 0xB7;
         TMR1IF = 0;     //Clear interrupt flag
         TMR1ON = 1;     //Start TMR1
    }


void main(void)
{
    // Encoder output goes into RC0 and sensor output goes to RC1

    TRISC= 0b00000011;     // Bits 0,1 inputs
    TRISD= 0b00000000;    // All bits as outputs

    Init_TMR1 ();
    Start_counter();
  
    while (1)
    {
        if(TMR1IF ==1) //Test interrupt flag
        {
            RD4 = 1;  // set output pulse high
             __delay_ms(100); //100ms
            RD4 = 0;  // set output pulse high

            TMR1ON = 0;  //Stops Timer1
            TMR1CS = 0;  //External clock from pin RC0/T1OSO/T1CKI (on the rising edge) bit1
            T1SYNC = 0;  //Synchronize external clock input bit2
            T1OSCEN = 0; //Oscillator is shut-off
            T1CKPS0 = 1;  //  Prescale 1:8
            T1CKPS1 = 1;
     
            TMR1IF = 0;  //Clear interrupt flag
       
            TMR1H = 0x8E;
            TMR1L = 0xB7;
               
            TMR1ON  = 1 ; //Start TMR1

        }
    }
}
I don't understand how to add c code for following part of assembly code in my code ?
Code:
Wait_trigger_L:       ;Loop waiting for trigger pulse from sensor to go low
   btfsc   PORTC,1
   goto   Wait_trigger_L
Wait_trigger_H:       ;Loop waiting for trigger pulse from sensor to go high
   btfss   PORTC,1
   goto   Wait_trigger_H
 
Last edited:

MaxHeadRoom

Joined Jul 18, 2013
30,663
Rung 2 & 3 keep looping until PORTC input 1 is low, if low it drops through to 5 & 6 to test the same PORTC input 1 and loops until High, then code continues.
Max.
 

Thread Starter

daljeet795

Joined Jul 2, 2018
295
Rung 2 & 3 keep looping until PORTC input 1 is low, if low it drops through to 5 & 6 to test the same PORTC input 1 and loops until High, then code continues.
Max.
I didn't understand What is 2 & 3 and 5 & 6 ?

Do you mean RC2 & RC3 and RC5 & RC6 ? Pin's of PORTC
 

Ian Rogers

Joined Dec 12, 2012
1,136
Use:

while(RC1); // wait while PortC.1 is high.
and
while(!RC1); // wait while PortC.1 is low.

***NOTE*** This code is virtually identical to a thread I'm dealing with on another forum!!!
 

Thread Starter

daljeet795

Joined Jul 2, 2018
295
Use:

while(RC1); // wait while PortC.1 is high.
and
while(!RC1); // wait while PortC.1 is low.
Spooky, ain't it?
@JohnInTX @Ian Rogers
Have you looked at assembly code post #56 ?
Les wrote code in assembly and I am trying to convert it into c
C:
/*
* File:   main.c
* Author: Daljeet
*/
#pragma config FOSC = HS
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config BOREN = ON
#pragma config LVP = OFF
#pragma config CPD = OFF
#pragma config WRT = OFF
#pragma config CP = OFF
#include <xc.h>
#define _XTAL_FREQ 20000000 // XTAL crystal FREQ

void Init_TMR1 (void)
    {
       TMR1ON = 0;  //Stops Timer1
       TMR1CS = 1;  //External clock from pin RC0/T1OSO/T1CKI (on the rising edge) bit1
       T1SYNC = 0;  //Synchronize external clock input bit2
       T1OSCEN = 0; //Oscillator is shut-off
       T1CKPS0 = 0;
       T1CKPS1 = 0;
    }

void Start_counter (void)
    {
         TMR1H =  0x8E;  //65536 - 29001 = 36535 = 0x8EB7
         TMR1L = 0xB7;
         TMR1IF = 0;     //Clear interrupt flag
         TMR1ON = 1;     //Start TMR1
    }

void main(void)
{
    // Encoder output goes into RC0 and sensor output goes to RC1
    TRISC= 0b00000011;     // Bits 0,1 inputs
    TRISD= 0b00000000;    // All bits as outputs
  
    Init_TMR1 ();
  
    Start_counter();

    while (1)
    {
        while (RC1 == 1)
        {
            if(TMR1IF ==1) //Test interrupt flag
            {
                 RD4 = 1;  // set output pulse high
                 __delay_ms(100); //100ms
                 RD4 = 0;  // set output pulse high
                 TMR1ON = 0;  //Stops Timer1
                 TMR1CS = 0;  //External clock from pin RC0/T1OSO/T1CKI (on the rising edge) bit1
                 T1SYNC = 0;  //Synchronize external clock input bit2
                 T1OSCEN = 0; //Oscillator is shut-off
                 T1CKPS0 = 1;  //  Prescale 1:8
                 T1CKPS1 = 1;

                 TMR1IF = 0;  //Clear interrupt flag

                 TMR1H = 0x8E;
                 TMR1L = 0xB7;
        
                  TMR1ON  = 1 ; //Start TMR1
            }
        }
 
        while (RC1 == 0)
        {
     
        }
     
    }
}
 
Last edited:

Ian Rogers

Joined Dec 12, 2012
1,136
Have you looked at assembly code post #56 ?
Les wrote code in assembly and I am trying to convert it into c
Then the code I'm working on has been lifted from here.... I have my suspicions...(I hope you both do not attend the same class)
RC1 and RC0 are symbiotic around timer1.. I mean that both can receive a clock when timer1 is set to external input... The T1OSCEN switches between RC0 and RC1 in counter mode.... I only bring this up just incase you get "crosstalk" between the sensor input and encoder input..
 

Thread Starter

daljeet795

Joined Jul 2, 2018
295
RC1 and RC0 are symbiotic around timer1.. I mean that both can receive a clock when timer1 is set to external input... The T1OSCEN switches between RC0 and RC1 in counter mode.... I only bring this up just incase you get "crosstalk" between the sensor input and encoder input..
@LesJones and @MaxHeadRoom understand assembly and I have no knowledge of assembly

assembly language is very difficult to understand rather than the c language
 
Top