直接获取一本完整100例的、未经授权的书籍代码包是不合适的,并且也不利于您真正学习,我将为您提供一个“授人以渔”的方案,包含:

(图片来源网络,侵删)
- 核心思想与学习方法:如何高效地学习和实践这100个例子。
- 精选代码示例:挑选了几个从基础到经典的例子,并提供详细的注释和解析,让您能快速上手。
- 代码获取途径:介绍在哪里可以合法地找到更多类似的代码资源。
- 推荐学习路线:一个循序渐进的学习计划。
核心思想与学习方法
“100例”的精髓不在于背代码,而在于通过实例掌握编程思想、硬件知识和调试技巧。
- 先硬件,后软件:在看代码前,先理解电路图,这个例子用了哪个LED?接在哪个引脚?用了什么传感器?如何连接到单片机?不理解硬件,代码就是空中楼阁。
- 逐行分析,理解透彻:不要只复制粘贴运行,逐行阅读代码,理解每一行的作用,特别是关键的初始化配置(如GPIO、定时器、串口)和主循环的逻辑。
- 勤于动手,修改验证:这是最重要的一步!
- 修改参数:比如LED闪烁的延时时间改长或改短。
- 增减功能:比如在流水灯的基础上,加上一个按键,当按键按下时,流水灯反向流动。
- 更换外设:比如用数码管代替LED显示数字。
- 学会查阅手册:遇到看不懂的寄存器(如
P0,TMOD,SCON),学会查阅所用单片机的数据手册 和 参考手册,这是从“会用”到“精通”的必经之路。 - 记录与总结:准备一个学习笔记,记录每个例子的功能、硬件连接、关键代码和自己的心得体会,这会成为您宝贵的知识库。
精选代码示例(基于经典的STC89C52/51单片机)
这里提供几个经典例子的完整代码,包含详细注释,您可以直接在Keil C51或Proteus等环境中仿真或烧录到开发板上运行。
例1:单个LED闪烁(Hello World)
这是单片机入门的第一个程序,目的是让一个LED灯以固定的频率亮灭。
硬件连接:

(图片来源网络,侵删)
- STC89C52单片机
- 一个LED(长脚为正极,短脚为负极)
- LED正极通过一个限流电阻(如220Ω~1kΩ)连接到单片机的 P1.0 引脚。
- LED负极连接到 GND(地)。
C51代码:
#include <reg52.h> // 包含STC89C52/51的头文件,定义了所有特殊功能寄存器
// sbit 是C51的关键字,用于定义一个特殊的位变量
// 这里定义 P1.0 这个引脚为 led,方便后续操作
sbit led = P1^0;
// 延时函数,简单的软件延时,不精确但足够用于LED闪烁
// 注意:这是一个空循环,延时时间与晶振频率有关
// 假设晶振为11.0592MHz,这个函数大约延时1ms
void delay_ms(unsigned int ms) {
unsigned int i, j;
for (i = ms; i > 0; i--)
for (j = 110; j > 0; j--);
}
void main() {
// 主函数,程序从这里开始执行
while (1) { // 无限循环,单片机程序通常都在一个死循环中运行
led = 0; // P1.0引脚输出低电平(0V),LED正极电压低于负极,LED点亮
delay_ms(500); // 延时500ms
led = 1; // P1.0引脚输出高电平(VCC,约5V),LED正负极电压相等,LED熄灭
delay_ms(500); // 延时500ms
}
}
代码解析:
#include <reg52.h>:包含了单片机寄存器的定义,没有这个文件,P1,TMOD等都是未定义的。sbit led = P1^0;:sbit是C51特有的关键字,用来定义一个单独的I/O口位,这里我们给P1.0口起了个别名叫led,让代码更易读。void main():C程序的入口。while(1):一个无限循环,保证单片机程序不会跑飞,会一直执行循环体内的代码。led = 0 / 1:控制I/O口的电平,对于51单片机,0是输出低电平(拉电流,点亮共阳极LED或熄灭共阴极LED),1是输出高电平(灌电流,熄灭共阳极LED或点亮共阴极LED),本例是典型的共阳极接法,即LED正极接VCC,负极通过电阻接单片机,此时led=0才会点亮LED。delay_ms():一个简单的延时函数,注意其精确度依赖于编译器和晶振频率。
例2:8位LED流水灯
让8个LED依次点亮,形成流水灯效果。
硬件连接:

(图片来源网络,侵删)
- 8个LED分别通过限流电阻连接到P1口的8个引脚(P1.0 ~ P1.7)。
- 所有LED的负极接地(共阳极接法)。
C51代码:
#include <reg52.h>
// 无需单独定义,直接操作整个P1口即可
// 延时函数
void delay_ms(unsigned int ms) {
unsigned int i, j;
for (i = ms; i > 0; i--)
for (j = 110; j > 0; j--);
}
void main() {
unsigned char led_pattern; // 定义一个无符号字符变量,用于存放LED的亮灭模式
while (1) {
// 方法一:移位法(更高效,推荐)
led_pattern = 0xFE; // 二进制 1111 1110,即P1.0亮,其余灭
for (int i = 0; i < 8; i++) {
P1 = led_pattern; // 将模式赋值给P1口
delay_ms(200);
led_pattern = (led_pattern << 1) | 0x01; // 左移一位,并在最低位补1
// 1111 1110 -> 1111 1101 -> 1111 1011 ...
}
// 方法二:查表法(更灵活,可自定义任意流水灯效果)
/*
unsigned char code led_table[] = {
0xFE, // 1111 1110 P1.0
0xFD, // 1111 1101 P1.1
0xFB, // 1111 1011 P1.2
0xF7, // 1111 0111 P1.3
0xEF, // 1110 1111 P1.4
0xDF, // 1101 1111 P1.5
0xBF, // 1011 1111 P1.6
0x7F // 0111 1111 P1.7
};
for (int i = 0; i < 8; i++) {
P1 = led_table[i];
delay_ms(200);
}
*/
}
}
代码解析:
- 移位法:通过一个变量
led_pattern,每次向左移动一位,就能控制下一个LED点亮。| 0x01是为了在移位后,熄灭的位始终为1(因为共阳极接法,1为熄灭)。 - 查表法:将LED的亮灭模式预先存放在一个数组
led_table中。code关键字告诉编译器将这个数组存放在程序存储器中,而不是RAM中,节省了宝贵的RAM资源,这种方法非常灵活,可以实现任意复杂的流水灯效果。 P1 = ...:P1是一个特殊功能寄存器,直接给它赋一个字节(8位)的值,就可以同时控制P1口的8个引脚。
例3:矩阵键盘扫描与数码管显示
这是一个综合了输入(键盘)和输出(显示)的经典例子。
硬件连接:
- 4x4矩阵键盘:行线连接P2.0~P2.3,列线连接P2.4~P
