Right-click up and back:
1. Writing in front
This is a template for MCU development. Here are some annotations and ideas. It is often used when developing, but I didn't understand it before. I learned after participating in the Blue Bridge Cup. If I have time and opportunity, I will combine these ideas of my predecessors and write a STM32 and embedded development template. This is very helpful for the project. Design and development.
Description: Applicable to STC15F2K60S2 MCU, other similar, only need to change the relevant timer settings, header file inclusion, etc., it is best to read this program on the basis of changes.
Note: Later, when I have time, I will sort out all the questions and answers of Blue Bridge Cup 51 MCU. Basically, they are all projects one by one, using this template. Thank you very much for your offer.
2. Source Program Analysis
This code actually has some details, I don't have detailed annotations, not to say that I don't want to make it, but because 51 MCU has different traditional and enhanced types, and the number of chips is relatively large, I think after finishing some commonly used 51 core chip development code, in the transmission, you can use it directly, I wish, one. Some of these STC15F2K60S2 have actually been tested. It can be used directly, no problem.
/* Author: An uncle in the group, add modifications and annotations to ABeiTian * Time: 27 August 2019 * Function: 51 MCU development template * Others: SCM STC15F2K60S2/IAP15, main frequency 12MHz, including matrix keyboard, digital tube and other IO */ #include "STC15F2K60S2.h" // Contains relevant header files #define u8 unsigned char // Macro definitions, unsigned char for simplicity and practicality #define NO_KEY 0xff // Macro defines some columns of data, no key press and three key states #define KEY_STATE0 0 #define KEY_STATE1 1 #define KEY_STATE2 2 // Digital tube display break code and digital tube read bit (because there are latches to control) u8 code smg_du[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x00}; u8 code smg_wei[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; // Matrix keyboard detection, using state machine instead of delay, will reduce the real-time performance of the system. unsigned char Key_Scan() { // Use static keywords to define local variables, make them static local variables, and make their life cycle longer. static unsigned char key_state = KEY_STATE0; u8 key_value = 0, key_temp; u8 key1, key2; // The following process belongs to the state machine detection process P30=0;P31=0;P32=0;P33=0;P34=1;P35=1;P42=1;P44=1; if(P44==0) key1=0x70; if(P42==0) key1=0xb0; if(P35==0) key1=0xd0; if(P34==0) key1=0xe0; if((P34==1)&&(P35==1)&&(P42==1)&&(P44==1)) key1=0xf0; P30=1;P31=1;P32=1;P33=1;P34=0;P35=0;P42=0;P44=0; if(P33==0) key2=0x07; if(P32==0) key2=0x0b; if(P31==0) key2=0x0d; if(P30==0) key2=0x0e; if((P33==1)&&(P32==1)&&(P31==1)&&(P30==1)) key1=0x0f; // Get the final key condition key_temp = key1 | key2; // Judgment of state switch(key_state) { case KEY_STATE0: if(key_temp != NO_KEY) { key_state = KEY_STATE1; } break; case KEY_STATE1: if(key_state == NO_KEY) { key_state = KEY_STATE0; } else { switch(key_temp) { case 0x77: key_value = 4;break; case 0x7b: key_value = 5;break; case 0x7d: key_value = 6;break; case 0x7e: key_value = 7;break; case 0xb7: key_value = 8;break; case 0xbb: key_value = 9;break; case 0xbd: key_value = 10;break; case 0xbe: key_value = 11;break; case 0xd7: key_value = 12;break; case 0xdb: key_value = 13;break; case 0xdd: key_value = 14;break; case 0xde: key_value = 15;break; case 0xe7: key_value = 16;break; case 0xeb: key_value = 17;break; case 0xed: key_value = 18;break; case 0xee: key_value = 19;break; } } break; case KEY_STATE2: if(key_temp == NO_KEY) { key_state = KEY_STATE0; } break; } return key_value; } // Initialization timer for subsequent interrupts, handling various functions in interrupts void Timer_Init(void) { AUXR |= 0x80; // 1T timer TMOD &= 0xF0; TL0 = 0xCD; TH0 = 0xD4; TF0 = 0; TR0 = 1; ET0 = 1; EA = 1; } bit key_flag; u8 test = 0; void main(void) { u8 key_val = NO_KEY; P2=0xa0;P0=0x00;P2=0x00; // Close buzzer Timer_Init(); // 1ms while(1) { if(key_flag) { key_flag = 0; key_val = Key_Scan(); switch(key_val) { case 4: test=1; break; case 5: test=1; break; case 6: test=1; break; case 7: test=1; break; case 8: test=2; break; case 9: test=2; break; case 10: test=2; break; case 11: test=2; break; case 12: test=3; break; case 13: test=3; break; case 14: test=3; break; case 15: test=3; break; case 16: test=4; break; case 17: test=4; break; case 18: test=4; break; case 19: test=4; break; } } } } // Interrupt Processing Procedure of Timer 0 void timer0() interrupt 1 using 1 { static int key_count=0, smg_count=0, i=0; key_count++;smg_count++; if(key_count==10) // 10ms interruption { key_count=0; key_flag=1; } if(smg_count==3) // 3ms interruption { smg_count=0; P2=0xc0;P0=0;P2=0; // Elimination of digital tube residual shadow P2=0xe0;P0=~smg_du[test];P2=0; P2=0xc0;P0=smg_wei[i];P2=0; i++; if(i==8) i=0; } }