1.引脚定义

P3口各引脚第二功能定义
标号 引脚 第二功能 说明
P3.0 10 RXD 串行输入口
P3.1 11 TXD 串行输出口
P3.2 12 INT0(上划线) 外部中断0
P3.3 13 INT1(上划线) 外部中断1
P3.4 14 T0 定时器/计数器0 外部输入端
P3.5 15 T1 定时器/计数器1 外部输入端
P3.6 16 WR(上划线) 外部数据存储器写脉冲
P3.7 17 RD(上划线) 外部数据存储器读脉冲

XTAL1(19脚) XTAL2(18脚):外接时钟引脚。XTAL1为片内震荡电路的输入端,XTAL2为片内震荡电路的输出端。

              8051时钟两种方式:①片内时钟震荡,两引脚外接晶振和震荡电容。

                         ②外部时钟方式,XTAL1接地,外部时钟信号从XTAL2脚输入。

RST(9脚):单片机复位引脚。当输入连续两个机器周期以上高电平时为有效。复位后程序计数器PC=0000H,读取第一条指令码。即从头开始执行程序。

ALE(30脚):在没有外部存储器期间,ALE以1/6振荡周期频率输出(6分频),当访问外部存储器时,以1/12振荡周期输出(12分频)。

EA(上划线)(31脚):接高电平时,单片机读取内部程序存储器。接低电平,单片机直接读取外部(ROM)。(板子上直接接高)

P0口(39~32脚):双向8位三态I/O口,早期51芯片内部无上拉电阻,为高阻态,需外部接上拉电阻。

P1口(1~8脚):准双向8位I/O口,之所以称它为"准双向",是因为改口作为输入使用前,要先向该口进行写1操作,有个"准"备过程,称为准双向口。

P2口(21~28脚):准双向8位I/O口。

P3口(10~17脚):准双向8位I/O口。

2.复位电路

按键按下,RST=5V,按键时长大于两个时钟周期,则复位。

上电自动复位:上电瞬间,电容充电,之后电容放电,τ = √(RC) >两个时钟周期 ,自动复位。

3.晶振

非极性电容,上电帮助晶振起振。12M左右 30pf,6M左右20pf。具体参考厂家提供的晶振要求负载电容选值。(Day0有详细介绍)

4.数码管

开发板中用的为共阴极。即WE选信号给低,则导通(WE提供一个GND作用)。

利用74HC573锁存器的锁存功能。(详细见Day0 ⑤锁存器),先控制位选信号P2.7口高,选定哪个数码管,后P2.7低锁存。再控制段选信号P2.6高,亮什么数字后,P2.6低锁存。

 //共阴极数码管静态显示1
#include <reg52.h>
sbit DUAN = P2^;
sbit WE = P2^; int main()
{
WE = ; //打开WE选信号
P0 = 0xDF; //选WE6的数码管,给低,其余给高
WE = ; //关闭WE选信号
DUAN = ; //打开段选信号
P0 = 0x06; //亮1,即bc接高,其余低
DUAN = ; //关闭段选信号 return ;
}

超级亮,但是别的数码管有淡淡的光,以下进行改进

 //共阴极数码管静态显示1      防干扰
#include <reg52.h>
sbit DUAN = P2^;
sbit WE = P2^; int main()
{
WE = ;
P0 = 0xDF;
WE = ;
P0 = 0xFF; //关闭所有显示,防止打开段选后发生混乱
DUAN = ;
P0 = 0x06;
DUAN = ;
P0 = 0xFF; //关闭所有显示,防止打开位选后发生混乱 return ;
}

接下来是数码管的动态扫描,其实是一个个显示,由于频率太快,人眼无法识别,达到目的。

  //共阴极数码管动态显示
#include <reg52.h>
sbit DUAN = P2^;
sbit WE = P2^;
unsigned char DuanTable[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,
0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
unsigned char WeTable[] = {0xFE,0xFD,0xFB,0xF7,0xEF,0xDF};
void delayms(unsigned int n);
int main()
{
unsigned int i = ;
while()
{
for(i = ; i < ; i++) {
DUAN = ;
P0 = DuanTable[i+];
DUAN = ;
P0 = 0xFF;
WE = ;
P0 = WeTable[i];
WE = ;
P0 = 0xFF;
delayms();
}
}
return ;
} void delayms(unsigned int n) //误差 -0.651041666667us
{
unsigned char a,b;
unsigned int i;
for(i = ; i < n; i++) {
for(b=;b>;b--)
for(a=;a>;a--);
}
}

5.中断

52单片机共有6个中断源

INT0:外部中断0.由P3.2端口线引入,低电平或下降沿引起。

INT1:外部中断1.由P3.3端口线引入,低电平或下降沿引起。

T0:定时器/计数器0中断,由T0计数器计满回零引起。

T1:定时器/计数器1中断,由T1计数器计满回零引起。

T2:定时器/计数器2中断,由T2计数器计满回零引起。

TI/RI:串行口中断,串行端口完成一帧字符发送/接收后引起。

52单片机中断级别
中断源 默认中断级别 序号(C语言用) 入口地址(汇编语言用)
INT0 外部中断0 最高 0 0003H
T0 定时器/计数器0中断 第2 1 000BH
INT1 外部中断1 第3 2 0013H
T1 定时器/计数器1中断 第4 3 001BH
TI/RI 串行口中断 第5 4 0023H
T2 定时器/计数器2中断 最低 5 002BH
中断允许寄存器IE  (1为开 0为关)
位序号
D7
D6
D5
D4
D3
D2
D1
D0
说明
全局中断位
无效位
定时/计数2
(52单片机)
串行口中断
定时/计数1
外部中断1
定时/计数0
外部中断0
位符号(写程序时可直接引用)
EA
--
ET2
ES
ET1
EX1
ET0
EX0
位地址
AFH
--
ADH
ACH
ABH
AAH
A9H
A8H
单片机复位时全部清零。可进行位寻址,即可对该寄存器每一位进行单独操作。
只有打开全局开关,其它各位的开关才可以开启。
每个位开关赋值为1则开,赋值为0则关。
使用方法
  ①整体赋值:IE=0x81;(开启全局中断,打开外部中断0)
  ②单独赋值:EA=1;EX0=1;(开启全局中断,打开外部中断0)
 
中断优先级寄存器IP
位序号 D7 D6 D5 D4 D3 D2 D1 D0
说明 无效位 无效位 无效位 串行口中断优先级控制位 定时器/计数器1中断优先级控制位 外部中断1中断优先级控制位 定时器/计数器0中断优先级控制位 外部中断0中断优先级控制位
位符号 -- -- -- PS PT1 PX1 PT0 PX0
位地址 -- -- -- BCH BBH BAH B9H B8H
 
 
 
 
 
 
 
 
 
 
单片机复位时全部清零。可进行位寻址。
每个位赋值为1,将对应中断定义为高优先级中断;赋值0,则定义为低优先级中断。
在没有设置中断优先级情况下,按照默认中断级别响应中断,设置后,则按设置顺序确定相应的先后顺序。
 
定时器/计数器工作方式寄存器TMOD
位序号 D7 D6 D5 D4 D3 D2 D1 D0
位符号 GATE C/T(上划线) M1 M0 GATE C/T(上划线) M1 M0
  定时器1 定时器0

单片机复位时全部清零。不可进行位寻址。

GATE:

GATE = 0 定时器/计数器启动与停止仅受TCON寄存器中TRX(X=0,1)来控制。

  当TR0=1,启动定时器T0。
  当TR1=1,启动定时器T1。
GATE = 1 定时器/计数器启动与停止由TCON寄存器中TRX(X=0,1)和外部中断引脚(INT0 或 INT1)上的电平状态共同控制。
  当INT0引脚为高电平时且TR0置位,TR0=1;启动定时器T0。
  当INT1引脚为高电平时且TR1置位,TR1=1;启动定时器T1。
 

C/T(上划线):定时器模式和计数器模式选择位

  C/T=0时为定时模式: 加1计数器对脉冲f进行计数,每来一个脉冲,计数器加1,直到计时器TFx满溢出。

  C/T=1时为计数模式: 加1计数器对来自输入引脚T0(P3.4)和T1(P3.5)的外信号脉冲进行计数,每来一个脉冲,计数器加1,直到计时器TFx满溢出。

 
M1M0:方式选择功能
 
定时器/计数器的4种工作方式
M1
M0
工作方式
功能说明
0
0
方式0
13位定时器/计数器
0
1
方式1
16位定时器/计数器
1
0
方式2
自动重载8位定时器/计数器
1
1
方式3
T0分为2个8位独立计数器,T1无方式3
 
 
 
 
 
 
 
控制寄存器TCON
位序号 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”,在查询方式下用软件清“0”。
TR1:定时器1运行控制位。由软件清“0”关闭定时器1。当GATE=1,且/INT1为高电平时,TR1置“1”启动定时器1;当GATE=0,TR1置“1”启动定时器1。
TF0:定时器0溢出标志。其功能及操作情况同TF1。
TR0:定时器0运行控制位。其功能及操作情况同TR1。
IE1:外部中断1请求标志位。
IT1:外部中断1触发方式选择位。当IT1=0,为低电平触发方式;当IT1=1,为下降沿触发方式。
IE0:外部中断0请求标志位。
IT0:外部中断0触发方式选择位。 当IT0=0,为低电平触发方式;当IT0=1,为下降沿触发方式。
 
中断响应条件
  ①CPU开中断(EA=1)
  ②此中断允许位为1
  ③中断源有中断请求
 
中断服务程序格式
void 函数名() interrupt 中断号 using 工作组
{
}
//using 工作组 指这个中断函数使用单片机内存中4组工作寄存器中哪一组,C51编译器在编译程序时会自动分配工作组,因此最后这句话可以省略不写。
//中断号见前 52单片机中断级别 表格
 
外部中断
涉及寄存器IE TCON (IP)
 //外部中断0 低电平触发
#include <reg52.h>
sbit DUAN = P2^;
sbit WE = P2^;
unsigned char DuanTable[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,
0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
unsigned char WeTable[] = {0xFE,0xFD,0xFB,0xF7,0xEF,0xDF};
void delayms(unsigned int n);
int main()
{
unsigned int i = ;
EA = ;//打开总中断
EX0 = ;//打开外部中断0中断
//IT0 = 0; 电平触发 由于TCON在复位时自动清零,所以可以省略
while()
{
for(i = ; i < ; i++) {
DUAN = ;
P0 = DuanTable[i+];
DUAN = ;
P0 = 0xFF;
WE = ;
P0 = WeTable[i];
WE = ;
P0 = 0xFF;
delayms();
}
}
return ;
} void delayms(unsigned int n) //误差 -0.651041666667us
{
unsigned char a,b;
unsigned int i;
for(i = ; i < n; i++) {
for(b=;b>;b--)
for(a=;a>;a--);
}
} void exter0() interrupt //中断函数无需在main前声明 中断全部显示0 P3,2口INT0
{
int i = ;
for(i = ; i < ; i++) {
DUAN = ;
P0 = DuanTable[];
DUAN = ;
P0 = 0xFF;
WE = ;
P0 = WeTable[i];
WE = ;
P0 = 0xFF;
delayms();
}
}

中断ing

 
定时器中断
涉及寄存器IE TMOF TCON (IP) THX TLX (x=0,1)
定时器中断程序初始化
  1.对TMOD赋值,以确定T0和T1的工作方式
  2.计算初值,并将初值写入TH0、TL0 或 TH1、TL1
  3.中断方式时,则对IE赋值,开发中断
  4.使TR0或TR1置位,启动定时器/计数器定时或计数(TCON)
 
定时器初值问题:
  假设时钟频率为12MHZ,12个时钟周期为一个机器周期,那么此时机器周期为1us。计满TH0、TL0需要2^16-1个数,再来一个脉冲计数器溢出,向CPU请求中断。例如要定时50ms
要给TH0和TL0装初值,在初值基础上计数50000后溢出,中断。若要定时1s,则产生20次50ms中断即可。
结论:用定时器方式1是,机器周期为Tcy,定时器产生一次中断时间为t,那么需要计数的个数N= t/Tcy.
  THX = (65535 -N) / 256      
  TLX = (65535 - N) % 256
//定时器0中断 方式1  中断显示0
#include <reg52.h>
sbit DUAN = P2^;
sbit WE = P2^;
unsigned char DuanTable[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,
0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
unsigned char WeTable[] = {0xFE,0xFD,0xFB,0xF7,0xEF,0xDF};
unsigned int t = ;
void delayms(unsigned int n);
int main()
{
unsigned int i = ;
TMOD = 0x01; //TMOD不能位寻址 定时器0工作方式1
TH0 = ( - ) / ;
TL0 = ( - ) % ;
EA = ;//打开总中断
ET0 = ;//打开定时器0中断
TR0 = ;
while()
{
for(i = ; i < ; i++) {
DUAN = ;
P0 = DuanTable[i+];
DUAN = ;
P0 = 0xFF;
WE = ;
P0 = WeTable[i];
WE = ;
P0 = 0xFF;
delayms();
}
if(t >= ) {
for(i = ; i < ; i++) {
DUAN = ;
P0 = DuanTable[];
DUAN = ;
P0 = 0xFF;
WE = ;
P0 = WeTable[i];
WE = ;
P0 = 0xFF;
delayms();
}
if(t >= )
t = ;
}
}
return ;
} void delayms(unsigned int n) //误差 -0.651041666667us
{
unsigned char a,b;
unsigned int i;
for(i = ; i < n; i++) {
for(b=;b>;b--)
for(a=;a>;a--);
}
} void T0_Time() interrupt //中断函数无需在main前声明 中断全部显示0 P3,2口INT0
{
TH0 = ( - ) / ;
TL0 = ( - ) % ;
t++;
}

practice:

59s循环计时。

 //60s倒计时 定时器0中断+数码管显示
#include <reg52.h>
sbit DUAN = P2^;
sbit WE = P2^;
unsigned char DuanTable[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,
0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
unsigned char WeTable[] = {0xFE,0xFD,0xFB,0xF7,0xEF,0xDF};
unsigned int t = , num = ;
void delayms(unsigned int n);
int main()
{
unsigned int i = ;
TMOD = 0x01; //TMOD不能位寻址 定时器0工作方式1
TH0 = ( - ) / ;
TL0 = ( - ) % ;
EA = ;//打开总中断
ET0 = ;//打开定时器0中断
TR0 = ;
while()
{
//十位数
DUAN = ;
P0 = DuanTable[num/];
DUAN = ;
P0 = 0xFF;
WE = ;
P0 = WeTable[];
WE = ;
P0 = 0xFF;
delayms(); //个位数
DUAN = ;
P0 = DuanTable[num%];
DUAN = ;
P0 = 0xFF;
WE = ;
P0 = WeTable[];
WE = ;
P0 = 0xFF;
delayms(); }
return ;
} void delayms(unsigned int n) //误差 -0.651041666667us
{
unsigned char a,b;
unsigned int i;
for(i = ; i < n; i++) {
for(b=;b>;b--)
for(a=;a>;a--);
}
} void T0_Time() interrupt //中断函数无需在main前声明 中断全部显示0 P3,2口INT0
{
TH0 = ( - ) / ;
TL0 = ( - ) % ;
t++;
if(t >= ) {
num--;
t = ;
} if(num == )
num = ;
}
 

十天学会单片机Day1点亮数码管(数码管、外部中断、定时器中断)的更多相关文章

  1. 十天学会单片机Day0点亮LED (锁存器、三极管、继电器)

    C51常用的数据类型 数据类型 关键字 所占位数 表示数范围 无符号字符型 unsigned char 8 0~255 有符号字符型 char 8 -128~127 无符号整型 unsigned in ...

  2. 《十天学会单片机和C语言编程》

    <十天学会单片机和C语言编程> 大家注意了这个文件只有最新版迅雷可以下载,下面的lesson几就是第几课.点击右键使用迅雷下载. ed2k://|file|[十天学会单片机和C语言编程]. ...

  3. 十天学会单片机Day4串行口通信

    并行与串行基本通信方式 1.并行通信方式 通常是将数据字节的各位用多条数据线同时进行传送. 并行通信控制简单.传输速度快:由于传输线较多,长距离传送时成本高且接收方的各位同时接收存在困难. 2.串行通 ...

  4. 十天学会单片机Day3 D/A与A/D转换器

    D/A转换器 1.二进制权电阻网络型D/A转换器 基准电压Vref 数据D(d3d2d1d0) 输出模拟电压V0 i0 = Vref/8R    i1 = Vref/4R     i2 = Vref/ ...

  5. 十天学会单片机Day2键盘检测(独立键盘、矩阵键盘)

    1.键盘的分类 编码键盘:键盘上闭合键的识别由专用的硬件编码器实现,并产生键编码号或键值的称为编码键盘,如计算机键盘 非编码键盘:靠软件编程来识别的称为非编码键盘.独立键盘.矩阵键盘 2.按键消抖   ...

  6. 十天学会单片机Day5 IIC总线AT2402芯片(EEPROM)应用

    1.采用串行总线技术可以使系统的硬件设计大大简化.系统的体积减小.可靠性提高.同时,系统的更改和扩充极为容易. 常用的串行扩展总线有: IIC (Inter IC BUS)总线.单总线(1-WIRE ...

  7. 十天学会单片机Day6 学会看数据手册 (IIC总线PCF859芯片( A/D D/A)应用)

    1.实际电路 2.引脚图 3.地址 高四位为固定地址1001,A2A1A0可编程地址,通过观察实际电路,可知A2A1A0 为000.最低位为读写为,1为读,0为写. 4.控制字 控制寄存器的高半字节用 ...

  8. 十年学会编程 著者: Peter Norvig 翻译: Dai Yuwen

    为何人人都这么着急? 信步走进任何一家书店,你会看到名为<如何在7天内学会Java>的书,还有各 种各样类似的书: 在几天内或几小时内学会Visual Basic, Windows, In ...

  9. PHP学习过程_Symfony_(3)_整理_十分钟学会Symfony

    这篇文章主要介绍了Symfony学习十分钟入门教程,详细介绍了Symfony的安装配置,项目初始化,建立Bundle,设计实体,添加约束,增删改查等基本操作技巧,需要的朋友可以参考下 (此文章已被多人 ...

随机推荐

  1. Oracle 11g新参数USE_LARGE_PAGES与AMM使用 (转载)

    在之前的文章(http://space.itpub.net/17203031/viewspace-774843)中,笔者介绍了如何在Linux 2.6内核中配置HugePage以及AMM与其的不兼容性 ...

  2. php mysql_affected_rows获取sql执行影响的行数

    php mysql_affected_rows函数用于获取执行某一SQL语句(如INSERT,UPDATE 或 DELETE )所影响的行数,本文章向大家介绍php mysql_affected_ro ...

  3. 下载和编译 Open XML SDK

    我们需要一些工具来开始 Open XML 的开发. 开发工具 推荐的开发工具是 Visual Studio 社区版. 开发工具:Visual Studio Community 2013 下载地址:ht ...

  4. 实验室中搭建Spark集群和PyCUDA开发环境

    1.安装CUDA 1.1安装前工作 1.1.1选取实验器材 实验中的每台计算机均装有双系统.选择其中一台计算机作为master节点,配置有GeForce GTX 650显卡,拥有384个CUDA核心. ...

  5. 慕课网-安卓工程师初养成-3-4 Java中的比较运算符

    来源:http://www.imooc.com/code/1299 比较运算符用于判断两个数据的大小,例如:大于.等于.不等于.比较的结果是一个布尔值( true 或 false ). Java 中常 ...

  6. url 参数的加号变成空格处理

    今天在调试客户端向服务器传递参数时,参数中的“+”全部变成了空格,原因是URL中默认的将“+”号转义了. 解决方法如下: 方法一.修改客户端 将客户端带“+”的参数中的“+”全部替换为‍“2B%”,这 ...

  7. 关于cookie

    CookieHelper.WriteCookie("DEPID", "theway", depid);   //先写入cookie //再读取cookie Us ...

  8. html5 搖一搖

    <script> // 首先在页面上要监听运动传感事件 function init(){ if (window.DeviceMotionEvent) { // 移动浏览器支持运动传感事件 ...

  9. C# 16进制与字符串、字节数组之间的转换(转)

    1.请问c#中如何将十进制数的字符串转化成十六进制数的字符串   //十进制转二进制 Console.WriteLine("十进制166的二进制表示: "+Convert.ToSt ...

  10. nice和taskset命令

    taskset -c 9,10 bash domain_analysis.sh && /home/work/odp/php/bin/php hourly_localdns_hijack ...