timer input capture

Go To Last Post
4 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

/*
 * timer input capture.cpp
 *
 * Created: 2/20/2020 10:04:58 PM
 * Author : kunal
 */ 
#define F_CPU 16000000UL
#include <avr/io.h>
#include<util/delay.h>
#include<avr/interrupt.h>
#include "uarts.h"
#include<stdlib.h>
unsigned int a,b,c,pw,tp;
 unsigned char firstcap[20];
 unsigned char thirdcap[20];
 unsigned char secondcap[20];
void timerintial()
{
    //normal mode
    TCCR4A=0x00;//(output compare mode for all 3 channels set to 00 and WGM11 and WGM10 and WGM11 set to zero)
    TCCR4B=0b01000010;//(positive edge,clk/8)
    ACSR=(0<ACIC);//(icpp pin event source)
}
void pedge1()
{   printString1("kk");
    //at first positive edge
    TCCR4B|=(1<<ICES4);
    while((TIFR4&(1<<ICF4))==0);//check for rising event
    printString1("oio");
    a=ICR4;
    itoa(a,firstcap,10);
    printString1(firstcap);
    TIFR4=(1<<ICF4);//clear flag
}
void nedge()
{    printString1("gk");
    //negative edge
    TCCR4B|=(0<<ICES4);
    while((TIFR4&(1<<ICF4))==0);//check for falling event
    printString1("pio");
    b=ICR4;
    itoa(b,secondcap,10);
    printString1(secondcap);
    TIFR4=(1<<ICF4);//clear flag
}
void pedge2()
{
     printString1("kk");
     //at first positive edge
     TCCR4B|=(1<<ICES4);
     while((TIFR4&(1<<ICF4))==0);//check for rising event
     printString1("oio");
     c=ICR4;
     itoa(c,thirdcap,10);
     printString1(thirdcap);
     TIFR4=(1<<ICF4);//clear flag
    
}
int main(void)
{     UART_Init1();
    printString1("welcome");
    char freq[14],duty[7],timeperiod[20],pulsewidth[30];
    while (1) 
    {   timerintial();
        pedge1();//a
        nedge();//b
        pedge2();//c
        if(a<b&&b<c)                                              
        {
            tp=c-a;//time period
            pw=b-a;//pulse width
            
        
        
        long frequency=F_CPU/tp;//calculate period
        float dutycycle=((float )pw/(float)tp)*100;//calculate dutyccycle
        itoa((int)dutycycle,duty,10);//converts int to string(char) ..decimel
        ltoa(frequency,freq,10);//converts long to string(char)...decimel
        itoa(tp,timeperiod,10);
        itoa(pw,pulsewidth,10);
        printString1(duty);//prints dutycycle
        printString1("\n");
        printString1(freq);//prints frequency
        printString1("\n");
        printString1(timeperiod);//prints timeperiod
        printString1("\n");
        printString1(pulsewidth);//prints pulsewidth
        printString1("\n");
        
        
        }
        else
        printString1("wrong");
        
    }
}
 

 

this is my code for measuring the frequency and duty cycle of waves by using the input capture mode of timers in avr 2560.

event detection part of code (function pedge and enedge are working fine ) but in the while loop if condition 

if(a<b&&b<c)
        {
            tp=c-a;//time period
            pw=b-a;//pulse width
       }     

this is always wrong ...means it is not going inside the if condition it is always going in else statements.and i am not able to figure out why is this happening as 'a 'is my first capture ,'b' is second and 'c' is third.

So any suggestions ?????????????????//

what i think is that data types of my variables and the conversion of int to char  ...... is incorrect and issue is with the conversion and data types part.

???

 

 

in the pic below values of a ,b ,c are printed .1-is first capture ,2 is second capture,3 is third capture.

Attachment(s): 

Kunal Gupta

github.com/gkunalupta

Last Edited: Thu. Feb 20, 2020 - 08:31 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kunalgupta wrote:
So any suggestions ?????????????????//

Try adding some "( )"

if((a<b) && (b<c))

Jim

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Note that printString will take time - maybe some milliseconds. This could affect your results. Collect your data then output the results.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


I'd wind back a bit and learn a bit more about C first. Learn how to pass things into and out of functions. Don't pass everything through globals and don't call key variables things like a, b, c etc. !

 

Your code is almost completely impenetrable.

 

By a complete coincidence I just happened to be reading this yesterday:

 

 

those two code segments actually do the same thing - which one can you read and understand the intention in?

 

Your:

        if(a<b&&b<c)                                              
        {
            tp=c-a;//time period
            pw=b-a;//pulse width

would be much easier to read as:

        if ((firstPositiveEgdge < negativeEdge) && (negativeEdge < secondPositiveEdge))
        {
            timePeriod = secondPositiveEdge - firstPositiveEdge;
            pulseWidth = negativeEdge - firstPositiveEdge; 

in fact I removed the comments because I don't believe they are necessary any more.

 

If you show this code to someone else (ie us lot here at Freaks) or you even come back to it yourself in 18 months when you have forgotten how it worked then this descriptive code tells you the whole story of what's going on with no further explanation needed. "pw=b-a" tells you very little indeed.

 

Don't be afraid of long names or spacing out the code with spaces around operators etc as it all just helps to make it more readable.