51单片机C语言教程该怎么学?

99ANYc3cd6
预计阅读时长 28 分钟
位置: 首页 C语言 正文

新概念 51单片机C语言教程 (从入门到实践)

前言:为什么学51单片机?

51单片机是嵌入式世界的“Hello, World!”,它结构简单、资料丰富、价格低廉,是学习嵌入式系统开发的绝佳入门平台,掌握51单片机,您不仅能理解计算机底层的运行原理,更能为后续学习ARM、STM32等更复杂的MCU打下坚实的基础。

新概念 51单片机c语言教程
(图片来源网络,侵删)

本教程将使用 C语言 进行教学,因为它比汇编语言更易读、易移植、可维护性更高,是现代嵌入式开发的主流语言。


第一部分:基础理论篇 (知其然)

第一章:认识你的伙伴——51单片机

  1. 什么是单片机?

    • 单片机,全称“单片微型计算机”(Single-Chip Microcomputer),又称“微控制器”(Microcontroller Unit, MCU)。
    • 它不是一块普通的芯片,而是将 CPU(中央处理器)、RAM(随机存储器)、ROM(只读存储器)、I/O(输入/输出)端口、定时器/计数器、中断系统 等计算机核心部件集成在一块芯片上的微型计算机。
    • 生活中的例子:您的电子表、遥控器、洗衣机、智能手环等内部,都有一个或多个单片机在工作。
  2. 51单片机家族

    • 始祖:Intel公司推出的8051系列。
    • 经典型号AT89S52,这是目前学习51单片机最主流、最经典的型号,资料多,仿真和烧录都非常方便。
    • 其他成员:AT89C51(已逐渐被S52取代,因为S52支持ISP在线编程)、STC89C52RC(国产,性能更强,支持ISP/IAP,是目前市场上的新宠)。
  3. 51单片机的核心结构

    新概念 51单片机c语言教程
    (图片来源网络,侵删)
    • CPU:8位,负责运算和控制。
    • 存储器
      • ROM (4KB - 8KB):用于存放程序代码,断电不丢失。
      • RAM (128B - 256B):用于存放程序运行中的临时变量,断电丢失。
    • I/O端口:4组8位共32个引脚(P0, P1, P2, P3),用于连接外部设备,如LED、按键、传感器等。
    • 定时器/计数器:通常有2-3个16位的定时器,用于精确定时或对外部脉冲计数。
    • 中断系统:允许CPU在处理紧急任务时,暂停当前程序,去执行更重要的任务,处理完后再返回原处继续执行。

第二章:开发环境搭建 (工欲善其事,必先利其器)

学习单片机编程,你需要两个核心软件和一个硬件工具。

  1. 编程软件 (IDE)

    • Keil C51:这是最经典、最权威的51单片机开发环境,它集成了代码编辑器、编译器、链接器和调试器。
    • 下载与安装:网上可以找到“Keil C51 V9.5x”版本(例如UV4),这是非常稳定且广泛使用的版本,安装时注意选择正确的版本(ARM或C51)。
  2. 烧录/下载工具

    • STC-ISP:这是用于烧录STC系列单片机的官方软件,如果你的板子是STC89C52,这个是必备的,它还集成了串口助手、波特率计算器等实用工具。
    • Proteus:强大的电路仿真软件,你可以在电脑上画出电路图,并运行你编写的程序,观察虚拟电路的运行结果,非常适合在没有硬件的情况下学习和验证。
  3. 硬件工具

    新概念 51单片机c语言教程
    (图片来源网络,侵删)
    • 51单片机最小系统板:包含核心芯片(如STC89C52)、晶振、复位电路、电源电路,是学习和开发的基础。
    • USB转TTL模块:用于将电脑的USB口转换为串口(UART),连接单片机进行程序烧录和串口通信。
    • 常用外设:LED灯、按键、电阻、杜邦线、面包板等。

第二部分:核心编程篇 (知其所以然)

第三章:点亮你的第一个LED灯——C语言与硬件的桥梁

这是单片机学习的“Hello, World!”,也是最激动人心的一步。

  1. 硬件原理

    • 51单片机I/O口操作:51单片机的I/O口可以设置为输入模式输出模式
    • 点亮LED:LED具有单向导电性,通常将其正极通过一个限流电阻连接到单片机的I/O口,负极接地,当I/O口输出高电平时,LED两端电压差接近0,不亮;当I/O口输出低电平时,LED被点亮。
  2. C语言核心概念:sfrsbit

    • 标准 C 语言没有操作特殊功能寄存器的能力,51单片机厂商为Keil C51扩展了两个关键字:
    • sfr (Special Function Register):用于定义一个8位的特殊功能寄存器。
      // 定义 P1 端口寄存器
      sfr P1 = 0x90;
    • sbit (Special Bit):用于定义一个特殊功能寄存器中的某一位。
      // 定义 P1 端口的第 0 位 (P1.0)
      sbit LED = P1^0; 
  3. 第一个程序:Blinking LED (闪烁的LED)

    #include <reg52.h> // 包含51单片机寄存器定义的头文件
    // sfr P1 = 0x90; // 在reg52.h中已经定义,我们直接使用
    sbit LED = P1^0; // 将LED连接到P1.0引脚
    void main(void) {
        // 主函数,程序从这里开始执行
        while(1) { // 无限循环,单片机程序通常都在循环中运行
            LED = 0; // P1.0输出低电平,点亮LED
            // 延时函数 (我们稍后会自己写一个)
            Delay(50000); 
            LED = 1; // P1.0输出高电平,熄灭LED
            Delay(50000);
        }
    }
    // 简单的延时函数 (非精确延时)
    void Delay(unsigned int t) {
        while(t--); // 空循环,消耗CPU时钟周期
    }

如何实践

  1. 在Keil中新建一个工程,选择你的单片机型号(如STC89C52RC)。
  2. 创建一个新的C文件,将上面的代码粘贴进去。
  3. 编译生成 .hex 文件。
  4. 使用STC-ISP软件,将.hex文件下载到你的单片机中。
  5. 观察开发板上连接在P1.0的LED是否开始闪烁!

第四章:输入与输出——与外部世界交互

  1. 按键输入

    • 硬件原理:按键一端接I/O口,另一端接地,当按键未按下时,I/O口通过一个上拉电阻接到VCC,读到的是高电平,当按键按下时,I/O口直接接地,读到的是低电平

    • C语言实现:读取I/O口的电平状态。

      sbit KEY = P3^2; // 假设按键连接到P3.2
      if (KEY == 0) { // 如果检测到低电平
          // 按键按下
          Delay(20000); // 简单消抖
          if (KEY == 0) { // 再次确认,防止误触发
              // 执行按键按下后的操作
              while(!KEY); // 等待按键释放
          }
      }
  2. 蜂鸣器发声

    • 硬件原理:蜂鸣器分为有源和无源,有源蜂鸣器直接接通电源就会响;无源蜂鸣器需要施加特定频率的脉冲信号才能发声,我们通常用无源蜂鸣器来播放不同音调。

    • C语言实现:通过定时器产生PWM(脉冲宽度调制)信号,控制蜂鸣器发声,简单起见,我们可以用软件延时模拟高低电平变化。

      sbit Buzzer = P2^5; // 蜂鸣器连接到P2.5
      void PlaySound(unsigned int duration) {
          unsigned int i;
          for(i=0; i<duration; i++) {
              Buzzer = ~Buzzer; // 电平翻转
              Delay(100); // 改变这个值可以改变音调
          }
      }

第五章:中断系统——高效的程序管理

想象一下你正在看书(主程序),突然电话响了(中断事件),你会放下书,去接电话(执行中断服务程序),接完电话后,你会在刚才的地方继续看书(返回主程序继续执行),这就是中断。

  1. 中断的优势

    • 提高效率:CPU无需不断查询某个事件是否发生(如按键按下),可以专注于其他任务,事件发生时,硬件会自动“打断”CPU。
    • 实时性强:能快速响应紧急事件。
  2. 51单片机的中断源

    • 外部中断0 (INT0):P3.2引脚
    • 外部中断1 (INT1):P3.3引脚
    • 定时器/计数器0中断 (TF0)
    • 定时器/计数器1中断 (TF1)
    • 串口中断 (RI/TI)
  3. 中断编程步骤

    1. 配置中断允许寄存器EA (总开关), EX0 (外部中断0允许), ET0 (定时器0中断允许)等。
    2. 配置中断优先级寄存器:设置中断的优先级(可选)。
    3. 编写中断服务函数:函数名固定,如 void EX0_ISR(void) interrupt 0
    4. 在主函数中开启中断
  4. 实例:按键中断控制LED

    #include <reg52.h>
    sbit LED = P1^0;
    void main(void) {
        EA = 1;    // 开启总中断
        EX0 = 1;   // 开启外部中断0
        IT0 = 1;   // 设置外部中断0为下降沿触发(按键按下时触发)
        while(1) {
            // 主程序可以做其他事情,不用一直等待按键
            LED = 1; // 默认熄灭
        }
    }
    // 外部中断0的中断服务函数
    void EX0_ISR(void) interrupt 0 {
        LED = ~LED; // 每次中断,LED状态翻转
    }

第六章:定时器/计数器——精准的脉搏

定时器是单片机的核心功能之一,用于精确定时、产生波特率、驱动电机等。

  1. 工作原理

    • 定时器本质上是一个加1计数器,它对单片机内部的机器周期脉冲进行计数。
    • 当计数器从某个初值开始,计数到溢出(从0xFF变回0x00)时,就会产生一个中断请求。
  2. 配置步骤

    1. 设置工作模式(模式0-3)。
    2. 计算并设置初值,以获得所需的定时时间。
    3. 启动定时器(TR0 = 1TR1 = 1)。
    4. 开启定时器中断(ET0 = 1ET1 = 1)。
  3. 实例:使用定时器实现精确的LED闪烁

    • 假设晶振频率为11.0592MHz,机器周期 = 12 / 晶振频率 = 1.085us。
    • 我们想让LED每500ms闪烁一次。
    • 使用定时器0,模式1(16位定时器)。
    • 需要的计数次数 = 500ms / 1.085us ≈ 460810。
    • 定时器最大计数值为65536,所以需要设置初值:65536 - 460810?这不对,说明需要多次中断才能达到500ms。
    • 更简单的方法:我们让定时器每50ms中断一次,然后中断10次就是500ms。
    • 50ms的计数次数 = 50ms / 1.085us ≈ 46081。
    • 初值 = 65536 - 46081 = 19455 (十六进制 0x4BFF)。
    #include <reg52.h>
    sbit LED = P1^0;
    unsigned int count = 0; // 中断计数器
    void Timer0_Init(void) {
        TMOD &= 0xF0; // 清空T0设置位
        TMOD |= 0x01; // 设置T0为模式1 (16位定时器)
        TH0 = 0x4B;   // 设置定时器初值高8位
        TL0 = 0xFF;   // 设置定时器初值低8位
        ET0 = 1;      // 开启定时器0中断
        EA = 1;       // 开启总中断
        TR0 = 1;      // 启动定时器0
    }
    void main(void) {
        Timer0_Init();
        while(1); // 主程序什么都不做,等待中断
    }
    // 定时器0的中断服务函数
    void Timer0_ISR(void) interrupt 1 {
        // 重新装载初值
        TH0 = 0x4B;
        TL0 = 0xFF;
        count++; // 中断次数加1
        if (count >= 10) { // 中断10次
            count = 0;
            LED = ~LED; // LED状态翻转
        }
    }

第七章:串行通信——单片机的“嘴巴”和“耳朵”

串口通信是单片机与PC、其他单片机或模块(如蓝牙、GPS)进行数据交换的常用方式。

  1. 基本概念

    • UART:通用异步收发器。
    • 异步:没有专门的时钟线,通过约定好的波特率来同步。
    • 波特率:每秒传输的比特数,常用的有9600, 19200, 115200等,通信双方必须设置相同的波特率。
  2. 51单片机串口寄存器

    • SCON:串口控制寄存器,设置工作模式、允许发送/接收。
    • PCON:电源控制寄存器,包含波特率倍增位SMOD
    • TMOD:定时器1用于产生波特率。
  3. 配置步骤

    1. 设置定时器1为模式2(8位自动重装模式),作为波特率发生器。
    2. 计算并设置定时器1的初值。
    3. 设置SCON寄存器,选择串口工作模式(通常为模式1,8位UART)。
    4. 开启串口中断ES和总中断EA
    5. 使用SBUF寄存器发送和接收数据。
  4. 实例:单片机向PC发送“Hello World!”

    #include <reg52.h>
    #include <stdio.h> // 为了使用printf重定向
    // 串口初始化,波特率设为9600
    void UART_Init(void) {
        SCON = 0x50; // 模式1, 允许接收
        TMOD &= 0x0F; // 清空T1设置位
        TMOD |= 0x20; // 设置T1为模式2 (8位自动重装)
        TH1 = 0xFD;   // 9600 baud @ 11.0592MHz
        TL1 = 0xFD;
        TR1 = 1;      // 启动定时器1
        EA = 1;       // 开启总中断
        ES = 1;       // 开启串口中断
    }
    // 重定向printf到串口
    char putchar(char c) {
        SBUF = c;
        while(!TI); // 等待发送完成
        TI = 0;      // 清除发送完成标志
        return c;
    }
    void main(void) {
        UART_Init();
        while(1) {
            printf("Hello World from 51!\r\n");
            Delay(50000); // 延时一段时间再发
        }
    }
    // 串口中断服务函数 (用于接收)
    void UART_ISR(void) interrupt 4 {
        if (RI) { // 如果是接收中断
            RI = 0; // 清除接收中断标志
            // 这里可以处理接收到的数据 SBUF
        }
    }

第三部分:项目实战篇 (学以致用)

掌握了以上核心知识,你已经具备了独立完成小型项目的能力,这里提供几个经典项目作为练习:

  1. 数字时钟

    • 功能:在LCD1602或数码管上显示年、月、日、时、分、秒。
    • 涉及技术:定时器(精确计时)、按键(调时调分)、显示驱动(LCD1602或数码管)。
  2. 温度计

    • 功能:使用DS18B20数字温度传感器测量环境温度,并显示在LCD1602上。
    • 涉及技术:单总线通信协议、定时器精确延时、LCD显示。
  3. 智能小车

    • 功能:通过红外或超声波传感器实现自动避障,通过蓝牙模块实现手机遥控。
    • 涉及技术:电机驱动(L298N)、传感器数据采集、串口通信、中断(用于检测传感器信号)。
  4. 电子密码锁

    • 功能:通过4x4矩阵键盘输入密码,密码正确则驱动舵机或继电器开门。
    • 涉及技术:矩阵键盘扫描、EEPROM(保存密码,使用AT24C02芯片)、舵机控制。

总结与进阶

  • 本教程从51单片机的硬件基础讲起,逐步深入到C语言编程、I/O操作、中断、定时器和串口通信等核心模块,并提供了实践项目,学习单片机是一个“理论+实践”反复迭代的过程,多动手、多调试、多思考,才能真正掌握。

  • 进阶方向

    1. 从51到ARM:当51单片机无法满足复杂需求时(如运行操作系统、处理复杂图形),可以学习更强大的ARM Cortex-M系列(如STM32)。
    2. 学习RTOS:在复杂项目中,使用实时操作系统(如FreeRTOS、RT-Thread)可以更好地管理任务和资源。
    3. 掌握更多外设:学习SPI、I2C等常用通信协议,掌握ADC(模数转换)、PWM(脉宽调制)等高级功能。

希望这份“新概念”教程能成为您打开嵌入式世界大门的钥匙,祝您学习愉快!

-- 展开阅读全文 --
头像
dede如何导出excel表格?
« 上一篇 昨天
C语言课程设计如何实现学生课程管理系统?
下一篇 » 昨天
取消
微信二维码
支付宝二维码

目录[+]