Microcontroller learning is difficult and always pits? Looking at these experiences will help you

(one)

I believe that many friends who love electronics, the word SCM should not be unfamiliar to it. However, some friends may only hear that he called the SCM. It may not be clear what his full name is.

Not to mention his full English name and abbreviation. The MCU is a microcomputer with a certain scale integrated on the integrated circuit chip. Abbreviated as: monolithic microcomputer or single chip computer (Single Chip Computer). The application of single-chip microcomputer can be seen everywhere, and it has a wide range of applications. It is mainly used in smart meters, real-time control, communications, and home appliances.

First of all, you must have the enthusiasm to learn microcontrollers, not to say that today went to the library to read a book on the one-chip computer in the afternoon, and tomorrow to play for a long time, the day after tomorrow did not know what the book is talking about.

Second, since you want to learn MCU, you must be willing to spend money if you don't buy some chips and come back to do it yourself (but later on will introduce you to a good hardware

The simulation software does not require you to use the experiment board and emulator directly on your PC, but the software is software, after all, it does not replace hardware in a specific sense, even if

You hold the book every day, turn it over, and never learn it! Friend who has just contacted SCM, read the data, will see more than the following words, but the specific

The concept is still rather vague, and it is as follows:

(1) Programmer The programmer is used to burn the SCM chip. It is to burn the HEX or BIN file into the SCM ROM for the SCM to run.

(2) Experiment board The experiment board is a board specially designed for beginners according to certain requirements. Generally, there is a minimum system for a single-chip microcomputer. The user only needs to write the program and burn the chips well.

To such a tool to be verified above. With the experimental board, for beginners, the need to solder a minimum system is eliminated. But for electronic developers, the role is not very great

(3) The emulator emulator directly places the HEX or BIN file on a chip, and then connects the pins of the chip to the experimental board or system. In this way, you can eliminate the unnecessary trouble of plugging and unplugging the chip.

Third, want to learn the essentials of the microcontroller - PC. Because writing programs, compiling or simulating are done through PC. If there is no PC, nothing can be done! ! ! It's better to have a PC

The above network, because if you do not have the ability to communicate with your MCU, you can't figure out the problems that you can't solve, and you can't figure it out. It's estimated that your enthusiasm for learning MCU will change over time.

Slowly exhausted. If you can access the forum or QQ group through the Internet, the problem will be solved quickly. This learning efficiency must be high! The real master is soaked out of the forum!

With the above three conditions, you can start learning your microcontroller. However, it really is not as simple as what I said. You will surely encounter many and many problems. such as

In order for the microcontroller to achieve a certain function, you may not know how to write a program. Or if you read a similar program on the data, you can't write it yourself. Encountered a similar situation,

Remember: Don't make noises!

(two)

Having said so much, I believe you have read a lot of information, and you should have the necessary tools at hand! (Do not forget about the conditions mentioned above). What exactly does that microcontroller have?

Function and role? Don't worry first! Next let's light up an LED (you should know what the LED is when you engage in electronics ^_^)

We take an LED on the minimum system of the one-chip computer, see whether we can light it! By the way, there have been several mentions of the minimum single-chip microcomputer system. The so-called single-chip minimum system is in the single-chip microcomputer.

Connect the minimum number of peripheral circuit components to the microcontroller. Generally only need to connect the crystal, VCC, GND, RST, under normal circumstances, AT89C51's 31 feet to be connected to high.

Microcontroller learning is difficult and always pits? Looking at these experiences will help you

#include "reg51.h" // header file definition. Or the specific difference with #include "at89x51.h" is that the latter defines more address space.

// In the Keil installation folder, find the appropriate file and compare it!

Sbit P1_0 = P1 ^ 0; // Define pins

Void main (void)

{

While(1)

{

P1_0 = 0; //Active low, if the LED is reversed then it is active high

}

}

It is so simple, we will be connected to the LED on the microcontroller P1_0 light up, of course, the LED is low to light. Because we connect the LED's positive resistance to VCC.

P1_0 = 0; Similar to the assignment statement in C language, that is, assign 0 to the P1_0 pin of the microcontroller and let it output the corresponding level. Then this will be able to meet our previous requirements.

While (1) statement just let the microcontroller work in an infinite loop, that is always output low. If we want to try to light up other LEDs, we're similar to the above statement. I will not talk about it here.

After lighting up a few LEDs, does it remind us of the lights that flow on the bustling streets? Can we also allow several LEDs to light sequentially? The answer is yes! its

The principle of real display is very simple, that is, after one LED is off, the other is on immediately, and turns in succession. Suppose we have 8 LEDs connected to the 8 pins of port P1. Hardware connection, at

Connect 7 LEDs to P1_1--P1_7. The routine is as follows:

#include"reg51.h"

Sbit P1_0 = P1 ^ 0;

Sbit P1_1 = P1 ^ 1;

Sbit P1_2 = P1 ^ 2;

Sbit P1_3 = P1 ^ 3;

Sbit P1_4 = P1 ^ 4;

Sbit P1_5 = P1 ^ 5;

Sbit P1_6 = P1 ^ 6;

Sbit P1_7 = P1 ^ 7;

Void Delay(unsigned char a)

{

Unsigned char i;

While( --a != 0)

{

For (i = 0; i "125; i++); // one; means empty statement, CPU idle.

} //i added from 0 to 125, CPU takes about 1 millisecond

}

Void main(void)

{

While(1)

{

P1_0 = 0;

Delay(250);

P1_0 = 1;

P1_1 = 0;

Delay(250);

P1_1 = 1;

P1_2 = 0;

Delay(250);

P1_2 = 1;

P1_3 = 0;

Delay(250);

P1_3 = 1;

P1_4 = 0;

Delay(250);

P1_4 = 1;

P1_5 = 0;

Delay(250);

P1_5 = 1;

P1_6 = 0;

Delay(250);

P1_6 = 1;

P1_7 = 0;

Delay(250);

P1_7 = 1;

}

}

Sbit defines the bit variable, unsigned char a defines the unsigned character variable a, in order to save the microcontroller internal resources, its effective value is 0~255. The main function calls the Delay() function.

The Delay function causes the microcontroller to spin, the LED remains lit, then goes off, and the next LED turns on. While(1) generates a loop.

(three)

Above we talked about how to make LED flow, but whether you find a problem: write too long! Can it be more simple? can! Can use C51's internal functions

INTRINS.H implementation. The function unsigned char _crol_(unsigned char a, unsigned char n) can make the variable a rotate left n bits, if we give the P1 mouth

0000 0001 Then when n is 1, it will produce the same effect as above!

#include"intrins.h"

#include"reg51.h"

Void Delay(unsigned char a)

{

Unsigned char i;

While( --a != 0)

{

For(i = 0; i "125; i++);

}

}

Void main(void)

{

Unsigned char b, i;

While(1)

{

b = 0xfe;

For(i = 0; i "8; i++)

{

P1 = _crol_(b, 1);

b = P1;

Delay(250);

}

}

}

Unsigned char _cror_(unsigned char a, unsigned char n) right shift in INTRINS.H function can also achieve the same effect! Here is no longer tired.

The tricks of running lights are many. I have also written a kind of curtain-like flow. The procedure is very simple. Interested friends can try to write on their own!

By the way, speaking so much, some friends still do not know how to use the compiled software? Here are a few to introduce to you? WAVE everyone must have heard of it! There is still one

Is KEIL2, I use KEIL2, the following talk about how to use the KEIL2 compiler software!

1. Install the software, this should not need to talk about it!

2. After installation, start KEIL software, left click on Project--"New Project--" enter the file name - "" select the chip we use (here we generally use Atmel's

AT89C51 or AT89C2051, point to determine.

3. Click File--"New--" to enter our program and save it as a .C file. (In general, we save the same file name as the previous project name.)

4. Expand Target 1 --> Right-click on Source Group 1 --> Add Files to Group 'Source Group 1'--> Select the .C file you just saved. Click ADD to close the pair.

Message box. This way, the .C file is added to Source Group 1.

5. Right-click Target 1 - "OpTIons for 'Target 1' - "Target fill in the size of the crystal, Output, in the Create HEX Files before the hook, point

set.

6. Click Project-->Rebuild All Traget Files if prompted

creaTIng hex file from "XXX". . .

"XXX" - 0 Error(s), 0 Waring(s).

Said that compile and generate HEX file success! The next step is to burn the HEX file to the MCU or to the emulator to see if it achieves the purpose in advance!

Oh! Now if you have a good sense of accomplishment yourself, if you let you do a stream of watercolor lights and develop a simple product, you can make a beautiful mobile lantern by adding a driver circuit.

It! Until now, you should know how powerful the microcontroller is. If you simply use digital circuit or analog circuit knowledge to design a mobile lantern, you may need to work hard.

And time only, with the MCU, it is not the same, as long as you write a program to control him on the line! Someone said such a sentence, it is not unreasonable, learn MCU, program thinking is very important!

(four)

Oh, friends! I believe that you have done a good job, and now you can play several tricks? You may say, as long as you want to, how flow will flow! haha, yes.

However, engineers designed such a single-chip microcomputer not only to make it a running light, but also to waste it. . . ^_^

Friends who have studied digital circuits must have made 8-way or 6-way answering devices. With pure digital circuit knowledge to do, design your own circuit, feel more difficult! Responder

The monitor is mostly 7-segment digital tube. Here we talk about how to use the SCM to make the digital display 0-9. Responder implementation, we will discuss later, because the answerer also involves the keyboard

content. The 8-segment digital tube is divided into two types: common yin and common yang. The 8-segment digital tube consists of 8 LEDs (also including a decimal point). If it is a common yang, the positive levels of the eight LEDs are connected together.

If it is a common cathode, the cathodes are connected together. The 8 LEDs correspond to the following numbers: ({0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f}; //0-9 digits)

a 0 1 2 3 4 5 6 7 8 9

__ 0011 1111,0000 0110, 0100 1111, 0101 1011

f | | b

|__|

|g | c

e |__|. Dp

d

Under normal circumstances, in order to facilitate the calculation or code acquisition, we will a-dp received a single chip on a Px.0--Px.7. x represents one of 0, 1, 2, and 3. So we only

To give a certain value to a port, the corresponding LED segment is lit, but pay attention to the hardware connection: the microcontroller may not be able to directly drive the LED, so we can control the three-level tube

Turn on or off to control the LED on and off!

If we take the a--dp of the common cathode digital tube to P0.0--P0.7 of the one-chip computer one by one, pay attention to: P0 mouth needs to pull up the resistance. What is a pull-up resistor? Simply put, it pulls the level

High to improve driving ability. For example: P0 = 0X3F; it is displayed as the number 0. Because 0X3F is binary 0011 1111, we lower to the high number, followed by 1111 1100,

The I/O levels are high, high, high, high, high, high, low, and low, that is, the corresponding a--dp is bright, bright, bright, bright, bright, bright, off, and off. In the above figure we can see that the g and dp segments are not

The other segments are bright, which is what we see as the number 0. Other numbers or characters can also be obtained in the same way. But some friends will ask, if we take a single typeface, won't we

Very troublesome? What else do you think about? ^-^ Oh, in fact, there are many LED model-taking software on the Internet. If you have a friend with a certain computer programming language, you can try to write one yourself.

The modulo program allows the computer to calculate for us, such as the value of 0X3F above.

#include"reg51.h"

Void Delay(unsigned char a)

{

Unsigned char i;

While( --a != 0)

{

For(i = 0; i "125; i++);

}

}

Void main(void)

{

P0 = 0X3F; //display 0

Delay(250);//Delay

P0 = 0X00;// Briefly turn off the display. If it is not turned off, the display may be blurred.

P0 = 0X06; //display 1

Delay(250);

P0 = 0X00;

. . . //The following shows the number 2-F, omitted.

}

See here, surely everyone can show 0-F! But what if you want to show two digits, three digits? Maybe some friends think so: pick one on the P0

Digital tube, and then a digital tube on the P1 mouth! However, if you want to display 4 digits and 5 digits? That is not a piece of AT8951 can not pick up! Difficult to not take 4 or more than 5?

Certainly not!

Speaking of here, we talk about the digital tube display, can be divided into two types: dynamic scanning and static display. What we said above is static display. But if we use dynamic scanning

Show, then you can solve the above problem, that can display multiple digital tubes. The static display we mentioned above connects the COM pin of the digital tube to the VCC or GND terminal, and the other connects to the PX.

On the mouth, as long as the corresponding high and low levels are output on the PX port, corresponding numbers or characters can be displayed. But if we use dynamic scanning methods, such as displaying 6 digital tubes, hardware

The connection can be solved as follows: a--dp is still connected to P0.0--P0.7, and 6 COM feet are connected to another port P2.0--P2.5. P0 mouth for segment selection (control digital character) P2 mouth for position selection

Which digital tube is turned on? This way we control the P0 and P2 ports to control 6 digital tubes. However, an attentive friend may ask such a question: P2 selection is to make the digital tube one bright

, it still can not control the six together or off it! ? ^_^ Think of it as right? How to do. . Is it wrong?

Hey, ask you a question? In the dark, holding a cigarette and shaking it quickly in front of you, what kind of phenomenon would you find? Is it because the original discontinuity turned into a look

Continued curve or straight line! Come back and think about our digital tube! The principle is the same, you can not forget, our single-chip computer can be a computer, computing speed of the computer

Degree, everyone can imagine!

Here to talk about 51 single-chip machine cycle and clock cycle concepts. The so-called machine cycle is the time to access the memory once. And 1 machine cycle includes 12 clock cycles. in case

The one-chip computer operates under 12M crystal, so one clock cycle is: 1/12 subtle. One machine cycle 12*1/12 = 1 subtle. If the crystal is 6M, what is the clock cycle and machine cycle?

? In the compilation, we must also be concerned about the length of the machine cycle for instruction execution. There are one cycle, two cycles, and four cycles.

Speaking, ran so far. . Or return to the original topic. If we consider the selected P2 as the “smoke” above, then we see that it is not 6 together.

Or it's gone! ^_^ Haha, this is the case. . Remember, there is only one digital tube that emits light at any one time. If you can understand this sentence, you really understand

What I mean! Friends, now give you a task, so that six digital tubes show 1,2,3,4,5,6 respectively. Can you handle it yourself? Try to write your own first. . .

#include"reg51.h"

Void Delay(unsigned char a)

{

Unsigned char i;

While( --a != 0)

{

For(i = 0; i "125; i++);

}

}

Void main(void)

{

While(1)

{

P0 = 0x06;//1 code segment

P2 = 0x01; // Strobe one, or P2_0 = 1;

Delay(20);//Delay about 20 milliseconds

P0 = 0X00; //Close display

P0 = 0x5b;//2 code segments

P2 = 0x02; // Strobe one, or P2_1 = 1;

Delay(20);

P0 = 0X00;

P0 = 0x4f; //3 code segment

P2 = 0x04; // Strobe one, or P2_2 = 1;

Delay(20);

P0 = 0X00;

P0 = 0x66; //4 code segment

P2 = 0x08; // gate one, or P2_3 = 1;

Delay(20);

P0 = 0X00;

P0 = 0x6d; //5 code segment

P2 = 0x10; // Strobe one, or P2_4 = 1;

Delay(20);

P0 = 0X00;

P0 = 0x7d; ///6 code segment

P2 = 0x20; // Strobe one, or P2_5 = 1;

Delay(20);

P0 = 0X00;

}

}

(Fives)

I believe we must have seen the digital clock. There must be a hall in the teaching building. Every time passing by, basically just casually glanced at, did not even think about his working principle. But today

You can also make him come, do you feel that you have a sense of accomplishment! Ha ha! ^_^

Following the above, let's start with a simple experiment: Displaying 10 digits 0--9 on a digital tube. What are you doing? It seems a bit difficult,

Don't look down first, oh, shut it down. Think about it yourself. How is it?

#include"reg51.h"

Unsigned char code SEG_TAB[ ]={0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f}; //0-9 digits

Void Delay(unsigned int a) //unsigned int is defined as a non-symbol shaping in the range of 0--32768

{

Unsigned char i;

While( --a != 0)

{

For(i = 0; i "125; i++);

}

}

Void main(void)

{

Unsigned char i;

While(1)

{

For(i = 0; i "10; i++)

{

P0 = SEG_TAB[ i ]; // Take the value in the SEG_TAB array

P2 = 0X01;

Delay(1000);

}

}

}

Does the display show from 0-9, beating? Does your heart jump with you? It is a step away from our goal! Yes, continue working hard!

Above only shows the number 0-9 of a digital tube, but how do you want him to display 6 numbers? So we can make a clock out and play it! Also remember to remember us

Speaking of the role of P2 mouth election! Oh, I didn't forget!

#include"reg51.h"

Unsigned char hour = 12, min = 0, sec = 0;

Unsigned char code SEG_TAB[ ] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f}; //0-9 digits

Void Delay(unsigned char a)

{

Unsigned char i;

While( --a != 0)

{

For(i = 0; i "125; i++);

}

}

Void disp(void)

{

P0 = SEG_TAB[ sec % 10 ];//Displays the ones place in seconds

P2 = 0X01;

Delay(15);

P2 = 0;

P0 = SEG_TAB[ sec / 10 ];//display tenths of seconds

P2 = 0X02;

Delay(15);

P2 = 0;

P0 = SEG_TAB[ min % 10 ];//Display ones digit

P2 = 0X04;

Delay(15);

P2 = 0;

P0 = SEG_TAB[ min / 10 ];//displays ten decimal places

P2 = 0X08;

Delay(15);

P2 = 0;

P0 = SEG_TAB[ hour % 10 ];//The ones digit when displaying

P2 = 0X10;

Delay(15);

P2 = 0;

P0 = SEG_TAB[ hour / 10 ];// Ten digits when displayed

P2 = 0X20;

Delay(15);

P2 = 0;

}

Void main(void)

{

While( 1 )

{

Disp( );

}

}

After compiling and burning the chip, observe the operating phenomenon. Hey. . How does it keep showing 12:00:00, is the clock not starting? Or, another reason? Oh, it turns out to be 3 variables

After sec,min,hour initialization, its value has not changed! How can we let him change the value? Some friends will think so: Delay the second place by 1 second, then add 1 to it.

The second ten seconds delay 10 seconds later, plus one, has been added to six, plus one unit, and so on. . This idea is good, but friends have you ever thought about the general delay of C language (unless you

Put him in the interrupt) is extremely inaccurate! Accumulated in this way, the error 24 hours a day is definitely very big. I used to write the clock in a time-delay way. The error is 8 seconds in 1 hour. It is

What concept! 24 * 24 = 24 hours a day, about 3 minutes, a month is 10 minutes. . Is there any other way to improve it? Have! This involves the microcontroller

Another important part of the core: microcontroller interrupts and the use of timers! Want to write more accurate (only here is relatively accurate compared to the previous approach, if you want to do

A more accurate clock, with a better clock chip, commonly used clock programs such as DS12887 and DS1302, must call interrupts and timers. Or we should first look at textbooks and books

Well, after all, people's books are definitely more than I have to write. Now let's talk about them briefly!

(six)

What is an interruption? Tell a more general example: For example, when you are watching TV at home, suddenly the phone rings. What is your first reaction? Did you run to answer the phone first? Finish the call

Afterwards, continue watching TV. This is an example of an interruption. The interruption was caused by the phone. You ran in the past and responded to the interruption. The answer to the call was the interruption! After finishing the call, continue watching TV.

That is to resume the interruption and wait for the arrival of the next interruption!

But this seems to have nothing to do with the microcontroller? Some friends may have such questions. Yes. SCM certainly will not watch TV, and will not answer the phone! ^_^ However, the class

Compared to this: For example, when a single-chip microcomputer is executing a certain task, suddenly there are more important events that require the microcontroller to respond. The microcontroller will respond to the response and perform more important tasks (interrupt handling

), the original task will continue to wait (site protection). After performing more important tasks, go back to the entry point of the interrupt and continue performing the original task (restore of field interruptions). 51 series

There are five interrupt sources for the microcontroller: external interrupt 0, timer T0 interrupt, external interrupt 1, timer T1 interrupt, serial port interrupt.

Perhaps some friends have probably grasped the meaning of it. Some friends are still stumbled. But it does not matter, we continue to look down, below we talk about the microcontroller's timer is even

What? How does it work? Timer, we literally can see its approximate meaning? Simply said: It is timed! That is, let the microcontroller count. Timer is divided into:

0 mode 1, mode 2 and mode 3 and other four kinds of work. Some friends will definitely ask: How to start the timer? Fan's timer, I believe we must have used it! But the timer of the one-chip computer,

How to start it? You should not always use your hand to turn the timer! ^_^ Of course not. We can start the timer as long as we give some instructions to the MCU! Here we are about timer 0,

Say how to start timer 0.

TMOD = 0X01; // Set Timer 0 Operation Mode 0

TH0 = (65536 - 5000) / 256; //Load the high 8 bit initial value

TL0 = (65536 - 5000) % 256; //Load low 8-bit initial value

TR0 = 1; //Start the timer

^_^, Simple, so we can start the timer. Among them TMOD is the T/C way control register:

D7 D6 D5 D4 D3 D2 D1 D0

_ _

GATE C/T M1 M0 GATE C/T M1 M0

|_________ __________| |_________ __________|

| T/C1 | | T/C0 |

C/T is the selection bit for the counter and TImer. If the value is 1, it is used as a counter. 0, for a regular period! GATE is the gating position. M1 and M0 workers

The choice of type: If M1=0; M0=0, it is the mode 0: 13-bit timer/counter. If M1=0; M0=1 is the mode 1,16 timer/counter. If M1=1; M0=0 is mode 2, 8 bits are automatically loaded

Timer/counter. If M1=1; M0=1 is mode 3, only applicable to T/C0, 2 8-bit timers/counters.

Having said a lot, I feel a bit confused. Then we still talk about the above. TMOD = 0X01;//As to why it is 0X01, we see: We have chosen timer 0 mode 0,

So T/C1 is all 0, and M1 of T/C0 is 0. M0 is 1, so D0-D7 is 0X01; 0X01 represents the hexadecimal number, this everyone should know it! Also D0-D7 represents a binary number.

Also need to convert!

TH0 = (65536 - 5000) / 256; // Loads the high 8 bit initial value. If 12M crystals are used, the timing is 5000 microseconds, which is 5 milliseconds; but if it is not under 12M, how should it be calculated?

What about it? If it is 11.0592M? Do you still remember the concepts of machine cycles and clock cycles that we talked about earlier? ^_^ Forgot, or look ahead! Ha ha! Nothing, study, forget

Look through the book again and check it out! In fact, the appeal of 5000 = 1 * C is obviously C = 5000, but if it is 11.0592M then it is not 1, it should be 1.085, then 5000 =

1.085 * C, then C is 5000 / 1.085 = ? How much more, everyone will calculate it? The same is true for TL0! However, attentive friends will find information on the Internet or

TH0, TL0 is not the same as the above, but the direct TH0 = 0XEC; TL0 = 0X78 is not the same as the above, do not forget that the microcontroller is also a computer oh. With C, straight

Then write the calculation formula on the line, the calculation will be completed by the microcontroller.

TR0 = 1; This sentence is to start timer 0, start counting! Oh, one more thing, some friends will ask, where did you come from 65536? Oh, you can not forget: set the timer 0

Working mode 0 is 16-bit (2 of the 16th power is how much you know by yourself) Simple, right? But how to use it with interrupts? Please continue to see the following explanation!

TMOD = 0X01; // Set Timer 0 Operation Mode 0

TH0 = (65536 - 5000) / 256; //Load the high 8 bit initial value

TL0 = (65536 - 5000) % 256; //Load low 8-bit initial value

TR0 = 1; //Start the timer

EA = 1;//Open total interrupt

ET0 = 1; // Timer interrupt. If 0 is off!

In this way, we initialize the timer T0 and interrupt, that is, after the timer is full 5 milliseconds, an interrupt is generated. After the interruption, how can we handle it? Oh! think carefully?

^_^

After each interruption, we can increment a variable by one. After 200 interruptions, isn't it 1 second? Is it more accurate than the delay we mentioned above?

I am very sure of that! But think of the one-second kind of time that allows the microcontroller to generate so many interrupts, the microcontroller will not be tired? Well, it's not good. If in the 12M crystal, T0 every time

Is it not possible to generate a maximum of 65.336 milliseconds? Then we let him interrupt once every 50 milliseconds! In this way we will get a second time 20 times! ·Shuang·

Well, so much to talk about, now let's write a time program! ^_^

#include"at89x51.h"

#define HI ((65536 - 50000) / 256)

#define LO ((65536 - 50000) % 256)

#define _TH0_TL0_ (65536 - 50000)

#define M 20 //(1000/25)

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

Unsigned hou = 12, min = 0, sec = 0;

Unsigned char SEG_TAB_B[ ] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //0-9 digits

Unsigned char SEG_TAB_A[ ] = {0x40, 0x79, 0x24, 0x30, 0x19, 0x12, 0x02, 0x78, 0x00, 0x10}; //0.-9.

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

Void Delay(unsigned char a)//time delay program a*1MS

{

Unsigned char j;

While(a-- != 0)

{

For (j = 0; j "125; j++);

}

}

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

Void Disp(void)//Digital display

{

P2_0 = 1;

P1 = SEG_TAB_B[ hou / 10 ];

Delay(5);

P2_0 = 0;

P2_1 = 1;

P1 = SEG_TAB_A[ hou % 10 ];

Delay(5);

P2_1 = 0;

P2_2 = 1;

P1 = SEG_TAB_B[ min / 10 ];

Delay(5);

P2_2 = 0;

P2_3 = 1;

P1 = S EG_TAB_A[ min % 10 ];

Delay(5);

P2_3 = 0;

P2_4 = 1;

P1 = SEG_TAB_B[ sec / 10 ];

Delay(5);

P2_4 = 0;

P2_5 = 1;

P1 = SEG_TAB_B[ sec % 10 ];

Delay(5);

P2_5 = 0;

}

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

Void IsrTImer0(void) interrupt 1 using 1 //Time 50ms

{

Static unsigned char count = 0; //define the static variable count

Count++;

If(count == M)

{

Count = 0;

Sec++;

If(sec == 60)

{

Min++;

Sec = 0;

If(min == 60)

{

Hou++;

Min = 0;

If(hou == 24)

{

Hou = 0;

}

}//if

}//if

}//if

}

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

Void Timer0Init(void) // Timer 0

{

TMOD = 0x01;

TH0 = HI;

TL0 = LO;

TR0 = 1;

ET0 = 1;

EA = 1;

}

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

Void main(void) //The main function

{

Timer0Init();

While(1)

{

Disp();

}

}

Simple, still can't read Oh, then you feel it yourself, if you can write a clock program, then your 51 MCU will learn 80%. Interrupted and

The timer/counter is a very important thing, and almost everywhere it is used will involve interrupts and timing! So everyone must master it! ^_^

Haha, quickly compile HEX files, build hardware, burn into SCM, power up to see the effect first! Oh, now you should have a sense of accomplishment. I can't think of a clock actually

Simple, hey! But the problem is! Although the clock is made, how is his accuracy? In an hour or two, you may not see any error, but what about one day or one year?

Halo, my God, if it's calculated by years, then this clock has no practical value at all! Everyone says that they can't write in C. The clock program with high precision comes! ! ! Is it a little regret

Let's learn to compile it! But since you have chosen C, don't regret it! Hey, think of C's high-level language, how could it be lost to the compilation?^_^ Ha ha! See the following code:

Static unsigned char count = 0;

TR0 = 0;

TL0 += (_TH0_TL0_ + 9) % 256;

TH0 += (_TH0_TL0_ + 9) / 256 + (char)CY;

TR0 = 1;

Count++;

In the interrupt handling service program, we add the above code. TR0 = 0; Turn off the timer T0 first, and then re-assign the TH0 and TL0, and then turn on TR0 = 1; burn into a single chip

Look at the effect of the machine and how it works. The first time you are more accurate. However, there are still errors! depressed! why? That is the error caused by the hardware, we can use software to make up for it! We first

Turn the clock on and let him walk for hours or days to see what the error is! Take an average. (here for example we are 10 seconds faster than 1 hour) then you can use the following statement

If(hour % 10 = 0)

{

Sec--;

}

To make up! This may appear like this: seconds directly jump! We can achieve this through subdivision. Don't be as big as 10 hours or smaller! The specific operation is still left to

Friends!

(Seven)

This time we talk about the keyboard, we must have seen the bank teller machine, take the money to enter the password you want to use the keyboard, supermarket shopping to retrieve the stored items to enter the password, and you are now in

Use the PC's keyboard. But how does the keyboard work? There are generally two ways: (1) scanning method, constantly scanning the keyboard status, sending CPU judgment and processing. If the number of keyboards is one

If it is large, it is obviously not suitable for the (2) line reversal method. It is judged whether the key is pressed or not by changing the state of the row and column!

Now we have a 4*4 keyboard at P1, P1.0-P1.3, P1.4---P1.7, and 4 4K7 pull-up resistors to VCC. code show as below:

//----Keyboard scanning program -------

//----Display the corresponding key value with the digital tube

//P1.0--P1.3 to accept -------

//P1.4 --- P1.7 --------

#include"reg51.h"

Unsigned char code tab[ ]={0x3F,0x06,0x5B,0x4F,

0x66, 0x6D, 0x7D, 0x07,

0x7F, 0x6F, 0x77, 0x7C,

0x39,0x5E,0x79,0x71};//16 keys to 0 to F

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

Void Delayt(unsigned char t)//Delay function

{

Unsigned char i;

For(t=0;i<<=t;t++)

For(i=0;i<<255;i++);

}

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

Bit pkey(void)// determines whether the key is pressed or not and is determined by the return value

{

P1=0xf0;

If(P1!=0xf0)

{

Delayt(25);

If(P1!=0xf0)

Return 1;

Else

Return 0;

}

Else

Return 0;

}

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

Void main(void)//main function

{

Unsigned char key,j,k,s;

While(1)

{

If(pkey()==1)

{

P1=0xfe;

k=0xfe;

For(j=0;j<<4;j++)

{

s=P1&0xf0;

Switch(s)

{

Case 0xe0: key=4*j+0; break;

Case 0xd0: key=4*j+1; break;

Case 0xb0: key=4*j+2; break;

Case 0x70: key=4*j+3; break;

Default: break;

}

k=(k<<<<1||0x01;

P1=k;

}//for

}//if

//if((P1&0xf0)==0xf0)

P0=tab[key];

P2=1;

Delayt(50);

}//while

}

There is also a line reversal method implemented as follows:

1. Same as the scan method, set the column line low, set the line high, read the line state

2. In contrast to 1, the row is set low, the column is set high, and the column is read.

3. If the key is pressed, the result of the 2 read states is the position of the key, so that 2 times output and 2 reads can complete key recognition! ! !

The subroutines are as follows:

Unsigned char key_vscan(void)

{

Unsigned char row, col;

P1 = 0xF0;

Row = P1&0xF0;

Row = row&0xF0;

P1 = 0x0F;

Col = P1&0x0F;

Col = col&0x0F;

Return(key_val(row|col));

}

Here we introduce the program that introduces one key and many functions, that is, pressing a key can execute different commands!

Void main (void)

{

Unsigned char b = 0;

While( 1 )

{

If(P1_0 == 0)

{

Delay(10);

If(P1_0 == 0)

{

b++;

If( b == N )//N is the number of keys

{

b = 0;

}

While(P3_2 == 0);// wait for the key to release

}

}

Switch( b )

{

Case 1: P2_0 = 0xFE;

Break;

Case 2: P2_1 = 0xfd;

//. . .. . .. . .. . .. .add your code here!

}

}

}

(8)// The above text was written in May 2005. Due to the time constraints, it has not been completed. I was bored and wrote some text later. This is written on June 5, 2006!

Here I would like to make a brief explanation of the above point. If you are just learning the microcontroller, then the code you write is VERY GOOD, but if you apply the above code to the product, then I can tell you that the above Write the key identification code is all junk code, ^ _ ^, which is silly now, huh, huh. why? Is my key not working properly?

Please see here:

If(P1_0 == 0)

{

Delay(10);//The problem is here, do you let the CPU idle here?

If(P1_0 == 0)

{

//. . .add your code here.

}

}

After entering the first if statement, it enters Delay(10); look at the Delay function and let the CPU execute (empty statement) completely, so when it is a big product or code, this is very costly internal resources of the microcontroller. . What is the solution? Oh, that's for sure.

There are roughly two solutions as follows:

1. Place the delay function in the interrupt and query the delay flag in the interrupt. /* Not only for keyboard recognition, but also for other delay codes. See EX1*/

2. Query the flag of the button directly in the interrupt. //见EX2。

EX1:

unsigned char Delaytime;

void Delay(unsigned char Delaytime)//

{

while(Delaytime !=0 );//等在这里,直到Delaytime为0。

}

void Timer0_interrupt(void) interrupt 1 using 2

{

if(Delaytime != )

Delaytime--;

//。 . .add your other code here

}

Delay函数具体延时多长时间,就要看你设定的T0定时器中断和Delaytime的乘积,比如你的定时器中断为50MS,Delaytime为20的话,那么50MS*20=1S。

EX2:

#define Press_key = P2 ^ 7;//定义按键的I/O

void P_key(void)

{

char new_value,old_value;

new_value = Press_key;

if(new_value && !old_value)//识别按键。

{

Turn_On_LEd( );

//。 . .add your other code here.

}

old_value = new_value;

}

void Timer0_interrupt(void) interrupt 1 using 2

{

P_key();

//. . .add your other code

}

当然在实际过程当中,并不是如此简单简洁的,还希望大家能够举一反三哦。 . . ^_^。

(九)

写了这么多了,大家也看了这么多了,感觉怎么样?大家也觉得不难吧。其实51也就那么简单,真的很希望大家看完这篇文字以后,很自信的说,51单片机也已经入门。这是对我写怎么多文字最好的回答。时隔13个月之久再来继续写这些东西,没有以前的激_情和热情,所以就草草了事结尾,希望大家不要在背地里骂我哦,^_^。当然以上讲的只是最简单的一些东西,单片机的功能非常之强大,只要你能想得到,就一定可以用单片机来实现的。

当然单片机和外部其他的芯片还有很多,比如数字温度传感器DS18B20,实时时钟芯片DS1302,还有比如访问AT24CXX的EEPROM存储器等,更多的电路,还要靠大家在平时的学习过程当中,慢慢掌握

Teaching Equipment

Special equipment for university physics laboratory

Teaching Equipment,Optical Bench Kit,Optical Instruments In Physics,Electrooptical Modulator Experimental Instrument

Yuheng Optics Co., Ltd.(Changchun) , https://www.yuhengcoder.com