Comprehensive Guide to 400 Examples of Microcontroller Programming (1-100)

Follow the blue words to get the “Entry Materials” for the complete tutorial from beginner to advanced on microcontrollers

The development board will guide you in, and we will help you soar

Written by | Wu Ji (WeChat: 2777492857)

The full text is about1582 words, reading takes about 5 minutes

Recently, some beginners have consulted me about implementing a certain function, but they have no ideas and don’t know where to start. What should they do?
Usually too busy to answer one by one, today I’m writing this article to address it.
This is a stage everyone must go through; there’s no need to blame or feel anxious.
How did I solve this problem?
By referencing more, practicing more, and then when encountering similar functions, you can apply what you’ve learned to new situations. It’s a clumsy method of gaining experience over time, without any fancy operations.
However, growth efficiency is something you can control; the more you practice and experience in the same amount of time, the faster you will grow compared to others.
Without references, creating from scratch is too difficult for someone inexperienced.
Therefore, I have compiled 100 examples of microcontroller programming, covering many small functions, with detailed comments, making it very suitable for beginners to reference. Utilizing these reference codes, you can work on your own projects and achieve twice the result with half the effort.
Due to space limitations, I will share 100 examples today. Those learning microcontrollers can contact me for arrangements.
Comprehensive Guide to 400 Examples of Microcontroller Programming (1-100)
Here are a few example codes:
1. LED Circular Left Shift Routine:
#include<reg52.h> // Include header file, generally no need to modify, the header file includes definitions of special function registers

void Delay(unsigned int t); // Function declaration
/*------------------------------------------------                    Main Function------------------------------------------------*/
void main (void){                  unsigned char i;  // Define a local unsigned char variable i, range 0~255
Delay(50000);P1=0xfe;           // Assign initial value
while (1)         // Main loop  {
for(i=0;i<8;i++)   // Add for loop, indicating that the program in the for loop executes 8 times  {
Delay(50000);   P1<<=1;   P1=P1|0x01;     // After left shifting, the rightmost bit automatically assigns 0, so this statement assigns 1  }
P1=0xfe;           // Reassign initial value  // Add other programs that need to run continuously in the main loop  }}/*------------------------------------------------ Delay function, with input parameter unsigned int t, no return value unsigned int defines an unsigned integer variable with a range of 0~65535------------------------------------------------*/
void Delay(unsigned int t){ while(--t);}
The main purpose of this code is to control the flashing of the LED light through the P1 register by left shifting the value of P1 and keeping the lowest bit as 1 to achieve the effect of lighting the LED sequentially. The Delay function is used to create a delay between LED flashes so that the changes can be observed by the human eye.
2. Digital Tube Blanking
// Multi-digit digital tubes display different numbers separately, this scanning display method is called dynamic scanning, and it keeps changing the assigned values
// When the high bit value is 0, that bit is not displayed, i.e., blanked out, such as the number 0010, actually displayed as 10, the first two bits are not displayed------------------------------------------------*/
#include<reg52.h> // Include header file, generally no need to modify, the header file includes definitions of special function registers
#define DataPort P0 // Define data port, replace DataPort with P0 in the program
sbit LATCH1=P2^2;// Define latch enable port for segment latch
sbit LATCH2=P2^3;//                 Bit latch
unsigned char code dofly_DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// Display segment code values 0~9
unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};// Corresponding to the respective digital tube lighting up, i.e., position code
unsigned char TempData[8]; // Global variable to store display values
void Delay(unsigned int t); // Function declaration
void Display(unsigned char FirstBit,unsigned char Num);
/*------------------------------------------------                    Main Function------------------------------------------------*/
main(){ unsigned int num; unsigned int j; while(1)      {           j++;           if(j==10)  // After detecting that the current value has been displayed for a short time, the value to be displayed increases by 1, achieving a change in displayed value             {                  j=0;                  num++;                  if(num==10000)// To display 0~9999                    num=0;                 }       if(num<1000)    // If less than 1000, the thousand's place is not displayed             TempData[0]=0;           else             TempData[0]=dofly_DuanMa[num/1000];// Decompose display information, e.g., to display 68, then 68/10=6  68%10=8             if(num<100)    // If less than 100, the thousand's and hundred's places are not displayed             TempData[1]=0;           else             TempData[1]=dofly_DuanMa[(num%1000)/100];           if(num<10)   // If less than 10, then the thousand's, hundred's, and ten's places are not displayed             TempData[2]=0;           else             TempData[2]=dofly_DuanMa[((num%1000)%100)/10];           TempData[3]=dofly_DuanMa[((num%1000)%100)%10];           Display(2,4);      }}/*------------------------------------------------ Delay function, with input parameter unsigned int t, no return value unsigned int defines an unsigned integer variable with a range of 0~65535------------------------------------------------*/
void Delay(unsigned int t){ while(--t);}/*------------------------------------------------ Display function, used for dynamic scanning of digital tubes. Input parameter FirstBit indicates the first bit to be displayed, e.g., assigning a value of 2 indicates starting from the third digital tube. Num indicates the number of bits to be displayed, e.g., if 99 two-digit values need to be displayed, this value is input as 2------------------------------------------------*/
void Display(unsigned char FirstBit,unsigned char Num){    unsigned char i;        for(i=0;i<Num;i++)    {         DataPort=0;   // Clear data to prevent flickering        LATCH1=1;     // Segment latch        LATCH1=0;                DataPort=dofly_WeiMa[i+FirstBit]; // Get position code         LATCH2=1;     // Bit latch        LATCH2=0;                DataPort=TempData[i]; // Get display data, segment code        LATCH1=1;     // Segment latch        LATCH1=0;                Delay(200); // Scan gap delay, too long will flicker, too short will cause ghosting            }
}
/*------------------------------------------------                    Timer initialization subroutine------------------------------------------------*/
void Init_Timer0(void){ TMOD |= 0x01;          // Use mode 1, 16-bit timer, using "|" symbol will not be affected when using multiple timers                      //TH0=0x00;              // Give initial value //TL0=0x00; EA=1;            // Enable global interrupt ET0=1;           // Enable timer interrupt TR0=1;           // Open timer switch}
/*------------------------------------------------                 Timer interrupt subroutine------------------------------------------------*/
void Timer0_isr(void) interrupt 1 { static unsigned char count; TH0=(65536-2000)/256;                  // Reassign value 2ms TL0=(65536-2000)%256;  Display(0,8);                // Call digital tube scanning if (count==PWM_ON)     {     DCOUT = 0;               // If the time equals the on time,                         // indicate that the action time is over, output low level    }  count++;if(count == CYCLE)       // Conversely, after the low level time ends, return to high level    {    count=0;        if(PWM_ON!=0)    // If on time is 0, maintain the original state           DCOUT = 1;      }
}
/*------------------------------------------------Key scanning function, returns scanned key value------------------------------------------------*/
unsigned char KeyScan(void){ unsigned char keyvalue; if(KeyPort!=0xff)   {    DelayMs(10);    if(KeyPort!=0xff)           {            keyvalue=KeyPort;            while(KeyPort!=0xff);                switch(keyvalue)                {                 case 0xfe:return 1;break;                 case 0xfd:return 2;break;                 case 0xfb:return 3;break;                 case 0xf7:return 4;break;                 case 0xef:return 5;break;                 case 0xdf:return 6;break;                 case 0xbf:return 7;break;                 case 0x7f:return 8;break;                 default:return 0;break;                }          }   }   return 0;}
This code is a digital tube display program for the 8051 microcontroller. It uses dynamic scanning to display numbers from 0 to 9999 sequentially on a 4-digit digital tube, then loops.
3. Independent Key Control of DC Motor Speed
/*-----------------------------------------------  The corresponding motor interface needs to be connected to the uln2003 motor control end using Dupont wires.  Small power motors of 5V-12V can be used.  Two buttons are used for acceleration and deceleration respectively------------------------------------------------*/
#include<reg52.h> // Include header file, generally no need to modify, the header file includes definitions of special function registers
#define KeyPort P3
#define DataPort P0 // Define data port, replace DataPort with P0 in the program
sbit LATCH1=P2^2;// Define latch enable port for segment latch
sbit LATCH2=P2^3;//                 Bit latch
sbit DCOUT = P1^1;// Define motor signal output port/*------------------------------------------------                  Global variables------------------------------------------------*/
unsigned char PWM_ON;   // Define speed level
#define CYCLE 10        // Cycle
unsigned char code dofly_DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// Display segment code values 0~9
unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};// Corresponding to the respective digital tube lighting up, i.e., position code
unsigned char TempData[8]; // Global variable to store display values
/*------------------------------------------------                  Function declarations------------------------------------------------*/
void DelayUs2x(unsigned char t);// us-level delay function declaration void DelayMs(unsigned char t); // ms-level delay void Display(unsigned char FirstBit,unsigned char Num);// Digital tube display function unsigned char KeyScan(void);// Key scanning void Init_Timer0(void);// Timer initialization/*------------------------------------------------                    Main Function------------------------------------------------*/
void main (void){unsigned char num;                  PWM_ON=0;Init_Timer0();    // Initialize timer 0, mainly for dynamic scanning of digital tube
TempData[0]=0x5E; //'d'TempData[1]=0x39; //'C'
while (1)         // Main loop  {
num=KeyScan();    // Continuously call key scan   if(num==1)// First key, increase speed level      {           if(PWM_ON<CYCLE)           PWM_ON++;          }           else if(num==2)// Second key, decrease speed level      {           if(PWM_ON>0)           PWM_ON--;          }          TempData[5]=dofly_DuanMa[PWM_ON/10]; // Display speed level  TempData[6]=dofly_DuanMa[PWM_ON%10];            }}/*------------------------------------------------ uS delay function, with input parameter unsigned char t, no return value unsigned char defines an unsigned character variable with a range of 0~255. For precise delay, please use assembly, the approximate delay length is as follows T=tx2+5 uS ------------------------------------------------*/
void DelayUs2x(unsigned char t){    while(--t);}/*------------------------------------------------ mS delay function, with input parameter unsigned char t, no return value unsigned char defines an unsigned character variable with a range of 0~255. For precise delay, please use assembly------------------------------------------------*/
void DelayMs(unsigned char t){      while(t--) {     // Approximate delay 1mS     DelayUs2x(245);         DelayUs2x(245); }}/*------------------------------------------------ Display function, used for dynamic scanning of digital tubes. Input parameter FirstBit indicates the first bit to be displayed, e.g., assigning a value of 2 indicates starting from the third digital tube. Num indicates the number of bits to be displayed, e.g., if 99 two-digit values need to be displayed, this value is input as 2------------------------------------------------*/
void Display(unsigned char FirstBit,unsigned char Num){      static unsigned char i=0;          DataPort=0;   // Clear data to prevent flickering       LATCH1=1;     // Segment latch       LATCH1=0;
       DataPort=dofly_WeiMa[i+FirstBit]; // Get position code        LATCH2=1;     // Bit latch       LATCH2=0;
       DataPort=TempData[i]; // Get display data, segment code       LATCH1=1;     // Segment latch       LATCH1=0;                  i++;       if(i==Num)              i=0;
}
/*------------------------------------------------                    Timer initialization subroutine------------------------------------------------*/
void Init_Timer0(void){ TMOD |= 0x01;          // Use mode 1, 16-bit timer, using "|" symbol will not be affected when using multiple timers                      //TH0=0x00;              // Give initial value //TL0=0x00; EA=1;            // Enable global interrupt ET0=1;           // Enable timer interrupt TR0=1;           // Open timer switch}
/*------------------------------------------------                 Timer interrupt subroutine------------------------------------------------*/
void Timer0_isr(void) interrupt 1 { static unsigned char count; TH0=(65536-2000)/256;                  // Reassign value 2ms TL0=(65536-2000)%256;  Display(0,8);                // Call digital tube scanning if (count==PWM_ON)     {     DCOUT = 0;               // If the time equals the on time,                         // indicate that the action time is over, output low level    }  count++;if(count == CYCLE)       // Conversely, after the low level time ends, return to high level    {    count=0;        if(PWM_ON!=0)    // If on time is 0, maintain the original state           DCOUT = 1;      } }
/*------------------------------------------------Key scanning function, returns scanned key value------------------------------------------------*/
unsigned char KeyScan(void){ unsigned char keyvalue; if(KeyPort!=0xff)   {    DelayMs(10);    if(KeyPort!=0xff)           {            keyvalue=KeyPort;            while(KeyPort!=0xff);                switch(keyvalue)                {                 case 0xfe:return 1;break;                 case 0xfd:return 2;break;                 case 0xfb:return 3;break;                 case 0xf7:return 4;break;                 case 0xef:return 5;break;                 case 0xdf:return 6;break;                 case 0xbf:return 7;break;                 case 0x7f:return 8;break;                 default:return 0;break;                }          }   }   return 0;}
The entire program workflow is: through key input (two keys are defined in the program, used for acceleration and deceleration respectively) to change the PWM duty cycle of the motor, thereby controlling the speed of the motor. Meanwhile, using the timer interrupt service program to implement dynamic display on the digital tube and control the motor PWM.
The program reads key input through the KeyScan function and displays the current PWM duty cycle, i.e., the speed level of the motor on the digital tube.
The motor interface is connected to the ULN2003 motor driver via Dupont wires, and small power motors from 5V to 12V can be used.
These examples are just to provide everyone with a reference and thought process, achieving a reciprocal effect; some codes may not be suitable for actual products.
It’s not easy to organize, so be a cultured observer and give a three-way arrangement!

end

Comprehensive Guide to 400 Examples of Microcontroller Programming (1-100)

Here are more of Wu Ji’s original‘s personal growth experiences, industry experiences, and technical dry goods.

1.What is the growth path of an electronic engineer? 10 years 5000-word summary

2.How to quickly understand others’ code and thinking

3.How to manage too many global variables in microcontroller development projects?

4.Why is C language development for microcontrollers mostly done using global variables??

5.How to achieve modular programming in microcontrollers? The practicality is astonishing!

6.Detailed explanation of the use and actual function of callback functions in C language

7.Step-by-step guide to implementing queue code in C language, easy to understand and super detailed!

8.Detailed explanation of the usage of pointers in C language, easy to understand and super detailed!

Leave a Comment

×