51 MCU-Comprehensive Routine

Publisher:skyshoucangLatest update time:2021-08-20 Source: eefocus Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

1. Use of other buttons

We have previously used P2.3 to output a low level to make K1, K2, K3, and K4 independent buttons. If we want to use K13, K14, K15, and K16 as independent buttons, we only need to output a low level on P2.0. The following is a simplified schematic diagram

1.png

 

2. Beauty and men

As the last topic of this chapter, we will combine all the knowledge we have learned to make a comprehensive routine to implement the functional code of the game of beauties and men.


The rules of the game are as follows:

Beautiful woman and man each holding a coin

When both players show heads: the man gets 3 dollars

When both players show tails: the man gets 1 dollar

When two people play one head and one tail: the woman gets 2 yuan

 

3. Development board implementation

We simulate this way. At the beginning of the program, we define two global variables man and woman and initialize them to 30, which means that each person holds 30 yuan to be displayed on the two digital tubes on the left and right ends. The man's money is displayed on the left digital tube, and the woman's money is displayed on the right digital tube.

3.png

We use K13 as a function to add 3 yuan to men and reduce 3 yuan for women.

Use K14 to add 1 yuan to men and reduce 1 yuan for women.

Use K15 to reduce 2 yuan for men and add 2 yuan for women.

The three buttons do not support continuous pressing!

4.png

Our rule is that whoever reaches 45 yuan or more first wins!

For example, when the man's money reaches or exceeds 45 yuan, the woman's money will not be displayed, and the two digital tubes will go out. If the woman's money reaches or exceeds 45 yuan, the man's money will not be displayed. This is common sense to show that whoever's money is still displayed is the winner.


When the winner is decided, the game ends and the buzzer starts to sound at intervals. When it sounds, all the digital tubes are off. When it is not sounding, only 4 digital tubes are on. The digital tubes show intervals and the buzzer sounds at intervals. To restart the game, you must reset the development board and restart it!

 

4. Partial code rewriting

When initializing the LedBuff[] array, the second and third elements are 0xBF, so that digital tubes 2 and 3 display the middle bar.


The infinite loop of the main function of this example takes longer to complete one cycle than the previous examples, so we only need to judge the times to be greater than 300, instead of exceeding 500 as before to execute the function code.


Because three keys are used, the function of each key is encapsulated as a function, so we define a macro "#define TIMES 300". When the function of the three keys judges times, we only need to write "if(times>=TIMES&&KEYxx==1)". In the future, if the code we write in the infinite loop is longer than the execution time of this routine, we can change the macro to a number smaller than 300.


Also, if you loop "SEG_task();" alone, all digital tubes will be dimmed. This is because this function is executed in a loop like this.

First cycle

P0=0xFF;

ADDR2 = 0;ADDR1 = 0;ADDR0 = 0;P0=LedBuff[0];i++;


Second cycle


P0=0xFF;

ADDR2 = 0;ADDR1 = 0;ADDR0 = 1;P0=LedBuff[1];i++;



In each loop, "P0=LedBuff[x];" does not last long enough and "P0=0xFF;" must be executed again. Therefore, if the refresh rate of "P0=0xFF;" is too high, the brightness of the digital tube will dim. To solve this problem, "P0=LedBuff[x];" must last longer before executing "P0=0xFF;", so we use a short delay after "SEG_task();".


Why didn't this happen in the previous routine "SEG_task();"? If you go back and look, you will know that the previous "SEG_task();" also executed the following codes

LedBuff[0] = LedChar[cnt%10];   

if(cnt>=10) LedBuff[1]= LedChar[(cnt/10)%10];  

if(cnt>=100) LedBuff[2]= LedChar[(cnt/100)%10];

if(cnt==0){ LedBuff[1]=0xFF; LedBuff[2]=0XFF; }


The execution of these codes takes time, so "P0=LedBuff[x];" is kept lit for a while to avoid being refreshed by "P0=0xFF;" for a long time.


#include

sbit ADDR2 = P1^2;

sbit ADDR1 = P1^1;

sbit ADDR0 = P1^0;

sbit ENLED = P1^4;

sbit ADDR3 = P1^3;

  

sbit BEEP = P1^6;

sbit KEY13 = P2^4;

sbit KEY14 = P2^5;

sbit KEY15 = P2^6;

#define TIMES 300 //The main loop of this routine takes longer than the previous routines, so the times of the keystroke need to be reduced to 300. Otherwise, if it is still 500, we need to hold down the key for a while before the function code responds.

unsigned char code LedChar[16]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E}; // Initialize the status value of the digital tube

unsigned char LedBuff[6]={0xFF, 0xFF, 0xBF, 0xBF, 0xFF, 0xFF}; //Initialize the digital tube display buffer

unsigned char man=30,woman=30; //Initialize the money of man and woman

  

void UPDATE_LED() //Update the digital tube display buffer

{

    LedBuff[5]=LedChar[man/10]; 

    LedBuff[4]=LedChar[man%10]; 

    LedBuff[1]=LedChar[woman/10]; 

    LedBuff[0]=LedChar[woman%10];

}

  

void SEG_task()//digital tube display function

{

    static unsigned char i=0;

   

    P0=0xFF; // All port status are turned off, and the LED in the digital tube is refreshed

    switch(i)

    {

        case 0:

        ADDR2 = 0;ADDR1 = 0;ADDR0 = 0;P0=LedBuff[0];i++;break;

        case 1:

        ADDR2 = 0;ADDR1 = 0;ADDR0 = 1;P0=LedBuff[1];i++;break;     

        case 2:

        ADDR2 = 0;ADDR1 = 1;ADDR0 = 0;P0=LedBuff[2];i++;break;  

        case 3:

        ADDR2 = 0;ADDR1 = 1;ADDR0 = 1;P0=LedBuff[3];i++;break;

        case 4:

        ADDR2 = 1;ADDR1 = 0;ADDR0 = 0;P0=LedBuff[4];i++;break;     

        case 5:

        ADDR2 = 1;ADDR1 = 0;ADDR0 = 1;P0=LedBuff[5];i=0;break; 

    }  

}

  

void KEY13_task()

    static unsigned char key_up=1;

    static unsigned int times=0; //Used to record the number of times the key judgment statement has been entered 

    if(key_up==0)

    {      

        times++;     

        if(times>=TIMES&&KEY13==1)

        {

            times=0;

            man+=3; // man's money plus 3 yuan

            woman-=3; //Deduct 3 yuan from the woman's money

            UPDATE_LED(); //Update the digital tube display buffer

        }

    }

    key_up=KEY13;

}

  

void KEY14_task()

    static unsigned char key_up=1;

    static unsigned int times=0; //Used to record the number of times the key judgment statement has been entered 

    if(key_up==0)

    {      

        times++;     

        if(times>=TIMES&&KEY14==1)

        {

            times=0;

            man+=1; // man's money plus 1 yuan

            woman-=1; // woman's money minus 1 yuan

            UPDATE_LED(); //Update the digital tube display buffer

        }

    }

    key_up=KEY14;

}

  

void KEY15_task()

    static unsigned char key_up=1;

    static unsigned int times=0; //Used to record the number of times the key judgment statement has been entered 

    if(key_up==0)

    {      

        times++;     

        if(times>=TIMES&&KEY15==1)

        {

            times=0;

            man-=2; // man's money minus 2 yuan

            woman+=2; // woman's money plus 2 yuan

            UPDATE_LED(); //Update the digital tube display buffer

        }

    }

    key_up=KEY15;

}

  

void BEEP_ON(unsigned char x)

{

    unsigned int i,time;

    for(time=0;time<2000;time++)//“time<2000” determines the chirping time

    {  

        if(x==1)BEEP=!BEEP;

        else BEEP=0;

        for(i=0;i<30;i++);

    }

}

  

void main()

{  

    unsigned int i,x; //For loop and delay

    ADDR3 = 1; // Enable 38 decoder

    ENLED = 0; // 

   

    P2 = 0xFE; //Let K13, K14, K15 have the conditions to be pulled low first

    UPDATE_LED(); //Update the digital tube display buffer

    while(1)

    {        

        SEG_task(); //digital tube display function

        KEY13_task(); //The task of the K13 key

        KEY14_task(); //The task of the K14 key

        KEY15_task(); //The task of the K15 key

    

        if(man>=45 || woman>=45) //As long as one of the parties has 45 yuan or more, the game ends and the program enters an infinite loop

        {

            if(man>=45){LedBuff[1]=0xFF; LedBuff[0]=0xFF;}//No longer display the woman's money

            else {LedBuff[5]=0xFF; LedBuff[4]=0xFF;} //Do not display the man's money anymore  

            while(1)

            {

                P0=0xFF; //Turn off all digital tubes

                BEEP_ON(1); //The buzzer beeps for a while

                for(i=0;i<300;i++) //Let the digital tube display for a period of time

                {

                    SEG_task();

                    for(x=0;x<200;x++);//This delay is added to make the digital tube display brighter, otherwise if only "SEG_task();" is looped, the display will be darker

                }

            }  

        }

    }

}


"man+=3;" is the simplified form of "man= man+3;".


2. Testimonials


We are now doing modular programming. After understanding the title of the game "Beauty and Men", reading the main function is much clearer.


The requirements of this topic are just like those of the National Electronic Design Competition. We need to complete the functions of each module step by step, including future product projects. Modular programming is for flexible use and increased readability. When we encounter similar requirements in other projects in the future, we can just adopt them. It is also convenient to maintain, but everyone needs to get used to writing very detailed comments.


Based on the code in this lecture, you can actually simply rewrite it into a simple basketball scorer. If you can implement it yourself, you can use a development board to score when you play basketball in the future, and you can fool some students who don’t understand it into thinking it’s a very high-end thing.

Reference address:51 MCU-Comprehensive Routine

Previous article:51 MCU-dual mode function package
Next article:51 MCU-Multiple File Writing

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号