avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[avr-gcc-list] Problems with if statement and negative numbers


From: Dale Seaburg
Subject: [avr-gcc-list] Problems with if statement and negative numbers
Date: Mon, 21 May 2001 17:57:09 -0500

I am attaching a code snippet of a problem that I have incurred using
avr-gcc.  It involves an 'if' statement that doesn't seem to handle
negative numbers.

The gcc is 2001.02.28, the same for the binutils and the avr-libc is
2001.02.11

This routine is called from a Timer 0 Interrupt Handler to poll two
lines which are hooked up to a grey-coded 2-bit shaft encoder.  The
routine decodes the greycode into one of two values: a 1 and a -1. 
These are then tested against an upper bound and a lower bound.  If they
fall into the area between the bounds, then the 1 or -1 is added to a
menu select variable 'ui_select'.

The problem manifests itself when the encoder only seems to advance, not
backup.  The ui_select variable only increases in value.  It never
decreases in value.

I have run the routine without the limit checks and it functions
correctly, in that the variable ui_select increases/decreases with the
appropriate turn of the encoder.  So, the culprit is in the limit
checking 'if' logic.

Further you'll see two 'if' statements at the bottom of the routine that
demonstrates the problem.  The LEDs attached to the PORTB (STK300 -
atmega103) show only a 1, not a 2, which indicates that the handling of
negative numbers, specifically a -1 doesn't work correctly.

BTW, this very routine does compile and work correctly on a PIC using a
Hi-Tech compiler.  Also, I did rearrange the limit checking logic to
avoid the check for a negative number.  It works, but looks awkward. 
And, I'm sure it costs some extra code.

Can anyone see my problem.  Or, do we have a bug in the compiler? 
Or...  { you fill in the blank }

Thanks for your help.

Dale Seaburg
01 const char greytbl[4][4] = {{0, -1, 1, 0},
02                                  {1, 0, 0, -1},
03                                  {-1, 0, 0, 1},
04                                  {0, 1, -1, 0} };
05 
06 volatile uint8_t grey,oldgrey = 0x00;
07 volatile signed int ui_select = 0;
08 volatile char val;
09
10 //   This routine is called from within the Timer 0 IH about every 13ms.
11 //   Handle Encoder Decode
12 void EncoderDecode()
13 {
14      // Sample PORTE FIRST, bits 4 & 5
15      grey = (inp(PINE) & 0x30) >> 4;
16 
17      wdt_reset();
18 
19      if (grey != oldgrey)
20      {
21              val = greytbl[oldgrey][grey];
22
23              // The two valid values returned from the greytable are:
24              // 1 for advance, -1 for backup.
25              // The 3rd value, a 0 is not seen due to the above IF statement.
26              // Now, check limits so we don't overstep
27
28              if (((val > 0) && (ui_select < ui_max)) ||
29                      ((val < 0) && (ui_select > 0)))
30              {
31                      ui_select += val;
32              }
33
34              if (val > 0) {
35                      outp(~1, PORTB); }  //  *****  DEBUG  *****
36              if (val < 0) {
37                      outp(~2, PORTB); }      //  *****  DEBUG  *****
38
39              oldgrey = grey;
40      }
41 //   outp((~val&0xBF)|(inp(PORTB)&0x60), PORTB);  //  *****  DEBUG  *****
42      outp(~(ui_select&0x0F)|(inp(PORTB)&0xF0), PORTB);  //  ***** DEBUG  
*****
43 }


reply via email to

[Prev in Thread] Current Thread [Next in Thread]