51单片机学习总结(史上最全版,自己总结)(11700字)

来源:m.fanwen118.com时间:2021.5.9

单片机学习总结

Lesson1 预备知识与点亮一个二极管

一、预备知识与流水灯

1、CPU ROM RAM STC I/O口

2、电平特性:高与低,TTL电平:高+5v,低0v;RS232电平:高-12v,低+12v,计算机与单片机通讯时要加电平转换芯片max232(实验板上左下角)

3、二进制:遇二进一;十六进制:十进制中的0-15分别表示为十六进制的0、1....9、A、B、

C、D、E、F,一般把四个二进制数放在一起转换为一个十六进制数,转换时先把二进制数转换成十进制数,再把十进制数转换成十六进制数。0001B>1H;1010B>AH;0010 1100>2CH(这里B表示的是二进制,H表示的十六进制)。0x表示十六进制。

4、二进制的逻辑运算:“与”、“?”、“&”;“或”、“+”、“|

51单片机学习总结史上最全版自己总结

;“异或”“?”,相同为0,不同为1。按位与&,按位或|,按位异或~,按位取反~

5、芯片缺口方向,芯片插反会导致短路。

二、80C51系列介绍

1、80C51的引脚封装:总线型:有4组 非总线型:只有20个引脚,送数据时,数据在总线上跑

51单片机学习总结史上最全版自己总结

2、C51知识:sfr,特殊功能寄存器声明;sfr16,sfr的16位数据声明;sbit,特殊功能位声明;bit,位变量声明。例如sfr SCON=0X98,sfr16 T2=0xCC,sbit 0V=PSW^2(第2位定义为ov)。单片机都是从0开始记值。

3、C-51的运算符:

51单片机学习总结史上最全版自己总结

4、单片机掌握几点:

51单片机学习总结史上最全版自己总结

5、stc-isp的使用

就德飞莱单片机而言,单片机类型为stc90c516RD+,com类型为com4,在下载程序时,一定要先把开发板上的电源断掉,过2秒钟再打开,顺序不能颠倒。 如果此界面长期没有变化,考虑以下几点:

51单片机学习总结史上最全版自己总结

6、Keil的使用:

(1)、先建工程,文件名没有后缀名,保存,选择atmel中的80c52

(2)、再建文件,有后缀名,后缀名.c(c语言)或.asm(汇编语言)

(3)、将文件添加在工程里,在左方,右击

(4)、建一个工程,就要建一个文件名

(5)、先下载程序,后打开电源

(6)、注释的方式有两种,一是//,换行无效;二是/* */,但是注释的语句不编译。

(7)、c语言区分大小写,默认端口P是大写字母;c语言的任何语句和标点都是在英文状态下书写的,中文符号是不能识别的,中文仅仅能作为注释使用。

(8)、建立工程时,选择芯片类型为AT89c52即可。

(9)、c语言中数值不区分大小写,标识符一定区分大小写。

(10)、一个函数由两部分组成:函数首部与函数体。函数首部包括函数名max,函数类型int,函数参数x、y,函数参数类型int,比如int max (int x,int y),也可以没有参数,如void main()。函数体包括声明部分(对变量和所调用函数)和执行部分。

6、自己动手需要的硬件材料

51单片机学习总结史上最全版自己总结

7、在字母上加上划线表示低电平有效。51单片机所有i/o口上电平默认为高电平

8、用位操作与总线操作两种方法写程序

(1)、位操作 (2)总线操作

#include <reg52.h> #include <reg52.h>

sbit D1=P1^0; void main() void main() {P1=0xfd; { D1=0; }

}

9、课后练习

对照TX-1C单片机学习板原理图写程序

用位操作和总线操作两种方法完成以下题目

1.熟练建立KEIL工程

2.点亮第一个发光管.

3.点亮最后一个发光管

4.点亮1、3、5、7

5.点亮二、四、五、六

6.尝试让第一个发光管闪烁

法一:#include<reg52.h>

sbit P1_1=P1^0;

void main()

{unsigned int i;

while(1)

{P1_1=0;

for(i=1;i<10000;i++);

P1_1=1;

for(i=1;i<10000;i++);

}}

法二:#include<reg52.h>

sbit P1_1=P1^0;

void yanshi();

void main()

{while(1)

{P1_1=0;

yanshi();

P1_1=1;

yanshi();}}

void yanshi()

{unsigned int i;

for(i=0;i<10000;i++);}

法三:#include<reg52.h>

void main()

{while(1)

{

int i;i=50000;

P1=0xfe;

while(i--);

P1=0xff;

i=50000;

while(i--);

}

}

7.尝试设计出流水灯程序

法一:直接法

#include<reg52.h>

//sbit P1_1=P1^0;

void yanshi();

void main()

{while(1)

{P1=0xfe;

yanshi();

P1=0xfd;

yanshi();

P1=0xfb;

yanshi();

P1=0xf7;

yanshi();

P1=0xef;

yanshi();

P1=0xdf;

yanshi();

P1=0xbf;

yanshi();

P1=0x7f;

yanshi();

}}

void yanshi()

{unsigned int i;

for(i=0;i<10000;i++);}

法二:使用数组

#include<reg52.h>

unsigned char table[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; void yanshi();

void main()

{unsigned int i;

while(1)

{

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

{P1=table[i]; (注意,在这里的大括号是一定要加的,否则) yanshi();

}}}

void yanshi()

{unsigned int i;

for(i=0;i<10000;i++);}

法三:左移右移

#include<reg52.h>

unsigned char table[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};

unsigned int i;

void yanshi();

void main()

{P1=0xfe;

while(1)

{P1=P1<<1;

P1=P1|0x01;(因为是左移而不是循环左移,所以要末位置一,这样的结果也会导致最后只挨个量一次)

yanshi();}

}

void yanshi()

{unsigned int i;

for(i=0;i<10000;i++);}

8、双灯左移右移闪烁(双灯左移7次,右移7次,然后全闪7次)

#include<reg52.h>

void main()

{unsigned char i;

unsigned char temp;

while(1)

{temp=0xfc;

P1=temp;

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

Delay(50000);

{temp<<=1;

temp=temp|0x01;

P1=temp;}之所以加入temp做中间变量,防止直接操作端口造成的短暂闪烁

Temp=0x3f;

P1=temp;

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

{Delay(50000);

Temp>>=1;

Temp|=0x80;

P1=temp;}

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

P1=0xff;

Delay(50000);

P1=0x00;

Delay(50000);}

} }

9、花样灯

10、PWM调光

三、流水灯

1、在使用总线操作点亮发光二极管时,注意顺序,比如从左往右依次为12345678个二极管,要想让246亮。系统默认高电平不亮低电平亮,即1010 1011,但是在赋值时要倒过来,即11010101,十六进制为d5,这样就可以了。

2、LED发光二极管,单向导电性,电源电压减去LED的正向压降的值除以工作电流即为LED的电阻。LED正常压降1.5v,正常工作电流10mA。

J9端低电平时LED亮,高电平时LED灭。具体解释如下:

51单片机学习总结史上最全版自己总结

A点就相当于单片机的I/O口,接5v相当于高电平1,灯不亮;接地相当于低电平0,灯亮。

3、单片机端口是标准双向口,可作为输出控制端,如控制灯亮灭;可作为输入信号端,如按键信号输入。

4、给端口赋值

(1)、SETB P1.1等价于sbit P1_1=P1^1,P1_1=1。

(2)、CLR P1.1等价于sbit P1_1=P1^1,P1_1=0。因为在C51中,没有P1_1这个表示,所以要预先定义。

(3)、while语句的两种形式:do语句while(条件);或while(条件)语句;。当循环条件为真即条件不为0时,循环会一直执行大括号中的语句。要想进行大循环时,用while

(1),要想停留在某句,用while(1);。

(4)、宏定义#define uint unsigned int 函数声明void Delay(unsigned int t );

(5)、for循环

(6)、调用函数时一定要提前声明;带参数的子函数调用;C51库函数的调用(可以实现流水灯)

(7)、蜂鸣器

四、共阳二极管

1、dp-a,这个小数点是最高位,a是最低位,若接在P1口,a所对应的应该是P1.0,dp对应的是P1.7.

2、一个共阳数码管显示数字变化

#include<reg52.h>

unsigned char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};

void Delay(unsigned int i);

void main(void)

{unsigned char i;

while(1)

{

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

{

P1=table[i];

Delay(60000);

}

}

}

void Delay(unsigned int t)

{

while(--t);

}

3、单个数码管模拟水流

#include<reg52.h>

void Delay(unsigned int t);//函数声明时的格式

void main()

{

unsigned char i;

while(1)

{

P1=0xfe; 如果在while之前就只会闪烁一次

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

{

Delay(10000); 如果没有延时会怎样

P1<<=1;

P1|=0x01;

}

}

}

void Delay(unsigned int t)//注意格式

{

while(--t);

}

4、8位数码管显一个数字 #include<reg52.h>

#define Port P0

void Delay(unsigned int i); sbit Duan_LATCH1=P2^2; sbit Wei_LATCH2=P2^3; void main()

{

P0=0xfe;

Wei_LATCH2=1;

Wei_LATCH2=0;

P0=0x3f;

Duan_LATCH1=1;

Duan_LATCH1=0;

Delay(60000);

while(1)

{

}

}

4、8位数码管显示两个不同的数字 #include<reg52.h> #define Port P0

void Delay(unsigned int i); sbit Duan_LATCH1=P2^2;

sbit Wei_LATCH2=P2^3;

void main()

{

while(1)

{

P0=0xfe;

Wei_LATCH2=1;

Wei_LATCH2=0;

P0=0x3f;

Duan_LATCH1=1;

Duan_LATCH1=0;

Delay(60000);

P0=0xfd;

Wei_LATCH2=1;

Wei_LATCH2=0;

P0=0x06;

Duan_LATCH1=1;

Duan_LATCH1=0;

Delay(60000);

}

}

void Delay(unsigned int i)

{

while(--i);

}

5、8位数码管动态扫描

#include<reg52.h>

#define Port P0

void Delay(unsigned int i);

unsigned char code Duan_table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

unsigned char code Wei_table[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; sbit Duan_LATCH1=P2^2;

sbit Wei_LATCH2=P2^3;

void main()

{int i;

while(1)

{

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

{

P0=Wei_table[i];

Wei_LATCH2=1;

Wei_LATCH2=0;

P0=Duan_table[i];

Duan_LATCH1=1;

Duan_LATCH1=0;

Delay(60000);

}

}

}

void Delay(unsigned int i)

{

while(--i);

}

6、显示3位

#include<reg52.h>

#define Port P0

void Delay(unsigned int i);

unsigned char code Duan_table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

unsigned char code Wei_table[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; sbit Duan_LATCH1=P2^2;

sbit Wei_LATCH2=P2^3;

unsigned char temp[8];

void main()

{unsigned char i,j;

while(1)

{

j++;

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

{

temp[0]=Duan_table[j/100];

temp[1]=Duan_table[(j/10)%10];

temp[2]=Duan_table[j%10];

P0=Wei_table[i];

Wei_LATCH2=1;

Wei_LATCH2=0;

P0=temp[i];

Duan_LATCH1=1;

Duan_LATCH1=0;

Delay(60000);

}

}

}

void Delay(unsigned int i)

{

while(--i);

}

Lesson2 简单的延时程序及蜂鸣器

1、简单的延时程序:

一个机器周期等于12个时钟周期。用软件仿真进行调试,设定时间。

2、子程序调用:

(1)、宏定义:#define uint unsigned int(不加分号,注意先后顺序)以后出现uint就是unsigned int

(2)、无参子函数的设计:声明时,函数类型名 函数名 参数类型名,没有可不写,如void delay()

(3)、含参子函数的设计:

#include<reg52.h>

#define uint unsigned int

sbit D1=P1^0;

void delay(uint z);

void main()

{

while(1)

{

D1=0;

delay(600);

D1=1;

delay(600);

}

}

void delay(uint z)

{

uint x,y;

for(x=100;x>0;x--)

for(z=y;y>0;y--);

}

(4)、c51库函数的调用

#include<reg52.h>

#include <intrins.h>把所用库函数的函数名调用上 #define uint unsigned int

#define uchar unsigned char

uchar temp;

sbit D1=P1^0;

void delay(uint z);

void main()

{temp=0xfe;

P1=temp;

while(1)

{

temp=_crol_(temp,1);

delay(600);

P1=temp;

delay(600);

}

}

void delay(uint z)

{

uint x,y;

for(x=100;x>0;x--)

for(z=y;y>0;y--);

}

(5)蜂鸣器

P2^3即是

Lesson 3数码显示器以及定时器

1、锁存器:一个下降沿可以把输入的数据保持在输出端。8个数码管的公共端都是位选端,位选低电平有效;段选是高电平有效。

#include<reg52.h>

sbit duan=P2^2;

sbit wei=P2^3;

void main()

{

wei=1;

P0=0x00;

wei=0xbf;(此条语句结果为第7位数码管亮,显示4)

duan=1;

P0=0x66;

duan=1;

while(1);

}

2、多个数码管静态显示

#include<reg52.h>

#define uint unsigned int

#define uchar unsigned char

sbit duan=P2^2;

sbit wei=P2^3;

uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

void delay (uint z);

void main()

{wei=1;

P0=0xea;

wei=0;

while(1)

{uint num;

for(num=0;num<16;num++)

{

duan=1;

P0=table[num];

duan=0;

delay(1000);

}

}

}

void delay (uint z)

{

uint x,y;

for(x=z;x>0;x--)

for(y=110;y>0;y--);

}

3、中断系统

(1)、中断响应条件:

中断源有中断请求;

此中断源的中断允许位为1;

CPU开中断(即EA=1)。

以上三条同时满足时,CPU才有可能响应中断。

(2)、TCON的中断标志

51单片机学习总结史上最全版自己总结

IT0(TCON.0),外部中断0触发方式控制位。 当IT0=0时,为电平触发方式。

当IT0=1时,为边沿触发方式(下降沿有效)。 IE0(TCON.1),外部中断0中断请求标志位。 IT1(TCON.2),外部中断1触发方式控制位。 IE1(TCON.3),外部中断1中断请求标志位。

TF0(TCON.5),定时/计数器T0溢出中断请求标志位。 TF1(TCON.7),定时/计数器T1溢出中断请求标志位。

(3)、中断允许控制

51单片机学习总结史上最全版自己总结

EX0(IE.0),外部中断0允许位;

ET0(IE.1),定时/计数器T0中断允许位;

EX1(IE.2),外部中断0允许位;

ET1(IE.3),定时/计数器T1中断允许位;

ES(IE.4),串行口中断允许位;

EA (IE.7), CPU中断允许(总允许)位。

4、定时器初始化程序应完成如下工作:

(1)、对TMOD赋值,以确定T0和T1的工作方式。

(2)、计算初值,并将其写入TH0、TL0或TH1、TL1。

(3)、中断方式时,则对IE赋值,开放中断。

(4)、使TR0或TR1置位,启动定时/计数器定时或计数。

8 5、中断函数不需要声明2=2828=256,

void exter0()interrupt 0(01234分别对应的是外部中断0、定时器/计数器T0、外部中断1、定时器/计数器T1、串行口中断)

{

d1=0;

} 单片机中各种周期的关系与定时器原理

? 我们现来理解几个比较重要的概念:

? 时钟周期:

时钟周期也叫振荡周期或晶振周期,即晶振的单位时间发出的脉冲数,一般有外部的振晶产生,比如12MHZ=12×10的6次方,即每秒发出12000000个脉冲信号,那么发出一个脉冲的时间就是时钟周期,也就是1/12微秒。通常也叫做系统时钟周期。是计算机中最基本的、最小的时间单位。

在8051单片机中把一个时钟周期定义为一个节拍(用P表示),二个节拍定义为一个状态周期(用S表示)。

机器周期:

在计算机中,为了便于管理,常把一条指令的执行过程划分为若干个阶段,每一阶段完成一项工作。例如,取指令、存储器读、存储器写等,这每一项工作称为一个基本操作。完成一个基本操作所需要的时间称为机器周期。一般情况下,一个机器周期由若干个S周期(状态周期)组成。8051系列单片机的一个机器周期同6个S周期(状态周期)组成。前面已说过一个时钟周期定义为一个节拍(用P表示),二个节拍定义为一个状态周期(用S表示),8051单片机的机器周期由6个状态周期组成,也就是说一个机器周期=6个状态周期=12个时钟周期。

在标准的51单片机中,一般情况下,一个机器周期等于12个时钟周期,也就是机器周期=12*时钟周期,(上面讲到的原因)如果是12MHZ,那么机器周期=1微秒。单片机工作时,是一条一条地从RoM中取指令,然后一步一步地执行。单片机访问一次存储器的时间,称之为一个机器周期,这是一个时间基准。

机器周期不仅对于指令执行有着重要的意义,而且机器周期也是单片机定时器和计数器的时间基准。例如一个单片机选择了12MHZ晶振,那么当定时器的数值加1时,实际经过的时间就是1us,这就是单片机的定时原理。

但是在8051F310中,CIP-51 微控制器内核采用流水线结构,与标准的 8051 结构相比指令执行速度有很大的提高。在一个标准的 8051 中,除 MUL和 DIV以外所有指令都需要 12 或 24 个系统时钟周期,最大系统时钟频率为 12-24MHz。而对于 CIP-51 内核,70%的指令的执行时间为 1 或2个系统时钟周期,只有 4 条指令的执行时间大于 4 个系统时钟周期。 所以在计算定时器的值时要注意这里的变化。 指令周期

指令周期是执行一条指令所需要的时间,一般由若干个机器周期组成。指令不同,所需的机器周期数也不同。对于一些简单的的单字节指令,在取指令周期中,指令取出到指令寄存器后,立即译码执行,不再需要其它的机器周期。对于一些比较复杂的指令,例如转移指令、乘法指令,则需要两个或者两个以上的机器周期。

系统时钟:

系统时钟:系统时钟就是CPU指令运行的频率,这个才是CPU真正的频率。

单片机内部所有工作,都是基于由晶振产生的同一个触发信号源,由这个信号来同步协调工作步骤,我们把这个信号称为系统时钟,系统时钟一般由晶振产生,但在单片机内部系统时钟不一定等于晶振频率,有可能小于晶振频率,也有可能大于晶振频率,具体是多少由单片机内部结构决定,正常情况和晶振频率会存在一个整数倍关系。系统时种是整个单片机工作节奏的基准,它每振荡一次,单片机就被触发执行一次操作。

一般来说,单片机只有一个时钟源.用了外部晶振,就不用内部RC,用了内部RC,就不用外部晶振.振荡器振荡,产生周期波.单片机在这样的周期波的作用一下有规律的一拍一拍的工作,波的频率越高,单片工作得就越快,波的频率越低,单片机工作得就越慢。

有了以上的概念以后,就可以正确的理解定时器的工作原理了,在8051F310单片机中,有3个定时器,如果定时器1工作在模式1下,如工作模式1下,是16位的计时器,最大数值是65535,当再加1时(=65536),就会发生溢出,产生中断,所以如果我们要它计1000个数, 那么定时初值就是65536-1000,结果就是64536,这个值送给TH、TL,因为是16进制的,所以高位是64536/256取商,低位是64536%256取余。

再者,就是每一计数的时间是多久?一般我们取12M晶振时,一个周期刚好是1us,计数1000个就是1ms,这是因为标准的51单片机是12时钟周期的(STC有6时钟和1时钟方式)。那么,如果我们晶振是12M,就比较好算,如果是其它的,就用12去除好了。比如是6M的,那么就是12/6=2,每个计数是2us,那么你要定时1ms就只要计数500个即可以。

定时器的初值跟定时器的工作方式,跟晶振频率都有关系。一个机器周期Tcy=晶振频率X12,计数次数N=定时时间t/机器周期Tcy,那么初值就X=65536-N,得出的数化成十六进制就行了。这里是用定时器O工作方式1做例子,如果是其它工作方式,就不能是65535了。工作方式0是8192,方式2,3是256。这里有一个公式:

TH=(65536-time/(12/ft))/256

其中,time就是要延时的100ms(要取100000us),ft是晶振频率。这个式子又可以简化成 TH=(65536-time*ft/12)/256

TL=(65536-time*ft/12)%256

在一本书上还看到了这样计算定时初值的:

TH0=-(50235/256); //重装100ms定时初值

TL0=-(50235%256); ///这里使用的6M晶体,

这里是6M晶体,延时100ms,那么按上面讲的原理,6M是每个计数为2us,100ms定时就是计数50000个。

那么,定时器初值要 65536-50000=15536,转成16进是3CB0。这就是要送给TH(=3C) 和TL(=B0)的值。

程序中写 TH0=-(50235/256);其实它是这样的TH0=0x100-(50235/256); 在51中,取负数,其结果就是它的值取反+1,也可以用0x100(十进制的256)去减,结果是多少呢?结果就是3C。

51单片机学习总结史上最全版自己总结

更多类似范文
┣ 单片机学习总结 2000字
┣ 单片机学习总结 1400字
┣ 单片机学习总结 800字
┣ 单片机学习个人总结 500字
┣ 更多单片机学习总结
┗ 搜索类似范文