The first benefit of pointers is that a function can encapsulate multiple parameters equivalent to those returned by the return statement.

Publisher:电子创新者Latest update time:2021-11-05 Source: eefocusKeywords:Pointer Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

1. Use proteus to draw a simple circuit diagram for subsequent simulation

2. Programming


/********************************************************************************************************************

---- @Project: Pointer

---- @File: main.c

---- @Edit: ZHQ

---- @Version: V1.0

---- @CreationTime: 20200808

---- @ModifiedTime: 20200808

---- @Description:

---- The baud rate is: 9600.

---- Communication protocol: EB 00 55 XX YY  

---- Send the EB 00 55 XX YY instruction to the MCU through the computer serial port debugging assistant, where EB 00 55 is the data header, XX is the dividend, and YY is the divisor. After receiving the instruction, the MCU will return 6 data. The first two data are the quotient and remainder of the first operation method, the middle two data are the quotient and remainder of the second operation method, and the last two data are the quotient and remainder of the third operation method.

---- For example, computer sends: EB 00 55 08 02

---- The microcontroller returns: 04 00 04 00 04 00 (04 is the quotient, 00 is the remainder)

---- Microcontroller: AT89C52

****************************************************************************************************************************/

#include "reg52.h"

/*——————Macro definition——————*/

#define FOSC 11059200L

#define BAUD 9600

#define T1MS (65536-FOSC/12/500) /*0.5ms timer calculation method in 12Tmode*/

 

#define const_voice_short 19 /*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*/

 

/*——————Variable function definition and declaration——————*/

/*Buzzer driver IO port*/

sbit BEEP = P2^7;

/*LED*/

sbit LED = P3^5;

 

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 only processed once*/

unsigned int uiRcregTotal = 0; /*Indicates 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 int uiVoiceCnt = 0; /*Buzzer beeping duration counter*/

 

unsigned char ucBeiChuShu_1 = 0; /* Dividend in the first method*/

unsigned char ucChuShu_1 = 1; /* Divisor in the first method*/

unsigned char ucShang_1 = 0; /* Quotient in the first method*/

unsigned char ucYu_1 = 0; /* remainder in the first method*/

 

unsigned char ucBeiChuShu_2 = 0; /* Dividend in the second method*/

unsigned char ucChuShu_2 = 1; /* Divisor in the second method*/

unsigned char ucShang_2 = 0; /* Quotient in the second method*/

unsigned char ucYu_2 = 0; /* remainder in the second method*/

 

unsigned char ucBeiChuShu_3 = 0; /* Dividend in the third method*/

unsigned char ucChuShu_3 = 1; /* Divisor in the third method*/

unsigned char ucShang_3 = 0; /* Quotient in the third method*/

unsigned char ucYu_3 = 0; /* remainder in the third method*/

 

/**

* @brief Timer 0 initialization function

* @param None

* @retval initialize T0

**/

void Init_T0(void)

{

TMOD = 0x01; /*set timer0 as mode1 (16-bit)*/

TL0 = T1MS; /*initial timer0 low byte*/

TH0 = T1MS >> 8; /*initial timer0 high byte*/

}

 

/**

* @brief Serial port initialization function

* @param None

* @retval initialize T0

**/

void Init_USART(void)

{

SCON = 0x50;

TMOD = 0x21;                    

TH1=TL1=-(FOSC/12/32/BAUD);

}

 

/**

* @brief peripheral initialization function

* @param None

* @retval Initialize peripheral

* Transfer the contents displayed by the digital tube to the following variable interfaces to facilitate the writing of higher-level window programs in the future.

* Simply change the content of the corresponding variables below to display the numbers you want.

**/

void Init_Peripheral(void)

{

ET0 = 1;/*Enable timer interrupt*/

TR0 = 1;/*Start timing interrupt*/

TR1 = 1;

ES = 1; /*Enable serial port interrupt*/

EA = 1;/*Open the general interrupt*/  

}

 

/**

* @brief initialization function

* @param None

* @retval initialize the MCU

**/

void Init(void)

{

LED = 0;

Init_T0();

Init_USART();

}

/**

* @brief delay function

* @param None

* @retval None

**/

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*/

          }

   }

}

/**

* @brief delay function

* @param None

* @retval None

**/

void Delay_Short(unsigned int uiDelayShort)

{

  unsigned int i;

  for(i=0;i  {

; /*A semicolon is equivalent to executing an empty statement*/

  }

}

 

/**

* @brief Serial port sending function

* @param unsigned char ucSendData

* @retval Function that sends a byte to the host computer

**/

void eusart_send(unsigned char ucSendData)

{

ES = 0; /* Disable serial port interrupt */

TI = 0; /* Clear the serial port transmission completion interrupt request flag */

SBUF = ucSendData; /* Send one 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 */

}

 

/**

* @brief Method 1

* @param None

* @retval 

* The first method is to use an empty function with no parameters. This is the most primitive method and it was also the one I used when I just graduated.

* This is a method that is often used when starting a project. It completely relies on global variables as the input and output ports of the function.

* To use this function, we need to assign the variables involved in the operation directly to the corresponding input global variables.

* After calling the function once, find the corresponding output variables, which are the results we want.

* In this function, the dividend ucBeiChuShu_1 and the divisor ucChuShu_1 are input global variables.

* The quotient ucShang_1 and remainder ucYu_1 are output global variables. The disadvantage of this method is that it is not intuitive to read.

* The encapsulation is not strong, and there is no input and output interface facing the user.

**/

void chu_fa_yun_suan_1(void) /* The first method to find the quotient and remainder*/

{

if(ucChuShu_1 == 0) /* If the divisor is 0, both the quotient and remainder are 0 */

{

ucShang_1 = 0;

ucYu_1 = 0;

}

else

{

ucShang_1 = (ucBeiChuShu_1) / (ucChuShu_1); /* find the quotient*/

ucYu_1 = (ucBeiChuShu_1) % (ucChuShu_1); /* find the remainder*/

}

}

 

/**

* @brief Method 2

* @param None

* @retval 

* The second method uses return to return parameters and functions with input parameters. This method already has complete input and output capabilities.

* This is much more intuitive than the first method. However, this method has its limitations, because return can only return one variable.

* If you want to use it in a function that returns multiple output results, you can't do anything. For example, this program cannot output

* The quotient and remainder can only be done in two functions. What if you want to output both the quotient and the remainder in one function?

* At this time, you must use pointers, which is the third method I will talk about below.

**/

unsigned char get_shang_2(unsigned char ucBeiChuShuTemp, unsigned char ucChuShuTemp)

{

unsigned char ucShangTemp;

if(ucChuShuTemp == 0) /* If the divisor is 0, the quotient is 0 */

{

ucShangTemp = 0;

}

else

{

ucShangTemp = (ucBeiChuShuTemp) / (ucChuShuTemp);

}

return ucShangTemp; /* Return the result of the operation*/

}

 

unsigned char get_yu_2(unsigned char ucBeiChuShuTemp, unsigned char ucChuShuTemp)

{

unsigned char ucYuTemp;

if(ucChuShuTemp == 0) /* If the divisor is 0, the remainder is 0 */

{

ucYuTemp = 0;

}

else

{

ucYuTemp = (ucBeiChuShuTemp) % (ucChuShuTemp);

}

return ucYuTemp; /* Return the remainder of the result after operation*/

}

 

/**

* @brief Method 3

* @param None

* @retval 

* The third method uses a function with a pointer, which allows you to output as many numbers as you want without being limited by the return.

* The calculation results are all OK, thumbs up! In this function, ucBeiChuShuTemp and ucChuShuTemp are input variables,

* They are not pointers, so they do not have output interface properties. *p_ucShangTemp and *p_ucYuTemp are output variables.

* Because they are pointers, they have output interface properties.

**/

void chu_fa_yun_suan_3(unsigned char ucBeiChuShuTemp, unsigned char ucChuShuTemp, unsigned char *p_ucShangTemp, unsigned char *p_ucYuTemp)

{

if(ucChuShuTemp == 0) /* If the divisor is 0, both the quotient and remainder are 0 */

{

*p_ucShangTemp = 0;

*p_ucYuTemp = 0;

}

else

{

*p_ucShangTemp = (ucBeiChuShuTemp) / (ucChuShuTemp);

*p_ucYuTemp = (ucBeiChuShuTemp) % (ucChuShuTemp);

}

}

 

/**

* @brief Serial port service program

* @param None

* @retval 

* The following function shows that multiple return statements can be inserted into an empty function.

* Using the return statement is very convenient for subsequent program upgrades and modifications.

**/

void usart_service(void)

{

// /*If there is no new data from the serial port after a certain period of time*/

// if(uiSendCnt >= const_receive_time && ucSendLock == 1)

// {

// The original statement is now replaced by two return statements

if(uiSendCnt < const_receive_time) /* If the delay has not exceeded the specified time, exit the program directly without executing any statements after return. */

{

return; /* Forcefully exit this subroutine and do not execute any of the following statements*/

}

if(ucSendLock == 0) /* If it is not the latest serial port data received, exit this program directly without executing any statements after return. */

[1] [2]
Keywords:Pointer Reference address:The first benefit of pointers is that a function can encapsulate multiple parameters equivalent to those returned by the return statement.

Previous article:The second biggest benefit of pointers is that pointers serve as input interfaces for arrays in functions.
Next article:51 MCU (using return) to determine the data header to receive

Latest Microcontroller Articles
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号