欢迎光临
我们一直在努力

嵌入式——51单片机1

【51单片机学习笔记】 最小系统、GPIO、数码管、按键、LED、外部中断、 定时器中断

📖今日学习:51单片机最小系统、GPIO口使用、LED点亮、数码管显示、按键检测;外部中断、定时器/计数器中断。

🔍文章大纲

  • 51单片机最小系统
  • GPIO口基础概念
  • LED灯驱动(输出)
  • 数码管显示(静态、动态扫描)
  • 按键输入检测(查询方式)
  • 中断系统基础概念
  • 外部中断
  • 定时器/计数器中断
  • ✨学习重点汇总
  • ⚠️易错点&踩坑记录
  • 📝今日学习小结
  • 在这里插入图片描述
    在这里插入图片描述

    1. 51单片机最小系统

    最小系统是单片机能够正常运行的最少硬件电路,4部分组成:

  • 单片机主控芯片(如STC89C52)
  • 电源电路:给单片机供电,一般5V直流供电
  • 晶振电路:提供系统时钟,常见11.0592MHz、12MHz。
    • 12MHz:机器周期 = 1us,方便延时计算
    • 11.0592MHz:串口波特率可以精准匹配,串口项目首选
  • 复位电路:上电复位,让单片机程序从0地址从头开始执行。
  • 机器周期:51单片机12个时钟周期 = 1个机器周期。
    晶振12MHz,时钟周期1/12us,机器周期恰好1us。

    2. GPIO口基础概念

    51单片机标准有4组IO口:P0、P1、P2、P3,每组8位(P0.0~P0.7)。

    IO口特点
    P0 开漏输出,无上拉电阻;做输出必须外接上拉电阻;可地址/数据复用
    P1 准双向口,内部带上拉电阻,普通IO,无复用功能
    P2 准双向口,带上拉;外部存储器高8位地址复用
    P3 准双向口,带上拉;引脚复用功能(外部中断、定时器、串口)

    准双向口:作为输入之前,必须先向端口写1,释放引脚,才能正确读取外部电平。
    P0口特殊:内部没有上拉,输出低电平有效,输出高电平是高阻态。

    寄存器操作示例:

    // P1口全部置0
    P1 = 0x00;
    // P1.0单独置1
    P1_0 = 1;

    3. LED灯点亮(GPIO输出)

    LED二极管:阳极接高电平,阴极接低电平才会点亮。
    两种硬件接法:

  • 共阴极:阴极接GND,IO输出高电平,灯亮。
  • 共阳极:阳极接VCC,IO输出低电平,灯亮。
  • 必须串联限流电阻(220Ω左右),防止电流过大烧毁LED和IO引脚。

    示例代码(P1.0控制LED,低电平点亮)

    #include <reg52.h>
    sbit led = P1^0;

    void main(void)
    {
    while(1)
    {
    led = 0; //点亮
    }
    }

    简单延时函数,实现LED闪烁

    void delay_ms(unsigned int t)
    {
    unsigned int i,j;
    for(i=t;i>0;i–)
    for(j=110;j>0;j–);
    }

    4. 数码管显示

    数码管由a~g七个段 + dp小数点组成。

    • 共阳数码管:公共端接VCC;段脚输出低电平点亮段。
    • 共阴数码管:公共端接GND;段脚输出高电平点亮段。

    静态数码管

    每个数码管段脚独立;只要赋值段码,数字持续显示。
    优点:程序简单,无闪烁;缺点:占用IO多,数码管数量多时不适合。

    段码表:
    共阴:0~9:0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F

    动态扫描数码管

    多位数码管,段选共用一套IO,位选控制哪一个数码管点亮。
    流程:

  • 送当前要显示数字的段码;
  • 打开对应位选,点亮这一位;
  • 短暂延时;
  • 关闭位选(消影);
  • 循环切换下一位;
  • 利用人眼视觉暂留,高速循环扫描,人眼看到多位同时显示。
    ⚠️消影很关键:不关闭位选直接切换段码,会出现重影乱码。

    动态扫描简单逻辑伪代码:

    while(1)
    {
    送第一位段码;
    开第一位位选;
    delay();
    关闭所有位选; //消影

    送第二位段码;
    开第二位位选;
    delay();
    关闭所有位选;
    }

    5. 按键输入检测(查询方式)

    按键原理:按下引脚电平翻转;松开恢复。
    机械按键存在机械抖动:按下/松开瞬间电平抖动5‑10ms,直接读取会误判多次。

    解决抖动两种方案:

  • 软件延时消抖:检测到电平变化,延时10ms再读一次电平确认。
  • 硬件消抖:外接电容。
  • 51准双向口做输入:读取按键前,IO口先写1。

    查询方式按键示例:

    sbit key = P3^2;
    void key_scan(void)
    {
    if(key == 0) //按键按下低电平
    {
    delay_ms(10); //软件消抖
    if(key == 0)
    {
    //按键处理业务
    }
    while(key == 0); //等待松开
    delay_ms(10);
    }
    }

    查询方式缺点:CPU一直循环扫描按键,占用CPU资源。可以使用外部中断实现按键检测。

    6. 51中断系统基础

    中断:CPU正在执行主程序,收到外部事件信号,暂停主程序,跳转去执行中断服务函数;执行完毕回到断点继续运行主程序。

    51单片机5个中断源:

    中断源中断号说明
    外部中断0 0 INT0(P3.2)
    定时器0中断 1 T0
    外部中断1 2 INT1(P3.3)
    定时器1中断 3 T1
    串口中断 4 UART

    关键寄存器:

  • IE:中断允许寄存器,总中断EA,各个中断使能位。
    • EA:总中断开关,必须置1,所有中断才能生效。
  • IP:中断优先级寄存器,高优先级可以打断低优先级中断。
  • 外部中断:TCON寄存器,设置触发方式(下降沿触发 / 低电平触发)。
  • 定时器:TMOD定时器模式寄存器;THx TLx定时器初值寄存器。
  • 中断服务函数格式:

    void 中断服务函数名(void) interrupt 中断号
    {
    //中断处理代码
    }

    ⚠️中断服务函数不要写延时、复杂业务;尽量简短快速执行完。

    7. 外部中断

    外部中断0:P3.2(INT0);外部中断1:P3.3(INT1)
    两种触发方式:

  • 低电平触发:引脚持续低电平,会不断反复触发中断;适合外部电平信号。
  • 下降沿触发(边沿触发):引脚从高电平跳变到低电平一瞬间触发一次,按键推荐使用。
  • 配置步骤:

  • 设置IT0/IT1选择触发方式;
  • EX0 / EX1打开对应外部中断;
  • EA=1开启总中断;
  • 编写interrupt对应中断号的中断服务函数。
  • 示例:外部中断0,下降沿触发按键

    #include <reg52.h>
    sbit led = P1^0;

    void int0_init(void)
    {
    IT0 = 1; //下降沿触发
    EX0 = 1; //开启外部中断0
    EA = 1; //打开总中断
    }

    //外部中断0服务函数,中断号0
    void int0_isr(void) interrupt 0
    {
    led = ~led; //按键触发翻转LED状态
    }

    void main(void)
    {
    int0_init();
    while(1)
    {
    //主循环可以做别的事情
    }
    }

    边沿触发:只会跳变瞬间进一次中断;低电平触发,如果引脚一直低电平,会反复进入中断。

    8. 定时器/计数器中断

    定时器本质:对机器周期计数;计数值溢出,触发定时器中断。

    • 定时器模式:对单片机内部机器周期计数,用来定时。
    • 计数器模式:对外部T0(P3.4)、T1(P3.5)引脚外部脉冲计数。

    TMOD寄存器:设置T0、T1工作模式;模式1最常用:16位定时器,TH高8位,TL低8位,最大计数65536。

    12M晶振机器周期1us;模式1,最多定时65536us = 65.536ms。
    定时时间 = (65536‑初值) * 机器周期。

    定时器配置步骤:

  • TMOD设置工作模式;
  • 给TH0、TL0装载计数初值;
  • ET0打开定时器0中断;
  • TR0启动定时器;
  • EA=1开启总中断;
  • 写定时器中断服务函数,中断里面重新给TH0 TL0赋初值!模式1不会自动重装。
  • 示例:12M晶振,定时器0模式1定时50ms中断

    void timer0_init(void)
    {
    TMOD |= 0x01; //T0模式1,16位定时器
    //50ms 初值 65536‑50000 = 15536
    TH0 = 15536 / 256;
    TL0 = 15536 % 256;
    ET0 = 1; //开启T0中断
    TR0 = 1; //启动定时器0
    EA = 1; //总中断打开
    }

    //定时器0中断服务函数,中断号1
    void timer0_isr(void) interrupt 1
    {
    //模式1,必须手动重装初值!!
    TH0 = 15536 / 256;
    TL0 = 15536 % 256;

    //定时到,业务处理
    }


    ✨学习重点

  • 最小系统四大部分:电源、晶振、复位、单片机;分清12M与11.0592M晶振用途,机器周期概念。
  • 4组GPIO:P0开漏无上拉;P1/P2/P3准双向口;准双向口做输入要先写1;P3口具备引脚复用功能。
  • LED:分清共阳、共阴极接法,必须串联限流电阻。
  • 数码管:分清共阴/共阳段码;动态扫描原理,消影操作必不可少,防止重影;视觉暂留实现多位同时显示。
  • 按键:机械抖动,软件延时消抖原理;查询扫描按键优缺点。
  • 中断核心概念:打断主程序,执行中断服务函数;EA总中断开关,不打开所有中断无效。
  • 外部中断:低电平触发 vs 下降沿(边沿触发);按键优先边沿触发。
  • 定时器中断:模式1为16位,不会自动重装初值,中断服务函数内手动重新赋值THx TLx;定时时间计算公式。
  • 中断服务函数规则:interrupt + 中断号;函数不能有参数、返回值;中断内部尽量简短,禁止大量延时。
  • ⚠️易错点&踩坑记录

  • ❌准双向IO做输入,忘记先写1,读按键一直电平错误。
  • ❌P0口输出忘记加上拉电阻,输出高电平是高阻态,LED/外设工作异常。
  • ❌LED省略限流电阻,直接接IO,烧坏LED或者单片机IO引脚。
  • ❌数码管动态扫描没有消影,切换段码时出现重影、乱码。
  • ❌按键不做消抖,按下一次多次触发,逻辑错乱。
  • ❌外部中断使用低电平触发,按键按住不放,不断重复进中断;按键场景优先下降沿触发。
  • ❌中断忘记打开总中断EA=1,中断完全不响应。
  • ❌定时器模式1,中断服务函数忘记手动重装TH0 TL0初值,只进一次中断,之后不再触发。
  • ❌定时器初值计算错误,定时时间和预期完全不符。
  • ❌中断服务函数里面写长延时、复杂业务逻辑;中断要快进快出,耗时逻辑放到主循环。
  • ❌中断服务函数写错中断号,跑到错误的中断处理,程序跑飞。
  • ❌混淆共阳、共阴数码管段码,写反,数码显示乱数字。
  • 📝今日学习小结

    今天学习51单片机基础硬件与软件编程:掌握最小系统组成;理解4组GPIO口电气特性;完成LED点亮闪烁;数码管静态、动态扫描显示;按键查询检测。
    学习51中断系统,掌握外部中断实现按键触发;定时器中断完成定时功能。

    赞(0)
    未经允许不得转载:171主机测评 » 嵌入式——51单片机1
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址