Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
Jan Waclawek
02/14/20 15:22
Read: 242 times
Bratislava
Slovakia


 
#190971 - please try again
Responding to: Grant Beattie's previous message
Hi Grant,

Have you actually replaced the
65536 - (SYS_CLK/(1*2*19200)), // 0xFEC7 (0.16%) // COMPILER BUG? Gives 0x01BA. :(
line in compiler by
65536 - (SYS_CLK/(1L*2*19200)), // gives 0xFEc8 as expected
and checked value in the table?

I now don't have Keil for some time, but a friend of mine tried on v8.12 and reported this fix resulting in the correct value in the table.

As Michael said above, the result from the formula actually is 0xFEC8.

Difference between using the suffixed value in the bracketed multiplication, versus using it only in the value before that bracket is, that in the default 16-bit integer arithmetics which is applied by default if there's no typecasting and explicit type prescribed by the prefix, 2*19200=38400 is out of the range of the 16-bit int (which is -32768..+32767) and the result (38400=0x9600) is considered to be signed, i.e. -27136. The subsequent division is with the already suffixed SYS_CLK, so the value of bracket is expanded to 32-bit signed "long int", i.e. 0x9600 -> 0xFFFF9600 (which is still -27136, but this time in 32-bit representation). The result of division is -442 or 0xFFFFFE46, and the result of subtraction (still performed in 32 bits) is 0x101BA, which is stored into the 16-bit array item truncated to 0x1BA, as you've noticed.

If the calculation starts by explicitly long int (i.e. 32-bit) 1L, then the 2*19200 won't overflow and convert to a negative value, and the whole calculation will result in the expected 0xFEC8 value.

The preprocessor "check" ought to use 0xFEC8, too:

#if(65536 - (SYS_CLK/(1*2*19200)) != 0xFEC8)
#warning "Compiler preprocessor BUG at UART1 Baud rate 19200!"
#endif

Note that the preprocessor does not need the 1L, as the rule for evaluating expressions in preprocessor conditional #if (expression) is different from evaluating the same expression in the program itself, namely in preprocessor the longest type is used regardless of the explicit typing suffix.



List of 6 messages in thread
TopicAuthorDate
Keil C51 Bug      Grant Beattie      02/11/20 14:10      
   integer overflow      Jan Waclawek      02/12/20 01:06      
      Same result (bad)      Grant Beattie      02/12/20 09:45      
         Spreadsheet Analysis       Michael Karas      02/13/20 23:18      
         please try again      Jan Waclawek      02/14/20 15:22      
            Yay      Grant Beattie      02/14/20 15:58      

Back to Subject List