Section 54: Pointer as array input interface in function

Publisher:HeavenlyWhisperLatest update time:2016-03-15 Source: eefocusKeywords:Pointer Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
Opening remarks:

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.

Keywords:Pointer Reference address:Section 54: Pointer as array input interface in function

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

IAR for AVR reports array is too large error [solved]
Solution: Right click on the project, go to options - General Options - Memory Model and change it to small
[Microcontroller]
IAR for AVR reports array is too large error [solved]
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号