If we don't know how to use pointers, when we want to pass an array of data into a function, we can only use global variables. The disadvantages of this method are that it is not intuitive to read, has weak encapsulation, and has no user-facing input interface.
In response to the above problems, this section will teach you a knowledge point: through pointers, add an array input interface to the function.
For details, please see the source code.
(1) Hardware platform:
Based on Zhu Zhaoqi 51 single-chip microcomputer learning board.
(2) Functions to be implemented:
Sort the 5 random data from large to small using the bubble method.
Through the computer serial port debugging assistant, send the EB 00 55 08 06 09 05 07 command to the microcontroller, where EB 00 55 is the data header, and 08 06 09 05 07 is the 5 random raw data involved in the sorting. After receiving the command, the microcontroller will return 13 data. The first 5 data are the sorting results of the first method, and the middle 3 data EE EE EE are the dividing lines between the first and second methods. For the convenience of observation, there is no practical meaning. The last 5 data are the sorting results of the second method.
For example, the computer sends: EB 00 55 08 06 09 05 07
The microcontroller returns: 09 08 07 06 05 EE EE EE 09 08 07 06 05
Please refer to Section 39 for the receiving part of the serial port program. Please refer to Section 42 for the sending part of the serial port program.
The baud rate is: 9600.
(3) The source code is explained as follows:
#include "REG52.H"
#define const_array_size 5 //The size of the array involved in sorting
#define const_voice_short 40 //Duration of the buzzer short call
#define const_rc_size 10 //Buffer array size for receiving serial port interrupt data
#define const_receive_time 5 //If no serial data comes in after this time, it is considered that a string of data has been received. This time can be adjusted according to the actual situation
void initial_myself(void);
void initial_peripheral(void);
void delay_long(unsigned int uiDelaylong);
void delay_short(unsigned int uiDelayShort);
void T0_time(void); //Timer interrupt function
void usart_receive(void); //Serial port receive interrupt function
void usart_service(void); //Serial port service program, in the main function
void eusart_send(unsigned char ucSendData);
void big_to_small_sort_1(void); //The first method sorts an array from big to small
void big_to_small_sort_2(unsigned char *p_ucInputBuffer); //The second method sorts an array from big to small
sbit beep_dr=P2^7; //Buzzer driver IO port
unsigned int uiSendCnt=0; //Timer used to identify whether the serial port has received a string of data
unsigned char ucSendLock=1; //Self-locking variable of the serial port service program. Each time a string of data is received, it is processed only once.
unsigned int uiRcregTotal=0; // represents how much data the current buffer has received
unsigned char ucRcregBuf[const_rc_size]; //Buffer array for receiving serial port interrupt data
unsigned int uiRcMoveIndex=0; //Intermediate variable used to parse data protocol
unsigned char ucUsartBuffer[const_array_size]; //The original data received from the serial port that needs to be sorted
unsigned char ucGlobalBuffer_1[const_array_size]; //Method 1, global variable array involved in specific sorting algorithm
unsigned char ucGlobalBuffer_2[const_array_size]; //Method 2, global variable array involved in the specific sorting algorithm
void main()
{
initial_myself();
delay_long(100);
initial_peripheral();
while(1)
{
usart_service(); //Serial port service program
}
}
/* Note 1:
* The first method uses an empty function without input and output interfaces. This is the most primitive approach, which relies entirely on
* Global variables are used as input and output ports of functions. If we want to use this function, we need to put the variables involved in the operation
* The variable is directly assigned to the corresponding input global variable. After calling the function once, the corresponding
* Output global variables. These output global variables are the results we want.
* In this function, ucGlobalBuffer_1[const_array_size] is both an input global variable and an output global variable.
* The disadvantages of this method are that it is not intuitive to read, has weak encapsulation, and has no input and output interface facing the user.
*/
void big_to_small_sort_1(void) //The first method sorts an array from big to small
{
unsigned char i;
unsigned char k;
unsigned char ucTemp; //In the process of exchanging data between two devices, it is used to temporarily store a variable to be exchanged
/* Note 2:
* The following is the famous bubble sorting method. This method is taught in almost all C language university textbooks. You can directly search for it on Baidu.
* I have searched for its working principle and detailed explanation steps, so I will not explain it in detail.
*/
for(i=0;i<(const_array_size-1);i++) //The number of bubbles is (const_array_size-1) times
{
for(k=0;k<(const_array_size-1-i);k++) //In each bubbling process, the number of pairwise comparisons required is (const_array_size-1-i)
{
if(ucGlobalBuffer_1[const_array_size-1-k]>ucGlobalBuffer_1[const_array_size-1-1-k]) //Compare the latter and the previous data
{
ucTemp=ucGlobalBuffer_1[const_array_size-1-1-k]; //Realize two data exchanges through an intermediate variable
ucGlobalBuffer_1[const_array_size-1-1-k]=ucGlobalBuffer_1[const_array_size-1-k];
ucGlobalBuffer_1[const_array_size-1-k]=ucTemp;
}
}
}
}
/* Comment 3:
* The second method, in order to improve the user experience of the first method, uses a pointer to add an input interface to the function.
* Why do we need to use pointers? Because in C language functions, arrays cannot be directly used as function parameters. Only pointers can be used as array parameters.
* For example, you cannot write a function void big_to_small_sort_2(unsigned char a[5]) like this, otherwise the compilation will fail.
* In this function, the *p_ucInputBuffer pointer is the input interface, and the output interface is still the global variable array ucGlobalBuffer_2.
* This method is more intuitive than the first method because it adds an array input interface to the function.
*/
void big_to_small_sort_2(unsigned char *p_ucInputBuffer) //The second method sorts an array from big to small
{
unsigned char i;
unsigned char k;
unsigned char ucTemp; //In the process of exchanging data between two devices, it is used to temporarily store a variable to be exchanged
for(i=0;i
{
ucGlobalBuffer_2[i]=p_ucInputBuffer[i]; //Before participating in the sorting algorithm, move all the data of the input interface to the global variable array.
}
//The following is the famous bubble sorting method. Please search Baidu for detailed explanation.
for(i=0;i<(const_array_size-1);i++) //The number of bubbles is (const_array_size-1) times
{
for(k=0;k<(const_array_size-1-i);k++) //In each bubbling process, the number of pairwise comparisons required is (const_array_size-1-i)
{
if(ucGlobalBuffer_2[const_array_size-1-k]>ucGlobalBuffer_2[const_array_size-1-1-k]) //Compare the latter and the previous data
{
ucTemp=ucGlobalBuffer_2[const_array_size-1-1-k]; //Realize two data exchanges through an intermediate variable
ucGlobalBuffer_2[const_array_size-1-1-k]=ucGlobalBuffer_2[const_array_size-1-k];
ucGlobalBuffer_2[const_array_size-1-k]=ucTemp;
}
}
}
}
void usart_service(void) //Serial port service program, in the main function
{
unsigned char i=0;
if(uiSendCnt>=const_receive_time&&ucSendLock==1) //Indicates that no new data is coming from the serial port after a certain period of time.
{
ucSendLock=0; //Lock after processing once, no need to come in every time unless there is new data to be received
//The following code enters the stage of data protocol parsing and data processing
uiRcMoveIndex=0; //Since it is to judge the data head, the subscript movement variable starts from 0 of the array and moves to the end
while(uiRcregTotal>=5&&uiRcMoveIndex<=(uiRcregTotal-5))
{
if(ucRcregBuf[uiRcMoveIndex+0]==0xeb&&ucRcregBuf[uiRcMoveIndex+1]==0x00&&ucRcregBuf[uiRcMoveIndex+2]==0x55) //judgment of data header eb 00 55
{
for(i=0;i
{
ucUsartBuffer[i]=ucRcregBuf[uiRcMoveIndex+3+i]; //The original data received from the serial port that needs to be sorted
}
//The first operation method relies on global variables
for(i=0;i
{
ucGlobalBuffer_1[i]=ucUsartBuffer[i]; //Put the data to be arranged into the input global variable array
}
big_to_small_sort_1(); //Calling an empty function once will produce the result, which is still stored in the ucGlobalBuffer_1 global variable array
for(i=0;i
{
eusart_send(ucGlobalBuffer_1[i]); ////Return the results sorted by the first method to the host computer for observation
}
eusart_send(0xee); //In order to facilitate the host computer to observe, send 3 more bytes ee ee ee as the dividing line between the first method and the second method
eusart_send(0xee);
eusart_send(0xee);
//The second operation method relies on the pointer to add an array input interface to the function
//Through the pointer input interface, directly pass the first address of the ucUsartBuffer array into it. The output result after sorting is still saved in the ucGlobalBuffer_2 global variable array
big_to_small_sort_2(ucUsartBuffer);
for(i=0;i
{
eusart_send(ucGlobalBuffer_2[i]); //Return the results sorted by the second method to the host computer for observation
}
break; //Exit the loop
}
uiRcMoveIndex++; //Because it is to judge the data head, the cursor moves towards the end of the array
}
uiRcregTotal=0; // Clear the buffer index to facilitate receiving new data from index 0 next time
}
}
void eusart_send(unsigned char ucSendData) //Function to send one byte to the host computer
{
ES = 0; //Disable serial port interrupt
TI = 0; // Clear the serial port transmission completion interrupt request flag
SBUF =ucSendData; //Send a byte
delay_short(400); //The delay between each byte is very critical and is also the most prone to error. Please adjust the delay size according to the actual project
TI = 0; // Clear the serial port transmission completion interrupt request flag
ES = 1; //Enable serial port interrupt
}
void T0_time(void) interrupt 1 //Timer interrupt
{
TF0=0; //Clear interrupt flag
TR0=0; //Disable interrupt
if(uiSendCnt
{
uiSendCnt++; //On the surface, the data is continuously accumulated, but in the serial port interrupt, it will be cleared every time a byte is received, unless there is no serial port data in the middle
ucSendLock=1; //Open the self-locking flag
}
TH0=0xfe; //Reinstall initial value (65535-500)=65035=0xfe0b
TL0=0x0b;
TR0=1; //Open interrupt
}
void usart_receive(void) interrupt 4 //Serial port receiving data interrupt
{
if(RI==1)
{
RI = 0;
++uiRcregTotal;
if(uiRcregTotal>const_rc_size) //Exceeds the buffer
{
uiRcregTotal=const_rc_size;
}
ucRcregBuf[uiRcregTotal-1]=SBUF; //Cache the data received by the serial port into the receiving buffer
uiSendCnt=0; // Feed the dog in time. Although the main function keeps accumulating, it will never grow as long as the serial port data has not been sent out, because each interrupt is cleared.
}
else //Send interrupt, clear the send interrupt flag in time
{
TI = 0;
}
}
void delay_long(unsigned int uiDelayLong)
{
unsigned int i;
unsigned int j;
for(i=0;i
{
for(j=0;j<500;j++) //Number of empty instructions in the embedded loop
{
; //A semicolon is equivalent to executing an empty statement
}
}
}
void delay_short(unsigned int uiDelayShort)
{
unsigned int i;
for(i=0;i
{
; //A semicolon is equivalent to executing an empty statement
}
}
void initial_myself(void) //Initialize the MCU in the first zone
{
beep_dr=1; //Use PNP transistor to control the buzzer, it will not sound when the output is high level.
//Configure the timer
TMOD=0x01; //Set timer 0 to working mode 1
TH0=0xfe; //Reinstall initial value (65535-500)=65035=0xfe0b
TL0=0x0b;
//Configure the serial port
SCON=0x50;
TMOD=0X21;
TH1=TL1=-(11059200L/12/32/9600); //I am not sure what this configuration code means, but it is related to the baud rate of the serial port.
TR1=1;
}
void initial_peripheral(void) // Initialize the periphery of the second zone
{
EA=1; //Open the general interrupt
ES=1; //Enable serial port interrupt
ET0=1; //Enable timer interrupt
TR0=1; //Start timing interrupt
}
Closing remarks:
The second method uses pointers to add an array input interface to the function, which is much more intuitive than the first method that uses global variables purely. However, there is still a small regret, because its output sorting result still depends on global variables. In order to make the function more perfect, can we add another output interface to the function? Of course we can. For more details, please listen to the next analysis - the third benefit of pointers, pointers are used as output interfaces of arrays in functions.
Previous article:Section 53: Pointers allow a function to encapsulate multiple parameters
Next article:Section 55: Pointer as array output interface in function
Recommended ReadingLatest update time:2024-11-16 13:42
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!
- 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
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- 27 operators "abandon Huawei"! The United States released the list of "5G clean networks"
- A summary of the most downloaded electronic technical materials this week (2020-04-17)
- JTAG debug test access port TAP
- About serial port loopback test
- 【ST NUCLEO-G071RB Review】SPI
- Can NXP's crossover processor RT1052 execute code in RAM?
- What are the consequences of not connecting high-power wireless data transmission equipment to an antenna?
- 【Application Case】How to implement anti-lost device with Bluetooth BLE
- How do C1 and C2 supercapacitors work?
- What is the difference between an industrial 4G router and a regular 4G router? Which one have you used?