AT89C2051用C语言该怎么入门?

99ANYc3cd6
预计阅读时长 23 分钟
位置: 首页 C语言 正文
  1. AT89C2051 简介:为什么选择它?
  2. 开发环境搭建:你需要什么软件和硬件?
  3. C 语言核心要点:针对 8051 内核的特殊性。
  4. 一个完整的 LED 闪烁示例:从零开始点亮一个 LED。
  5. 常用外设驱动示例:如按键、定时器。
  6. 总结与进阶

AT89C2051 简介

AT89C2051 是 Atmel(现已被 Microchip 收购)生产的一款 8 位单片机,基于经典的 Intel 8051 内核

at89c2051 c语言
(图片来源网络,侵删)

主要特点:

  • 内核:标准的 8051 内核。
  • Flash 存储器:2KB,可重复擦写 1000 次。
  • RAM:128 字节。
  • 工作频率:最高 24MHz。
  • I/O 端口:15 个可编程 I/O 口(P1.0-P1.7, P3.0-P3.7, P3.6 作为外部中断 INT1,P3.7 作为 RXD)。注意:它没有 P0 口和 P2 口,这是它与标准 8052 的一个重要区别。
  • 定时器/计数器:2 个 16 位定时器(Timer 0 和 Timer 1)。
  • 中断系统:5 个中断源(2 个外部中断,2 个定时器中断,1 个串口中断)。
  • 串行通信:1 个全双工 UART。
  • 特殊功能:内置精密模拟比较器。
  • 封装:20 脚 PDIP 或 SOIC,体积小巧。

为什么适合学习?

  • 经典内核:学习 8051 是嵌入式开发的基石,理解了它,再学其他 MCU(如 STM32, PIC)会事半功倍。
  • 资源简单:2KB Flash 和 128B RAM 的限制,迫使你写出精简高效的代码,有助于理解底层资源管理。
  • 资料丰富:作为一款非常古老的芯片,网上有海量的教程、数据手册和应用笔记。
  • 成本低廉:芯片本身和开发板都非常便宜。

开发环境搭建

要在 AT89C2051 上运行 C 语言,你需要一个 交叉编译器,因为你的 PC 是 x86 架构,而 AT89C2051 是 8051 架构,编译器需要生成能在 8051 上运行的机器码。

软件环境

  1. C51 编译器

    at89c2051 c语言
    (图片来源网络,侵删)
    • Keil C51 (µVision):这是最经典、最广泛使用的 8051 开发环境,它集成了编辑器、编译器、链接器和调试器,虽然有商业版,但有一个功能受限的评估版(代码大小限制在 2KB 以内),对于 AT89C2051 评估版已经完全够用!
    • SDCC (Small Device C Compiler):一个开源的、跨平台的 C 编译器,支持 8051 及其他多种 8 位 MCU,完全免费,没有代码大小限制,是 Keil 的一个优秀替代品。
    • 推荐初学者强烈推荐 Keil C51,因为它非常成熟,教程和示例最多,熟悉后再可以尝试 SDCC。
  2. 烧录软件

    • 编译后生成的 .hex 文件需要通过编程器(烧录器)写入到 AT89C2051 的 Flash 中。
    • 常用的烧录软件和硬件有:
      • ProGIS:配合并口或 USB 转并口的编程器。
      • STC-ISP:虽然主要用于 STC 单片机,但很多兼容 8051 的编程器也支持其格式。
      • USBasp:一个开源的 USB 编程器,配合 avrdude 等软件可以烧录 8051。
      • 最简单的方式:购买一块集成了 USB 转串口和烧录电路的 AT89C2051 开发板,通常会提供配套的烧录软件。

硬件环境

  • AT89C2051 芯片或开发板:推荐直接购买开发板,上面通常已经集成了晶振、复位电路、USB 转串口、LED 和按键,省去了焊接和搭建最小系统的麻烦。
  • USB 数据线:用于供电和程序下载。

C 语言核心要点 (与标准 C 的区别)

在 8051 上写 C,需要了解其特殊的内存结构和寄存器访问方式,Keil C51 提供了扩展关键字来访问这些硬件资源。

A. 特殊功能寄存器 访问

8051 的 I/O 端口、定时器、中断等都是通过 SFR 来控制的,Keil C51 允许你直接用 C 语言读写它们。

  • sfr:定义一个 8 位的 SFR。

    sfr P1 = 0x90; // 定义 P1 端口地址为 0x90
  • sbit:定义一个 SFR 中的 1 位(如 I/O 口的某一位)。

    sbit LED = P1^0; // 定义 P1.0 引脚为 LED
    sbit KEY = P3^2; // 定义 P3.2 引脚为按键 (INT0)

B. 内存模型

8051 有 4 个主要的内存空间,Keil C51 使用关键字来指定变量存储的位置。

  • data:直接寻址区 (128字节,地址 0x00-0x7F),访问速度最快。

    unsigned char data i; // 变量 i 存在最快访问的 data 区
  • bdata:可位寻址区 (16字节,地址 0x20-0x2F),可以像 SFR 一样用 sbit 操作其中的每一位。

    unsigned char bdata flags; // 变量 flags 存在可位寻址区
    sflag flag_busy = flags^0; // 定义 flag_busy 为 flags 的第 0 位
  • idata:间接寻址区 (256字节,地址 0x00-0xFF),速度比 data 慢。

    unsigned char idata j;
  • xdata:外部数据区 (最多 64KB),用于访问外部 RAM。

    unsigned int xdata sensor_value;
  • code:代码区 (最多 64KB),用于存储常量、查找表等。

    unsigned char code seg_table[] = {0x3F, 0x06, 0x5B, ...}; // 数码管段码表

现代 Keil 默认会自动优化变量位置,通常你不需要显式指定,但在对性能要求极高的地方,手动指定 data 仍然有用。

C. 中断处理函数

使用 interrupt 关键字来定义中断服务函数。

  • interrupt 0 -> 外部中断 0 (INT0)
  • interrupt 1 -> 定时器 0 溢出中断
  • interrupt 2 -> 外部中断 1 (INT1)
  • interrupt 3 -> 定时器 1 溢出中断
  • interrupt 4 -> 串口中断
void Timer0_ISR() interrupt 1 // 定时器0中断服务函数
{
    // 中断处理代码
    // ... ...
    TF0 = 0; // 手动清除定时器0溢出标志位 (某些模式下自动清除)
}

中断函数中要注意:

  1. 尽量保持简短。
  2. 如果需要修改共享变量,要关闭中断或使用 volatile 关键字。
  3. 如果使用寄存器组切换(using n),要小心。

完整示例:LED 闪烁

这是嵌入式开发的 "Hello, World!",假设我们将 LED 连接到 P1.0 引脚。

步骤 1:硬件连接

  • AT89C2051 的 P1.0 引脚连接一个 LED 的正极。
  • LED 的负极通过一个限流电阻(如 330Ω)连接到 GND。

步骤 2:Keil C51 代码

#include <reg2051.h> // 包含 AT89C2051 的特殊功能寄存器定义头文件
// sbit 定义
sbit LED = P1^0; // 将 P1.0 引脚命名为 LED
void main(void)
{
    // 1. 初始化
    // P1 口作为准双向口,默认为输入模式,输出前最好先写 1
    P1 = 0xFF; // 将 P1 的所有引脚设置为高电平
    // 2. 主循环
    while(1) // 无限循环
    {
        LED = 0; // P1.0 输出低电平,LED 点亮 (共阴极接法)
        // 软件延时
        unsigned int i, j;
        for(i=0; i<20000; i++)
        {
            for(j=0; j<100; j++);
        }
        LED = 1; // P1.0 输出高电平,LED 熄灭
        // 软件延时
        for(i=0; i<20000; i++)
        {
            for(j=0; j<100; j++);
        }
    }
}

步骤 3:编译与烧录

  1. 在 Keil µVision 中新建一个 "C51 Project"。
  2. 将上面的代码保存为 main.c 并添加到项目中。
  3. 设置目标选项:
    • Target -> Device:选择 Atmel -> AT89C2051
    • Output -> Create HEX File:勾选,以便生成烧录文件。
  4. 编译项目,会生成 main.hex 文件。
  5. 使用烧录软件(如 ProGIS 或开发板自带软件)将 main.hex 文件下载到 AT89C2051 芯片中。
  6. 给芯片上电,你就能看到 LED 开始闪烁了。

常用外设驱动示例

A. 按键检测

假设按键连接在 P3.2 (INT1),按键另一端接地,采用 查询方式

#include <reg2051.h>
sbit KEY = P3^2;
void main(void)
{
    P3 = 0xFF; // 初始化 P3 口
    while(1)
    {
        if(KEY == 0) // 检测按键是否被按下 (低电平有效)
        {
            // 按键消抖
            unsigned int i;
            for(i=0; i<20000; i++);
            if(KEY == 0) // 再次确认按键是否仍然按下
            {
                // 执行按键按下后的操作,例如点亮 LED
                P1^0 = 0; // LED 亮
                // 等待按键释放
                while(KEY == 0);
                // 再次消抖
                for(i=0; i<20000; i++);
            }
        }
    }
}

B. 定时器应用 (精确延时)

软件延时不够精确,使用定时器可以实现更精确的延时。

目标:使用定时器 0,实现一个 50ms 的定时,并每 20 次定时(即 1 秒)翻转一次 LED。

#include <reg2051.h>
sbit LED = P1^0;
unsigned int time_count = 0; // 用于记录定时次数
void Timer0_Init(void)
{
    // 1. 设置定时器模式
    TMOD &= 0xF0; // 清空 T0 的设置位
    TMOD |= 0x01; // 设置 T0 为 16 位定时器模式
    // 2. 计算初值 (假设晶振为 12MHz)
    // 12MHz -> 1us/机器周期
    // 50ms = 50000us
    // 定时器初值 = 65536 - 50000 = 15536
    // 15536 的十六进制是 0x3CB8
    TH0 = 0x3C; // 高位
    TL0 = 0xB8; // 低位
    // 3. 开启定时器
    TR0 = 1; // 启动 Timer0
}
void main(void)
{
    P1 = 0xFF;
    LED = 1;
    Timer0_Init();
    // 4. 开启总中断和定时器0中断
    EA = 1;  // 全局中断允许
    ET0 = 1; // 允许 Timer0 中断
    while(1); // 主循环等待中断
}
// Timer0 中断服务函数
void Timer0_ISR() interrupt 1
{
    // 1. 重新装载初值
    TH0 = 0x3C;
    TL0 = 0xB8;
    // 2. 执行定时任务
    time_count++;
    if(time_count >= 20)
    {
        time_count = 0;
        LED = ~LED; // 翻转 LED 状态
    }
}

总结与进阶

AT89C2051 虽然古老,但它是一个完美的嵌入式系统入门平台,通过它,你可以学到:

  • 单片机最小系统:电源、晶振、复位电路。
  • GPIO 操作:输入、输出、上拉电阻的概念。
  • 中断系统:理解中断的机制和重要性。
  • 定时器/计数器:实现精确定时和事件计数。
  • UART 通信:实现单片机与 PC 之间的串口通信。
  • 底层思维:理解硬件资源(RAM, Flash, I/O)的有限性,学会编写高效代码。

进阶方向:

  1. 掌握 Keil 调试器:使用 Keil 自带的仿真器进行在线调试,设置断点、观察变量,极大提高开发效率。
  2. 学习更复杂的外设:如利用内部模拟比较器、驱动数码管、使用 74HC595 扩展 I/O 等。
  3. 尝试 SDCC:体验开源工具链,了解不同编译器的差异。
  4. 转向现代 MCU:在掌握了 8051 的基础后,可以轻松过渡到功能更强大的 ARM Cortex-M 系列(如 STM32),你会发现很多概念是相通的。

希望这份指南能帮助你顺利开启 AT89C2051 的 C 语言开发之旅!

-- 展开阅读全文 --
头像
dede5.6后台空白是什么原因导致的?
« 上一篇 03-13
如何在notepad里运行c语言程序?
下一篇 » 03-13

相关文章

取消
微信二维码
支付宝二维码

目录[+]