问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

AT89C51使用示例(Proteus & Keil)

创作时间:
作者:
@小白创作中心

AT89C51使用示例(Proteus & Keil)

引用
CSDN
1.
https://blog.csdn.net/2301_77603222/article/details/143643502

AT89C51单片机是嵌入式系统中常用的基础型单片机,其操作简单,功能强大。本文将通过Proteus和Keil软件的配合,详细介绍AT89C51单片机的基础功能,包括最小系统、IO口、计数器和中断等。通过本文的学习,读者可以快速上手理解AT89C51单片机的基础功能。

1. 最小系统

最小系统是单片机能够正常工作的最基本电路,主要包括以下四个部分:

  • 时钟电路:XTAL1和XTAL2连接晶振,负责产生稳定的频率,为单片机提供时钟信号。
  • 复位电路:RES端口用于高电平复位。
  • 电源电路:VCC端口为单片机提供工作电压。
  • 程序下载:EA端口当该端口为高电平时,使用片内ROM。

2. IO口

在仿真启动时可观察到P1,P2,P3口均对外输出高电平,而P0口对外不输出电压。

在Proteus中,高电平显示为红色,低电平为蓝色,无电为灰色。

2.1 P0上拉电阻

可以通过添加一个排阻并添加电源来实现P0口的高电平输出。本质上其他端口实现高电平输出也是使用与此相同的方式,即通过将端口与电源和电阻串联来实现。

2.2 端口的编程定义

可以使用以下代码来定义每一个端口的名称:

sbit KEY1 = P2^5;
sbit KEY2 = P2^1;
sbit LED1 = P0^0;
sbit LED2 = P0^7;

2.3 IO示例

以下是一个示例程序,通过P2口的单刀单掷开关来控制P0口的LED灯:

#include "REG51.h"

sbit KEY1 = P2^5;
sbit KEY2 = P2^1;
sbit LED1 = P0^0;
sbit LED2 = P0^7;

void main(void) {
    int scanNum1 = 1;
    int scanNum2 = 1;
    while(1)
    {
        if(KEY1 == 0 && scanNum1%2 == 1)
        {
            scanNum1++;
            LED1 = ~LED1;
        }
        if(KEY1 == 1 && scanNum1%2 == 0)
        {
            scanNum1++;
            LED1 = ~LED1;
        }
        
        if(KEY2 == 0 && scanNum2%2 == 1)
        {
            scanNum2++;
            LED2 = ~LED2;
        }
        if(KEY2 == 1 && scanNum2%2 == 0)
        {
            scanNum2++;
            LED2 = ~LED2;
        }
    }
}

3. 计数器

3.1 定时器与计数器的区别

定时器是对内部机器周期(周期信号)的计数,计数器是对外部输入引脚信号(可以是非周期信号)的计数。

3.2 计数器的初始化步骤

  1. TMOD 寄存器的设定
  2. 计数器的计数初值
  3. 中断系统的管理
  4. 计数器的启动

3.3 TH0 TL0 的初始化

TH0 和 TL0 分别为计数器计数值的高八位和底八位。因为计数器是对机器内部周期进行计数,单片机经过一个震荡周期会进行12次计数(计数器计数值的最小单位即是一个震荡周期的1/12)。因此计数器计数10000即是1ms。由于单片机中使用二进制来保存数据,TH0 和 TL0 分别只能存储八位二进制数,那么计数器的储值上限是二进制的 1111 1111 1111 1111,转化为十进制为 65535。换句话说,计数器的计数时长为6.5ms,想要获得更长的计数时间可以在代码中定义其他变量来辅助计数。

3.4 计数器的使用示例

通过计数器逐个点亮P2口的LED灯,每个灯的点亮间隔为1s:

#include "REG51.h"

sbit LED1 = P2^0;
sbit LED2 = P2^1;
sbit LED3 = P2^2;
sbit LED4 = P2^3;
sbit LED5 = P2^4;
sbit LED6 = P2^5;
sbit LED7 = P2^6;
sbit LED8 = P2^7;

int count;
    
void main(void) {
    TMOD = 0x01;
    TH0 = (65536 - 10000)/256;  //定时器初值
    TL0 = (65536 - 10000)%256;
    EA = 1;  //打开中断允许总开关
    ET0 = 1;  //定时器0中断允许
    TR0 = 1;  //定时器0启动控制
    while(1)
    {
            
    }
}

void time0_int(void) interrupt 1 {
    TH0 = (65536 - 10000)/256;
    TL0 = (65536 - 10000)%256;
    count++;
    if(count == 100)
    {
        LED1 = ~LED1;
    }
    else if(count == 200)
    {
        LED2 = ~LED2;
    }
    else if(count == 300)
    {
        LED3 = ~LED3;
    }
    else if(count == 400)
    {
        LED4 = ~LED4;
    }
    else if(count == 500)
    {
        LED5 = ~LED5;
    }
    else if(count == 600)
    {
        LED6 = ~LED6;
    }
    else if(count == 700)
    {
        LED7 = ~LED7;
    }
    else if(count == 800)
    {
        LED8 = ~LED8;
    }
    else if(count == 900)
    {
        P2 = 0xFF;
        count = 0;
    }
}

4. 中断

4.1 中断类型

  1. 外部中断
  2. 定时器/计数器中断
  3. 串口中断

区别:即触发中断的条件不一样。外部中断触发条件时管脚出现下降沿(由输出高电平变为输出低电平);定时器/计数器触发条件为定时器/计数器溢出;串口中断的触发条件时串口完成一帧数据的接收或发送。

4.2 中断示例

以下为一个中断示例:

采用外部中断和计数器中断来控制P2口的LED灯:

  1. 当计数器溢出时,P2口的TIMER灯状态翻转
  2. 当中断引脚为低电平时,P2口的INTER灯状态翻转

#include "REG51.h"

sbit TIMER = P2^2;
sbit INTER = P2^7;
int count;
    
//中断初始化
static void InitInterrupt(void)
{
    IT0 = 1;   //设置外部中断0的触发方式为低电平触发
    EX0 = 1;   //打开外部中断0的中断允许
    EA = 1;    //打开中断的总允许
}

static void InitTimer(void)
{
    TMOD = 0x01;  //设置计数模式
    TH0 = (65536 - 10000)/256;  //设置计数器计数初值
    TL0 = (65536 - 10000)%256;  //
    EA = 1;       //打开中断的总允许
    ET0 = 1;      //定时器0中断允许
    TR0 = 1;      //定时器0启动
}

void main(void) {
    InitTimer();
    InitInterrupt();
    while(1) {}
}

void time0_int(void) interrupt 1 {
    TH0 = (65536 - 10000)/256;
    TL0 = (65536 - 10000)%256;
    count++;
    if(count%100 == 0) TIMER = ~TIMER;
    if(count%200 == 0) {TIMER = ~TIMER; count = 0;}
}

void Externa10_Handler() interrupt 0
{
    INTER = ~INTER;
}
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号