Notes of the 7th Blue Bridge Cup single chip microcomputer group national competition

Notes of the 7th Blue Bridge Cup single chip microcomputer group national competition:

After finishing this topic, I have a lot of feelings and some good ideas. I want to share them and consolidate them

1. Get rid of the dependence of flag bit:
Good programming I think is to use the most concise and clear program, "the nearest path" to realize a function. If there is a problem, I think this method is a little low. It has little effect on the improvement of thinking and programming ability. I must avoid this problem in future programming.
2. After writing the program, if you find that the phenomenon is wrong, you must summarize it. Why is it wrong? What is the reason why the effect didn't come out?
3. Manufacturing register, (this is my name) this routine is very, very, very practical.

Let's start the text:
Don't be frightened by the title. The title method is right this time. It is "Paper Tiger"
Although this session is simple, I feel it deeply, so I write a summary and record it.

1, Personal errors:

First of all, I just listed the wrong places in the experiment

1. '&' and '& &':
(corresponding to the above, one is' bit and 'and' logic and '). I didn't know what to think at that time. I felt logic and good-looking. Let's change the operation of the matrix keys to logic and look at the program;

#include "bsp_key.h"
unsigned char key_trigger()
	unsigned char number = 7;
	unsigned char temp;
	P44 = 0; P42 = 1;
	temp = P3;
	P42 = 0; P44 = 1;
	temp = (temp << 4) | (P3 & 0X0F);  //Here (P3 & 0x0f) I wrote (P3 & & 0x0f)
		case 0x80: number = 4; break;
		case 0x40: number = 5; break;
		case 0x20: number = 6; break;
		case 0x10: number = 7; break;

		case 0x08: number = 8; break;
		case 0x04: number = 9; break;
		case 0x02: number = 10; break;
		case 0x01: number = 11; break;	
		case 0x00: number = 0; break;
		default: number = 0; break;
	return number;

I have noted the above error points, and the reason for the error is very simple: (but the key part of my program is invalid)

Reason: (for the second column of keys)
When no key is pressed: the default I/O of the fourth bit of P3 is high level, and the logic and will be "true" in the future. As a result, the lower four digits of temp will always be '0001', and the upper four digits will not be affected. However, after entering the switch for matching, xxx0001 becomes xxxx1110, that is, 0X 'X' E. obviously, there will be no matching key, so no matter which key is pressed, it only corresponds to entering the default command.

When a key is pressed:
When less than 4 keys are pressed, the lower four bits of P3 will be made, and at least one I/O port is high, which also ensures the logic 'true'
When the second column is pressed down, P3 is low, and all four I/O ports are '0', which leads to logical 'false', but after negation, it is 1111, and there is no corresponding case.

2. Forced conversion:
This part is ambiguous.

sprintf(seg_buf,"-2-%05u",(unsigned int)(100000 / read_555_number));

Here is to print the string to SEG with sprintf_ BUF.
Some say that placeholders are integers. If they represent floating-point numbers, the floating-point numbers will be cast.
But I have proved through experiments that forced conversion is needed. After all, forced conversion is more reliable. Even if you don't bring it, there will be no problem.
(if no phenomenon is added, the display data becomes garbled)
3. Carelessness

	temp = (((timer_init[0] / 10) << 4) | (timer_init[0] % 10));
	temp = (((timer_init[1] / 10) << 4) | (timer_init[1] % 10));
	temp = (((timer_init[2] / 10) << 4) | (timer_init[2] % 10));

In DS1302, I even wrote% as * resulting in an error in the initial writing time.
Timer 0 reads the frequency. I even use timer 1 to read it. I'm also drunk.

2, Advantages:

1 . Manufacturing register
(this advantage is reflected incisively and vividly in this routine, which is not only convenient to review errors, but also has a clear idea.)

unsigned char running_mode = 0x00;
frequencyFrequency period
Voltage parametersUpper voltage thresholdLower voltage threshold
timeHour settingMinute settingSecond setting
Type of last voltage fluctuationLast voltage fluctuation time

(define a register as above, and store the corresponding values in different situations. When we need to deal with different situations, we only need to judge this one flag bit. It saves a lot of flag bits and has a clear idea.)
Here are some examples to illustrate the benefits:

void key_pricedure()
	case 7: //time
		if(running_mode & 0x40)  
			running_mode = 0x40;
		else running_mode = 0x40; //Enter else statement to make
	case 4: //function
		switch(running_mode & 0xf0)
			case 0x40:  //time
				if(++running_mode == 0x44) running_mode = 0x41;	
void seg_pricedure()
		case 0x40:
			sprintf(seg_buf,"%2d-%2d-%2d",(unsigned int)user_timer[0],(unsigned int)user_timer[1],(unsigned int)user_timer[2]);
		case 0x41:
		case 0x42:
		case 0x43:
			sprintf(seg_buf,"%2d-%2d-%2d",(unsigned int)user_timer[0],(unsigned int)user_timer[1],(unsigned int)user_timer[2]);			

(press S7 for the first time to enter the time display interface)
When pressing S7 for the first time, because the register is initialized with 0x00, it is 0 in the if bracket, (0 & any number = 0), so it does not enter the if statement. After entering else, make the register system bit ox40 corresponding to our advance configuration. It can be seen that the program enters the time display interface and judges our register in the display processing function, It is found that the register becomes 0x40, corresponding to the time to start reading DS1302_ Timer [] in the array and starts to display the contents of the array, that is, the current time.

(press S4 to enter the time setting interface)
After we press S4, the switch statement judges the high four bits of our register. (careful students will find that the high four bits of our register store the mode and the low four bits store the state in this mode.) Due to running_ Mode & 0xf0 means that we only judge the high four bits, and the low four bits do not consider their values. We change the state according to our mode. According to our configuration of the register, if we keep pressing S4, we will be in the state of hour, minute and second set by time, and change it through the addition and subtraction keys.
Speaking of this, there is a question here. I wonder if you have taken it into account?
If the time keeps going, it's not very uncomfortable to set, so we can't let the time go when setting.
The implementation method is to make it read the time into the array only in the time display interface (i.e. 0x40), and other setting states (0x41,0x42...) do not read the time, which has the effect of time pause.

(when the title requires that S7 is pressed again, it indicates that the time setting is successful.)
When we press S7 again, judge running_ Whether mode & 0x40 is true. If we don't press other mode keys, the upper four bits of our register are still 0x40, so if it is 1 in parentheses (any number & itself = any number), it means that we pressed S7 for the second time. According to the requirements of the topic, we need to re assign DS1302 to the parameters after we changed the edge, and enter the time display interface at the same time.
Here is also a point to consider!
What is the effect of pressing other mode keys at the set time?
I'll just talk about the conclusion and principle here. You can know why if you think about it.
The answer is:
Enter other states, but the next time you press the time display interface, it is still adding according to the time before the setting.

What about one, two, three?
If you understand this technique, you don't have to worry about it.

2 . Decrease flag bit
I will also reduce the use of marker bits in the future, which is really helpful to improve my personal thinking.
(compared with the sign position, I heard someone say "what to do if there is a problem? If one sign position is not enough, come ten" two days ago. It's really about the pain point, so it has to be changed)
After reading what I wrote here and 1s flashing, I'll say goodbye to what I wrote before!

void timer1() interrupt 3
if((dida_number - seg_delay) > 1000)
		case 0x41:
			seg_buf[0] = ' '; seg_buf[1] = ' ';
		case 0x42:
			seg_buf[3] = ' '; seg_buf[4] = ' ';
		case 0x43:
			seg_buf[6] = ' '; seg_buf[7] = ' ';
		case 0x21:
			seg_buf[0] = ' '; seg_buf[1] = ' '; seg_buf[2] = ' '; seg_buf[3] = ' ';
		case 0x22:
			seg_buf[4] = ' '; seg_buf[5] = ' '; seg_buf[6] = ' '; seg_buf[7] = ' ';
	if((dida_number - seg_delay) > 2000) 
	seg_delay = dida_number;

This principle is too simple for me to introduce.
Let's think about it. If you can use it, you will know the power of this!

The boss has good suggestions on my program. Please leave a message! thank!!!
if (put forward reasonable suggestions for program improvement)
If necessary, you can send me the calendar program written by me. Although it's not very good, I hope it will help you!
There are also some learning materials.
I need to write a private chat about all the procedures of the national and provincial competitions over the years, but it may be paid! But after sales.

(at present, the national competition has written 6 sessions, and the provincial competition has written 11 sessions + 1 light and temperature detection of little bee teacher)

But you can have a private chat if you have a problem. Although I'm also a little white, I'll try my best to solve it!

Keywords: Single-Chip Microcomputer

Added by paragkalra on Thu, 17 Feb 2022 19:40:29 +0200