Bit operations in the C language programming of the AVR Microcontroller

Source: Internet
Author: User

Original address: http://www.eefocus.com/lsm1989/blog/11-05/219293_343a9.html maybe specific unknown

 

In the textbooks of the Standard C language, bit operations are basically not involved. However, in the single-chip microcomputer system program, various registers in bytes need to be operated frequently, these registers are usually a combination of data in binary units. Each of the eight-bit registers has its own control object, such as the direction register ddrb of port B, as shown in

It actually controls the direction of the 8 port PB0-PB7 of the Pb port, that is to say, every bit of it controls the direction of a port, if we want to set the port PB0-PB3 to the output port, the PB4-PB7 is set as the input port, without the bitwise operator, we can directly use the value assignment statement ddrb = 0x0f to achieve, this is completely achievable.
However, if the following situation occurs: in the program, the status of the Eight-bit ports of the Pb port is originally 1, 3, 5, and 7. 0, 2, 4, and 6 are output (ddrb = 0x55). Next, set the 1st bits of the Pb port to output. The status of other ports remains unchanged, then, set the 2nd bits as the input, and the status of other ports remains unchanged. How can this problem be achieved? Maybe we can still use the value assignment statement, for example, ddrb = 0x55, ddrb = 0x57, and ddrb = 0x53, this is absolutely correct. However, we may not have noticed that when changing one of the values, we also need to consider the status of the other 7 bits, and be careful not to accidentally change the values of other bits.
Is there a way to modify the status of a certain bit without changing the status of other places?
This leads to the concept of bit operations in the C language programming of single-chip microcomputer.
Let's look at this statement: ddre | = (1 <Pe5); this statement sets the 5th bits of the PE port to the output port, and the status of other ports remains unchanged. How is it implemented? First, let's look at the expression 1 <Pe5. We have already introduced that the macro definition of the AVR registers is defined in the header file IO. H. We can call it directly.

Let's take a look at how Pe5 is defined in Io. H (find iom64.h in the winavr installation directory). We can see that the eight bits of the PE port are defined as follows:
/* Port e data register-Porte */
# Define Pe7 7
# Define pe6
# Define Pe5
# Define PE4 4
# Define pe3 3
# Define Pe2 2
# Define pe1 1
# Define pe0 0
It can be seen that in fact, Pe5 = 5; then 1 <Pe5, it is easy to understand, its role is to shift 1 to 5 places, the final result is expressed as 0b00100000 in binary format, ddre | = (1 <Pe5); actually ddre = ddre | (1 <Pe5); first, "|" indicates "or, ddre is the direction register of port E, which is defined in iom64.h:

# Define ddre _ sfr_io8 (0x02); it actually defines an identifier, which corresponds to an address in the ram of the data storage area. We will not go into it for the moment. Let's look back at ddre = ddre | (1 <Pe5); the function implemented in this sentence is actually the content (data) in the ddre register) perform or operation with the binary number 0b00100000. We know that the result of two operations is: if one is 1, the result is 1. if the original value in ddre is 0b10001010 (0x8a), and it is "or" with 0b00100000, the result is 0b1010101010 (0xaa ). We can see that the values except the 5th bits in ddre have not changed, and the 5th BITs have changed to 1, our goal is to set 5th bits as the output port (to set 5th bits to 1 ).
Now let's take a look at several bitwise operators in the language:
Shift Operator: Left shift <, right shift>
And OPERATOR :&
Or OPERATOR: |
Inverse operators :~
XOR operator: ^
There are only six bitwise operators in total. Now let's take a look at the functions of these operators;
Left Shift Operator: expression x <n, which means to move data x n places to the left, here, both X and N must be unsigned integer data (all bitwise operator operation objects are unsigned integer );
For example, X is an unsigned char data (that is, X is a single-byte data with a total of eight digits), and the initial value of X is 0x00000001, perform the x <n operation:
When n = 0, x <n indicates that X is shifted to 0 places. Actually, X is not moved, and the value of X is not changed.
When n = 1, x <n indicates that X shifts 1 bit left, and the calculation result is 0b00000010.
When n = 2, x <n indicates that X shifts two places to the left, and the calculation result is 0b00000100.
...
When n = 7, x <n indicates that X shifts 7 digits left, and the calculation result is 0b0000000.
When n = 8, x <n indicates that X shifts 8 digits left, and the calculation result is 0b00000000.
From the result, when n is between 1-7 values, the result of the operation is always one shift to the left, but when n> = 8, the value of X is always 0, this is because X is an integer variable with only 8 bits and its maximum binary length is 8 bits. When N exceeds 8, the result of the shift operation has exceeded the range of 8 bits, overflow occurs.
The principle of right shifting is similar to that of left shifting, but its operation result is the opposite of that of left shifting.
In C language programming of single-chip microcomputer, shift operations are often used to multiply data by (left shift) or divide by (right shift) 2 by the N power multiplication and division operations, using shift operations to realize multiplication and division operations can significantly improve the operation speed and efficiency of single chip microcomputer. We can read related C language books to learn more about its detailed principles.
Operations such as "anti", "and", "or", and "Non" are often used to operate a certain bit of a register,
For example, to make the second-bit output of port B high without changing the status of other ports, we can use the following method:
Portb | = (1 <PBS ),
In fact, to set one of the eight-bit registers to 1, you can use the following statement: Register name (such as portb) |=( 1 <X ), in the formula, X indicates the X-th digit.
Conversely, if you want to set a bit of an 8-bit register to 0, you can use the following statement: Register name (such as portb) & = ~ (1 <X), where X represents the X-th digit.

When I wrote it, I always felt clear in my mind, but I couldn't express it. I wanted to use single chip microcomputer to explain how to use C language to develop single chip microcomputer programs, but there is always no way to express the combination of the two intuitively. Some puzzles!
This may be the reason why many books on single-chip microcomputer C language development have separated the C language explanation from the specific program design. There is no better way to explain the Specific Single-Chip Microcomputer Development while gradually integrating the knowledge of C language into the instance.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.