别怕!51 单片机从入门到应用,小白也能轻松吃透

别怕!51 单片机从入门到应用,小白也能轻松吃透

这篇教程专为单片机小白打造,从 51 单片机基础讲起,带你搭建开发环境,学习汇编与 C 语言编程。通过 LED 灯闪烁、按键控制、数码管显示等基础实验,以及简易电子钟、温度检测系统等应用案例,结合代码实操,助你快速掌握 51 单片机开发。

一、本篇背景在电子技术的广阔领域中,单片机作为一种高度集成化的计算机芯片,以其体积小、成本低、功能强等特点,在工业控制、智能家居、汽车电子等众多领域得到了广泛的应用。51 单片机作为单片机家族中的经典代表,具有结构简单、易于学习等优点,成为了众多电子爱好者和初学者入门单片机编程的首选。本文将以小白的视角,详细介绍 51 单片机的基础知识、开发环境搭建、编程语言、基本实验以及一些常见的应用案例,帮助初学者逐步掌握 51 单片机的开发技术。

二、51 单片机基础知识2.1 什么是 51 单片机51 单片机是指以 Intel 8051 内核为基础发展起来的一系列单片机的统称。它最早由 Intel 公司在 1980 年推出,具有 8 位 CPU、4KB 程序存储器(ROM)、128B 数据存储器(RAM)、两个 16 位定时 / 计数器、64KB 外部数据存储器和程序存储器寻址空间等基本资源。后来,许多半导体公司如 Atmel、STC 等在 8051 内核的基础上进行了改进和扩展,推出了各具特色的 51 单片机产品,这些产品在功能和性能上有所提升,但基本的指令系统和架构仍然与 8051 兼容。

2.2 51 单片机的硬件结构51 单片机的硬件结构主要由 CPU、存储器、I/O 接口、定时 / 计数器、中断系统等部分组成。

CPU(中央处理器):是单片机的核心,负责执行程序指令,完成数据的运算和处理。存储器:包括程序存储器(ROM)和数据存储器(RAM)。程序存储器用于存储用户编写的程序代码,数据存储器用于存储程序运行过程中的临时数据。I/O 接口:是单片机与外部设备进行数据交换的通道,51 单片机通常有 4 个 8 位的并行 I/O 口(P0、P1、P2、P3),可以实现数据的输入和输出。定时 / 计数器:用于实现定时和计数功能,可用于产生精确的定时信号、测量脉冲信号的频率等。中断系统:允许单片机在执行主程序的过程中,响应外部或内部的中断请求,暂停主程序的执行,转去执行相应的中断服务程序,处理完中断后再返回主程序继续执行。2.3 51 单片机的引脚功能51 单片机通常采用双列直插式(DIP)封装,具有 40 个引脚。不同的引脚具有不同的功能,下面简要介绍一些主要引脚的功能:

电源引脚:VCC(+5V)和 GND(地),为单片机提供电源。时钟引脚:XTAL1 和 XTAL2,用于连接外部晶体振荡器,为单片机提供时钟信号。复位引脚:RST,当该引脚出现高电平并保持一定时间时,单片机将进行复位操作,恢复到初始状态。并行 I/O 口引脚:P0、P1、P2、P3 口的引脚,用于实现数据的输入和输出。控制引脚:如 ALE/PROG、PSEN、EA/VPP 等,用于控制单片机的工作模式和数据传输。三、开发环境搭建3.1 硬件准备51 单片机开发板:市面上有多种类型的 51 单片机开发板可供选择,初学者可以选择一款功能较为齐全、价格适中的开发板,如普中科技的 51 单片机开发板。USB 转串口线:用于将开发板与计算机连接,实现程序的下载和调试。电源适配器:为开发板提供电源。3.2 软件准备Keil C51:是一款专门用于 51 单片机编程的集成开发环境(IDE),支持 C 语言和汇编语言编程,具有代码编辑、编译、调试等功能。STC-ISP 下载软件:用于将 Keil C51 编译生成的程序代码下载到 STC 系列 51 单片机中。3.3 开发环境搭建步骤安装 Keil C51:下载 Keil C51 安装程序,按照安装向导的提示进行安装。安装完成后,打开 Keil C51,创建一个新的工程,选择合适的单片机型号。安装 STC-ISP 下载软件:下载 STC-ISP 下载软件,解压后运行安装程序。安装完成后,打开 STC-ISP 下载软件,设置好单片机型号、串口波特率等参数。连接开发板:使用 USB 转串口线将开发板与计算机连接,确保开发板的电源开关处于打开状态。编写并编译程序:在 Keil C51 中编写 51 单片机程序代码,点击编译按钮进行编译。如果代码没有错误,编译器将生成一个十六进制(.hex)文件。下载程序:打开 STC-ISP 下载软件,选择刚才生成的.hex 文件,点击下载按钮,将程序下载到单片机中。四、编程语言4.1 汇编语言汇编语言是一种面向机器的低级语言,它使用助记符来表示机器指令,与单片机的硬件结构密切相关。汇编语言的优点是执行效率高、代码简洁,适合对程序执行时间和内存空间要求较高的场合。下面是一个简单的 51 单片机汇编语言程序示例,实现 LED 灯的闪烁:

代码语言:javascript代码运行次数:0运行复制ORG 0000H ; 程序起始地址

LJMP MAIN ; 跳转到主程序

ORG 0030H ; 主程序起始地址

MAIN:

SETB P1.0 ; 将 P1.0 引脚置高电平,点亮 LED 灯

LCALL DELAY ; 调用延时子程序

CLR P1.0 ; 将 P1.0 引脚置低电平,熄灭 LED 灯

LCALL DELAY ; 调用延时子程序

SJMP MAIN ; 跳转到主程序开头,循环执行

DELAY: ; 延时子程序

MOV R7, #200 ; 设置外层循环次数

D1: MOV R6, #250 ; 设置内层循环次数

D2: DJNZ R6, D2 ; 内层循环,R6 减 1,不为 0 则继续循环

DJNZ R7, D1 ; 外层循环,R7 减 1,不为 0 则继续循环

RET ; 子程序返回

END ; 程序结束4.2 C 语言C 语言是一种高级编程语言,具有结构化、模块化、可读性强等优点,易于学习和掌握。在 51 单片机开发中,使用 C 语言可以大大提高开发效率,减少开发周期。下面是一个使用 C 语言实现 LED 灯闪烁的程序示例:

代码语言:javascript代码运行次数:0运行复制#include // 包含 51 单片机的头文件

#define uchar unsigned char // 定义无符号字符型变量

#define uint unsigned int // 定义无符号整型变量

sbit LED = P1^0; // 定义 P1.0 引脚为 LED 控制引脚

// 延时函数

void delay(uint time) {

uint i, j;

for(i = 0; i < time; i++)

for(j = 0; j < 123; j++);

}

void main() {

while(1) {

LED = 1; // 点亮 LED 灯

delay(500); // 延时 500ms

LED = 0; // 熄灭 LED 灯

delay(500); // 延时 500ms

}

}五、基本实验5.1 LED 灯闪烁实验LED 灯闪烁实验是 51 单片机开发中最基础的实验之一,通过该实验可以熟悉 51 单片机的 I/O 口操作和延时函数的使用。实验步骤如下:

硬件连接:将开发板上的 LED 灯连接到 P1.0 引脚。编写程序:使用 C 语言编写 LED 灯闪烁的程序代码,如上述示例所示。编译并下载程序:在 Keil C51 中编译程序,生成.hex 文件,然后使用 STC-ISP 下载软件将程序下载到单片机中。观察实验现象:下载完成后,开发板上的 LED 灯将开始闪烁。5.2 按键控制 LED 灯实验按键控制 LED 灯实验可以让我们了解 51 单片机的输入输出控制原理。实验步骤如下:

硬件连接:将开发板上的按键连接到 P3.2 引脚,LED 灯连接到 P1.0 引脚。编写程序:使用 C 语言编写按键控制 LED 灯的程序代码,示例代码如下:代码语言:javascript代码运行次数:0运行复制#include

#define uchar unsigned char

#define uint unsigned int

sbit KEY = P3^2; // 定义按键连接的引脚

sbit LED = P1^0; // 定义 LED 连接的引脚

void main() {

while(1) {

if(KEY == 0) { // 检测按键是否按下

while(KEY == 0); // 等待按键释放

LED = ~LED; // 取反 LED 灯的状态

}

}

}编译并下载程序:同 LED 灯闪烁实验。观察实验现象:按下按键,LED 灯的状态将发生改变。5.3 数码管显示实验数码管显示实验可以让我们学习 51 单片机的数码管驱动原理和段码编码方法。实验步骤如下:

硬件连接:将开发板上的数码管连接到相应的 I/O 口。编写程序:使用 C 语言编写数码管显示的程序代码,示例代码如下:代码语言:javascript代码运行次数:0运行复制#include

#define uchar unsigned char

#define uint unsigned int

uchar code SEG_CODE[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F}; // 数码管段码表

sbit LSA = P2^2;

sbit LSB = P2^3;

sbit LSC = P2^4;

void main() {

uchar i;

while(1) {

for(i = 0; i < 10; i++) {

LSA = 0; LSB = 0; LSC = 0; // 选择第一个数码管

P0 = SEG_CODE[i]; // 显示数字 i

for(uint j = 0; j < 50000; j++); // 延时

}

}

}编译并下载程序:同前两个实验。观察实验现象:数码管将依次显示 0 - 9 的数字。六、常见应用案例6.1 简易电子钟简易电子钟可以实现时间的显示和调整功能,是一个比较综合的 51 单片机应用案例。实现步骤如下:

硬件连接:使用数码管显示时间,按键用于时间调整,同时可以使用定时器来实现精确的计时。编写程序:使用 C 语言编写电子钟的程序代码,包括时间计时、数码管显示、按键扫描等功能。示例代码如下:代码语言:javascript代码运行次数:0运行复制#include

#define uchar unsigned char

#define uint unsigned int

uchar code SEG_CODE[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F}; // 数码管段码表

sbit LSA = P2^2;

sbit LSB = P2^3;

sbit LSC = P2^4;

sbit KEY1 = P3^2; // 调整小时按键

sbit KEY2 = P3^3; // 调整分钟按键

uchar hour = 0, minute = 0, second = 0; // 初始化时间

// 延时函数

void delay(uint time) {

uint i, j;

for(i = 0; i < time; i++)

for(j = 0; j < 123; j++);

}

// 数码管显示函数

void display_time() {

uchar h1, h2, m1, m2;

h1 = hour / 10;

h2 = hour % 10;

m1 = minute / 10;

m2 = minute % 10;

LSA = 0; LSB = 0; LSC = 0; P0 = SEG_CODE[h1]; delay(5); // 显示小时十位

LSA = 1; LSB = 0; LSC = 0; P0 = SEG_CODE[h2]; delay(5); // 显示小时个位

LSA = 0; LSB = 1; LSC = 0; P0 = 0x40; delay(5); // 显示冒号

LSA = 1; LSB = 1; LSC = 0; P0 = SEG_CODE[m1]; delay(5); // 显示分钟十位

LSA = 0; LSB = 0; LSC = 1; P0 = SEG_CODE[m2]; delay(5); // 显示分钟个位

}

// 定时器初始化函数

void timer_init() {

TMOD = 0x01; // 设置定时器 0 为模式 1

TH0 = (65536 - 50000) / 256; // 定时器初值

TL0 = (65536 - 50000) % 256;

ET0 = 1; // 使能定时器 0 中断

EA = 1; // 全局中断使能

TR0 = 1; // 启动定时器 0

}

// 定时器中断服务函数

void timer0_isr() interrupt 1 {

TH0 = (65536 - 50000) / 256; // 重新加载初值

TL0 = (65536 - 50000) % 256;

static uint count = 0;

count++;

if(count >= 20) { // 每 1 秒

count = 0;

second++;

if(second >= 60) {

second = 0;

minute++;

if(minute >= 60) {

minute = 0;

hour++;

if(hour >= 24) {

hour = 0;

}

}

}

}

}

// 按键扫描函数

void key_scan() {

if(KEY1 == 0) {

delay(20); // 消抖

if(KEY1 == 0) {

while(KEY1 == 0);

hour = (hour + 1) % 24;

}

}

if(KEY2 == 0) {

delay(20); // 消抖

if(KEY2 == 0) {

while(KEY2 == 0);

minute = (minute + 1) % 60;

}

}

}

void main() {

timer_init();

while(1) {

display_time();

key_scan();

}

}编译并下载程序:同前面的实验。观察实验现象:数码管将显示当前的时间,按下按键可以调整时间。6.2 温度检测系统温度检测系统可以实时检测环境温度,并将温度值显示在数码管上。实现步骤如下:

硬件连接:使用温度传感器(如 DS18B20)采集温度数据,数码管显示温度值。编写程序:使用 C 语言编写温度检测系统的程序代码,包括温度传感器驱动、数码管显示等功能。示例代码如下:代码语言:javascript代码运行次数:0运行复制#include

#include

#define uchar unsigned char

#define uint unsigned int

sbit DQ = P3^7; // DS18B20 数据引脚

uchar code SEG_CODE[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F}; // 数码管段码表

sbit LSA = P2^2;

sbit LSB = P2^3;

sbit LSC = P2^4;

// 延时函数

void delay(uint time) {

uint i, j;

for(i = 0; i < time; i++)

for(j = 0; j < 123; j++);

}

// DS18B20 初始化函数

bit ds18b20_init() {

bit presence;

DQ = 1;

_nop_();

DQ = 0;

delay(500); // 延时 480 - 960us

DQ = 1;

delay(60); // 延时 60 - 240us

presence = DQ;

delay(440); // 延时 480 - 960us

return presence;

}

// DS18B20 写一个字节函数

void ds18b20_write_byte(uchar dat) {

uchar i;

for(i = 0; i < 8; i++) {

DQ = 0;

_nop_();

DQ = dat & 0x01;

delay(60); // 延时 60 - 120us

DQ = 1;

dat >>= 1;

}

}

// DS18B20 读一个字节函数

uchar ds18b20_read_byte() {

uchar i, dat = 0;

for(i = 0; i < 8; i++) {

DQ = 0;

_nop_();

dat >>= 1;

DQ = 1;

if(DQ)

dat |= 0x80;

delay(60); // 延时 60 - 120us

}

return dat;

}

// 读取 DS18B20 温度函数

int ds18b20_read_temp() {

uchar LSB, MSB;

int temp;

ds18b20_init();

ds18b20_write_byte(0xCC); // 跳过 ROM 操作

ds18b20_write_byte(0x44); // 启动温度转换

delay(750); // 等待转换完成

ds18b20_init();

ds18b20_write_byte(0xCC); // 跳过 ROM 操作

ds18b20_write_byte(0xBE); // 读取温度寄存器

LSB = ds18b20_read_byte();

MSB = ds18b20_read_byte();

temp = (MSB << 8) | LSB;

temp = temp * 0.0625 * 10 + 0.5; // 转换为实际温度值

return temp;

}

// 数码管显示函数

void display_temp(int temp) {

uchar t1, t2, t3;

t1 = temp / 100;

t2 = (temp % 100) / 10;

t3 = temp % 10;

LSA = 0; LSB = 0; LSC = 0; P0 = SEG_CODE[t1]; delay(5); // 显示百位

LSA = 1; LSB = 0; LSC = 0; P0 = SEG_CODE[t2] | 0x80; delay(5); // 显示十位,带小数点

LSA = 0; LSB = 1; LSC = 0; P0 = SEG_CODE[t3]; delay(5); // 显示个位

}

void main() {

int temp;

while(1) {

temp = ds18b20_read_temp();

display_temp(temp);

}

}编译并下载程序:同前面的实验。观察实验现象:数码管将显示当前的环境温度值。七、小结下:通过本文的学习,我们从 51 单片机的基础知识入手,逐步了解了开发环境的搭建、编程语言的使用、基本实验的实现以及常见应用案例的开发。对于初学者来说,掌握 51 单片机的开发技术需要不断地实践和积累,通过完成更多的实验和项目,加深对单片机原理和编程方法的理解。希望本文能够帮助广大电子爱好者和初学者快速入门 51 单片机开发,开启电子技术的探索之旅。

相关推荐

传统戏剧种傩戏 非物质文化遗产傩戏【非物质文化遗产】→MAIGOO百科
2018世界杯32强名单全部出炉(18年世界杯32强名单)
beat365中国在线体育

2018世界杯32强名单全部出炉(18年世界杯32强名单)

📅 09-08 👀 2020
肯泰罗的进化路线是什么推荐携带什么技能是否值得培养
‎微店开店宝
百特365平台可靠吗

‎微店开店宝

📅 08-02 👀 2869