2019竞赛部&秘书部第六次硬件培训

一、51单片机介绍

1.1 什么是单片机

单片机

单片机(Single-Chip Microcomputer)是一种集成电路芯片,是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU、随机存储器RAM、只读存储器ROM、多种I/O口和中断系统、定时器/计数器等功能(可能还包括显示驱动电路、脉宽调制电路、模拟多路转换器、A/D转换器等电路)集成到一块硅片上构成的一个小而完善的微型计算机系统,在工业控制领域广泛应用。从上世纪80年代,由当时的4位、8位单片机,发展到现在的300M的高速单片机。 Intel公司推出了MCS-51系列单片机:集成 8位CPU、4K字节ROM、128字节RAM、4个8位并口、1个全双工串行口、2个16位定时/计数器。寻址范围64K,并有控制功能较强的布尔处理器。

STC89C52(DIP40封装)
AT89C51(PLCC44封装)

51单片机开发板

1.2 单片机的应用

智能仪器仪表:数字示波器、数字信号源、数字万用表、感应电流表等。
在这里插入图片描述
工业自动化:数据采集、测控技术。
在这里插入图片描述
消费类电子产品:洗衣机、电冰箱、空调机、电视机、微波炉、手机、IC卡、汽车电子设备等。
在这里插入图片描述
通讯方面:调制解调器、程控交换技术、手机、小灵通等。
在这里插入图片描述
武器装备:飞机、军舰、坦克、导弹、航天飞机、鱼雷制导、智能武器等。
在这里插入图片描述
凡是与控制或简单计算有关的电子设备都可以用单片机来实现,根据具体实际情况还可以选择不同性能的单片机,如:atmel,stc,pic,avr,80C51,arm等。

1.3 最小系统的组成

在这里插入图片描述

时钟电路

单片机各外围部件运行都以时钟控制信号为基准,有条不紊,一拍一拍的工作。时钟电路为单片机工作提供基本时钟信号,在51系列单片机内部有一个高增益反相放大器,其输入引脚为XTAL1,输出端引脚为XTAL2,只需在XTAL1和XTAL2之间跨接晶振和微调电容,就可以构成一个稳定的自激振荡器。常用的晶振主要为12M、11.0592M,11.0592M主要在串口通信时用,得到一个精准的波特率,电容常用30pF主要作用是,过滤掉晶振部分的高频信号,让晶振工作的时候更加稳定。
在这里插入图片描述

复位电路

复位的作用:
  假如我们的单片机程序有 100 行,当某一次运行到第 50 行的时候,突然停电了,这个时候单片机内部有的区域数据会丢失掉,有的区域数据可能还没丢失。那么下次打开设备的时候,我们希望单片机能正常运行,所以上电后,单片机要进行一个内部的初始化过程,这个过程就可以理解为上电复位,上电复位保证单片机每次都从一个固定的相同的状态开始工作。这个过程跟我们打开电脑电源开电脑的过程是一致的。
  当我们的程序运行时,如果遭受到意外干扰而导致程序死机,或者程序跑飞的时候,我们就可以按下一个复位按键,让程序重新初始化重新运行,这个过程就叫做手动复位,最典型的就是我们电脑的重启按钮。
  当程序死机或者跑飞的时候,我们的单片机往往有一套自动复位机制,比如看门狗,具体应用以后再了解。在这种情况下,如果程序长时间失去响应,单片机看门狗模块会自动复位重启单片机。
在这里插入图片描述
复位电路实现原理:只要在RST引脚上加一个持续时间为24个振荡周期(即两个机器周期)的高电平就可以了。一个机器周期为12个振荡周期(12*1/12M)为1us,所以需要2us高电平。

(1)开机复位
 在电路图中,电容的的大小是10uf,电阻的大小是10k。在5V正常工作的51单片机中小于1.5V的电压信号为低电平信号,而大于1.5V的电压信号为高电平信号。所以根据公式,可以算出电容充电到电源电压的0.7倍,即电容两端电压为3.5V、电阻两端电压为1.5V时,需要的时间约为
 T=RC=10K*10UF=0.1S。
也就是说在单片机上电启动的0.1S内,电容两端的电压从0-3.5V不断增加,这个时候10K电阻两端的电压为从5-1.5V不断减少(串联电路各处电压之和为总电压),所以RST引脚所接收到的电压是5V-1.5V的过程,也就是高电平到低电平的过程。
单片机RST引脚是高电平有效,即复位;低电平无效,即单片机正常工作。所以在开机0.1S内,单片机系统RST引脚接收到了时间为0.1S左右的高电平信号,所以实现了自动复位。
(2)按键复位
  在单片机启动0.1S后,电容C两端的电压持续充电为5V,这是时候10K电阻两端的电压接近于0V,RST处于低电平所以系统正常工作。当按键按下的时候,开关导通,这个时候电容两端形成了一个回路,电容被短路,所以在按键按下的这个过程中,电容开始释放之前充的电量。随着时间的推移,电容的电压在0.1S内,从5V释放到变为了1.5V,甚至更小。根据串联电路电压为各处之和,这个时候10K电阻两端的电压为3.5V,甚至更大,所以RST引脚又接收到高电平,单片机系统自动复位。

二、预备知识

2.1 电平特性

数字电路中只有两种电平:高电平和低电平
高电平:5V或者3.3V,取决单片机电源。
低电平:0V
RS232电平:计算机串口的电平
高电平:-12V
低电平:+12V
所以当我们用单片机跟电脑通信的时候,我们要通过各种元器件将单片机的电平转换为计算机可识别的电平才能跟电脑进行通信。
在这里插入图片描述

2.2 进制知识

二进制
由于数字电路中的只有两种电平的特性,计算机中使用的数字采用都是二进制的二进制是使用0和1两个数码来表示的数,它的基数是2,进位规则是“逢二进一”。
十六进制
十六进制的基数是F,进位规则是“逢十六进一”。
在这里插入图片描述

2.3 逻辑运算

在这里插入图片描述

2.4 基本时序

在这里插入图片描述
(1) 振荡周期: 也称时钟周期, 是指为单片机提供时钟脉冲信号的振荡源的周期,我们开发板上为12MHZ。
(2) 状态周期: 每个状态周期为时钟周期的 2 倍, 是振荡周期经二分频后得到的。
(3) 机器周期: 一个机器周期包含 6 个状态周期S1~S6, 也就是 12 个时钟周期。 在一个机器周期内, CPU可以完成一个独立的操作。
(4) 指令周期: 它是指CPU完成一条操作所需的全部时间。 每条指令执行时间都是有一个或几个机器周期组成。MCS - 51 系统中, 有单周期指令、双周期指令和四周期指令。

三、初步应用

3.1 建立工程

(1)点击工程-新建uVision工程-选择文件的保持位置-命名工程
在这里插入图片描述
(2)选择ATMEL公司的AT89C51芯片
在这里插入图片描述在这里插入图片描述
(3)点击新建文件创建新的文档在这里插入图片描述
(4)将新建文件保持为带.C后缀的文件
在这里插入图片描述
(5)添加文件到组中-选择保存好的.C文件
在这里插入图片描述
在这里插入图片描述
工程创建结束,可以开始编辑代码啦!

3.2 点亮第一盏LED

硬件里面的Hello World!

LED即发光二极管,是一种半导体固体发光器件。LED的工作原理:LED的工作是有方向性的只有当正级接到LED阳极,负极接到LED的阴极的时候才能工作,如果反接LED是不能正常工作的
在这里插入图片描述
图示为共阴极接法的LED电路,其中74HC245 为八总线收发器芯片,即可以将数据从A 总线端口传送到B 总线端口,也可将数据从B 总线端口传送到A 总线端口。传送方向由方向控制管脚DIR(芯片1 脚)输入的逻辑电平而定。在此电路中的作用主要是为了提高驱动能力,增加数码管的亮度。470欧的RLED是限流电阻,主要作用是防止电流过大烧坏LED,100欧的RP20为上拉电阻,主要作用是使引脚默认为高电平输出。

51中的具体代码:

#include "reg52.h" //将reg52的头文件包括进工程中,此头文件定义了许多默认
                   //的寄存器名,如P1可以直接调用无需定义
sbit LED1=P1^0;//将P1.0引脚定义为LED1方便之后的直接调用和修改
void main()
{
 LED1=1;//使P1^0输出高电平,点亮LED1
}

bit,sbit,sfr,sfr16都用于单片机的C语言编程。
bit——定义位变量,定义位变量时可以为变量赋值,但不能指定变量的地址。
 定义格式:bit 变量名=变量值。
sbit——此类型变量只要用于访问可位寻址的特殊功能寄存器中的某个位。
 定义格式:sbit 变量名=位地址;
sfr——此类型变量可以访问指定的8位特殊功能寄存器,地址范围为0x80~0xFF。
 定义格式:sfr 变量名=变量地址。
sfr16—定义一个16位的特殊功能寄存器。
 定义格式:sfr 变量名=变量地址
在这里插入图片描述
P3口第二功能各引脚功能定义:

P3.0:RXD串行口输入
P3.1:TXD串行口输出
P3.2:INT0外部中断0输入
P3.3:INT1外部中断1输入
P3.4:T0定时器0外部输入
P3.5:T1定时器1外部输入
P3.6:WR外部写控制
P3.7:RD外部读控制

3.3 流水灯程序

/***********************************************************
*		              LED流水灯实验												  																		  
***********************************************************/

#include "reg52.h"			 //此文件中定义了单片机的一些特殊功能寄存器
#include<intrins.h>		//因为要用到左右移函数,所以加入这个头文件

typedef unsigned int u16;	  //对数据类型进行声明定义
typedef unsigned char u8;

#define led P0	   //将P0口定义为led 后面就可以使用led代替P0口
/*********************************************************
* 函 数 名         : delay
* 函数功能		   : 延时函数,i=1时,大约延时10us
*********************************************************/
void delay(u16 i)
{
	while(i--);	//一直进行自减,每一次自减所用的时间为10us
}

/*******************************************************
* 函 数 名       : main
* 函数功能		 : 主函数
* 输    入       : 无
* 输    出    	 : 无
*******************************************************/
void main()
{
	u8 i;
	while(1)
		{
		    P0=0x01;//P0=0000_0001,所以P0.0到P0.7的状态为0000_0001即只有P0.7为高电平
			delay(50000);
		   	for(i=0;i<8;i++)
	     	{
		    	P0=(0x01<<i); //将1右移i位,然后将结果赋值到P0口,当i=1时P0的值变为1000_0000,即P0.0为高电平.
		    	delay(50000); //大约延时450ms
	       	}
		}		 		
}

3.4 程序的烧录

(1)点击目标选项-进行输出设置-勾选产生HEX文件在这里插入图片描述
在这里插入图片描述
(2)对普中烧写软件进行必要的设置-选择芯片类型为STC90Cxx series-选择串口号-调整波特率-打开文件
在这里插入图片描述
(3)选择keil输出的hex即十六进制文件
在这里插入图片描述
(4)点击程序下载-先断电后上电-程序烧写完成
在这里插入图片描述

四、进阶应用

4.1 数码管介绍

LED数码管根据LED的不同接法可以分为2类:共阴和共阳。
在这里插入图片描述
使用LED显示器时,要注意区分这两种不同的接法。为了显示数字或字符,必须对数字或字符进行编码。七段数码管加上一个小数点,共计8段。因此为LED显示器提供的编码正好是一个字节。根据电路连接图显示16进制数的编码已列在下表。
共阳数码管码表
0xC0 , 0xF9 , 0xA4 , 0xB0 , 0x99 , 0x92
  0    1    2    3    4    5
0x82 , 0xF8 , 0x80 , 0x90 , 0x88 , 0x83
  6    7    8    9   A    B
0xC6 , 0xA1 , 0x86 , 0x8E ,  0xFF
 C    D    E   F    无显示
共阴数码管码表
0x3f , 0x06 , 0x5b , 0x4f , 0x66 , 0x6d
  0   1   2    3   4   5
0x7d , 0x07 , 0x7f , 0x6f ,  0x77 , 0x7c
  6  7   8   9   A   B
0x39 , 0x5e , 0x79 , 0x71 , 0x00
C     D   E    F   无显示

4.2 静态显示原理

LED显示器工作方式有两种:静态显示方式和动态显示方式。静态显示的特点是每个数码管的段选必须接一个8位数据线来保持显示的字形码。当送入一次字形码后,显示字形可一直保持,直到送入新字形码为止。这种方法的优点是占用CPU时间少,显示便于监测和控制。缺点是硬件电路比较复杂,成本较高。

4.3 动态显示原理

动态显示的特点是将所有数码管的段选线并联在一起,由位选线控制是哪一位数码管有效。选亮数码管采用动态扫描显示。所谓动态扫描显示即轮流向各位数码管送出字形码和相应的位选,利用发光管的余辉和人眼视觉暂留作用,使人的感觉好像各位数码管同时都在显示。动态显示的亮度比静态显示要差一些,所以在选择限流电阻时应略小于静态显示电路中的。

4.4 数码管应用

静态数码管代码

/**************************************************************************************
*		              静态数码管显示实验												  *
实现现象:下载程序后数码管静态显示0。
注意事项:																				  
***************************************************************************************/

#include "reg52.h"			 //此文件中定义了单片机的一些特殊功能寄存器

typedef unsigned int u16;	  //对数据类型进行声明定义
typedef unsigned char u8;


u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
					0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值


/*******************************************************************************
* 函 数 名       : main
* 函数功能		 : 主函数
* 输    入       : 无
* 输    出    	 : 无
*******************************************************************************/
void main()
{	
	P0=~smgduan[0];
	while(1);
}

动态数码管代码

#include "reg52.h"			 //此文件中定义了单片机的一些特殊功能寄存器

typedef unsigned int u16;	  //对数据类型进行声明定义
typedef unsigned char u8;

sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;

u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
					0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值

/*******************************************************************************
* 函 数 名         : delay
* 函数功能		   : 延时函数,i=1时,大约延时10us
*******************************************************************************/
void delay(u16 i)
{
	while(i--);	
}

/*******************************************************************************
* 函 数 名         : DigDisplay
* 函数功能		   : 数码管动态扫描函数,循环扫描8个数码管显示
*******************************************************************************/
void DigDisplay()
{
	u8 i;
	for(i=0;i<8;i++)
	{
		switch(i)	 //位选,选择点亮的数码管,
		{
			case(0):
				LSA=0;LSB=0;LSC=0; break;//显示第0位
			case(1):
				LSA=1;LSB=0;LSC=0; break;//显示第1位
			case(2):
				LSA=0;LSB=1;LSC=0; break;//显示第2位
			case(3):
				LSA=1;LSB=1;LSC=0; break;//显示第3位
			case(4):
				LSA=0;LSB=0;LSC=1; break;//显示第4位
			case(5):
				LSA=1;LSB=0;LSC=1; break;//显示第5位
			case(6):
				LSA=0;LSB=1;LSC=1; break;//显示第6位
			case(7):
				LSA=1;LSB=1;LSC=1; break;//显示第7位	
		}
		P0=smgduan[i];//发送段码
		delay(100); //间隔一段时间扫描	
		P0=0x00;//消隐
	}
}

/*******************************************************************************
* 函 数 名       : main
* 函数功能		 : 主函数
* 输    入       : 无
* 输    出    	 : 无
*******************************************************************************/
void main()
{	
	while(1)
	{	
		DigDisplay();  //数码管显示函数	
	}		
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值