Analysis on the Structure of 51 Single Chip Microcomputer Development Comprehensive Experiment Program

One, the main program main.c

The MCU model used is: STC89C52RC (Package: LQFP-44)
According to convention, first look at the main function:

/*************************
实验:综合实验程序
*************************/

#include "main.h"

void main()
{
    
    
	EA = 1;           //开总中断
	BeepInit();  //蜂鸣器初始化为不叫的状态
	ConfigTimer0(1);  //定时器0初始化定时为1ms
 	ConfigTimer2(2);  //定时器2初始化定时为2ms
	int0_Init();  //外部中断0
	int1_Init();  //外部中断1
	ConfigUART(9600);  //配置波特率为9600
	Ds1302Init();  	//DS1302函数的初始化,写入初始时间,此代码可以注释掉,如果不注释掉则单片机每次启动就会对DS1302进行时间重置
	Ds1302ReadTime();  //读取DS1302的时间

  while(1)
	{
    
    
		KeyScan();  //按键扫描
		if(KeyFlag == 1) //如果有按键按下
		{
    
    
			if(KeyState == 1) DisplayData(); //在数码管按键移位缓存中对显示缓存数组进行移位
			DigDisplay();  //进行数码管动态扫描
		}
		else  //没有按键按下
		{
    
    
			DigDisplay();  //进行数码管动态扫描显示万年历
		}
	}
}

Combined with the above program, its structure in the main function is as follows:
Main function block diagram
that is, the program initializes various functions at the beginning, and then enters the while(1) endless loop, scans the matrix keys in the while(1) loop, and performs digital Tube dynamic scan display.
So, what do the sub-functions called in the main function do? Here we can follow the steps of the program, jump to the content of the sub-functions one by one, and check the functions of each sub-function. The specific operation steps are as follows :
1), compile the entire keil project, 0 error 0 warning
Insert picture description here
2), move the mouse to a certain sub-function, click the right mouse button, and then click Go To Definition Of "sub-function"
Insert picture description here

1、BeepInit()

You can see that the value in BeepInit() is to clear the variable beep

#include "beep.h"

void BeepInit()
{
    
    
	beep = 0;
}

For the variable beep, we use the same method to view the content of the beep.
Insert picture description here
We see that the variable beep only defines the pin P1.5 of the single-chip microcomputer.
That is to say, the buzzer initialization function is only the pin of the single-chip microcomputer controlling the buzzer Pull down operation, we combine the schematic diagram. The
Insert picture description here
buzzer is driven by the transistor Q8, and the P1.5 pin can control the on and off of the transistor.

2 、 ConfigTimer0 (1)

We also jump to ConfigTimer0(1)

/* 配置并启动T0,ms-T0定时时间 */
void ConfigTimer0(uint16 ms)
{
    
    
    uint32 tmp0;
    
    tmp0 = (SYS_MCLK*ms)/1000 ; //计算所需的计数值
    tmp0 = 65536 - tmp0;        //计算定时器重载值
    tmp0 = tmp0 + 33;           //补偿中断响应延时造成的误差   
    T0RH = (uint8)(tmp0>>8);   //定时器重载值拆分为高低字节
    T0RL = (uint8)tmp0;
    TMOD &= 0xF0;   //清零T0的控制位
    TMOD |= 0x01;   //配置T0为模式1
    TH0 = T0RH;     //加载T0重载值
    TL0 = T0RL;
    ET0 = 1;        //使能T0中断
    TR0 = 1;        //启动T0
}

Sub-function: ConfigTimer0(1) is mainly to initialize the timer 0 of 51 single-chip microcomputer. You don’t need to study the configuration process of each register in the function too deeply. There are many functions on the Internet like this kind of function, and there are also various registers in books. Introduction of functions. We pass the parameter ms to directly configure the timer timing when calling the function, that is to say, here we configure Timer0 with a unit timing time of 1ms, and every 1ms, the microcontroller will enter the interrupt service function of timer 0 and execute The content in the interrupt service function.
For other sub-functions in the main function, we can also use the same method to analyze them one by one, so I won't repeat them here.

3、Ds1302Init();

In the DS1302 initialization function, it is mainly to write data to the DS1302 related registers: TIME[n]

/*******************************************************************************
* 函 数 名         : Ds1302Init
* 函数功能		     : 初始化DS1302.
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/

void Ds1302Init()
{
    
    
	unsigned char n;
	Ds1302Write(0x8E,0X00);		 //禁止写保护,就是关闭写保护功能
	for (n=0; n<7; n++)//写入7个字节的时钟信号:分秒时日月周年
	{
    
    
		Ds1302Write(WRITE_RTC_ADDR[n],TIME[n]);	
	}
	Ds1302Write(0x8E,0x80);		 //打开写保护功能
}

We use Go To Definition Of "sub-function" to view the array TIME[n]

//---DS1302时钟初始化2020年12月30日星期三12点30分00秒。---//
//---存储顺序是秒分时日月周年,存储格式是用BCD码---//
unsigned char TIME[7] = {
    
    0x00,0x30, 0x12, 0x30, 0x12, 0x03, 0x20};
///秒///分时日月/周///年///

Here our code comments are also very clear. If this function is called in main.c, the time in DS1302 will be initialized to the time set in our TIME array every time the program is reset.
If a button battery is installed on the development board, we call Ds1302Init() when downloading the program for the first time, set the time in DS1302 to the current time, and then comment out the function Ds1302Init() in the main function. After the program is reset, the time in the DS1302 will not be initialized. At the same time, because we have a button battery to power the DS1302, even if the development board is powered off, the time in the DS1302 will continue to go, that is, the next time Turn on the development board, call Ds1302ReadTime(); in the main function, and read the time in DS1302 as the current accurate time.

Second, the use of internal resources of the microcontroller

Through the analysis of the main function just now, you can also see that the content of the main function is very concise, so how do we use the content of the introduction to develop complex functions on the board? Here we will use the internal resources of our microcontroller (Timer0, Timer1, Timer2, INT0, INT1), let's introduce what we have done using the internal resources of the microcontroller in our comprehensive experimental program.

1. Timer 0 (Timer0)

Regarding the work done by Timer0, we need to analyze the interrupt service function of Timer0. You can refer to the following flowchart.
Insert picture description here
Here we define independent timing parameters for each function, such as led_time, AD_time, mov_time, etc., When T0 is timed to 1ms, enter the interrupt service function, accumulate the timing parameters of each function separately, determine the value of the timing parameter through the if statement, and execute the corresponding action when the timing parameter is accumulated to our set value.

2. Timer 1 (Timer1)

It seems that there is no use of Timer1 related functions in the main function. In fact, the configuration of T1 is done in ConfigUART (9600). We configure T1 as the second working mode as a baud rate generator. To realize the serial communication function of the single-chip microcomputer, in the ConfigUART(9600) function, we set the serial communication baud rate to 9600. Here you can also modify it to other baud rates for use. Common baud rates are 4800, 9600, 115200 Wait, the higher the baud rate, the faster the communication speed, but the greater the probability of communication errors. This is mainly because we actually use the crystal oscillator of our single-chip microcomputer to calculate the baud rate through timer 1 as the timing. Basic clock, and when calculating the high baud rate, the crystal frequency (11.0592MHz) we used may not be able to accurately calculate this frequency, and there will be some errors. Within the allowable range of error, serial communication can still be completed. When the error is large, the communication baud rate will be inconsistent, and then the communication will go wrong.
Now that it is mentioned that Timer 1 is used as a baud rate generator to realize serial communication, then we will also analyze the serial communication content of our development board by the way. When the MCU serial port receives data, the program enters the serial port interrupt function. We can find this function in the usart.c file:

/****************************
*串口中断服务函数
****************************/
void InterruptUART() interrupt 4    //串口中断是中断4
{
    
    
	EA=0;
	if(RI)  //接收数据完成(RI)
	{
    
    
		INT_NUM++;
		dataRead[INT_NUM] = SBUF;
		UART_Explain();
		RI = 0; 
	}
	EA=1;
	TR2 = 1;       //启动T2
}


In the serial port interrupt service function, the main function called is UART_Explain(). This function parses the data received by the serial port. When the data is our target data, the corresponding action is executed.

3. Timer 2 (Timer2)

The microcontroller STC89C52RC we use has timer 2. Here we use timer 2 as the stepping state switching timing of the stepper motor, except for the initialization function ConfigTimer2(2) called in the main function (configuration T2 is 16 for heavy In addition to reprinting mode), we can also find the T2 interrupt service function in the timer2.c file. The content of the function is the configuration of the content related to the stepper motor.
Here, by the way, I will also explain about the wiring of the stepper motor. There is a red wire in the 4-phase 5-wire 5V stepper motor cable that we use. This red wire is connected to our VCC, which means that the red wire corresponds to the development. The pin of VCC on the board, and then insert the cable into the pin header.
Insert picture description here
In order to make the motor rotation obvious, you can paste a small piece of paper or wrap a piece of solder wire
Insert picture description here
on the motor shaft. For serial communication, you can refer to and use the serial port to program For download, please refer to https://blog.csdn.net/Stark_/article/details/111466231 In
serial communication, we can send: forward, reverse, acceleration, deceleration, stop and other commands to control the motor rotation.

4. External interrupt 0 (INT0) and external interrupt 1 (INT1)

In our exti.c file, we have configured the content of the external interrupt service function,

void led_water() interrupt 0 //每一个外部中断信号都会使得LED移位方向改变
{
    
    
	led_flag=~led_flag;
}

void beep_on() interrupt 2
{
    
    
		beep = 1;
}

The led_water() function is triggered by the external interrupt independent button on our development board. In addition to the matrix button, there are two independent buttons on our development board. One is the MCU reset button. The system restarts, one is the external interrupt trigger button, press it to trigger the change of the flow direction of the water lamp.
The beep_on() function is triggered by our infrared pair tube, which triggers the buzzer to sound by blocking the infrared pair tube.

Guess you like

Origin blog.csdn.net/Stark_/article/details/111794689