Common C language errors in MCU development
[Copy link]
When developing microcontrollers, there are often some insignificant problems. These problems are actually very basic C language knowledge points and some small details. But precisely because they are very basic and small details, we tend to ignore them. As a result, sometimes we spend a long time entangled in a problem and can't find the problem. When we find out that the cause is so simple and insignificant, everyone will feel miserable.
1. ! is different from ~
! is the logical NOT symbol, ~ is the bitwise inversion symbol.
Don't use the wrong value when assigning a value to an IO port pin!
LCD_CS_n_DR &= !LCD_CD_n_MASK; //Error
LCD_CS_n_DR &= ~LCD_CD_n_MASK; //Correct
2.<< and >> have lower priority than + and -
For example, if you want to implement c=x*2+1, you will get an error if you don't add brackets.
c = x<<1+ 1; // Wrong, c=x*(1+1)
c = (x<<1) + 1; // Correct, c=x*2+1
3. Prevent overflow during shifting
Actually, using shifting instead of multiplication and division is a good method. I like to use shifting instead of multiplication and division to optimize a piece of code. However, sometimes there will be problems, such as overflow. When it is obvious that overflow is likely, we will pay attention to it, such as
char m = c<<4; //c is of type char, overflow may occur
But sometimes the problem is not obvious, such as when the shift occurs in array index or function parameter. Here is a code that uses LCD to display characters:
char m = Font8x16[c*16+1]; //c is a character, find the dot matrix font of c
We can use left shift operations instead of multiplication to optimize, such as
char m = Font8x16[(c<<4)+1]; //c is a character, find the dot matrix font of c
This is a good method, but in fact the above code is wrong. When executing c<<4, because there is no obvious assignment process, we may think that there is no problem, but in fact the high bits of c have been lost, so we get the wrong result. A feasible approach is to perform a forced conversion first, such as
char m = Font8x16[(uint16)c<<4)+1]; //c is a character, find the dot matrix font of c
4. Mixed operations of unsigned and signed numbers will be forced to be converted to unsigned operations
When a signed number and an unsigned number are used for arithmetic operations, the system will automatically convert the signed number to an unsigned number before performing the operation (even if you use the signed number type conversion). The following two ways of writing the transport result is the same:
char a = (unsigned char)b / (signed char)c;
char a = (unsigned char)b / (unsigned char)c;
5. Local variables should be initialized
If a local variable is not initialized, and the microcontroller allocates the same memory area for it each time, problems may occur when you use local variables in a function like this:
void fun(char a)
{
char b;
if(a==0)
b = 2;
}
If the value of a passed is 0 when fun is called for the first time, then b = 2; when fun is called again, even if a is not 0, if b still uses the previous memory area, its value will always be 2.
If you want to avoid this mistake, you should develop the habit of initializing local variables.
|