1、单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,单片机知识汇总,编程指南,源码工作室,单片机知识汇总,一,.,数码管,.,键盘,.,流水灯,.,蜂鸣器,简单的,IO,控制:,输出:,P0_1=1,时,P0.1,为,5V,输出,P0_1=0,时,P0.1,为,0V,输出,输入:,首先令:,P0_1=1,在进行读取操作:,temp=P0_1,一,.,数码管,.,键盘,.,流水灯,.,蜂鸣器,总结:,IO,输入输出操作相对比较简单容易理解,主要涉及到简单的模拟电路知识,理解硬件接法,理解矩阵扫描键盘的思想,二,.LCD1602,工作原理,知识点,编程步骤,知识
2、点,1.,硬件:引脚功能,序号,引脚名,I/O,口,1,VSS,2,VCC,3,VEE,4,RS,5,RW,6,EN,7,DB0,8,DB1,9,DB2,10,DB3,11,DB4,12,DB5,13,DB6,14,DB7,15,A,16,K,不同的硬件引脚名与,I/O,口对应关系取决于硬件连接检查方法:,1,、看电路图。,2,、借助万用表,2.,软件:写指令:清屏指令,功能:,清除液晶显示器,即将,DDRAM,的内容全部填入“空白”的字符码,20H;,光标归位,即将光标撤回液晶显示屏的左上方,;,将地址计数器,(AC),的值设为,0,。,3.,软件:写指令:,光标归位指令,功能:,把光标撤回
3、到显示器的左上方,;,把地址计数器,(AC),的值设置为,0;,保持,DDRAM,的内容不变,4.,软件:写指令:,输入模式设置指令,功能:设定每次写入,1,位数据后光标的移位方向,并且设定每次写入的一个字符是否移动。,参数设定的情况如下所示:,位名设置,I/D 0=,写入新数据后光标移,1=,写 入新数据后光标右移,S 0=,写入新数据后显示屏不移动,1=,写入新数据后显示屏整体右移,1,个字,5.,软件:写指令:,显示开关控制指令,功能:控制显示器开,/,关、光标显示,/,关闭以及光标是否闪烁。参数设定的情况如下:位名设置,D0=,显示功能关,1=,显示功能开,C0=,无光标,1=,有光标
4、B0=,光标不闪烁,1=,光标闪烁,6.,软件:写指令:,设定显示屏或光标移动方向指令,功能:使光标移位或使整个显示屏幕移位。参数设定的情况如下:,S/C R/L,设定情况,0 0,光标左移,1,格,且,AC,值减,1 0 1,光标右移,1,格,且,AC,值加,1 1 0,显示器上字符全部左移一格,但光标不动,1 1,显示器上字符全部右移一格,但光标不动,7.,软件:写指令:,功能设定指令(非常重要的指令),功能:设定数据总线位数、显示的行数及字型。参数设定的情况如下:,位名设置,DL 0=,数据总线为,4,位,1=,数据总线为,8,位,N 0=,显示,1,行,1=,显示,2,行,F0=57
5、点阵,/,每字符,1=510,点阵,/,每字符,8.,软件:写数据:,DDRAM,地址,我们往DDRAM里的00H地址处送一个数据,譬如0 x31(数字1的代码)并不能显示1出来。这是令初学者很容易出错的地方,原因就是如果你要想在DDRAM的00H地址处显示数据,则必须将00H加上80H,即0X80+0 x00,若要在DDRAM的01H处显示数据,则必须将01H加上80H即 0X80+0 x01。依次类推,9.,软件:读状态:读取忙信号,功能:,读取忙碌信号,BF,的内容,,BF=1,表示液晶显示器忙,暂时无法接收单片机送来的数据或指令,;,当,BF=0,时,液晶显示器可以接收单片机送来的数
6、据或指令,;,读取地址计数器,(AC),的内容。,10.,时序,读状态,输入:,RS=L,,,RW=H,,,E=H,输出:,DB0,DB7=,状态字,写指令,输入:,RS=L,,,RW=L,,,E=,下降沿脉冲,,DB0,DB7=,指令码 输出:无,读数据,输入:,RS=H,,,RW=H,,,E=H,输出:,DB0,DB7=,数据,写数据,输入:,RS=H,,,RW=L,,,E=,下降沿脉冲,,DB0,DB7=,数据 输出:无,读状态 输入:RS=0,RW=1,E=1,读数据 输入:RS=1,RW=1,E=1,写指令,输入:,RS=0,,,RW=0,,,E=,下降沿脉冲,,DB0,DB7=,指
7、令码,写数据,输入:,RS=1,,,RW=0,,,E=,下降沿脉冲,,DB0,DB7=,数据,编程步骤:,初始化液晶,1,、功能设定指令,2,、显示开关指令,3,、输入模式指令,4,、清屏,While,(,1,),写入显示地址,写入显示数据,编写子函数,LCD_busy,(),LCD_writecmd,(),LCD_writedat,(),LCD_int,(),三,.,中断,工作原理,知识点,编程步骤,工作原理,知识点,1.,结构:结构框图,看懂图中每个开关的作用,每个开关对应一位寄存器,2,、结构:中断优先级,很好的理解优先级的概念,3.,软件:寄存器:,TCON,IT0,(,TCON.0,
8、外部中断,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.,软件:寄存器:,SCON,RI,(,SCON.0,),,串行口接收中断标志位。当允许串行口接收数据时,每接收完一个串行帧,由硬件置位,RI,。注意,,RI,必
9、须由软件清除。,TI,(,SCON.1,),,串行口发送中断标志位。当,CPU,将一个发送数据写入串行口发送缓冲器时,就启动了发送过程。每发送完一个串行帧,由硬件置位,TI,。,CPU,响应中断时,不能自动清除,TI,,,TI,必须由软件清除。,4.,软件:寄存器:,IE,EX0(IE.0),,外部中断,0,允许位;,ET0(IE.1),,定时,/,计数器,T0,中断允许位;,EX1(IE.2),,外部中断,0,允许位;,ET1(IE.3),,定时,/,计数器,T1,中断允许位;,ES,(,IE.4),,串行口中断允许位;,EA(IE.7),,,CPU,中断允许(总允许)位。,5.,软件:寄存
10、器:,IP,PX0,(,IP.0,),外部中断,0,优先级设定位;,PT0,(,IP.1,),定时,/,计数器,T0,优先级设定位;,PX1,(,IP.2,),外部中断,0,优先级设定位;,PT1,(,IP.3,),定时,/,计数器,T1,优先级设定位;,PS,(,IP.4,),串行口优先级设定位;,PT2,(,IP.5,),,定时,/,计数器,T2,优先级设定位。,编程指南,1,、中断源有中断请求;,2,、此中断源的中断允许位为,1,;,3,、,CPU,开中断(即,EA=1,)。,以上三条同时满足时,,CPU,才有可能响应中断。,1,、开总中断(,EA=1,),must,2,、开对应中断(如
11、ET0=1,),must,3,、外部中断设置,IT0,、,IT1,may,当,IT0=0,时,为电平触发方式。,当,IT0=1,时,为边沿触发方式(下降沿有效),.,4,、设置优先级,IP,(如果需要),if,5,、中断函数,四、定时计数器,工作原理,知识点,编程步骤,工作原理,时钟一般是与中断配合的,所以一般我们把中断时钟合并到一起理解,结构框图,1.,结构:结构框图,2.,软件:寄存器:,TMOD,80C51,单片机定时,/,计数器的工作由两个特殊功能寄存器控制。,TMOD,用于设置其工作方式;,TCON,用于控制其启动和中断申请。,T1,T0,2.,软件:寄存器:,TMOD,GATE,
12、门控位。,GATE,0,时,只要用软件使,TCON,中的,TR0,或,TR1,为,1,,就可以启动定时,/,计数器工作;,GATA,1,时,要用软件使,TR0,或,TR1,为,1,,同时外部中断引脚或也为高电平时,才能启动定时,/,计数器工作。即此时定时器的启动条件,加上了或引脚为高电平这一条件。,:,定时,/,计数模式选择位。,0,为定时模式;,=1,为计数模式。,3.,软件:寄存器:,TMOD:,方式,0,方式,0,为,13,位计数,由,TL0,的低,5,位(高,3,位未用)和,TH0,的,8,位组成。,TL0,的低,5,位溢出时向,TH0,进位,,TH0,溢出时,置位,TCON,中的,
13、TF0,标志,向,CPU,发出中断请求。,4.,软件:寄存器:,TMOD:,方式,1,方式,1,的计数位数是,16,位,由,TL0,作为低,8,位、,TH0,作为高,8,位,组成了,16,位加,1,计数器。,计数个数与计数初值的关系为,:,5.,软件:寄存器:,TMOD:,方式,2,方式,2,为自动重装初值的,8,位计数方式。,计数个数与计数初值的关系为:,工作方式,2,特别适合于用作较精确的脉冲信号发生器。,6.,软件:寄存器:,TMOD:,方式,3,方式,3,只适用于定时,/,计数器,T0,,定时器,T1,处于方式,3,时相当于,TR1=0,,停止计数。,工作方式,3,将,T0,分成为两个
14、独立的,8,位计数器,TL0,和,TH0,。,7.,软件:寄存器:,TCON,TF1,(,TCON.7,):,T1,溢出中断请求标志位。,T1,计数溢出时由硬件自动置,TF1,为,1,。,CPU,响应中断后,TF1,由硬件自动清,0,。,T1,工作时,,CPU,可随时查询,TF1,的状态。所以,,TF1,可用作查询测试的标志。,TF1,也可以用软件置,1,或清,0,,同硬件置,1,或清,0,的效果一样,.,TR1,(,TCON.6,):,T1,运行控制位。,TR1,置,1,时,,T1,开始工作;,TR1,置,0,时,,T1,停止工作。,TR1,由软件置,1,或清,0,。所以,用软件可控制定时,
15、/,计数器的启动与停止。,TF0,(,TCON.5,):,T0,溢出中断请求标志位,其功能与,TF1,类同,.,TR0,(,TCON.4,):,T0,运行控制位,其功能与,TR1,类同。,TCON,的低,4,位用于控制外部中断,已在前面介绍。,TCON,的高,4,位用于控制定时,/,计数器的启动和中断申请。其格式如下:,8.,软件:寄存器:计数初值计算,方式,0 X=8192-T(fosc/12),方式,1 X=65536-T(fosc/12),方式,2,、方式,3 X=256-T(fosc/12),放入寄存器方法:,TH0=(65536-1000)/256;/,高八位,TL0=(65536-
16、1000)%256;/,低八位,TH0=(65536-1000)8;/,高八位,TL0=(65536-1000)/,低八位,编程步骤,1,)确定工作方式:把工作方式控制字写入到,TMOD,中;,2,)设置定时或计数的初值:根据问题要求,求出定时或计数的初值,写入到寄存器,THO,、,TLO,或,THI,、,TLI,中。,3,)如果需要中断,使定时器中断允许位,ET0,或,ETI,置位,如果要求中断嵌套,还应设置相应的中断优先级,然后置位,EA,,使,CPU,开放中断;如果不需要中断,仅以软件方式对计数器溢出标志,TFO,或,TFI,进行查询,则可略去此步骤;,4,)启动定时器计数器:将,TRO
17、或,TRI,置,1,即可启动定时器计数器,五、串口通信,工作原理,知识点,编程步骤,工作方式,将数据一位一位的传入接收设备,接收设备将数据转换成一个字节或多个自己的并行数据后,进行处理,知识点,1.,串口:硬件:结构框图,80C51,串行口的结构,2.,串口:硬件:硬件接法,根据通信距离不同,电路连接方式不同的。如果是单片机与单片机之间通信,(,近距离,),,又不使用握手信号,只需要,3,根信号线:,TXD,,,RXD,,,GND,见,(a),。如果距离在,15m,左右,通过,RS232,接口,提高信号的幅度以加大传送距离,,(,如单片机与,PC,机之间通信,),连接方法见,(b),。,2.
18、串口:硬件:硬件接法,3.,串口:软件:寄存器:,SCON,SCON,是一个特殊功能寄存器,用以设定串行口的工作方式、接收,/,发送控制以及设置状态标志:,SM0,和,SM1,为工作方式选择位,可选择四种工作方式:,SM2,,多机通信控制位,主要用于方式,2,和方式,3,。当接收机的,SM2=1,时可以利用收到的,RB8,来控制是否激活,RI,RB8,0,不激活,RI,,收到的信息丢弃;,RB8,1,时收到的数据进入,SBUF,,并激活,RI,,进而在中断服务中将数据从,SBUF,读走)。,当,SM2=0,时,不论收到的,RB8,为,0,和,1,,均可以使收到的数据进入,SBUF,,并激活,
19、RI,(即此时,RB8,不具有控制,RI,激活的功能)。通过控制,SM2,,可以实现多机通信。,在方式,0,时,,SM2,必须是,0,。在方式,1,时,若,SM2=1,,则只有接收到有效停止位时,,RI,才置,1,。,REN,,允许串行接收位。由软件置,REN=1,,则启动串行口接收数据;若软件置,REN=0,,则禁止接收。,TB8,,在方式,2,或方式,3,中,是发送数据的第九位,可以用软件规定其作用。可以用作数据的奇偶校验位,或在多机通信中,作为地址帧,/,数据帧的标志位。,在方式,0,和方式,1,中,该位未用。,RB8,,在方式,2,或方式,3,中,是接收到数据的第九位,作为奇偶校验位或
20、地址帧,/,数据帧的标志位。在方式,1,时,若,SM2=0,,则,RB8,是接收到的停止位,TI,,发送中断标志位。在方式,0,时,当串行发送第,8,位数据结束时,或在其它方式,串行发送停止位的开始时,由内部硬件使,TI,置,1,,向,CPU,发中断申请。在中断服务程序中,必须用软件将其清,0,,取消此中断申请。,RI,,接收中断标志位。在方式,0,时,当串行接收第,8,位数据结束时,或在其它方式,串行接收停止位的中间时,由内部硬件使,RI,置,1,,向,CPU,发中断申请。也必须在中断服务程序中,用软件将其清,0,,取消此中断申请。,4.,串口:软件:寄存器:,SCON,:方式一,方式,1,
21、是,10,位数据的异步通信口。,TXD,为数据发送引脚,,RXD,为数据接收引脚,传送一帧数据的格式如图所示。其中,1,位起始位,,8,位数据位,,1,位停止位。,5.,串口:软件:寄存器:,PCON,SMOD,(,PCON.7,)波特率倍增位。在串行口方式,1,、方式,2,、方式,3,时,波特率与,SMOD,有关,当,SMOD=1,时,波特率提高一倍。复位时,,SMOD=0,。,6.,串口:软件:寄存器:,PCON,:波特率计算,串行口的四种工作方式对应三种波特率。由于输入的移位时钟的来源不同,所以,各种方式的波特率计算公式也不相同。,方式,1,的波特率,=,(,2,SMOD,/32,),(
22、T1,溢出率),T1,溢出率,=,fosc,/12256,(,TH1,),串行通信的程序设计步骤,设置串口寄存器,设置波特率参数。波特率的参数有:特许寄存器,PCON,的,SMOD,位和,SCON,寄存器;,设置波特率,允许定时,/,计数器工作,设置计数初值,开启定时,/,计数器,设置中断允许,允许串行中断。程序中我们一般采用中断接收方式故设置,EA=1,和,ES=1,注意:,编写相应的中断服务程序。当有数据达到串口时,系统自动执行所编写的中断服务程序;,收发相应数据。注意发送操作完成时要将,TI,清零,接收工作完成后需要将,RI,清零。,单片机基础知识,周期,时钟周期,:晶振的振荡周期,又
23、称为时钟周期,为单片机最小的时序单位;,机器周期,:一个机器周期由,12,个时钟周期组成,是计算机执行一种基本操作的时间单位;,指令周期,:执行一条指令所需要的时间。一个指令周期由,14,个机器周期组成,依据指令不同而不同。,引脚,MOVC,MOV,MOVX,特殊功能寄存器,需要记住的,可位寻址的,需要记住,但根本不用记得,程序命名,直观移动增加序号区分:,lesson1_1,lesson1_2,增加时间,Led(3/28),Led(3/29),得到部分结果随时压缩备份,程序分块编写,/*,*Function:1602,液晶读写函数,*,Author :LAB9,*Date :2012-02-
24、05,*/,/*,包含头文件*,/,#include,#include,/*,管脚定义*,/,/*,全局变量*,/,程序中尽量不出现,PX,口,#define,LCD_data,=P0;,好处:,方便程序移植,函数前使用详细说明如,/*,函数名:,main,功 能:主函数,变 量:无,返回值:无,*,/,函数内部增加注释,注释不用每步都加,增加注释目的为方便别人理解,模块化编程概述,为什么要引入模块化编程?,通过以上几讲内容,我们初步掌握了单片机,C,语言编程的基本原理与基本方法。同时我们可以观察并体会到,随着代码量的增加,将所有代码都放在同一个,.c,文件中的做法越发使得程序结构混乱、可读性
25、与可移植性变差,而模块化编程是解决这个问题的常用而有效的方法。,模块化设计原则,高内聚,:一个,c,文件里面的函数,只有相互之间的调用,而没有调用其他文件里面的函数,这样可可以视为高内聚。尽量减少不同文件里函数的交叉引用。,低耦合,:一个完整的系统,模块与模块之间,尽可能的使其独立存在。也就是说,让每个模块,尽可能的独立完成某个特定的子功能。模块与模块之间的接口,尽量的少而简单。,模块化编程的三种手段,实现模块化编程的,三个主要手段,是,函数,、,宏定义,与,头文件,。下面讲解一下头文件操作的详细步骤。,第一步 创建头文件,建立一个,.c,文件(源文件)和一个,.h,文件(头文件)。原则上文件
26、名可以任意命名,但强烈推荐如下原则:,.c,文件与,.h,文件同名;文件名要有意义,最好能够体现该文件代码的功能。例如延时函数相关的源文件与头文件命名为,delay.c,与,delay.h,。,第二步,防重复包含处理,在,.h,文件中加入如下代码:,#,ifndef,XXX,#define XXX,./,此处添加代码,#,endif,其中的,XXX,原则上可以是任意字符,但同一个工程中各个,.h,文件的,XXX,不能相同,因此强烈推荐如下的规则:将,.h,文件的文件名全部大写,“,.”,替换成下划线“,_”,,首尾各添加,2,个下划线“,_”,作为,XXX,。例如对于,delay.h,文件,其
27、内容如下:,#,ifndef,_DELAY_H_,#define _DELAY_H_,./,此处添加代码,#,endif,因为在同一个工程内,文件名都是唯一的,因此这种命名规则可以保证,XXX,不会重复。之后要添加到,.h,文件的代码都放在第,3,行的位置。,这样处理之后,当,.h,文件第一次被包含时,符号,XXX,是未被定义过的,因此符合,#,ifndef,的条件,编译器会继续编译第,1,行以后的代码。然后编译到第,2,行,先定义一下符号,XXX,,然后开始编译第,3,行直到最后一行,#,endif,的代码。而此后此,.h,文件再次被包含时,符号,XXX,在第一次包含该,.h,文件时已被定义
28、过了,不符合第一行,#,ifndef,的条件,则该,.h,文件的内容就不会被编译器编译。总之,这样处理之后既能保证,.h,文件的有效内容被编译,又能保证,.h,文件的有效内容不被重复编译。,第三步,代码封装,将需要模块化的代码封装成函数与宏定义。函数体放在,.c,文件中,需要被外部调用的函数还要在,.h,文件中声明一下;需要被外部调用的宏定义放在,.h,文件中,仅会被本,.c,文件调用的宏定义放在,.c,文件中。,第四步,尽量少用或不用全局变量,必须要用的全局变量的声明要放在,.c,文件中,需要被外部调用的全局变量还要在,.h,文件中重新用,extern,修饰声明一下,用来告诉编译器有这个变量的存在(因为编译器的编译过程是按文件来的,链接过程才是各个文件的合并,如果没有这一步,extern,修饰声明就在另一个文件调用了这个变量,编译器会提示没有此变量)。,第五步,添加源文件,将,.c,文件添加到工程之中,同时在需要调用,.h,文件中的宏或者函数(这里的函数是对应的,.c,文件中函数的声明)的其他,.c,文件中添加代码将该,.h,文件包含进去(例如,#,includedelay.h,)。,第六步,使用,头文件中的函数、宏定义、全局变量可以在包含了对应,.h,文件的,.c,文件中自由调用使用了,






