51单片机知识点回顾
一、单片机又称单片微控制器(单片微型计算机),就是一块集成芯片,具有特殊功能,而它的功能实现需要我们使用者来编程实现。二、单片机封装表面有一小原点,这个小圆点所对应的引脚就是芯片第一脚,逆时针方向数下去,既1到最后一个脚。三、单片机时钟脚单片机晶振的作用是为系统提供基本的时钟信号。单片机系统里都有晶振,在单片机系统里晶振作用非常大,全程叫晶体振荡器,他结合单片机内部电路产生单片机所需的时钟频率,单
一、单片机又称单片微控制器(单片微型计算机),就是一块集成芯片,具有特殊功能,而它的功能实现需要我们使用者来编程实现。
二、单片机封装表面有一小原点,这个小圆点所对应的引脚就是芯片第一脚,逆时针方向数下去,既1到最后一个脚。
三、单片机时钟脚
单片机晶振的作用是为系统提供基本的时钟信号。
单片机系统里都有晶振,在单片机系统里晶振作用非常大,全程叫晶体振荡器,他结合单片机内部电路产生单片机所需的时钟频率,单片机晶振提供的时钟频率越高,那么单片机运行速度就越快,单片接的一切指令的执行都是建立在单片机晶振提供的时钟频率。
1.外接时钟引脚
一种是片内时钟震荡方式,需在这两个引脚之间接石英晶体和震荡电容(一般取10p~30p),
一种是外部时钟方式,即将XTAL1接地,外部时钟信号从XTAL2脚引入。
XTAL1为片内震荡电路的输入端,XTAL2为片内震荡电路的输出端
片内振荡电路:单片机内部带有振荡电路,如果要外接晶振,连接一个晶振和两个电容即可
注:如果压测量所接晶振是否起振,可用一下方式侧量
(1)用示波器看波形是最直接的,抓晶振的两只脚波形,看看波形是否正确。(两只脚的幅度不同,但波形都一样的!)
单片机的两个信号输入脚一个是(XTAL1)一个是(XTAL2)对应单片机内部的电路是高增益放大器,当外面接晶振的时候,XTAL1对应高增益放大器的输入端,XTAL2对应高增益放大器的输出端,所以你测量的时候应该是高增益输出端有信号也就是XTAL2
晶振波形一般是正弦波或者方波,当输出波形是方波时,一般上升沿比较抖,且包含了较多的高频信号,这个时候就要保证测试的带宽足够,理论值是带宽是被测信号频率的2倍,实际测试方波时带宽应该是被测信号频率的10倍。
除了带宽之外,在测试晶振时,还有一点应该重点注意:晶振对电容负载较敏感,探头电容相对较大,相当于一个很重的负载并联在晶振电路中,容易导致电路停振而得不出正确的测量结果。
所以在进行晶振测试的时候,需要保证足够的带宽和较小的输入电容。
示波器测试晶振的正确方法
首先我们来回答标题的问题,用200M示波器绝对可以测试10M晶振的波形,可是为什么测出来的波形是图1的形状呢?
这是因为在测试的时候,探头选择了&TImes;1档位,ZDS2000系列标配的ZP1025S探头在&TImes;1档时带宽为10MHz,输入电容为55 pF±10 pF,由此导致了波形的失真。
让我们将探头档位调为&TImes;10档,此时探头带宽为250MHz,输入电容为13pF±5 pF,我们来看看此时的波形吧
(2)用数字万用表的电压档测电压也行,因晶振波形的占空比为50%,所以测得的平均电压为1/2Vcc左右
2.内建RC震荡电路与晶振振荡电路
(1)RC震荡电路主要是容易受电源电压和环境温度影响比较大,导致误差大
(2)晶振震荡电路比较精确,但是不耐摔
所以现在其实大部分是使用内建RC震荡器,因为成本节约,再者现在单片机工艺也很成熟,内建RC精度也可以。
四、复位电路
对51单片机而言,当连续输入两个机器周期以上高电平时有效,复位后程序计数器
PC=0000H,既从程序存储器的0000H单元读取第一条指令码,通俗讲就是单片机从头开始执行。
复位电路图
五、引脚IO
1.首先来讲讲高阻态
高阻态,指的是电路的一种输出状态,既不是高电平也不是低电平
高阻态的实质:电路分析时高阻态可做开路理解。你可以把它看作输出(输入)电阻非常大。他的极限可以认为悬空。也就是说理论上高阻态不是悬空,它是对地或对电源电阻极大的状态
拿51单片机P0口来说
(1)双向IO ,当P0口用于一般I/O口时,内部接Vcc的那个开关管是与引脚(端口)脱离联系的,这个时候,只有拉地的那个开关管其作用,P0口作为输出,是必须外接上拉电阻的,不然就无法输出高电平;
(2)P0口作为输入,则必须先对端口写1,使拉地的开关管断开,这个时候,如果不接上拉电阻,则是高阻状态,就是一个双向口
如图:
“1”时断开,“0”时闭合。很明显可以看出,当开关闭合时,输出直接接地,所以输出电平为0。而当开关断开时,则输出端悬空了,即高阻态。这时电平状态未知。
所以就有了第一句所讲“高阻态,指的是电路的一种输出状态,既不是高电平也不是低电平”。如果接上拉电阻,则本身输出高电平,对输入信号的逻辑无影响(注意是对逻辑无影响,对实际参数有无影响我不确定,但是我认为是有的)。
所以,高阻态该端口不会影响到该通信线的电平变化,但还是可以读取端口的电平。一般高阻态都是作为模拟量输入的,因为高阻态不会影响到输入的电平,可以准确的读取模拟量。
2.双向与准双向
双向与准双向,根本原则是双向包含了高阻这个状态,而不在于是否需要先写1或者不写,P1~P3口因为有内部上拉电阻,因此无论如何不是双向;P0口内部无上拉电阻,在处于数据/地址功能时,自动完成3态的转换,是双向,处于一般I/O口时,如果不接外部上拉,而且先向端口写了1,那么就处于高阻状态,此时,它也是一个人为的双向口,这与它处于地址/数据功能时的自动双向有区别,以及与P1~P3处于输入时输出锁存器为1是有区别的
3.
总而言之,若果IO做输入使用前,要先进项写1操作,单片机才能读取外部信号。
准双向IO:顾名思义使其先有个“准”被过程,置1 的操作。
像P0口这样,内部没上拉,要做输出的话,一定要挂上拉电阻(一般选择10K),否则无法输出高电平
六、逻辑电平
1.常用的逻辑电平有:TTL、CMOS、ECL、PECL、LVDS、LVPECL、RS232、RS422、RS485、CML、SSTL、HSTL等
RS232/RS422/RS485是串口(UART)的电平标准,RS232是单端输入输出,RS422和RS485是差分输入输出;
ECL、PECL、LVPECL、LVDS、CML是差分输入输出电平;
SSTL主要用于DDR存储器,HSTL主要用于QDR存储器
2.
TTL电平:
输出高电平>2.4V,输出低电平<0.4V。在室温下,一般输出高电平是3.5V,输出低电平是0.2V。最小输入高电平和低电平:输入高电平>=2.0V,输入低电平<=0.8V,噪声容限是0.4V。
CMOS电平:
1逻辑电平电压接近于电源电压,0逻辑电平接近于0V。而且具有很宽的噪声容限
七、数据类型
数据类型 关键字 所占位数 表示数的范围
无符号字符型 unsigned char 1字节(8位) 0~255即(2^8)-1
有符号字符型 (signed 可省略) char 1字节(8位) -128~127即 -2^7~(2^7)-1)
无符号整型 unsigned int 2字节(16位) 0~65535即(2^16)-1
有符号整型 (signed 可省略) int 2字节(16位) 32768~32767即 -2^15~(2^15)-1
无符号长整型 unsigned long 4字节(32位) 0~(2^32)-1
有符号长整型 (signed 可省略) long 4字节(32位) -2^31~(2^31)-1
单精度实型 float 4字节(32位) 3.4e-38~3.4e38
双精度实型 double 8字节(64位) 1.7e-308~1.7e308
在一般系统中,float和double,float只能提供7位有效,double能提供到15-16位。
float a = 123.1235
八、数据类型扩充定义
(1)sbit-声明一个特殊寄存器中的某一位
(2)sfr-特殊功能寄存器数据声明,声明一个8位寄存器
(3)sfr16 - 就是声明一个16位
看看51的头文件声明
sfr P0 = 0X80;这句话就是将单片机内部地址0x80重命名叫P0,之后我们再程序直接操作P0就是对0x80地址处寄存器进行操作。也就是说sfr这个关键字就是我们与单片机沟通的桥梁,单片机本身不认识P0,它只知道内部地址。
sbit亦是如此,只不过它寄存器中的某一位而已。
注意:头文件定义如若定义为大写,你写程序写成小写编译器就会出错
九、51常用头文件
#include<math.h> 包含各种运算函数 常用
#include<stdio.h> stdio为standard input output的缩写,意为“标准输入输出”,scanf和printf是标准输入输出函数,其头文件为stdio.h
#include<stdlib.h>
是baiC语言中的一个头文件,stdlib 头文件里包du含了C语言的一些函数,该文件zhi包含了的C语言标准库函数的定义。
拓展资料:
1. stdlib.h里面dao定义了五种类型、一些宏和通用工具函数,例如size_t、wchar_t、div_t、ldiv_t和lldiv_t;宏例如EXIT_FAILURE、EXIT_SUCCESS、RAND_MAX和MB_CUR_MAX等。
2. 常用的函数如malloc()、calloc()、realloc()、free()、system()、atoi()、atol()、rand()、 srand()、exit()等。
3. stdlib.h的解释*Purpose:* This include file contains the function declarations focommonly* used library functions which either don't fit somewhere else, or,* cannot be declared in the normal place for other reasons.意思是一些常用的函数。
4. 不知道把它们放到哪里合适,就都放到了stdlib.h这个头文件中,stdlib.h可以提供一些函数与符号常量,具体如下:根据ISO标准,stdlib.h提供以下类型:size_t, wchar_t, div_t, ldiv_t, lldiv_t常量NULL, EXIT_FAILURE, EXIT_SUCESS, RAND_MAX, MB_CUR_MAX函数atof, atoi, atol, strtod, strtof, strtols, strtol, strtoll, strtoul, strtoull, rand, srand, callc, free, maloc, realloc, abort, atexit, exit, getenv, system, bsearch, qsort, abs, div, labs, ldiv, llabs, tlldiv, mblen, mbtowc, wctomb, mbstowcs, wcstombs
#include<intrins.h>
intrins.h 在C51单片机编程中,头文bai件INTRINS.H的函数使用起来,就会du让你像zhi在用汇编时一样简便dao.
内部函数 描述
_crol_ 字符循环左移
_cror_ 字符循环右移
_irol_ 整数循环左移
_iror_ 整数循环右移
_lrol_ 长整数循环左移
_lror_ 长整数循环右移
_nop_ 空操作8051 NOP 指令
_testbit_ 测试并清零位8051 JBC 指令函数名: _crol_,_irol_,_lrol_
十、头文件的作用
(1)在代码中引用头文件意义就是将这个头文件的全部内容放到引用头文件的位置处,免去我们每次编写同类程序都要将头文件的额语句重复编写。
(2)头文件的两种写法区别
#include<reg51.h>
#include‘’reg51.h"
使用<>包含头文件时,编译器先进入软件安装文件夹处搜索这个头文件,若果搜索不到,编译器报错。
使""包含头文件时,编译器先进入工程所在的文件夹处开始搜索这个头文件,若果在当前工程文件夹没找到这个头文件,编译器会到软件安装文件夹处搜索这个头文件,若果搜索不到,编译器报错。
像51、52头文件正常在我们软件安装地方,所以我们一般写成#include<reg51.h>
想要打开头文件的内容,将鼠标移至reg51.h上,单击右键,选择
十一、main函数
(1)无轮一个程序有多大或者有多小,所有单片机在运行是总是从主函数先运行
(2)void main()
void :表示“空”,即没返回值意思
无参数:void main(void)括号里写“void”,表示空;不写也是一样
十二、周期
1.时钟周期:是指振荡源的周期,如 外部晶振 10MHz,那么它的时钟周期就是 1/10MHz=0.1us;
它是单片机最小时间单位,一个时钟周期,CPU仅完成一个最基本动作,对单排及而言,时钟频率越高,单片机工作速度越快。
2.机械周期:单片机执行一单位指令所需要的 时钟周期 个数,如 1T,就表示,需要 1个时钟周期;12T 即为 12个时钟周期。这些都只是 一单位指令的时间(如自增、自减 等)。
T:在13.6有在解释
当然在现在消费电子领域中,对功耗要求大,有时候就不需要很高的频率来运行,因为频率越高,单片机跑的速度越快,功耗越高
十三、中断
中断指CPU在处理某一件事A时,发生了另一件事B,请求CPU,迅速去处理(中断发生);CPU暂时停止当前工作转去处理事件B(中断服务函数);待将事件B处理完后,再回到原来事件A被中断的地方继续处理事件A(中断返回),所以这么整一个过程就叫中断。
1.引起CPU中断的叫中断源
2.处理完再回到原来被中断的地方叫断点
3.设计到中断就得考虑到一个关键词-----优先级
现在的51单片机基本都可以编写寄存器控制其等级
默认中断级别
外部中断0 最高 序号0
T0定时器中断 第2 序号1
外部中断1 第3 序号2
T1定时器中断 第4 序号3
TI/RI串行口中断 第五 序号4
T2定时器中断 最低 序号5
4.中断允许寄存器 IE
最高位-->最低位
EA----全局中断允许位,要开启其他中断切记要打开全局中断。
ET2--定时器2中断允许位 第5位
ES---串行口中断允许位
ET1--定时器1中断允许位
EX1---外部中断1允许位
ET0---定时器0中断允许位
EX0---外部中断0允许位
5.中断优先级寄存器IP
IP用来设定各个中断源属于两级中断的哪一级(高优先级还是低优先级),复位后IP全部清零
PS---串行口中断优先级控制位
PS = 1,定义为高优先级中断
PS = 1,定义为低优先级中断
PT1--定时器1中断优先级控制位
PX1--外部中断1中断优先级控制位
PT0--定时器0中断优先级控制位
PX0--外部中断0中断优先级控制位
在51系列单片机中,高优先级能打断低优先级行程中断嵌套,若几个同等级中断向CPU请求中断,在没有设置中断优先级的情况下,按照默认中断优先级响应中断。
6.定时器中断
(1)定时器系统是单片机内部一个独立硬件部分,它与CPU和晶振通过某些控制线连接并相互作用,CPU开启定时定时器功能,定时器便在晶振作用下自动计时。
(2)定时器实质就是加1计数器(16位),由高8位和低8位两个组成。
TMOD定时器工作方式寄存器
TCON控制寄存器,控制定时器启动和停止及溢出标志
(3)首先先来连了解,定时器原理
定时器、计数器结构实际是通过里面的加1计数器进行计数的。
加1计数器输入的技术脉冲有两个来源,一个是有系统时钟振荡器输出的脉冲经N分频后送来的;另一个是T0或T1引脚的外部驶入脉冲,每来一个脉冲计数器加1,当加到计数器全部为1 (计数器有16位),再输入一个脉冲计数器就回零,这时候计数器就溢出,TCON寄存器的TF0或者TF1置1 ,向CPU请求中断。
分析上面这一段话
第一点,我们现在学习AT8951或者STC895主频是以12T指令运行(单片机数据会说明是几T),所以当加1计数器脉冲来源有系统震荡器提供时,振荡器脉冲需要经12分频后送进来;而这里12分频并不是真的分频,N分频并不是把周期除以N,而是指:原来的信号经过N个周期后,新的信号跳变一,所以结果就是脉冲的周期翻倍。
所以每来一个脉冲计数器加1,当单片机是以12T指令运行时,加1计数器加1的时间计数就等于12*T,当你时钟为12MHZ,那么计数器没加1时间就是12*1/12 = 1us.
且因为机械周期代表着单片机执行一单位指令(自加、自减),所以也就有了书上所说1个机器周期等于12个振荡周期(时钟周期)
由此可见,溢出时计数器的值减去计数初值才是我们加1计数器的计数值。
体外话,现在很多51单片机都是以1T运行的,1T快(如CMS5880举个例子而已,因为最近刚好项目在用这个单片机)
(4)定时器、计数器工作方式寄存器TMOD
GATE—门控制位。
GATE=0,定时器/计数器启动与停止仅受TCON寄存器中TRx位来控制。
GATE=1,定时器/计数器启动与停止由TCON寄存器中TRx位和外边中断引脚(INT0或INT1)上的电平状态来共同控制
C/T—定时器模式和计数器模式选择位。
C/T=0,定时器模式。
C/T=1,计数器模式
M1:M0—工作方式选择位。
每个定时器/计数器由4中工作方式,他们由M1和M0设定,对应关系如下表所示。
定时器/计数器的4种工作方式
M1 | M0 | 工作方式 |
0 | 0 | 方式0:13位定时器/计数器 |
0 | 1 | 方式1:16位定时器/计数器 |
1 | 0 | 方式2:8位初始值自动重置的8位定时器/计数器 |
1 | 1 | 方式3:仅适用于T0,分成两个8位计数器,T1停止计数 |
(5)定时器、计数器控制寄存器TTCON
位序号 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
位符号 | TF1 | TR1 | TF0 | TR0 | IE1 | IT1 | IE0 | IT0 |
位地址 | 8FH | 8EH | 8DH | 8CH | 8BH | 8AH | 89H | 88H |
TF1—定时器1溢出标志位。
当定时器1计满溢出时,由硬件使TF1置1,并且申请中断。进入中断服务程序后,由硬件自动清0。需要注意的是,如果使用定时器的中断,那么该位完全不用人为去操作,但是如果使用软件查询的方式的话,当查询到该位置1后,就必须用软件清0。
TR1—定时器1运行控制位。
由软件清0关闭定时器1;当GATE=0时,TR1置1启动定时器1。
TF0—定时器0溢出标志位。
该位与TF1功能和操作方法相同。
TR0—定时器0运行控制位。
该位与TR1功能和操作方法相同
IE1—外部中断1请求标志。
当IT1=0时,外部中断INT1为电平触发方式,每个机器周期采用INT1引脚,若INT1引脚为低电平,则置1,否则IE1清0。
当IT1=1时,外部中断INT1为边沿触发方式,当采集到INT1由高电平向低电平的跳变时则将IE1置1。IE1=1表示外部中断1正向CPU申请中断。当CPU响应中断转向中断服务程序时,该位由硬件清0。
IT1—外部中断1触发方式选择位。
IT1=0,电平触发方式,引脚INT1上低电平触发中断。
IT0=1,边沿触发方式,引脚INT1上由高电平向低电平的跳变触发中断。
IE0—外部中断0请求标志。
这一位的用法与IE1相同。
IT0—外部中断0触发方式选择位。
这一位的用法与IT1相同。
软件上外部中断0触发
void main(void)
{
// IT0=0; //低电平触发
IT0=1; //下降沿触发
EA=1; //打开总中断
EX0=1; //外部中断0允许位
while(1)
{
P0=Disp_Tab[LedNumVal%10];
}
}
/********************************************************
* INT0中断函数 *
********************************************************/
void counter(void) interrupt 0
{
EX0=0;
LedNumVal++; //中断计数
EX0=1;
}
(6)定时器计数工作 方式-方式1:16位定时器如何计算初值
分析:在89C51计数工作原理,当启动定时器,TL0便在机器周期作用下开始加1计数,当TL0挤满后向TH0进一位,直到吧TH0也寄满,此时计数器溢出,置TF0为1 ,向CPU请求中断,这就是定时器0的工作方式1。
(第一种,这种工作方式就是你计数多少,先65536-计数的值,得到的值然后开始在这值上面进行计数直到溢出。常用
第二种,还有一种比较少用的,就是你吧值装进去TH0和TL0,然后计数就在这个值上面进行倒计时,知道清零。)
第一种:所以定时器一启动,它便在原来数值上开始加1计数,若在程序开始时,我们没有设置TH0和TL0,他们默认都是0;16位定时器计满需 65536us。
现在假设我们要定时50ms,那就是50000us,等于要计数50000个数后,定时器溢出,此时刚好50ms中断一次
那么TH0 TL0
65536-50000 = 15536
TH0 = 15536/256 = 60
TL0 = 求剩下的余数,就是15536-(60*256) = 176
换种方式写就是下面写法
TH0 = (65536-50000)>>8 = (65536-50000)/256
TL0 = (65536-50000)%256
有时候我们为了节省单片机运行时间,我们自己先计算好值直接赋值进去也可以
TH0 = 0x3C
TL0 = 0xB0
装初值完后,计数开始在15536上面进行计数累加,知道溢出。
第二种;顾名思义,就是你装多少值,在这上面进行倒计时计数。这种不较少
另:中断服务函数写法(无需声明)
void 函数名()interrupt 中断号 using 工作组
{
}
void Time() interrupt 3
{
}
中断号:编译器识别不同中断的唯一符号,务必写正确
using 工作组,是指这个中断函数使用单片机内存中4组工作寄存器中的哪一组,C51编译器在编译会自动分配总做足,因此我们常常省略不写
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)