Some development skills of single chip microcomputer

Publisher:TapirLatest update time:2014-02-21 Source: elecfansKeywords:MCU Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

  Many friends are learning MCU development technology, but they will inevitably encounter various problems during development. Some problems may not affect the overall situation, but some problems directly affect the cost, size and performance of the product. Here are a few tips from the author, hoping to help everyone's work.

  1. Embedding assembly language in C language

  In the development of single-chip microcomputers, we usually use C language to write the main program, so that we can make full use of the calculation library functions and powerful data processing capabilities provided by C language tools. However, the controllability of C language is not as good as that of assembly language. In some processing with strict timing requirements, we still need to use more flexible assembly language to write. Shanghai AVR single-chip microcomputer training This leads to the problem of mixed programming of C language and assembly language, which is generally divided into three ways: 1. Assembly language calls C language function; 2. C language calls assembly language; 3. Assembly language is embedded in C language. Here we mainly introduce the third method, that is, assembly language is embedded in C language.

  The following program is the main program calling the precise 205μS delay subroutine and making P1.0 output high and low level square waves alternately.

  /*------------Program name test.c------------*/

  #include P crystal frequency 12.000MHz《》

  /****************/

  void delay(void) //delay 205μS

  {

  #pragma asm

  MOV R0, #100

  LOOP:

  DJNZ R0, LOOP

  #pragma endasm

  }

  /***************/

  void main (void) //Main function, which makes P1.0 output high and low level square waves alternately

  {

  while(1)

  {P1_0=!P1_0;

  delay();}

  }

  The specific implementation process is:

  1. First, compile a delay program in assembly language, compile it in the Keil development environment, and then perform software simulation. The crystal frequency setting should be consistent with your requirements. During simulation, pay attention to the time display in the register window on the left, and adjust the parameters of the delay program to get the precise delay we need.

  2. Use C51 to write the shell of the main program and the delay subroutine (waiting to embed assembly language), assuming that the name of this program is test.c.

  3. Put the assembly delay subroutine obtained in step 1 into the delay subroutine shell written in C51. Note that #pragma asm and #pragma endasm statements are added at the beginning and end respectively. This method tells the C51 compiler through asm and endasm that the intermediate lines do not need to be compiled into assembly lines.

  4. According to the instructions of Keil, create project files and add source programs.

  5. Click the C source program containing the assembler and right-click. Select Options for File 'test.c' in the pop-up drop-down menu (Figure 1). The interface shown in Figure 2 will appear. Check Generate Assembler SRC File and Assembler SRC File to make them effective.

  6. Load the package library file according to the compilation mode of the project, usually C51S.LIB in Small mode (the file is in C:\\Keil\\C51\\Lib\\C51S.LIB), as shown in Figure 3.

  7. Click Rebuild target (Rebuild all target files) to get the compilation results (Figure 4).

   ed22.jpg

  Figure 1

  ed23.jpg

  Figure 2

  ed24.jpg

  Figure 3

  ed25.jpg

  Figure 4

  2. Extending external interrupts using software

  As we all know, the 51 MCU has only two external interrupts. The book once introduced a method to expand the external interrupt source, but it requires additional hardware overhead (see Figure 5). The external interrupt source input (/INT0 or /INT1) is introduced through the NOR gate and connected to a certain I/0 port. In this way, each "source" may cause an interrupt. In the interrupt service program, the software query can determine which interrupt source is being requested. The query order is determined by the interrupt source priority, which can achieve the expansion of multiple external interrupt sources.

  ed26.jpg

  Figure 5[page]

  Although this method expands the external interrupt source, it also has some unsatisfactory aspects. For example, to design a circuit with 8 interrupt sources, an 8-input NOR gate (OR gate) is required, which is obviously not conducive to volume and cost. Here we introduce the method designed by the author to expand the external interrupt source, which is implemented by pure software without adding any components (see Figure 6).

  ed27.jpg

  Figure 6

  #include 《 P》

  static unsigned char data m; //m is a global variable

  /*-------Delay subroutine-------*/

  void delay(unsigned int k)

  {

  unsigned int i, j;

  for(i=0;i

  for (j=0;j<121;j++)

  {;}}

  }

  /*---External interrupt INT0 subroutine---*/

  void init0()interrupt 0

  {

  delay(10); //Delay 10mS to resist jitter interference

  if (P3_2 == 0)

  {

  EX0=0; //Disable INT0 interrupt

  EA=0; // turn off the general interrupt

  P3_2=0; //Set P3.2 to low level

  P2=0xff; //Set P2 port to all 1s

  m=P2; //Read the status of P2 port to m

  P2=0x00; //Restore P2 port to all 0

  P3_2=1; //Set P3.2 to high level

  IT0=1; //Set INT0 to edge trigger

  EX0=1; //Open INT0 interrupt

  EA=1;} //Open the general interrupt

  }

  /********Main program************/

  void main(void)

  {

  P2=0x00; // Set P2 port to all 0

  P3_2=1; // Set P3.2 to high level

  IT0=1; // Set INT0 to edge trigger

  EX0=1; // Enable INT0 interrupt

  EA=1; //Open the general interrupt

  while(1) // infinite loop

  {

  P0=m; // Output the content of global variable m to port P0

  P3_0=! P3_0; //P3.0 is inverted to indicate the program status

  delay(500); //delay 500mS

  }

  }

  Program explanation: When no button is pressed, the light-emitting diode of P3.0 flashes to display the program status. When the main program is initialized, set P2 port to all 0, set P3.2 to high level, set INT0 to edge trigger, and open interrupt. When any of the 8 buttons is pressed, it will cause INT0 interrupt. After entering the interrupt service subroutine, first turn off the interrupt, then set P3.2 to low level, set P2 port to all 1, and then read the status of P2 port to m. By querying the status word of m, you can know the interrupt source being applied. The method we use here is to output m to P0 port to light up the LED for indication. When exiting the interrupt, reopen the interrupt.

  3. Generation of library functions

  When you provide your own program to others but it is inconvenient to disclose the source code, making the source code into a library function is a feasible way to protect your intellectual property rights and interests. Here we introduce the method of generating library functions and their use.

  /*------------Program name test1.c------------*/

  void delay(unsigned int k)

  {

  unsigned int i, j;

  for(i=0;i

  for (j=0;j<121;j++)

  {;}}

  }

  1. According to the instructions for using Keil, create the project file test1.uv2 and add the source program test1.c above.

  2. Click the project, click Options for Target 'Target 1' in the pop-up drop-down menu, and in the Output page, select "Create Library:" and compile, and a "Lib" file with the same name as the project will be generated in the specified path (Figure 1). It should be noted that the storage mode (Large or Small) should be the same as the system setting used.

  ed28.jpg

  Figure 1

  3. Create another project file test2.uv2.

  /*------------Program name test2.c------------*/

  #include P crystal frequency 12.000MHz《》

  /****************/

  extern void delay(void);

  void main (void) //Main function, which makes P1.0 output high and low level square waves alternately

  {

  while(1)

  {P1_0=!P1_0;

  delay();}

  }

  4. Add test2.c containing the main program and test1.LIB just generated to the project (Figure 2). In the Output page, check Create hex file.

   ed29.jpg

  Figure 2

  5. Click Rebuild target to get the compilation result (Figure 3).

  ed30.jpg

  Figure 3

[page]

  4. Modify the Startup.a51 start code

  The microcontroller is inevitably disturbed during operation, which may sometimes cause a crash. We can use the "watchdog" to reset and restart the microcontroller. According to the author's experience, the data in the memory area may not be completely destroyed at this time, mainly because the PC pointer is confused. Shanghai Analog Circuit/Digital Circuit Training However, the program written in C51 will execute a section of Startup.a51 "starting code" after reset, causing all memory to be cleared and all running data to be lost. The solution to this problem is to modify the Startup.a51 "starting code". This January's article "Talking about the Application of C Language in Microcontroller Development" also talked about this issue, but many readers don't know how to do it in the Keil integrated development environment? Here we will explain it in detail through an experimental program. The experiment uses the S2 test board of the lecture "Teaching You to Learn Microcontrollers Step by Step" (the circuit principle of the S2 board can be found in the February 2003 issue of "Electronic Production").

  /*------------Program nametest3.c------------*/

  #include P crystal frequency 11.0592MHz《》

  #define uchar unsigned char

  #define uint unsigned int

  uchar code DATA_7SEG[10]={0xC0,0xF9,0xA4,0xB0,0x99,//0~9 digital tube font code

  0x92, 0x82, 0xF8, 0x80, 0x90};

  uchar data counter1, counter2; //define two software counters

  void delay(uint k) //delay subroutine

  {

  uint i, j;

  for(i=0;i

  for (j=0;j<121;j++)

  {;}}

  }

  void main(void) //Main program

  { delay(1); //delay 1mS

  while(1) // infinite loop

  {

  if (counter1==counter2) // if the two count values ​​are equal

  {P0= DATA_7SEG[counter1]; //output to P0 port for display

  delay(500); //delay 500mS

  counter1++;counter2++;//count value increases

  if (counter1 >= 10) { counter1 = 0; counter2 = 0; } // count value loops from 0 to 9

  }

  else

  { counter1=0xff; counter2=0xff; // otherwise the count value is set to 0xff

  //…………Error handling

  }

  }

  }

  1. According to the instructions for using Keil, create the project file test3.uv2 and add the source program test3.c above. In the Output page, check Create hex file.

  2. Click Rebuild target (Rebuild all target files) to get the compilation results.

  3. After the compilation is successful, burn the generated test3.hex file into the single-chip microcomputer 89C51, insert the 89C51 chip into the S2 test board, and after power on, the digital tube on the right starts to display from 0 to 9 in a cycle. When a certain number (such as 5) is displayed, press the RESET key, and the digital tube on the right starts to display from 0 to 9 in a cycle again. This is because when the power is reset (hot start), C51 executes a "starting code" to clear all 128 units of the memory, resulting in the loss of the count value (such as 5).

  The steps to solve this are as follows:

  4. Click "File", select "Open" in the drop-down menu, select C:KeilC51LibStartup.a51 in the pop-up search path and open it. You can see the following code:

  …………………………………………………………………………………………………………

  …………………………………………………………………………………………………………

  IDATALEN EQU 80H ; the length of IDATA memory in bytes.

  ;

  XDATASTART EQU 0H ; the absolute start-address of XDATA memory

  XDATALEN EQU 0H ; the length of XDATA memory in bytes.

  ;

  PDATASTART EQU 0H ; the absolute start-address of PDATA memory

  PDATALEN EQU 0H ; the length of PDATA memory in bytes.

  …………………………………………………………………………………………………………

  …………………………………………………………………………………………………………

  We change IDATALEN EQU 80H; the length of IDATA memory in bytes. to IDATALEN EQU 00H; the length of IDATA memory in bytes. Then save and close.

  5. Add Startup.a51 to the test3.uv2 project (Figure 4).

  201102141209496013.jpg

  Figure 4

  6. Click Rebuild target to get the compilation results.

  7. Burn the generated test3.hex file into the 89C51 microcontroller, insert the 89C51 chip into the S2 test board, and after power on, the digital tube on the right starts to display cyclically from 0 to 9. When it displays 5, press the RESET key, and the digital tube on the right continues to count and display from 5 (note: this time it does not start from 0), realizing the continuous counting function after hot start.

  This technology is very useful. For example, if the "watchdog" is activated (i.e., hot start) due to interference or other factors, the data being processed will not be lost, so it can continue to work. Some readers may ask, once the interference destroys the data, the data that continues to work may be wrong, isn't it a mistake on top of a mistake? For this problem, we can adopt data redundancy, such as the value being counted is stored in two memory units (such as counter1 and counter2 in this example). When using, the data of the two memory units are compared. If they are not equal, it means that the interference has destroyed the data, and error processing can be performed. Otherwise, the data can be considered correct and valid.

[page]

  5. Absolute address access

  The anti-interference ability of the MCU system is very important during operation. MCUs with strong anti-interference ability can work normally in complex industrial environments. MCUs with poor anti-interference ability will have more abnormal working and low working efficiency at best, and will not be able to run at all and often freeze. Therefore, the quality of a MCU system design is directly related to its anti-interference ability.

  In order to improve the reliability of RAM area data, we can create two flags flag1 and flag2 in two RAM units that are far apart (such as 20H, 75H, etc.), write the flag word (such as 88H) during initialization, and compare whether the two flags are equal when accessing RAM data. If they are not equal, it means that the RAM area data may be wrong. At this time, the program jumps to the error handling subroutine, otherwise it executes normally. This method makes the data reliability higher during program execution. Shanghai FPGA/CPLD Training This involves absolute address access in C language. The following are three methods.

  1. Use the _at_ keyword

  Its usage is relatively simple, just add _at_ and the address constant after the data declaration. However, please note that absolute address variables cannot be initialized, and bit type functions and variables cannot be specified with _at_.

  Example 1:

  #include 《 P》

  static unsigned char data flag1 _at_ 0x0020; // Position the two flags at 20H and 75H

  static unsigned char data flag2 _at_ 0x0075;

  /******************/

  void main()

  {

  //When entering the main program initialization, set flag1 and flag2 to 0x88

  flag1=0x88; flag2=0x88;

  while(1)

  {

  if ((flag1 == 0x88) && (flag2 == 0x88)) // flags are equal

  {//Normal working process}

  else

  {//Error handling}

  }

  }

  2. Method using pointers

  Example 2:

  #include 《 P》

  char data *point1; //define two pointers to the data area

  char data *point2;

  /******************/

  void main()

  {point1=0x20;point1=0x75;//points to 20H, 75H units

  //When initializing, set the flags *point1 and *point2 to 0x88

  *point1=0x88; *point2=0x88;

  while(1)

  {

  if ((*point1 == 0x88) && (*point2 == 0x88)) // flags are equal

  {//Normal working process}

  else

  {//Error handling}

  }

  }

  3. Absolute macro "P" declared using #include

  Example 3:

  #include 《 P》

  #include 《 P》

  /******************/

  void main()

  { //Set the flags DBYTE[0x20] and DBYTE[0x75] to 0x88 during initialization

  DBYTE[0x20]=0x88;DBYTE[0x75]=0x88;

  while(1)

  {

  if ((DBYTE[0x20]==0x88)&& (DBYTE[0x75]==0x88)) // Flags are equal

  {//Normal working process}

  else

  {//Error handling}

  }

  }

  6.C language calls assembly language

  In order to enable C language to call assembly language, the assembly program must have clear boundaries, parameters, return values ​​and local variables like the C program. In order to make the assembly program segment compatible with the C program, the segment name should be specified and defined for the assembly program. If you want to pass parameters, you must ensure that the storage area used by the assembly program to pass parameters is consistent with the storage area used by the C program. And declare it in the called C language. The conversion rules of function names are shown in Table 1. The registers for receiving parameters are shown in Table 2. The comparison between the return value type and the register is shown in Table 3.

  Function name conversion rules

  Declaration assembly symbol name description in the main function

  Void func(void) FUNC No parameter passing

  Void func(char) _FUNC with register parameter passing

  Void func(void) reentrant_? FUNC Reentrant function including stack parameter passing

  Table 1

  Receive parameter register

  Parameter number charintLong, float general pointer

  1R7R6, R7R4~R7R1~R3

  2R5R4, R5--

  3R3R2, R3--

  Table 2

  Return value type and register comparison

  Return value type register description

  BitC (flag bit) is returned by the specific flag bit

  Char/unsigned char/1_byte pointer R7 single byte returned by R7

  Int/ unsigned int/2_byte pointer R6, R7 double byte is returned by R6, R7, the high bit is in R6, the low bit is in R7

  Long/ unsigned long R4~R7 Four bytes are returned from R4~R7, the high bit is in R4, the low bit is in R7

  FloatR4~R7 32bit IEEE format, exponent and sign are in R7

  The general pointer R1~R3 ​​storage type is in R3, the high bit is in R2, and the low bit is in R1

  Table 3

  The following two examples illustrate this.

  Example 4 (no parameter passing):

  1. According to the instructions of Keil, create a project file and add the main program test4.c written in C51 (Figure 5).

  /*------------Program nametest4.c------------*/

  #include P crystal frequency 12.000MHz《》

  /****************/

  void delay(void); //delay function declaration

  /***************/

  void main (void) //Main function, which makes P1.0 output high and low level square waves alternately

  {

  while(1)

  {P1_0=!P1_0;

  delay();}

  }

  ed31.jpg

  Figure 5

[page]

  2. Use assembly language to compile a 205μS precise delay program ttest4.asm and add it to the project (Figure 6).

  UDELAY SEGMENT CODE

  RSEG UDELAY

  PUBLIC DELAY

  DELAY: MOV R0, #100

  LOOP:

  DJNZ R0, LOOP

  RET

  END

  ed32.jpg

  Figure 6

  3. Click Rebuild target (Rebuild all target files) to get the correct compilation results (Figure 7).

  ed34.jpg

  Figure 7

  Example 5 (with parameter passing):

  1. According to the instructions of Keil, create a project file and add the main program test5.c written in C51 (Figure 8).

  /*------------Program nametest5.c------------*/

  #include P crystal frequency 12.000MHz《》

  /****************/

  void delay(unsigned int k); //delay function declaration

  /***************/

  void main (void) //Main function, which makes P1.0 output high and low level square waves alternately

  {

  while(1)

  {P1_0=!P1_0;

  delay(500);}

  }

  ed35.jpg

  Figure 8

  2. Use assembly language to compile a delay program ttest5.asm and add it to the project (Figure 9). Because of parameter passing, an underscore "_" must be added before the function name.

  UDELAY SEGMENT CODE

  RSEG UDELAY

  PUBLIC _DELAY

  _DELAY:

  DJNZ R6, $

  DJNZ R7, $

  RET

  END

  ed36.jpg

  Fig. 9

  3. Click Rebuild target to get the correct compilation results (Figure 10).

   ed37.jpg

  There is another method, which is to use the compiler to automatically complete the segment arrangement, so it is also convenient to implement mixed programming of C language and assembly language. The process is:

  1. Use C51 to write the main program test.c and the shell of the delay subroutine delay.c (waiting to embed assembly language). In the main program, the delay subroutine should be declared as an external function: extern void delay (delay).

  2. Click the delay.c source code and right-click it. Select Options for File 'test.c' in the pop-up drop-down menu. Check Generate Assembler SRC File and Assembler SRC File to make them effective.

  3. Load the package library file according to the compilation mode of the project, usually C51S.LIB in Small mode (the file is in C:\\Keil\\C51\\Lib\\C51S.LIB).

  4. Click Rebuild target to get a delay.SRC file.

  5. Rename delay.SRC to delay.A51.

  6. Load delay.A51 into the project group and remove delay.c and C51S.LIB.

  7. Click Rebuild target again to get the body of the delay.A51 assembly statement.

  8. Put the precise assembly delay subroutine obtained through other experiments into the body of delay.A51, save it and load it into the Source Group 1 project group, then click Rebuild target to get the correct compilation result.

Keywords:MCU Reference address:Some development skills of single chip microcomputer

Previous article:Design of LED display screen for subway train
Next article:Principle and overall design of single chip microcomputer controlled LED outline display

Recommended ReadingLatest update time:2024-11-16 17:32

Proteus simulation and source program of laser communication based on PPM modulation of PIC16F877A microcontroller
Software: MPLAB X IDE v4.15 compiled proteus 8.6 simulation. 1. Simulation circuit diagram; 2. Send and receive source program with comments. Please see the comments. Principle: 1) ADC reads and displays the ADC reading with LED, and outputs it through usart. 2) Transmits to another microcontroller through the PPM pri
[Microcontroller]
Proteus simulation and source program of laser communication based on PPM modulation of PIC16F877A microcontroller
How to select low-power MCU for embedded microcontrollers
script src="/jf/jf-arcMain-1.js" type=text/javascript /script script type=text/javascript /script script src="http://pagead2.googlesyndication .com/pagead/show_ads.js" type=text/javascript /script script src="http://pagead2.googlesyndication.com/pagead/js/r20110914/r20110914/show_ads_impl.js" /script script
[Microcontroller]
How to select low-power MCU for embedded microcontrollers
51 single chip matrix keyboard and left and right water lights control C program
Download the schematic diagram used in this program:  click here  . The microcontroller chip used is stc89c52; just find the corresponding part used in this program. This is the circuit diagram of the entire microcontroller development board. Ignore the others. Download hex file and project file: http://www.51hei.com/
[Microcontroller]
【Blue Bridge Cup MCU Group】External Interrupt
Register TCON to be operated: ITx EXx Programming steps: (1) Select the trigger mode (2) Enable external interrupt (3) Enable general interrupt IT0=1; //IT0=1, falling edge triggers external interrupt 0, IT0=0 edge trigger EX0=1; //Use external interrupt 0 EA=1; The external interrupt pins are as shown
[Microcontroller]
【Blue Bridge Cup MCU Group】External Interrupt
Proteus simulation and source code of simple calculator based on single chip microcomputer
The schematic diagram of the calculator simulation design of the 51 single-chip microcomputer is as follows (the proteus simulation project file can be downloaded in the attachment of this post) The microcontroller source program is as follows: #include reg51.h //header file #define uint unsigned int  #define uchar
[Microcontroller]
Proteus simulation and source code of simple calculator based on single chip microcomputer
51 single chip microcomputer----sbit
sbit: defines the bit variable of the special function register. Typical application: sbit P0_0=P0^0; // defines P0_0 as the first bit of port P0 for bit operation. Usage:​ In C language, if you write P1.0 directly, the C compiler cannot recognize it, and P1.0 is not a legal C language variable name, so you have t
[Microcontroller]
Hardware circuit design principles and engineering application solutions based on single chip microcomputer
0 Introduction With the continuous improvement of the automation level of aviation equipment, multi-core cables are increasingly used, and the performance of cables also greatly affects the normal operation of equipment. As the number of cores in multi-core cables increases, their interconnection becomes more c
[Microcontroller]
Hardware circuit design principles and engineering application solutions based on single chip microcomputer
Research on Multi-interrupt Processing Technology of Single Chip Microcomputer
1. Introduction: The application of interrupt technology has greatly improved the effective use rate of CPU and effectively improved the utilization rate of resources. The performance of interrupt has also become a standard for measuring chip performance. Newly developed chips have added many interrupt sources.
[Microcontroller]
Research on Multi-interrupt Processing Technology of Single Chip Microcomputer
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
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号