|
From: | Rick Altherr |
Subject: | Re: [avr-chat] Comparisson with negative values |
Date: | Mon, 19 Nov 2007 10:02:56 -0800 |
Sure. A few things are actually dubious here. volatile is reserved for cases where the contents of the variable might change without direct intervention from the code. Examples would be if the variable was a pointer referencing a register. In your case, the values should be set somewhere in your code, so volatile is not necessary. Second, you have specified error to be a uint16_t. This means that error will be a unsigned 16-bit integer. So, when error is set to reference - feedback, the negative number is implicitly converted to an unsigned number. A side effect of the way signed numbers are stored in computers is that when they are treated as unsigned number, they become very large. Let's consider this in hexadecimal for a bit to illustrate the point. A value of 1 would be 0x0001. Now, if we subtract 1 from 0, we would logically expect the result to be -1. In the world of computer arithmetic, however, you get 0x0000 - 0x0001 = 0xFFFF. In the case of a uint16_t, this is interpreted as 65535. Now, if you define the variable as an int16_t, the number is considered to be in 2s compliment which correctly translates 0xFFFF to -1. So, the corrected snippet of code would be: uint16_t reference; uint16_t feedback; int16_t error; error = reference - feedback; if (error>0) set_pwm(pwm+1); if (error<0) set_pwm(pmw-1); Beware that there are side effects here. If the result of reference - feedback is a large positive number (>32767), the result will be a large negative number. So, make sure that reference - feedback always results in a number between -32768 and 32767. Rick On Nov 19, 2007, at 9:30 AM, John wrote:
-- Rick Altherr "He said he hadn't had a byte in three days. I had a short, so I split it with him." -- Slashdot signature |
smime.p7s
Description: S/MIME cryptographic signature
[Prev in Thread] | Current Thread | [Next in Thread] |