The relationship between the AVR microcontroller register DDRx PORTx PINx and the corresponding IO port (x represents a port, such as port A, port B, etc.)
The following table uses the second bit PB2 of port B as an example and assumes that PB2 is floating.
DDRB.2
PORTB.2
Read the result of PINB.2
Status of pin PB2
1
1
1
PB2 push-pull output
1
1
0
0
PB2 push-pull output
0
0
1
1
PB2 weak pull-up, can be used as input
0
0
×
PB2 high impedance, can be used as input
When reading PINB.2, the actual level of the PB2 pin is read.
If PB2 is directly connected to VCC, then the result of reading PINB.2 at any time is 1
If PB2 is directly connected to GND, then the result of reading PINB.2 at any time is 0.
The following is a standard C language example:
#include
unsigned char abc; //define a variable
void main(void) //main function
{
DDRB = 0b11110000;
PORTB = 0b11001100;
while (1) //main loop
{
abc = PINB; //Read the actual level of port B
}
}
If the entire B port is left floating,
Then the result of abc is: 0b110011**
If the 7th bit of port B is connected to GND, the 0th bit is connected to VCC, and the other bits are left floating,
Then the result of abc is: 0b010011*1 (PB7 works in the "short circuit" state)
The “*” indicates uncertainty, which can be regarded as 0 in an ideal state.
Port declaration: include
#include "D:\\ICC_H\\CmmICC.H"
#define OUT_BUZ sbi(DDRB,3) //PB3
#define BUZ_ON cbi(PORTB,3)
#define BUZ_OFF sbi(PORTB,3)
/*--------------------------------------------------------------------
Program name:
Program function: Notes
: Tips: Input: Return: --------------------------------------------------------------------*/ void main(void) { OUT_BUZ; //Set the corresponding IO port as outputwhile (1) { BUZ_ON; //I call delay50ms(20); BUZ_OFF; //I don’t call delay50ms(20); } }
During system debugging
, change the statement: delay50ms(20); to the statement: delay50ms(1);. You can hear that the calling frequency is higher, it is so noisy!
Taking ATMEGA16 as an example, this book explains each functional component of AVR in a relaxed and humorous way, and provides Protel circuit diagram and ICCAVR source code.
All the information is found on the Internet, and I have sorted it out. Let's learn it together!
Lesson 1 AVR IO output LED display program
System Function
Use AVR to control 8-bit LED, flash when you want it to flash, flash when you don't want it to flash, flash left and right, flash desperately, and demonstrate the "lighting technique" of AVR microcontroller.
Hardware Design
For details about the I/O structure and related introduction of AVR, please refer to the Datasheet. Here we only give a brief introduction to some of them. The following is the I/O pin configuration table of AVR:
AVR I/O Port Pin Configuration Table
DDRXn PORTXn PUD I/O Mode Internal Pull-up Resistor Pin Status Description
0 0 X Input invalid tri-state (high impedance)
0 1 0 Input valid Output current (uA) when external pin is pulled low
0 1 1 Input invalid tri-state (high impedance)
1 0 X Output invalid push-pull 0 Output, sink current (20mA)
1 1 X Output invalid push-pull 1 Output, output current (20mA)
Although the AVR I/O port can output a large current enough to light up a lamp when it outputs "1" alone, the total I/O output of the AVR is limited after all. Therefore, experienced lamp liters consider that there may be other strenuous work to do in addition to lighting the lamp, and will design the AVR I/O port to light up the lamp when it outputs "0" and turn off the lamp when it outputs "1". This connection method is also called "current injection connection method". [page]
AVR main control circuit schematic (click on the image to enlarge, no magnifying glass required!)
LED control circuit schematic (click on the image to enlarge, no magnifying glass required!)
Software Design
The following part is copied from TXT and copied to the web page. There are many spaces missing in the code part, so it is a bit messy. Please understand!
//Target system: Based on AVR MCU
//Application software: ICC AVR
/*0101010101010101010101010101010101010101010101010101010101010101010101010101010101
----------------------------------------------------------------------
Experiment content:
Turn on the light, and let the light flash left and right, flash as hard as possible.
----------------------------------------------------------------------
Hardware connection:
Switch the LED indicator enable switch of the PD port to the "ON" state.
----------------------------------------------------------------------
Notes:
(1) If you have loaded the library program, please copy the "ICC_H" folder under the "library program" in the root directory of the CD to disk D.
(2) Please read carefully: "Product Information\\Development Board Experiment Board\\SMK Series\\SMK1632\\Instructions" in the root directory of the CD
----------------------------------------------------------------------
101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010*/
#include
#include "D:\\ICC_H\\CmmICC.H"
#define LED_DDR DDRD
#define LED_PORT PORTD
/*--------------------------------------------------------------------
Program name:
Program function:
Notes:
Tips:
Input:
Return:
--------------------------------------------------------------------*/
void main(void)
{
uint8 i,j;
LED_DDR=0XFF;
while(1)
{
for(i=0;i<4;i++)
{
LED_PORT^=0xFF; //I flash! Flash as hard as I can!
delay50ms(10);
}
j=0x01;
for(i=0;i<8;i++)
{
j<<=1;
LED_PORT=j; //I flash to the left!
delay50ms(10);
}
j=0x80;
for(i=0;i<8;i++)
{
j>>=1;
LED_PORT=j; //I flash to the right!
delay50ms(10);
}
}
}
The purpose of this section is to learn the IO output function of AVR. For AVR, it is different from the traditional 51 microcontroller and needs to set the IO pin direction. Perform the following debugging
:
(1) Change the IO direction, that is, change "LED_DDR=0XFF;" to "0X00" and observe the phenomenon.
(2) Change the statement: delay50ms(10); to the statement: delay50ms(1);. You can see that the LED flashes faster and your eyes are dazzled!
Things need to be used flexibly. The following is a watch made of LED, and the interior is made of AVR and ATmega48. Please think about how to realize the following functions.
The IO port of the AVR microcontroller is a standard bidirectional port. First, you need to set the state of the IO port, that is, input or output.
The DDRx register is the port direction register of the AVR microcontroller. By setting DDRx, the state of the x port can be set.
If the corresponding bit of the DDRx port direction register is set to 1, the corresponding bit of the x port is in the output state. If the corresponding bit of the DDRx port direction register is set to 0, the corresponding bit of the x port is in the input state.
For example:
DDRA = 0xFF; //Set all ports of port A to output state, because the binary corresponding to 0xFF is 11111111b
DDRA = 0x0F //Set the high 4 bits of port A to input state and the low 4 bits to output state, because the binary corresponding to 0x0F is 00001111b
The PORTx register is the output register of the AVR microcontroller. After the port output state is set, the corresponding bit of port x can be input high or low to control the external device by setting PORTx.
For example:
PORTA = 0xFF; // All port lines of port A output high
PORTA = 0x0F; //Port A high 4 bits output low level, low 4 bits output high level
Tip:
Use bitwise logical operators to set specific ports.
PORTA = 1<<3; //Port A, the 4th position is high level, the others are low level, it should be 00000001, after shifting 3 bits left, it is 00001000
PORTA = 1<<7; //Similarly, the 8th position is high level
Sometimes we want to set a certain bit of the port to a high level, but keep the high and low levels of other bits unchanged. How can we do this? C language is very powerful, there is a way! As follows:
PORTA |=1<<3; //The 4th bit of port A is high, and the high and low levels of other bits are not affected.
The above statement is a simplified way of writing. It can be broken down into:
PORTA = PORTA | (1<<3); //The number 1 is shifted left by 3 bits and then bitwise ORed with port A. The result is that the 4th bit of port A is high, and the high and low levels of other bits are not affected.
Then everyone will ask, how to set a certain bit to a low level while keeping the high and low levels of other bits unchanged? It is recommended that you think about it for 1 minute before reading the following content.
PORTA &=~(1<<3); // Explain, first shift 1 left by 3 bits to become 00001000b, then invert it bit by bit to become 11110111b, and then perform a bitwise AND operation with port A, so that the 4th bit of port A is set to a low level, and the high and low levels of other bits remain unchanged.
The decomposed statement is:
PORTA = PORTA & (~(1<<3)); // The result is the same
Flip the high and low levels of the corresponding bit of a port, that is, the original high level becomes a low level, and the low level becomes a high level. Haha! It's so simple!
PORTA = ~PORTA; //Invert PORTA bit by bit and assign it to PORTA
There is also a bitwise logical operation called XOR, which is also very interesting. It can realize level flipping. If you are interested, you can read the book. It can give you an idea!
Here's another question!
We all know that given two variables a and b, the common way to swap two variables in programming is to define an intermediate variable c, and then:
c=a;
a=b;
b=c;
The contents of variables a and b are exchanged through the intermediate variable c!
But think about whether we can use C language to exchange variables a and b without using intermediate variables? The answer is definitely yes, because C language is very powerful!
However, I still hope that everyone will think about it before looking at the answer, and then analyze it carefully after reading the answer to experience the cleverness of programming!
Answer:
The bitwise XOR logic operation of C language is used. Since there is no intermediate variable and the speed of logical operation is very fast, the whole exchange process is much faster than the conventional method!
a ^= b;
b ^= a;
a ^= b;
The process is to XOR a with b, XOR b with a, and then XOR a with b and it's done!
XOR logic table
1 ^ 1 0
0 ^ 1 1
1 ^ 0 1
0 ^ 0 0
adm is amazing. You know all this. You seem to be an expert in programming.
For problems like swapping variables, it is difficult for beginners to figure out the solution on their own if you have not read relevant information.
int a,b;
a=3;
b=5;
a=a+b //a=8 b=5
b=ab //a=8 b=3
a=ab //a=5 a=3
This is just a matter of algorithmic skills, and it is now rare to encounter a situation where there is not enough memory.
For problems like swapping variables, it is difficult for beginners to figure out the solution on their own if you have not read relevant information.
int a,b;
a=3;
b=5;
a=a+b //a=8 b=5
b=ab //a=8 b=3
a=ab //a...
I learned another trick, which is really clever! They are similar in nature.
I learned these from others, but logical operations are more than twice as fast as arithmetic operations. I wrote a program and simulated it in AVR Studio! The
program is as follows:
#include
void main (void)
{
int a=10,b=20;
unsigned char x=30,y=40;
a = a + b;
b = a - b;
a = a - b;
x ^= y;
y ^= x;
x ^= y;
while (1);
}
First, just for calculation, arithmetic operation takes 8 clock units, and logical operation takes 3 clock units, because arithmetic operation involves negative numbers. What about
variable assignment? Int assignment takes 4 clock units, and unsigned char assignment takes 2 clock units.
In summary, arithmetic operation takes 12 units, and logical operation takes 5 units, which is 2.4 times more efficient! After the project is compiled, a .cof debugging file will be generated (I use ICC, CV should also have it). Use AVR Studio to open this .cof file, select the processor model (M16) and enter the software simulation. Press Alt+O shortcut keys to set the processor frequency, so that you can see the running time, otherwise you can only see the running clock, and the time is not accurate. Next is to press F11 to execute in a single step, and F10 to execute a process at once, such as: loop, function, etc. The clock and running time can be reset at any time by right-clicking the mouse, so that the numbers are more intuitive and there is no need to add or subtract.
Previous article:Design of solar controller based on AVR
Next article:Multi-point temperature measurement system based on AVR microcontroller and DS18B20
Recommended ReadingLatest update time:2024-11-17 01:46
- Popular Resources
- Popular amplifiers
- Principles and Applications of Single Chip Microcomputers 3rd Edition (Zhang Yigang)
- Metronom Real-Time Operating System RTOS for AVR microcontrollers
- Learn C language for AVR microcontrollers easily (with video tutorial) (Yan Yu, Li Jia, Qin Wenhai)
- ATmega16 MCU C language programming classic example (Chen Zhongping)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- Rambus Launches Industry's First HBM 4 Controller IP: What Are the Technical Details Behind It?
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- Several issues on hysteresis compensation
- Does anyone have the BAP protocol in Volkswagen's CAN protocol?
- [RVB2601 Creative Application Development] 8 If more than a certain number of letters are not shot down, the game will be displayed as over.
- NRF51822 production capacity is urgent, what should be used as a replacement?
- [Construction Monitoring and Security System] 9. Kaluga loads project configuration from SD card
- pspice study notes - circuit simulation process
- [NUCLEO-L552ZE Review] + How to receive complete serial port data (solved)
- There was a problem defining the variable
- Comprehensive analysis of embedded learning routes, taking you into embedded
- A collection of practical automotive electronics information, free points download for a limited time