Tick counting problem

Discussion in 'C Programming' started by JJ, Feb 13, 2009.

  1. JJ

    JJ Guest

    Hello,

    I have problem with counting ticks of an encoder.
    I can achieve about 5 kHz without errors.
    Above this frequency, I loose ticks.

    I use second AVR processor as the generator of
    two signals -- I just test my device, without real encoder.

    What to do to improve frequency ?

    Below, I present my program.
    Processor: AVR ATmega16
    You should connect an Encoder in the way:
    Canal A : PD2 i PD3
    Canal B: PD4

    #include <stdio.h>
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/signal.h>
    #include "lcd.h"

    long int licz = 0;
    int flagaA = 0, flagaB = 0;

    SIGNAL (SIG_INTERRUPT0)
    {
    if (!(inb(PIND) & 16)) /* if 0 on canal B */
    flagaA = 1;
    else /* otherwise, (1 on canal B) */
    flagaB = 1;

    }

    SIGNAL (SIG_INTERRUPT1)
    {
    if (inb(PIND) & 16) { /* if 1 on canal B */
    if (flagaA) /* if flagaA is set */
    licz++, flagaA = 0;
    } else if (flagaB) /* if flagaB is set */
    licz--, flagaB = 0;

    }

    int main(void)
    {
    char s[16];

    outp(0, DDRD);

    /* Setting interrupts INT 0 i INT1 -- rising, falling edge
    */
    outp((1<<INT0)|(1<<INT1), GIMSK);
    outp((1<<ISC01)|(1<<ISC00) | (1<<ISC11), MCUCR);

    initLCD();

    sei(); /* star interrupts */

    for (;;) {
    cursorHome();
    sprintf(s, "%ld ", licz);
    showStringOnLCD(s);
    }

    return 0;
    }
     
    JJ, Feb 13, 2009
    #1
    1. Advertising

  2. JJ

    Bartc Guest

    "JJ" <> wrote in message news:gn4u98$ang$...
    > Hello,
    >
    > I have problem with counting ticks of an encoder.
    > I can achieve about 5 kHz without errors.
    > Above this frequency, I loose ticks.
    >
    > I use second AVR processor as the generator of
    > two signals -- I just test my device, without real encoder.
    >
    > What to do to improve frequency ?
    >
    > Below, I present my program.
    > Processor: AVR ATmega16
    > You should connect an Encoder in the way:
    > Canal A : PD2 i PD3
    > Canal B: PD4


    You might try posting to comp.arch.embedded too, somebody there might be
    more familiar with the capabilities of this cpu, in case it is not a C
    problem.

    --
    Bartc
     
    Bartc, Feb 13, 2009
    #2
    1. Advertising

  3. JJ

    JJ Guest

    On Fri, 13 Feb 2009 17:57:01 -0600, Anthony Fremont wrote:
    > JJ wrote:
    >> Hello,
    >>
    >> I have problem with counting ticks of an encoder. I can achieve about 5
    >> kHz without errors. Above this frequency, I loose ticks.
    >>
    >> I use second AVR processor as the generator of two signals -- I just
    >> test my device, without real encoder.
    >>
    >> What to do to improve frequency ?

    >
    > Make the ISR run faster. You'll have to optimize the ISR code as much
    > as possible. You can do this by doing less work in the ISR or perhaps
    > rewriting the ISR in assembler. Maybe get rid of some/all of those if
    > statements. How many ints/second do you need to handle?


    Hello,

    10 kHz would be enough.

    I have ATmega16 -- 16 MHz. Even if execution of interrupt procedure lasts
    1000 cycles (I don`t think so it lasts as long), we should have 16000000 /
    1000 = 16 kHz.

    I think, my program should be able to count with higher frequencies
    according to high processor speed, and not so slow (I think not slower
    than e.g. 1000 cycles) interrupt procedure.
     
    JJ, Feb 14, 2009
    #3
  4. JJ

    Bartc Guest

    "JJ" <> wrote in message news:gn62ko$l8a$...
    > On Fri, 13 Feb 2009 17:57:01 -0600, Anthony Fremont wrote:
    >> JJ wrote:
    >>> Hello,
    >>>
    >>> I have problem with counting ticks of an encoder. I can achieve about 5
    >>> kHz without errors. Above this frequency, I loose ticks.
    >>>
    >>> I use second AVR processor as the generator of two signals -- I just
    >>> test my device, without real encoder.
    >>>
    >>> What to do to improve frequency ?

    >>
    >> Make the ISR run faster. You'll have to optimize the ISR code as much
    >> as possible. You can do this by doing less work in the ISR or perhaps
    >> rewriting the ISR in assembler. Maybe get rid of some/all of those if
    >> statements. How many ints/second do you need to handle?

    >
    > Hello,
    >
    > 10 kHz would be enough.
    >
    > I have ATmega16 -- 16 MHz. Even if execution of interrupt procedure lasts
    > 1000 cycles (I don`t think so it lasts as long), we should have 16000000 /
    > 1000 = 16 kHz.
    >
    > I think, my program should be able to count with higher frequencies
    > according to high processor speed, and not so slow (I think not slower
    > than e.g. 1000 cycles) interrupt procedure.
    >


    Try making the interrupt routine slower (by inserting delays). If the
    performance gets worse then perhaps the routine does need speeding up
    (although 10K operations per second doesn't sound too demanding).

    I don't really understand your code or your processor, or how you're
    counting whatever it is you're counting, but in the following:

    > for (;;) {
    > cursorHome();
    > sprintf(s, "%ld ", licz);
    > showStringOnLCD(s);
    > }


    All these 3 routines probably take hundreds of times longer to execute than
    your interrupt routines.

    Is it possible they are causing some interrupts to be missed? That they
    could temporarily mask interrupts?

    How do you establish that ticks are being missed: that after say 3 seconds
    at 5kHz, the count only shows 12000 or something? Suppose you just did an
    empty loop for 3 seconds (experiment with a loop count that delays by that
    much), then displayed the count, would it be 12000 or 15000?

    --
    Bartc
     
    Bartc, Feb 14, 2009
    #4
  5. JJ

    JJ Guest

    On Sat, 14 Feb 2009 14:25:15 -0600, Anthony Fremont wrote:

    > JJ wrote:
    >> On Fri, 13 Feb 2009 17:57:01 -0600, Anthony Fremont wrote:
    >>> JJ wrote:
    >>>> Hello,
    >>>>
    >>>> I have problem with counting ticks of an encoder. I can achieve
    >>>> about 5 kHz without errors. Above this frequency, I loose ticks.
    >>>>
    >>>> I use second AVR processor as the generator of two signals -- I just
    >>>> test my device, without real encoder.
    >>>>
    >>>> What to do to improve frequency ?
    >>>
    >>> Make the ISR run faster. You'll have to optimize the ISR code as
    >>> much as possible. You can do this by doing less work in the ISR or
    >>> perhaps rewriting the ISR in assembler. Maybe get rid of some/all
    >>> of those if statements. How many ints/second do you need to handle?

    >>
    >> Hello,
    >>
    >> 10 kHz would be enough.
    >>
    >> I have ATmega16 -- 16 MHz. Even if execution of interrupt procedure
    >> lasts 1000 cycles (I don`t think so it lasts as long), we should have
    >> 16000000 / 1000 = 16 kHz.

    >
    > Do those do one instruction per clock cycle? A PIC running at that speed
    > would only execute 4,000,000 instructions per second max.
    >
    >> I think, my program should be able to count with higher frequencies
    >> according to high processor speed, and not so slow (I think not slower
    >> than e.g. 1000 cycles) interrupt procedure.

    >
    > You're just going to have to look at the assembler output from the C
    > compiler to see how many instructions it generates. It does seem like your
    > code should execute in less than 1000 cycles though. There is always some
    > extra overhead in ISR entry and exit that eats up some cycles, and jumps eat
    > up cycles too while the pipeline is refilled. I'd start by looking at the
    > generated assembler.


    Hello,

    This code:

    #include <stdio.h>
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/signal.h>

    unsigned long int licz = 0;
    unsigned char flagaA = 0, flagaB = 0;

    SIGNAL (SIG_INTERRUPT0)
    {
    // cli();
    if (PIND & 4) {
    (!(PIND & 16)) ? (flagaA = 1) : (flagaB = 1);
    } else {
    if (PIND & 16) {
    if (flagaA)
    licz++, flagaA = 0;
    } else {
    if (flagaB)
    licz--, flagaB = 0;
    }
    }
    // sei();

    }

    int main(void)
    {
    outp(0, DDRD);

    outp((1<<INT0), GIMSK);
    outp((1<<ISC00), MCUCR);

    sei();

    for (;;)
    ;

    return 0;

    }

    Looks that in assembler:

    encoder.elf: file format elf32-avr

    Sections:
    Idx Name Size VMA LMA File off Algn
    0 .text 0000014a 00000000 00000000 00000094 2**0
    CONTENTS, ALLOC, LOAD, READONLY, CODE
    1 .data 00000000 00800060 0000014a 000001de 2**0
    CONTENTS, ALLOC, LOAD, DATA
    2 .bss 00000006 00800060 00800060 000001de 2**0
    ALLOC
    3 .noinit 00000000 00800066 00800066 000001de 2**0
    CONTENTS
    4 .eeprom 00000000 00810000 00810000 000001de 2**0
    CONTENTS
    Disassembly of section .text:

    00000000 <.text>:
    0: 0c 94 2a 00 jmp 0x54
    4: 0c 94 47 00 jmp 0x8e
    8: 0c 94 45 00 jmp 0x8a
    c: 0c 94 45 00 jmp 0x8a
    10: 0c 94 45 00 jmp 0x8a
    14: 0c 94 45 00 jmp 0x8a
    18: 0c 94 45 00 jmp 0x8a
    1c: 0c 94 45 00 jmp 0x8a
    20: 0c 94 45 00 jmp 0x8a
    24: 0c 94 45 00 jmp 0x8a
    28: 0c 94 45 00 jmp 0x8a
    2c: 0c 94 45 00 jmp 0x8a
    30: 0c 94 45 00 jmp 0x8a
    34: 0c 94 45 00 jmp 0x8a
    38: 0c 94 45 00 jmp 0x8a
    3c: 0c 94 45 00 jmp 0x8a
    40: 0c 94 45 00 jmp 0x8a
    44: 0c 94 45 00 jmp 0x8a
    48: 0c 94 45 00 jmp 0x8a
    4c: 0c 94 45 00 jmp 0x8a
    50: 0c 94 45 00 jmp 0x8a
    54: 11 24 eor r1, r1
    56: 1f be out 0x3f, r1 ; 63
    58: cf e5 ldi r28, 0x5F ; 95
    5a: d4 e0 ldi r29, 0x04 ; 4
    5c: de bf out 0x3e, r29 ; 62
    5e: cd bf out 0x3d, r28 ; 61
    60: 10 e0 ldi r17, 0x00 ; 0
    62: a0 e6 ldi r26, 0x60 ; 96
    64: b0 e0 ldi r27, 0x00 ; 0
    66: ea e4 ldi r30, 0x4A ; 74
    68: f1 e0 ldi r31, 0x01 ; 1
    6a: 02 c0 rjmp .+4 ; 0x70
    6c: 05 90 lpm r0, Z+
    6e: 0d 92 st X+, r0
    70: a0 36 cpi r26, 0x60 ; 96
    72: b1 07 cpc r27, r17
    74: d9 f7 brne .-10 ; 0x6c
    76: 10 e0 ldi r17, 0x00 ; 0
    78: a0 e6 ldi r26, 0x60 ; 96
    7a: b0 e0 ldi r27, 0x00 ; 0
    7c: 01 c0 rjmp .+2 ; 0x80
    7e: 1d 92 st X+, r1
    80: a6 36 cpi r26, 0x66 ; 102
    82: b1 07 cpc r27, r17
    84: e1 f7 brne .-8 ; 0x7e
    86: 0c 94 9a 00 jmp 0x134
    8a: 0c 94 00 00 jmp 0x0
    8e: 1f 92 push r1
    90: 0f 92 push r0
    92: 0f b6 in r0, 0x3f ; 63
    94: 0f 92 push r0
    96: 11 24 eor r1, r1
    98: 8f 93 push r24
    9a: 9f 93 push r25
    9c: af 93 push r26
    9e: bf 93 push r27
    a0: 82 9b sbis 0x10, 2 ; 16
    a2: 0a c0 rjmp .+20 ; 0xb8
    a4: 84 99 sbic 0x10, 4 ; 16
    a6: 04 c0 rjmp .+8 ; 0xb0
    a8: 81 e0 ldi r24, 0x01 ; 1
    aa: 80 93 64 00 sts 0x0064, r24
    ae: 39 c0 rjmp .+114 ; 0x122
    b0: 81 e0 ldi r24, 0x01 ; 1
    b2: 80 93 65 00 sts 0x0065, r24
    b6: 35 c0 rjmp .+106 ; 0x122
    b8: 84 9b sbis 0x10, 4 ; 16
    ba: 1a c0 rjmp .+52 ; 0xf0
    bc: 80 91 64 00 lds r24, 0x0064
    c0: 88 23 and r24, r24
    c2: 79 f1 breq .+94 ; 0x122
    c4: 80 91 60 00 lds r24, 0x0060
    c8: 90 91 61 00 lds r25, 0x0061
    cc: a0 91 62 00 lds r26, 0x0062
    d0: b0 91 63 00 lds r27, 0x0063
    d4: 01 96 adiw r24, 0x01 ; 1
    d6: a1 1d adc r26, r1
    d8: b1 1d adc r27, r1
    da: 80 93 60 00 sts 0x0060, r24
    de: 90 93 61 00 sts 0x0061, r25
    e2: a0 93 62 00 sts 0x0062, r26
    e6: b0 93 63 00 sts 0x0063, r27
    ea: 10 92 64 00 sts 0x0064, r1
    ee: 19 c0 rjmp .+50 ; 0x122
    f0: 80 91 65 00 lds r24, 0x0065
    f4: 88 23 and r24, r24
    f6: a9 f0 breq .+42 ; 0x122
    f8: 80 91 60 00 lds r24, 0x0060
    fc: 90 91 61 00 lds r25, 0x0061
    100: a0 91 62 00 lds r26, 0x0062
    104: b0 91 63 00 lds r27, 0x0063
    108: 01 97 sbiw r24, 0x01 ; 1
    10a: a1 09 sbc r26, r1
    10c: b1 09 sbc r27, r1
    10e: 80 93 60 00 sts 0x0060, r24
    112: 90 93 61 00 sts 0x0061, r25
    116: a0 93 62 00 sts 0x0062, r26
    11a: b0 93 63 00 sts 0x0063, r27
    11e: 10 92 65 00 sts 0x0065, r1
    122: bf 91 pop r27
    124: af 91 pop r26
    126: 9f 91 pop r25
    128: 8f 91 pop r24
    12a: 0f 90 pop r0
    12c: 0f be out 0x3f, r0 ; 63
    12e: 0f 90 pop r0
    130: 1f 90 pop r1
    132: 18 95 reti
    134: cf e5 ldi r28, 0x5F ; 95
    136: d4 e0 ldi r29, 0x04 ; 4
    138: de bf out 0x3e, r29 ; 62
    13a: cd bf out 0x3d, r28 ; 61
    13c: 11 ba out 0x11, r1 ; 17
    13e: 80 e4 ldi r24, 0x40 ; 64
    140: 8b bf out 0x3b, r24 ; 59
    142: 81 e0 ldi r24, 0x01 ; 1
    144: 85 bf out 0x35, r24 ; 53
    146: 78 94 sei
    148: ff cf rjmp .-2 ; 0x148
     
    JJ, Feb 14, 2009
    #5
  6. JJ

    Guest

    On Feb 14, 9:04 am, JJ <> wrote:
    > Hello,
    >
    > I have problem with counting ticks of an encoder.
    > I can achieve about 5 kHz without errors.
    > Above this frequency, I loose ticks.
    >
    > I use second AVR processor as the generator of
    > two signals -- I just test my device, without real encoder.
    >
    > What to do to improve frequency ?
    >
    > Below, I present my program.
    > Processor: AVR ATmega16
    > You should connect an Encoder in the way:
    > Canal A : PD2 i PD3
    > Canal B: PD4


    You need to look at the listing assembly code of your interrupt
    routines and look up the instruction set for the controller and work
    out how many cycles your interrupt consume. Many instructions are 2 or
    3 or 4 cycles per instruction. I would guess that it probably takes
    200 to 400 cycles. Based on this you can guestimate based on the speed
    of your CPU clock. The way you have the two interrupts really means
    you will need to be able to run each interrupt twice within a single
    period of your input pulse to ensure you will not miss any pulses.
    Also your LCD routines probably even block interrupts when they write
    to output.

    You best way is to not use interrupts but do it in a main loop,
    continusally check pin and increment a counter when it changes from
    low to high or whatever, and then set an output pin if the count value
    is over a certain amount, and then use a second MCU to read that pin
    and use the LCD. Either that or code the subroutine in assembly. You
    might be able to get away with only a couple of instructions if you
    are very careful about how you use the registers, but either way the
    interupt and return from interrupt instructions I believe use alot of
    cpu cycles, I believe it was at least 12 or 24.

    Basically speaking the cpu isn't fast enough for what you want to do.
    Look at stepping up your clock speed. From what you say I would guess
    you are running at 4Mhz
     
    , Feb 15, 2009
    #6
  7. JJ

    JJ Guest

    On Sat, 14 Feb 2009 14:25:15 -0600, Anthony Fremont wrote:
    > JJ wrote:
    >> On Fri, 13 Feb 2009 17:57:01 -0600, Anthony Fremont wrote:
    >>> JJ wrote:
    >>>> Hello,
    >>>>
    >>>> I have problem with counting ticks of an encoder. I can achieve
    >>>> about 5 kHz without errors. Above this frequency, I loose ticks.
    >>>>
    >>>> I use second AVR processor as the generator of two signals -- I just
    >>>> test my device, without real encoder.
    >>>>
    >>>> What to do to improve frequency ?
    >>>
    >>> Make the ISR run faster. You'll have to optimize the ISR code as
    >>> much as possible. You can do this by doing less work in the ISR or
    >>> perhaps rewriting the ISR in assembler. Maybe get rid of some/all
    >>> of those if statements. How many ints/second do you need to handle?

    >>
    >> Hello,
    >>
    >> 10 kHz would be enough.
    >>
    >> I have ATmega16 -- 16 MHz. Even if execution of interrupt procedure
    >> lasts 1000 cycles (I don`t think so it lasts as long), we should have
    >> 16000000 / 1000 = 16 kHz.

    >
    > Do those do one instruction per clock cycle? A PIC running at that speed
    > would only execute 4,000,000 instructions per second max.
    >
    >> I think, my program should be able to count with higher frequencies
    >> according to high processor speed, and not so slow (I think not slower
    >> than e.g. 1000 cycles) interrupt procedure.

    >
    > You're just going to have to look at the assembler output from the C
    > compiler to see how many instructions it generates. It does seem like your
    > code should execute in less than 1000 cycles though. There is always some
    > extra overhead in ISR entry and exit that eats up some cycles, and jumps eat
    > up cycles too while the pipeline is refilled. I'd start by looking at the
    > generated assembler.


    Hello,

    I didn`t disable interrupts myself in any code.
    But, after translating code to assembler, I can see many "cli"
    instructions in my source code.
    When I cut LCD library and left pure interrupt function and
    main(), there were no "cli" instructions in source code.

    Now, I did loops at the begining
    of main():

    for(i=0;i<10000;i++)
    for(j=0;j<10000;j++)
    ;

    after that I initialize LCD and
    display counter -- to avoid "cli"
    instructions (there are no such instructions
    in C code, but they apear in assembler code
    generated by winavr) which could be in
    LCD library.
    It improved situation (I can count with a little
    bit more frequencies), but not as much I would like.
     
    JJ, Feb 15, 2009
    #7
  8. JJ

    Bartc Guest

    "JJ" <> wrote in message news:gn4u98$ang$...
    > Hello,
    >
    > I have problem with counting ticks of an encoder.
    > I can achieve about 5 kHz without errors.
    > Above this frequency, I loose ticks.
    >
    > I use second AVR processor as the generator of
    > two signals -- I just test my device, without real encoder.


    > SIGNAL (SIG_INTERRUPT0)
    > {
    > if (!(inb(PIND) & 16)) /* if 0 on canal B */
    > flagaA = 1;
    > else /* otherwise, (1 on canal B) */
    > flagaB = 1;
    >
    > }
    >
    > SIGNAL (SIG_INTERRUPT1)
    > {
    > if (inb(PIND) & 16) { /* if 1 on canal B */
    > if (flagaA) /* if flagaA is set */
    > licz++, flagaA = 0;
    > } else if (flagaB) /* if flagaB is set */
    > licz--, flagaB = 0;
    >
    > }


    The interaction doesn't seem simple. You have two inputs: you are counting
    one input on B, but input A seems to reverse the counting direction of input
    B.

    Your only output is the net count on B.

    What are the frequencies of the two inputs? How have you established these
    (with frequency counter/scope..)? What is the phase with respect to each
    other? Could one signal interrupt while processing the other?

    If you have a second count that only counts the total pulses on B, how does
    this behave with higher frequencies?

    --
    Bartc





    >
    > int main(void)
    > {
    > char s[16];
    >
    > outp(0, DDRD);
    >
    > /* Setting interrupts INT 0 i INT1 -- rising, falling edge
    > */
    > outp((1<<INT0)|(1<<INT1), GIMSK);
    > outp((1<<ISC01)|(1<<ISC00) | (1<<ISC11), MCUCR);
    >
    > initLCD();
    >
    > sei(); /* star interrupts */
    >
    > for (;;) {
    > cursorHome();
    > sprintf(s, "%ld ", licz);
    > showStringOnLCD(s);
    > }
    >
    > return 0;
    > }
    >
     
    Bartc, Feb 15, 2009
    #8
  9. JJ

    Richard Bos Guest

    JJ <> wrote:

    > I have problem with counting ticks of an encoder.
    > I can achieve about 5 kHz without errors.
    > Above this frequency, I loose ticks.
    >
    > I use second AVR processor as the generator of
    > two signals -- I just test my device, without real encoder.
    >
    > What to do to improve frequency ?


    Simple: overclock your computer. I recommend cooling with some kind of
    fluid, preferably something colder than mere water.

    Richard
     
    Richard Bos, Feb 15, 2009
    #9
  10. JJ

    JJ Guest

    On Sat, 14 Feb 2009 13:31:27 +0000, Bartc wrote:
    > "JJ" <> wrote in message news:gn62ko$l8a$...
    >> On Fri, 13 Feb 2009 17:57:01 -0600, Anthony Fremont wrote:
    >>> JJ wrote:
    >>>> Hello,
    >>>>
    >>>> I have problem with counting ticks of an encoder. I can achieve about
    >>>> 5 kHz without errors. Above this frequency, I loose ticks.
    >>>>
    >>>> I use second AVR processor as the generator of two signals -- I just
    >>>> test my device, without real encoder.
    >>>>
    >>>> What to do to improve frequency ?
    >>>
    >>> Make the ISR run faster. You'll have to optimize the ISR code as much
    >>> as possible. You can do this by doing less work in the ISR or perhaps
    >>> rewriting the ISR in assembler. Maybe get rid of some/all of those if
    >>> statements. How many ints/second do you need to handle?

    >>
    >> Hello,
    >>
    >> 10 kHz would be enough.
    >>
    >> I have ATmega16 -- 16 MHz. Even if execution of interrupt procedure
    >> lasts 1000 cycles (I don`t think so it lasts as long), we should have
    >> 16000000 / 1000 = 16 kHz.
    >>
    >> I think, my program should be able to count with higher frequencies
    >> according to high processor speed, and not so slow (I think not slower
    >> than e.g. 1000 cycles) interrupt procedure.
    >>
    >>

    > Try making the interrupt routine slower (by inserting delays). If the
    > performance gets worse then perhaps the routine does need speeding up
    > (although 10K operations per second doesn't sound too demanding).
    >
    > I don't really understand your code or your processor, or how you're
    > counting whatever it is you're counting, but in the following:
    >
    >> for (;;) {
    >> cursorHome();
    >> sprintf(s, "%ld ", licz);
    >> showStringOnLCD(s);
    >> }

    >
    > All these 3 routines probably take hundreds of times longer to execute
    > than your interrupt routines.
    >
    > Is it possible they are causing some interrupts to be missed? That they
    > could temporarily mask interrupts?
    >
    > How do you establish that ticks are being missed: that after say 3
    > seconds at 5kHz, the count only shows 12000 or something? Suppose you
    > just did an empty loop for 3 seconds (experiment with a loop count that
    > delays by that much), then displayed the count, would it be 12000 or
    > 15000?


    Hello,

    My generator generates known numer of ticks on both chanels with different
    phase.
    I read LCD -- it shows smaller numer at higher frequencies.

    When I add "cli" at begining of interrupt function and "sei" at the end --
    LCD shows "0" at higher frequencies. And it works correctly at smaller
    frequencies.
    So, I think, that processor tries to run interrupt function when previous
    hasn`t finished yet.
    I think, I must optimalize my code and write it in assembler.

    The second thing is, when I change type of "licz" to int (not long int),
    it can count ticks faster.

    So, I`m almost sure, my code is too slow.

    Now, I use only INT0 in my program, and I can count ticks with a little
    bit more frequency -- but not enough still.
    I need about 10 kHz.

    unsigned long int licz = 0;
    unsigned char flagaA = 0, flagaB = 0;

    SIGNAL (SIG_INTERRUPT0)
    {
    // cli();
    if (PIND & 4) {
    (!(PIND & 16)) ? (flagaA = 1) : (flagaB = 1);
    } else {
    if (PIND & 16) {
    flagaA && (licz++, flagaA = 0);
    } else {
    flagaB && (licz--, flagaB = 0);
    }
    }
    // sei();

    }

    int main(void)
    {
    char s[16];
    outp(0, DDRD);
    outp((1<<INT0), GIMSK);
    outp((1<<ISC00), MCUCR);
    sei();
    .....
    }
     
    JJ, Feb 16, 2009
    #10
  11. JJ

    Bartc Guest

    "JJ" <> wrote in message news:gncauj$rmc$...
    > On Sat, 14 Feb 2009 13:31:27 +0000, Bartc wrote:
    >> "JJ" <> wrote in message news:gn62ko$l8a$...
    >>> On Fri, 13 Feb 2009 17:57:01 -0600, Anthony Fremont wrote:


    >> Is it possible they are causing some interrupts to be missed? That they
    >> could temporarily mask interrupts?
    >>
    >> How do you establish that ticks are being missed: that after say 3
    >> seconds at 5kHz, the count only shows 12000 or something? Suppose you
    >> just did an empty loop for 3 seconds (experiment with a loop count that
    >> delays by that much), then displayed the count, would it be 12000 or
    >> 15000?

    >


    > My generator generates known numer of ticks on both chanels with different
    > phase.
    > I read LCD -- it shows smaller numer at higher frequencies.
    >
    > When I add "cli" at begining of interrupt function and "sei" at the end --
    > LCD shows "0" at higher frequencies. And it works correctly at smaller
    > frequencies.
    > So, I think, that processor tries to run interrupt function when previous
    > hasn`t finished yet.
    > I think, I must optimalize my code and write it in assembler.
    >
    > The second thing is, when I change type of "licz" to int (not long int),
    > it can count ticks faster.
    >
    > So, I`m almost sure, my code is too slow.


    OK, but with a 16MHz device I would have thought it could service 10K
    interrupts per second.

    The interaction between the two inputs is still difficult to grasp but, have
    you thought of making use of any automatic counters on the chip? (Or even
    have an external counter for the low bits at least.)

    Have you tried making licz short int or char? Although dealing with overflow
    efficiently might require some assembler.

    And, with the two inputs asynchronous (not sure if your single INT0 below is
    triggered by both signals), it's quite possible to have one interrupt while
    servicing another. (This is why I suggested asking in comp.arch.embedded as
    someone may have already solved a similar problem.)


    > Now, I use only INT0 in my program, and I can count ticks with a little
    > bit more frequency -- but not enough still.
    > I need about 10 kHz.


    --
    Bartc
     
    Bartc, Feb 16, 2009
    #11
  12. JJ

    JJ Guest

    On Mon, 16 Feb 2009 23:42:41 +0000, Bartc wrote:
    > "JJ" <> wrote in message news:gncauj$rmc$...
    >> On Sat, 14 Feb 2009 13:31:27 +0000, Bartc wrote:
    >>> "JJ" <> wrote in message news:gn62ko$l8a$...
    >>>> On Fri, 13 Feb 2009 17:57:01 -0600, Anthony Fremont wrote:

    >
    >>> Is it possible they are causing some interrupts to be missed? That they
    >>> could temporarily mask interrupts?
    >>>
    >>> How do you establish that ticks are being missed: that after say 3
    >>> seconds at 5kHz, the count only shows 12000 or something? Suppose you
    >>> just did an empty loop for 3 seconds (experiment with a loop count that
    >>> delays by that much), then displayed the count, would it be 12000 or
    >>> 15000?

    >>

    >
    >> My generator generates known numer of ticks on both chanels with different
    >> phase.
    >> I read LCD -- it shows smaller numer at higher frequencies.
    >>
    >> When I add "cli" at begining of interrupt function and "sei" at the end --
    >> LCD shows "0" at higher frequencies. And it works correctly at smaller
    >> frequencies.
    >> So, I think, that processor tries to run interrupt function when previous
    >> hasn`t finished yet.
    >> I think, I must optimalize my code and write it in assembler.
    >>
    >> The second thing is, when I change type of "licz" to int (not long int),
    >> it can count ticks faster.
    >>
    >> So, I`m almost sure, my code is too slow.

    >
    > OK, but with a 16MHz device I would have thought it could service 10K
    > interrupts per second.
    >
    > The interaction between the two inputs is still difficult to grasp but, have
    > you thought of making use of any automatic counters on the chip? (Or even
    > have an external counter for the low bits at least.)
    >
    > Have you tried making licz short int or char? Although dealing with overflow
    > efficiently might require some assembler.


    Hello,

    Thanks Bart and Anthony for all the advices - it is great be able to
    benefit from this group's experience.

    I did two things:
    -- now my program uses only one interrupt - it made
    my program faster, but only a little bit,
    -- I changed internal frequency rate - default it is 1MHz,
    I changed it to 8MHz and my program runs 8 times
    faster ;)
     
    JJ, Feb 17, 2009
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Bruce W.1

    Kill the tick sound on refresh?

    Bruce W.1, Feb 2, 2004, in forum: ASP .Net
    Replies:
    4
    Views:
    833
    charles
    Feb 3, 2004
  2. Martin Eyles

    tick marks

    Martin Eyles, Sep 6, 2005, in forum: ASP .Net
    Replies:
    10
    Views:
    863
    Alvin Bruney - ASP.NET MVP
    Sep 13, 2005
  3. John
    Replies:
    5
    Views:
    1,821
    OHM \( One Handed Man \)
    Apr 15, 2006
  4. WindAndWaves

    tick the boxes

    WindAndWaves, Nov 23, 2004, in forum: HTML
    Replies:
    1
    Views:
    2,103
    Mark Parnell
    Nov 23, 2004
  5. graphicsxp

    update gridview on checkbox tick/untick

    graphicsxp, Jul 12, 2006, in forum: ASP .Net
    Replies:
    1
    Views:
    1,120
    S. Justin Gengo
    Jul 12, 2006
Loading...

Share This Page