51单片机入门总结(一):基本概念、最小系统、流水灯与按键实验(附完整代码)

文章目录

    • 前言
    • 一、51单片机基本概念
      • [1.1 什么是51单片机](#1.1 什么是51单片机)
      • [1.2 51单片机典型内部资源](#1.2 51单片机典型内部资源)
      • [1.3 最小系统](#1.3 最小系统)
      • [1.4 IO口特点](#1.4 IO口特点)
    • 二、51单片机的基本实现方式
      • [2.1 硬件实现方式](#2.1 硬件实现方式)
      • [2.2 软件实现方式](#2.2 软件实现方式)
      • [2.3 开发流程](#2.3 开发流程)
      • [2.4 时钟与周期](#2.4 时钟与周期)
    • 三、流水灯实验
      • [3.1 实验目的](#3.1 实验目的)
      • [3.2 硬件连接](#3.2 硬件连接)
      • [3.3 实验原理](#3.3 实验原理)
      • [3.4 完整代码:库函数循环移位版](#3.4 完整代码:库函数循环移位版)
      • [3.5 数组版流水灯](#3.5 数组版流水灯)
      • [3.6 实验现象](#3.6 实验现象)
    • 四、独立按键实验
      • [4.1 实验目的](#4.1 实验目的)
      • [4.2 硬件连接](#4.2 硬件连接)
      • [4.3 按键消抖原理](#4.3 按键消抖原理)
      • [4.4 完整代码:按键控制 LED 亮灭切换](#4.4 完整代码:按键控制 LED 亮灭切换)
      • [4.5 扩展:按键控制流水灯启停](#4.5 扩展:按键控制流水灯启停)
      • [4.6 实验现象](#4.6 实验现象)
    • 五、常见问题
      • [5.1 程序下载失败](#5.1 程序下载失败)
      • [5.2 LED 不亮](#5.2 LED 不亮)
      • [5.3 按键不灵敏](#5.3 按键不灵敏)
      • [5.4 延时不准](#5.4 延时不准)
    • 六、总结

前言

51单片机是很多嵌入式初学者的第一块开发板。它结构简单、资料丰富,非常适合理解单片机的基本工作原理、GPIO控制、延时、按键消抖等入门知识。

本文从51单片机的基本概念出发,总结其基本实现方式、最小系统、开发流程,并给出两个经典实验:流水灯独立按键。代码基于 Keil C51 和常见 STC89C52 / AT89C51 开发板,可直接参考移植。

注意:不同开发板的 LED、按键引脚可能不同,请以实际原理图为准。


一、51单片机基本概念

1.1 什么是51单片机

单片机(MCU)可以理解为"把一台微型计算机集成到一块芯片上"。它通常包含:

  • CPU:执行指令、运算
  • ROM / Flash:存储程序
  • RAM:存储临时数据
  • IO口:输入输出
  • 定时器 / 计数器
  • 中断系统
  • 串口通信
  • 时钟电路

51单片机是指以 Intel 8051 内核为基础的一类 8 位单片机。常见型号有:

  • AT89C51 / AT89C52
  • STC89C52 / STC89C52RC
  • STC12、STC15 等增强型51

其中 STC89C52RC 在入门开发板中非常常见。

1.2 51单片机典型内部资源

以 STC89C52 / AT89C52 为例:

资源 说明
CPU 8位
Flash 8KB 左右
RAM 256B 左右
IO口 P0、P1、P2、P3,共32位
定时器 2~3个
中断 外部中断、定时器中断、串口中断等
串口 1个 UART
时钟 常用 11.0592MHz 或 12MHz 晶振

1.3 最小系统

51单片机要正常工作,至少需要以下电路:

  1. 电源电路:通常 5V 供电,加滤波电容。
  2. 晶振电路:晶振 + 两个小电容,接到 XTAL1、XTAL2。
  3. 复位电路:上电复位 + 按键复位,接到 RST。
  4. EA 引脚:EA 接 VCC,表示从内部程序存储器取指令。

这就是常说的"51最小系统"。

1.4 IO口特点

51单片机有 P0、P1、P2、P3 四组 IO:

  • P0:开漏输出,作为普通 IO 时通常需要外接上拉电阻,常见 10K 排阻。
  • P1、P2、P3:准双向 IO,内部有弱上拉。
  • P3 口有第二功能,例如串口、外部中断、定时器输入等。
  • 写 1 时可以作为输入读取;写 0 时输出低电平。

在代码中,常用 sbit 定义单个引脚:

c 复制代码
sbit LED1 = P2^0;
sbit KEY1 = P3^1;

也可以用字节方式控制一整组 IO:

c 复制代码
P2 = 0xFE;  // 1111 1110

二、51单片机的基本实现方式

2.1 硬件实现方式

51单片机的硬件实现通常是:

最小系统 + 外设电路 + 下载接口

外设包括:

  • LED:用于显示
  • 按键:用于输入
  • 数码管:用于显示数字
  • 蜂鸣器:用于发声
  • 传感器:如温度、红外、超声波等

常见开发板会通过排针、排阻、限流电阻把外设连接到单片机 IO 口。

2.2 软件实现方式

51单片机一般使用 C 语言开发,常用 Keil uVision 编写和编译。核心步骤:

  1. 包含头文件:#include <reg52.h>
  2. 定义引脚:sbit
  3. 编写延时函数
  4. main() 中写主循环
  5. 编译生成 .hex 文件
  6. 用 STC-ISP 等工具烧录到单片机

基本程序结构:

c 复制代码
#include <reg52.h>

void main()
{
    while(1)
    {
        // 循环执行
    }
}

51单片机程序通常是"主循环 + 中断"的结构:

  • 主循环处理常规任务
  • 中断处理紧急或周期性任务,如定时器、串口接收

2.3 开发流程

  1. 新建 Keil 工程
  2. 选择单片机型号,如 AT89C52 或 STC89C52
  3. 新建 .c 文件并加入工程
  4. 编写代码
  5. 编译,生成 .hex
  6. 打开 STC-ISP,选择串口和固件
  7. 给开发板冷启动下载
  8. 观察实验现象

2.4 时钟与周期

传统 8051 中:

  • 时钟周期 = 1 / 晶振频率
  • 机器周期 = 12 个时钟周期
  • 指令周期 = 1~4 个机器周期

例如 12MHz 晶振:

  • 时钟周期 = 1/12 us
  • 机器周期 = 1us

因此,软件延时函数中的循环次数需要根据晶振频率调整。


三、流水灯实验

3.1 实验目的

  • 掌握 51单片机 GPIO 输出控制
  • 理解 LED 低电平点亮 / 高电平点亮
  • 掌握延时函数和循环移位
  • 实现 LED 依次点亮效果

3.2 硬件连接

常见开发板连接方式:

  • LED 阳极通过限流电阻接 VCC
  • LED 阴极接 P2.0 ~ P2.7
  • 所以 低电平点亮,高电平熄灭

例如:

text 复制代码
P2.0 -> LED1 -> 电阻 -> VCC
P2.1 -> LED2 -> 电阻 -> VCC
...
P2.7 -> LED8 -> 电阻 -> VCC

如果开发板是共阴接法,则高电平点亮,代码需要取反。

3.3 实验原理

输出 0xFE

text 复制代码
0xFE = 1111 1110

最低位 P2.0 为 0,所以 P2.0 对应的 LED 点亮。

延时后,让这个 0 循环左移:

text 复制代码
1111 1110  -> P2.0 亮
1111 1101  -> P2.1 亮
1111 1011  -> P2.2 亮
...
0111 1111  -> P2.7 亮

再回到 1111 1110,形成流水灯。

3.4 完整代码:库函数循环移位版

c 复制代码
#include <reg52.h>
#include <intrins.h>

typedef unsigned char u8;
typedef unsigned int u16;

// 约1ms延时,12MHz晶振下近似,实际可调整
void delay_ms(u16 ms)
{
    u16 i, j;
    for(i = ms; i > 0; i--)
        for(j = 110; j > 0; j--);
}

void main()
{
    u8 led = 0xFE;  // 1111 1110,P2.0先亮

    while(1)
    {
        P2 = led;           // 输出到P2口
        delay_ms(500);      // 延时500ms
        led = _crol_(led, 1); // 循环左移1位
    }
}

3.5 数组版流水灯

如果不使用 _crol_,也可以用数组:

c 复制代码
#include <reg52.h>

typedef unsigned char u8;
typedef unsigned int u16;

u8 code led_table[] = {
    0xFE, 0xFD, 0xFB, 0xF7,
    0xEF, 0xDF, 0xBF, 0x7F
};

void delay_ms(u16 ms)
{
    u16 i, j;
    for(i = ms; i > 0; i--)
        for(j = 110; j > 0; j--);
}

void main()
{
    u8 i;

    while(1)
    {
        for(i = 0; i < 8; i++)
        {
            P2 = led_table[i];
            delay_ms(500);
        }
    }
}

3.6 实验现象

下载程序后,LED 会从 P2.0 到 P2.7 依次点亮,形成流水效果。

注意事项:

  • 如果 LED 不亮,先确认是共阳还是共阴。
  • 如果亮度异常,检查限流电阻。
  • 如果顺序相反,可以改用 _cror_ 或调整数组顺序。
  • 延时时间与晶振频率有关。

四、独立按键实验

4.1 实验目的

  • 掌握 51单片机 GPIO 输入检测
  • 理解按键按下为低电平的常见电路
  • 掌握软件消抖
  • 实现按键控制 LED

4.2 硬件连接

常见独立按键接法:

text 复制代码
P3.1 -> 按键 -> GND

由于 P3 口内部有弱上拉:

  • 按键未按下:P3.1 为高电平
  • 按键按下:P3.1 被拉到 GND,为低电平

所以代码中判断:

c 复制代码
if(KEY1 == 0)
{
    // 按键按下
}

4.3 按键消抖原理

机械按键在按下和松开瞬间会产生 5~10ms 左右的抖动,导致单片机可能误判多次。

软件消抖方法:

  1. 检测到低电平
  2. 延时 20ms
  3. 再次检测
  4. 如果仍为低电平,确认按下
  5. 等待按键释放

4.4 完整代码:按键控制 LED 亮灭切换

c 复制代码
#include <reg52.h>

typedef unsigned char u8;
typedef unsigned int u16;

sbit KEY1 = P3^1;
sbit LED1 = P2^0;

void delay_ms(u16 ms)
{
    u16 i, j;
    for(i = ms; i > 0; i--)
        for(j = 110; j > 0; j--);
}

void main()
{
    LED1 = 1;  // 默认熄灭,低电平点亮

    while(1)
    {
        if(KEY1 == 0)          // 检测按键
        {
            delay_ms(20);      // 消抖
            if(KEY1 == 0)      // 再次确认
            {
                LED1 = !LED1;  // 状态翻转
                while(KEY1 == 0); // 等待松手
            }
        }
    }
}

4.5 扩展:按键控制流水灯启停

思路:用一个标志位控制流水灯是否运行。

c 复制代码
#include <reg52.h>
#include <intrins.h>

typedef unsigned char u8;
typedef unsigned int u16;

sbit KEY1 = P3^1;

bit run_flag = 1;  // 1运行,0停止

void delay_ms(u16 ms)
{
    u16 i, j;
    for(i = ms; i > 0; i--)
        for(j = 110; j > 0; j--);
}

void main()
{
    u8 led = 0xFE;

    while(1)
    {
        if(KEY1 == 0)
        {
            delay_ms(20);
            if(KEY1 == 0)
            {
                run_flag = !run_flag;
                while(KEY1 == 0);
            }
        }

        if(run_flag)
        {
            P2 = led;
            delay_ms(500);
            led = _crol_(led, 1);
        }
    }
}

注意:上面这种写法在 delay_ms(500) 期间无法及时检测按键。实际项目中更推荐用定时器中断来刷新流水灯,这样按键响应更灵敏。

4.6 实验现象

  • 按下按键,LED 亮;再按一次,LED 灭。
  • 或者按下按键,流水灯开始 / 停止。

注意事项:

  • 如果按键无反应,检查接线和上拉。
  • 如果一按就连续触发,说明消抖不够或等待松手没写好。
  • 如果按键引脚不同,修改 sbit KEY1 = P3^1;
  • 如果 LED 极性不同,修改 LED1 = !LED1; 或初始电平。

五、常见问题

5.1 程序下载失败

  • 检查串口是否选对
  • 检查开发板是否冷启动
  • 检查单片机型号和波特率
  • 检查 TX、RX 是否交叉连接

5.2 LED 不亮

  • 确认 LED 是共阳还是共阴
  • 确认引脚是否对应
  • 确认限流电阻是否正常
  • P0 口作为普通 IO 时可能需要上拉电阻

5.3 按键不灵敏

  • 检查按键是否一端接 IO,一端接 GND
  • 检查 IO 是否配置为输入
  • 加入 20ms 软件消抖
  • 等待松手,避免一次按下触发多次

5.4 延时不准

  • 延时函数与晶振频率有关
  • 12MHz 和 11.0592MHz 下延时不同
  • 需要精确定时建议使用定时器中断

六、总结

51单片机入门可以围绕三条主线:

  1. 基本概念:单片机是什么、最小系统、IO口、时钟、复位。
  2. 基本实现方式:Keil 编写 C 程序,生成 hex,烧录运行,通过 GPIO 控制外设。
  3. 经典实验
    • 流水灯:学习输出控制、延时、循环移位。
    • 独立按键:学习输入检测、按键消抖、状态切换。

掌握流水灯和按键后,就可以继续学习:

  • 数码管动态显示
  • 定时器中断
  • 外部中断
  • 串口通信
  • PWM 控制
  • 矩阵按键
  • 温度传感器、红外、超声波等模块

51单片机虽然简单,但它是理解嵌入式系统很好的起点。把 GPIO、延时、中断、定时器这些基础打牢,后面学习 STM32、Arduino、ESP32 等平台会轻松很多。


本文为学习笔记,欢迎交流指正。如果对你有帮助,可以点赞收藏。

相关推荐
M78佐菲37 分钟前
51单片机学习笔记(2)
linux·笔记·嵌入式硬件·学习·51单片机
LeeAmos11 小时前
CMIS V5.3 中文版
笔记
今儿敲了吗1 小时前
01词频统计器
笔记·python
浔溺1 小时前
al+大数据每日学习笔记37
大数据·笔记·学习
TheBestRucy1 小时前
PyTorch 基本使用学习笔记
pytorch·笔记·学习
志尊宝1 小时前
Vue3 零基础每日笔记(016):v-for 列表渲染——key 的作用与为什么不能用 index
javascript·vue.js·笔记
ouynagda1 小时前
51 单片机 LED 流水灯 + 数码管动态扫描学习笔记(STC89C52)
笔记·单片机·学习
祖力551 小时前
51单片机(中断、定时器、PWM)
单片机·嵌入式硬件·51单片机
扎陵半导体1 小时前
电子系统中的隔离芯片:关键作用与性能指标
单片机·嵌入式硬件·国产芯片·隔离器·隔离芯片·光隔