Looking for Input Capture example C code or tutorial

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

Hello clever people!

The short version:

I'm looking for Input Capture example code or tutorial. I want to measure the time between 2 pulses.
If you have some simple C code you could post, or point me to a tutorial, that would be awesome, thanks!

The long version:

I'm trying to build a tachometer to measure rpm using an infrared sensor. The infra red sensor and circuit has been tested, I can count pulses and display on an LCD.

Now I want to transition from 'counter' to 'tachometer'.

I need to measure the time between falling edges of each incoming pulse. I have never used Input Capture before, so I don't know what to do. I read the ATMEGA16 datasheet, and now my head hurts.

If someone could point me to some (preferably commented) example code (Codevision C / WinAVR C) or a tutorial, it would help me figure out what is going on.

Thanks
Pete

Last Edited: Sun. Jun 18, 2017 - 08:19 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've posted tacho code before, so do a search. The input capture is very simple- set your timer up with the required prescale, enable the input capture, select the edge and enable the capture interrupt. In the capture isr, read the capture value, subtract it from the previos value and store the result. In the main line code read the result and do the computation to convert it from a period to a frequency. You also want to filter the value to make it readable.

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

Hi Kartman, thanks for your reply - I think I have found your original post.

I've realized that I'm getting a step ahead of myself.
I was able to count pulses with the sensor attached to the external interrupt pin.

Before I can measure pulses on the input capture pin, I really need to test an intermediate step - counting pulses when triggered by the input capture pin.

It appears that my Input Capture is not ever firing - I can't get any counts when the sensor is attached to the ICP pin.

Here's what I have so far....

/*****************************************************
This program was produced by the
CodeWizardAVR V1.24.9 Standard
Automatic Program Generator
© Copyright 1998-2006 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com



Chip type           : ATmega16
Program type        : Application
Clock frequency     : 8.000000 MHz
Memory model        : Small
External SRAM size  : 0
Data Stack size     : 256
*****************************************************/

#include 

// Alphanumeric LCD Module functions
#asm
   .equ __lcd_port=0x1B ;PORTA
#endasm
#include   
#include 
#include 
#include 
 

//-------------------------------------------------------------------------------------------------

//---Prototypes----
void setup(void);

//-------------------------------------------------------------------------------------------------
// Declare your global variables here

char name_string[]                = "  Company Ltd  ";
char model_string[]             = "   Tachometer   ";

char count_string[]             = "Counts:         ";


int ticks                               = 0;
int count                               = 0;


//-------------------------------------------------------------------------------------------------

// Timer 1 input capture interrupt service routine
interrupt [TIM1_CAPT] void timer1_capt_isr(void)
{
    count++;

}


//-------------------------------------------------------------------------------------------------


// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
   // if i connect the sensor to the external irq pin, and put:
   //   count++; here, it counts OK.        

}

//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------


// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
 ticks++;
 
 if (ticks == 500)
 {
       PORTD.3 = 1;     // pulse a line so I can see it on a scope
 }

 if (ticks == 1000)
 {
       
        PORTD.3 = 0;
        ticks = 0;
      
        
 }

}

//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------

void main(void)
{
// Declare your local variables here

setup();

// Global enable interrupts
#asm("sei")


    delay_ms(100);


    lcd_init(16);                 // LCD module initialization
               
    lcd_gotoxy(0,0);
    lcd_puts(name_string);
    lcd_gotoxy(0,1);
    lcd_puts(model_string);

    delay_ms(500);

    lcd_gotoxy(0,0);                 // display the top line of the LCD

    lcd_puts(count_string);  


while (1)
      {
        
        if (PINB.0 == 0)      // Reset to zero?
        {
            count = 0;
        }      
                      
                   
        count_string[14]  =  (count % 100 / 10) + 48;               
        count_string[15]  =  (count % 10 / 1) + 48;               
        
        lcd_gotoxy(0,0);                                  
        lcd_puts(count_string);   // display the number of counts
        
    
        
        
        

      }
}

//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
void setup(void)
{

  // Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTA=0x00;
DDRA=0x00;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=P State6=P State5=P State4=P State3=P State2=P State1=P State0=P 
PORTB=0xFF;
DDRB=0x00;

// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTC=0x00;
DDRC=0x00;     

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=Out Func2=In Func1=In Func0=In 
// State7=P State6=P State5=P State4=P State3=0 State2=P State1=P State0=P 
PORTD=0xF7;
DDRD=0x08;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 125.000 khertz
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x03;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: T1 pin Falling Edge
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: On
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x06;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;


// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Falling Edge
// INT1: Off
// INT2: Off
GICR|=0x40;
MCUCR=0x02;
MCUCSR=0x00;
GIFR=0x40;


// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x01;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// LCD module initialization
lcd_init(16);

}


//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------


Can anyone spot what's wrong?

Thanks
Pete

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

Quote:

Can anyone spot what's wrong?

Quote:

// Timer/Counter 1 initialization
// Clock source: T1 pin Falling Edge

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Quote:

// Timer/Counter 1 initialization
// Clock source: T1 pin Falling Edge

Hmmm. I thought that was so we get an interrupt on the falling edge of the Input Capture pin.

Is this not the case? What should it be?

Thanks
Pete

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

Quote:

Is this not the case?

Perhaps look in the datasheet for the description of external clocks for the timers and what would be applied to a Tn pin.

If you use "timer as counter" then you use that pin.

You said you are applying your signal to the ICP pin.

For your stated test any prescaler is OK so TCCR1B=0x01 is OK. In practice with input capture you may use a prescaler to get the appropriate timing range.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Aha, I think I (half) understand what you are saying.

The timer itself should not be incremented by an outside pulse - it should free-run off the system clock, to provide the 'time-stamp' that gets stored when an Input Capture event (triggered by the outside pulse) occurs. Is that correct?

So I set up to use the system clock, Input Capture on falling edge, and interrupt on Input Capture.


// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 125.000 kHz
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: On
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x03;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

... but still no counts are being captured.

I added a pin-toggle to the ICP Interrupt Service Routine, so I could check with a scope - the interrupt is definitely not happening. Any ideas?

// Timer 1 input capture interrupt service routine
interrupt [TIM1_CAPT] void timer1_capt_isr(void)
{
    count++; 
    PORTD.3 = 1;     // pulse a line so I can see it on a scope
    delay_ms(1);
    PORTD.3 = 0;

}

Thanks for your help!
Pete

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

Well, the first sanity check is to verify that the signal is indeed right on the ICP1 pin. Is it? How have you determined that?

Quote:

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x01;

I doubt whether the Wizard gave you that value--on a Mega16 that is TOIE0.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

theusch wrote:

I doubt whether the Wizard gave you that value....

You're absolutely right - I had been cut-and-pasting from the wizard's preview screen, instead of re-writing the project from scratch every time I made a change. If I was paying attention, I would have seen that the wizard produced:

TIMSK=0x21;

That's with Timer0 for real-time int, and Timer1 for the ICP.

Thanks so much, I'm now able to count pulses on the Input Capture pin!

I will now go back and carefully read Kartman's example code, and see if I can turn this counter into a tachometer.

Cheers!
Pete

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

For "fast" signals, you want to use the T1 pin and set up the timer-as-counter. The result is essentially what you are doing now, but you don't need to service an interrupt every hit. That becomes important at high speeds--say, >10kHz. You can then count up to a few MHz, about AVR clk/4. Say clk/10 without fussing. You need a clean signal for that.

With the timer-as-counter you use a second timer at (say) 10ms or 100ms and capture the counts (TCNT1) for later processing and then clear TCNT1 for the next go-round.

ICP can give you cycle-accurate timing. As one can't read a display that is jumping a lot in the LSDs the update is normally made a few times a second anyway, using the latest value or some kind of average over the past n samples.

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

hi all freaks :D
i need to work with input capture too.
because of em4095
i saw codes of this sites before
but i work with codevision

as u know the signal on demod_out pin is like this

http://www.apdanglia.org.uk/em4001protocl.html

and the 1 and 0 codes pattern (manchester pattern)

so i need to sense them somehow
i found out i have to use input capture
and i have to measure lenght of pulses,
to identify 1 and 0s,
but i dont know how
help me plz... :|

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

I posted code years ago to decode manchester for the dali lighting protocol. Search for me and dali

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

tnx for answering,kartman
i read them before
but as i told u , i want to do it in codevision
and none of those projects are in this compiler
i tried to use them
but i couldnt
i put my code here

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

I can't see any code.

With the code I posted, apart from the isr declaration, the rest of the code should work in CodeVision. Changing that should be as easy as reading the manual.

In future - point out exactly what doesn't work. Myself and others can quickly put you straight.

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

thank you again for answering and sorry for code
i totally forgot that :lol: :lol:
i think i used ur code
this is my code:
actully there wasnt any errors
and i have some questions about that
first of all
i should say i changed some pins,
cause i use m32
i wrote them in code,i think so....
but it didnt work
maybe my em4095 doesnt work??!!ha??

 /*****************************************************
This program was produced by the
CodeWizardAVR V2.05.3 Standard
Automatic Program Generator
© Copyright 1998-2011 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project : 
Version : 
Date    : 2013-05-27
Author  : Techno-Electro
Company : If You Like This Software,Buy It
Comments: 


Chip type               : ATmega32A
Program type            : Application
AVR Core Clock frequency: 8.000000 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 512
*****************************************************/

#include 

// Alphanumeric LCD functions
#include 

// Standard Input/Output functions
#include 
#include 
// *********************************************** 
// Variables for System 
// *********************************************** 
unsigned char time_1ms; 
void rf_bit_store(char bit_value); 
// *********************************************** 
// Initialize Variables for flags
// *********************************************** 
unsigned char flag_1ms =0;    // timer 1 ms     

unsigned char flag_err =0;         // header error
unsigned char parity_err =0;    // parity error

// *********************************************** 
// Constant define
// *********************************************** 
#define REL 0x08        // Relay =PB3                                                                  
#define BUZ 0x04        // Buzzer =PB2                                                                  
#define LED 0x02        // indicator =PB1
#define DEM 0x01         // RF Data input EXT-INT0 from PB0/ICAP

#define RXD 0x01        // PD0/RXD <--- ROUT SP232 <--- PC TXD  
#define TXD 0x02         // PD1/TXD ---> TINP SP232 ---> PC RXD
#define CLK 0x20        // EXT-T1 input for RF read clock =Pb1                                                                                                                                                   // External interrupt used to read clock

#define SHD 0x40         // RF shot down for RF disable =PD6
#define MOD 0x80        // RF 100% modulation =PD7

// *********************************************** 
// Global variables for buffer
// *********************************************** 
char rf_buff[16];                          // rf buffer  
char rf_buff_ptr =0;                // rf buffer pointerÍ
char rf_bit_ptr = 0;                // rf bit pointer

// *********************************************** 
// Global variables
// *********************************************** 
char bit_value = 1;                  // received bit value
char bit_saved = 1;                    // flag of next bit will be store  
char edge_dir = 1;                        // Edge Direction is riging                                         

char stable_width =0;                 // RF uncertainty
char bit_trans_num =0;            // number of bit stored

int  old_width =0;                    // old width of captured timer1 value
int  timer_over =0;                    // flag of time overflow
// Timer1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
// Place your code here
  TCNT1H = 0x00;                     // reload counter high value
  TCNT1L = 0x00;                     // reload counter low value

}

// Timer1 input capture interrupt service routine
interrupt [TIM1_CAPT] void timer1_capt_isr(void)
{
// Place your code here
  int value;                            // temporary of catured value
  int width;                            // temporary of width calc. 
    
  value = ICR1L;                      // Read low byte first (important)
  value |= (int)ICR1H << 8;           // Read high byte and shift into top byte

 if (edge_dir)                           // change ICP capture direction of edge. 
  {
   TCCR1B &= ~0x40;
   TCCR1B |= 0x20;                 // ICP capture direction edge to riging 
   edge_dir =0;                       // for next cature direction is falling.    
  }
 else
  {
   TCCR1B &= ~0x20;
   TCCR1B |= 0x40;                 // ICP capture direction edge to falling 
   edge_dir =1;                       // for next capture direction is riging
  }

 width = value - old_width; // width = new captured width - old captured width
 old_width = value;          // updata old captured width for next width calc.
    
  // receiving manchester code from RFID card. 
    // 1st received bit is must be 1 for 1st bit is header after reset, 
    // if pulse width is more than 40 then received bit to invert.
 if (width > 40)                            // narrow pulse width is under 32,
  {
   if (bit_value) PORTB |=LED;    // debug indictor for input bits
   else PORTB &= ~LED;
   bit_value = ~bit_value;     // received bit is inverting
   rf_bit_store(bit_value);    // save inverted bit
   ++bit_trans_num;                    // increament number of saved bits
   bit_saved = 0;                      // skip bit store when bit invertedö
  }
        
 if (bit_saved)                        // will be bit store?
  {
   if (bit_value) PORTB |=LED;    // debug indictor for input bits 
   else PORTB &= ~LED;
                
   rf_bit_store(bit_value);    // bit store in rf buffer
   ++bit_trans_num;                    // number of stored bits +1
  }
 bit_saved = ~bit_saved;          // skip next store for next bit 
}

// Timer2 overflow interrupt service routine
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
// Place your code here
 TCNT2 = 0x8D;             // reload counter value
 flag_1ms = 1;               // flag_1ms =1
 timer_over++;                // 1ms timer +
}

// Declare your global variables here
void em4095_init();
void timer1_init(char edge);
void set_rf_edge(char edge);

void get_bits_num (char num_bits, char edge);
void fill_rf_buff(char num_byte);
void invert_rf_buff(void);
char get_buff_bit(void);
char get_buff_byte(void);
void find_header(void);
void checksum_h(void);
void tx_buff_bin(void);
void tx_buff_hex(void);

void main(void)
{
// Declare your local variables here

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTB=0x01;
DDRB=0xFE;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTD=0xCF;
DDRD=0xC0;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: 8000.000 kHz
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x05;
TCNT2=0x8D;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x64;

// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 9600
UCSRA=0x00;
UCSRB=0x18;
UCSRC=0x06;
UBRRH=0x00;
UBRRL=0x33;


// Alphanumeric LCD initialization
// Connections are specified in the
// Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
// RS - PORTA Bit 0
// RD - PORTA Bit 1
// EN - PORTA Bit 2
// D4 - PORTA Bit 4
// D5 - PORTA Bit 5
// D6 - PORTA Bit 6
// D7 - PORTA Bit 7
// Characters/line: 8
lcd_init(8);

// Global enable interrupts
#asm("sei")
em4095_init();                             // init EM4095 RFID reader
timer1_init(0);                             // init timer1 from EXT-T1 (EM4095-CLK)
fill_rf_buff(16);
putsf("EM4095 RFID Card Reader V2.0");
while (1)
    {
      // Place your code here
     PORTD |= MOD;                                // turn off indicatorî
     delay_ms(20);                                // turn off time =20 ms,
     PORTD &= ~MOD;                            // start EM4095 read mode
     fill_rf_buff(16);                      // erase rf buffer 16 bytes. 

        // EM type (Read only) data format
        // 1111 11111 = Header = 9 bit­
        // xxxxP, xxxxp= Custom #1,#2  = 10 bit
        // xxxxP,xxxxP = data #1,#2  = 10 bit
        // xxxxP,xxxxP = data #3,#4  = 10 bit
        // xxxxP,xxxxP = data #5,#6  = 10 bit
        // xxxxP,xxxxP = data #7,#8  = 10 bit
        // PPPP0 = 4 Parity + 1 stop = 5 bit
        // data 55 bits + header 9 bits =64 bits®
        
        // Manchester code detecting method
        // Header (9 bits)
        // ______--__--__--__--__--__--__--__--__-- (wave)
        // 0-0 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1 0-1  (edge)
        // (x) (1) (1) (1) (1) (1) (1) (1) (1) (1)  (code)
        
        // Custom-ID (10 bits) 
        // --__--__--__--__--__--____----__--____-- (wave)
        // 1-0 1-0 1-0 1-0 1-0 1-0 0-1 1-0 1-0 0-1  (edge)
        // (0) (0) (0) (0) (0) (0) (1) (0) (0) (1)  (code)
        //  D7  D6  D5  D4  Pr  D3  D2  D1  D0  Pr  (Pr =parity)
              
        // find manchester pattern in received bits
        // output is number of received bits =bit_trans_num
        get_bits_num(64, 0);                 // receive 64 bits stream within 60ms     
        PORTB &= ~LED;                              // Indicator turn offî

        find_header();                            // check head is 9 bit =1?
        checksum_h();                                // check horizontal parity

        
        if (flag_err == 0)                        // has no head error?
        { 
            if (parity_err == 0)                // has no parity error? 
             {
             // tx_buff_bin();                    // 64 binary display code to UART.            
             tx_buff_hex();                    // 10 hexa dispaly code to UART.            
             PORTB |=REL;                        // turn on relay.
             }
            else PORTB |=BUZ;                    // if error available then turn on buzzer.        
        }                                                

        // Total cycle time = reste 20ms + receive 60ms + output 120ms = 200msâ
        delay_ms(120);                            // output time = 120ms                                
        PORTB &= ~BUZ;                            // turn off buzzer.
        PORTB &= ~REL;                            // turn off relay.
    }    
      
}

void em4095_init()
 {
  PORTB |= BUZ;                    // Buzzer =on      
  PORTB |= LED;                    // LED =on
  delay_ms(100);                    // delay 100ms

  PORTB &= ~BUZ;                    // Buzzer =off      
  PORTB &= ~LED;                    // LED =off
  delay_ms(100);                    // delay 100ms

  PORTD |= SHD;                    // EM4095 shot down                                                 
  PORTD |= MOD;                    // EM4095 max outut
  PORTB |= LED;                    // LED =on
  delay_ms(100);                    // delay 100ms
     
  PORTD &= ~SHD;                    // EM4095 ready
  PORTD &= ~MOD;                    // EM4095 min output
  PORTB &= ~LED;                    // LED =off
  delay_ms(100);                    // delay 100ms
 }

void timer1_init(char edge)
{
  TCCR1B = 0x00;             // stop timer1 
    TCNT1H = 0x00;
    TCNT1L = 0x00;            // start from 0000

    ICR1H  = 0x00;
    ICR1L  = 0x00;            // using timer1 capture

    TCCR1A = 0x00;
    TCCR1B = 0x00;            // stop timer1, 

    if (edge ==1) TCCR1B = 0x40;  // ICAP capture from T1 riging.
    else TCCR1B = 0x20;    // ICAP capture from T1 falling. 
    TIMSK |= 0x24;             // timer1 capture, overflow interrupt sources
}

void set_rf_edge(char edge)
{
  if(edge)
  {
   timer1_init(1);                 // setup timer1 to rising edge
   edge_dir =1;                    // status =rf_fe_toggle on
  }
  else
  {
   timer1_init(0);             // setup timer1 to falling edge
   edge_dir =0;                    // status =rf_fe_toggle off
  }
}

void get_bits_num (char num_bits, char edge)
{
 set_rf_edge(edge);          // change direction of caturing edge¤

    // force save flag =1 for must save 1st received bit.
 bit_saved = 1;                           

  // If captured width is more than 40 then bit to inverting
 bit_value = 0;                                // bit value =0

 rf_buff_ptr = 0;             // byte pointer =0¤
 rf_bit_ptr = 0;                 // bit pointer =0¤
 bit_trans_num = 0;                // number of save bit =0¤
 timer_over = 0;                 // time over value =0
 old_width = 0;                                // old width =0

 TCCR1B = 0x00;                            // stop Timer1 from EXT-T1 
 TCNT1H = 0x00;                                             
 TCNT1L = 0x00;                            // tiemr0 =0x0000¤
 TCCR1B = 0x07;                            // start timer1  
 TIMSK |= 0x20;                             // enable timer1 capture interrupt¡

    // If number of saved bit is less than num_bits then receiving bit
  while (bit_trans_num < num_bits && timer_over < 60)
  {
  } 
    // If number of saved bit is more than num_bits 
    // or tiem is more than 60ms then exit receiving bit 
  TIMSK &= ~0x20;                         // stop timer1 capture interrupt¡

  rf_buff_ptr = 0;                         // reset buffer pointer¤
  rf_bit_ptr = 0;             // reset bit pointer¤
}

void fill_rf_buff(char num_byte)
{
 int i;
 rf_buff_ptr =0;
 rf_bit_ptr =0;
 for(i =0; i 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hi,

how to set counter, to count external hardware pulse?? at rate of 1Hz.

i need code for Bascom-avr. 
i want to make digital speedometer using ATmega16 and reed-relay switch(for counting rotation of wheel)

please

thank you

 

ihope you find me

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

Please do not double post, you have already a thread on this. http://www.avrfreaks.net/forum/s...

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

Topic locked