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. */
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
- Naxin Micro and Xinxian jointly launched the NS800RT series of real-time control MCUs
- How to learn embedded systems based on ARM platform
- Summary of jffs2_scan_eraseblock issues
- Application of SPCOMM Control in Serial Communication of Delphi7.0
- Using TComm component to realize serial communication in Delphi environment
- Bar chart code for embedded development practices
- Embedded Development Learning (10)
- Embedded Development Learning (8)
- Embedded Development Learning (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Intel promotes AI with multi-dimensional efforts in technology, application, and ecology
- ChinaJoy Qualcomm Snapdragon Theme Pavilion takes you to experience the new changes in digital entertainment in the 5G era
- Infineon's latest generation IGBT technology platform enables precise control of speed and position
- Two test methods for LED lighting life
- Don't Let Lightning Induced Surges Scare You
- Application of brushless motor controller ML4425/4426
- Easy identification of LED power supply quality
- World's first integrated photovoltaic solar system completed in Israel
- Sliding window mean filter for avr microcontroller AD conversion
- What does call mean in the detailed explanation of ABB robot programming instructions?
- STMicroelectronics discloses its 2027-2028 financial model and path to achieve its 2030 goals
- 2024 China Automotive Charging and Battery Swapping Ecosystem Conference held in Taiyuan
- State-owned enterprises team up to invest in solid-state battery giant
- The evolution of electronic and electrical architecture is accelerating
- The first! National Automotive Chip Quality Inspection Center established
- BYD releases self-developed automotive chip using 4nm process, with a running score of up to 1.15 million
- GEODNET launches GEO-PULSE, a car GPS navigation device
- Should Chinese car companies develop their own high-computing chips?
- Infineon and Siemens combine embedded automotive software platform with microcontrollers to provide the necessary functions for next-generation SDVs
- Continental launches invisible biometric sensor display to monitor passengers' vital signs
- STM32 pin short circuit to ground analysis
- [ART-Pi Review] 1: Demo Experience
- DSP core + coprocessor
- Fundamentals of Electronic Components and Practical Circuits (Revised Edition)
- Mastering Verilog HDL: Detailed Examples of IC Design Core Technologies.part01.rar
- PCI bus interface design based on FPGA.pdf
- Double gifts are waiting for you! In 2022, let Infineon understand you better!
- Tuya Smart Module SDK Development Course Series - 5. Secondary Development of Modules
- The following points should be noted when selecting semiconductor discharge tubes
- Development Trends of Main IPTV Technologies