100例代码如何高效学习与实战应用?

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

如何使用本资源

  1. 准备工作:您需要一块开发板(例如基于STC89C52、STM32F103等主流型号)和相应的下载/调试工具(如STC-ISP、ST-Link)。
  2. 循序渐进:请严格按照模块顺序学习,后面的实例会综合运用前面学到的知识。
  3. 动手实践最重要的一点! 请务必亲手将代码敲入编译器,编译、下载到开发板中观察现象,调试和修改是学习的最佳途径。
  4. 理解原理:不要只复制粘贴代码,在运行之前,先阅读“实例说明”和“代码解析”,理解代码背后的硬件原理和编程思想。

目录与代码实例

以下实例主要以经典的 STC89C52RC 单片机为例,因为它的寄存器操作和引脚定义对于初学者非常直观,大部分代码稍作修改即可应用于其他51内核单片机或AVR、STM32等。

单片机c语言程序设计实训100例代码
(图片来源网络,侵删)

第一部分:基础入门篇 (1-20例)

这个阶段的目标是熟悉开发环境、掌握GPIO(通用输入/输出)的基本操作、最简单的延时函数和C51语言特点。

序号 实例名称 核心知识点 实例说明 代码解析
1 点亮一个LED灯 GPIO输出、最小系统 最经典的“Hello, World!”程序,控制一个LED灯的亮灭。 - 定义sbit LED = P1^0;,指定P1.0口控制LED。
- LED = 0; 点亮LED(低电平点亮)。
- LED = 1; 熄灭LED。
2 LED流水灯 循环移位、数组控制 8个LED灯从左到右循环点亮,形成流水灯效果。 - 使用_crol_(a, b)_cror_(a, b)函数(需包含intrins.h)实现循环移位。
- 在while(1)循环中不断移位并延时。
3 LED闪烁 延时函数、定时器 让一个LED灯以固定的时间间隔(如1秒)闪烁。 - 编写一个简单的软件延时函数void delay_ms(unsigned int ms)
- 在while(1)中交替执行LED=0; delay_ms(500);LED=1; delay_ms(500);
4 按键控制LED GPIO输入、消抖 按下一个独立按键,控制一个LED灯的状态翻转(亮变灭,灭变亮)。 - 定义sbit KEY = P3^2;,指定P3.2口为按键输入。
- 消抖是关键:检测到按键按下后,延时10-20ms再次检测,确认是真实按下。
- 使用if(KEY == 0)检测低电平。
5 独立按键控制LED亮灭 GPIO输入、状态判断 按下按键,LED亮;松开按键,LED灭。 - 实时检测按键状态,并根据状态直接控制LED。
- if(KEY == 0) { LED = 0; } else { LED = 1; }
6 双按键控制LED 多路输入、逻辑判断 按键K1控制LED亮,按键K2控制LED灭。 - 定义两个按键引脚,分别检测它们的状态。
- 使用if-else if结构判断是哪个按键被按下。
7 数码管静态显示 数码管原理、段选/位选 在一个共阴/共阳数码管上稳定显示一个数字(如'8')。 - 了解数码管是7段LED组成的。
- 定义一个共阴极数码管的段选码数组unsigned char code seg_code[] = {0x3f, ...}
- P0 = seg_code[8]; 即可显示数字8。
8 数码管动态扫描显示 动态扫描、人眼视觉暂留 在两个或多个数码管上分别显示不同的数字(如"12")。 - 核心思想:快速轮流点亮每个数码管,利用人眼视觉暂留效应,看起来是同时亮的。
- 分时操作:打开第一个数码管的位选,送第一个数字的段选码 -> 延时几毫秒 -> 关闭位选 -> 打开第二个数码管的位选,送第二个数字的段选码 -> ... 循环。
9 独立按键计数器 按键消抖、变量累加 每按下一次按键,数码管显示的数字加1,到9后归0。 - 在按键检测成功后,执行一个计数变量count++
- 处理进位:if(count > 9) count = 0;
- 将count的值通过数码管显示出来。
10 中断控制LED 外部中断、中断服务函数 使用外部中断0(INT0,P3.2)来控制LED状态翻转,不占用主循环。 - 初始化IT0 = 1;(下降沿触发),EX0 = 1;(允许INT0中断),EA = 1;(开启总中断)。
- 编写void EX0_interrupt() interrupt 0中断服务函数,在里面执行LED = ~LED;
- 主循环可以执行其他任务。
11 定时器中断实现精确延时 定时器、中断、中断优先级 使用定时器0中断,实现比软件延时更精确的1秒定时,并控制LED闪烁。 - 初始化定时器0,工作在模式1(16位定时器)。
- 计算初值,使其每50ms中断一次。
- 在中断服务函数中设置一个软件计数变量,中断20次就是1秒。
- 1秒到后,翻转LED状态。
12 PWM控制LED亮度 PWM(脉冲宽度调制)、定时器 通过改变PWM的占空比,实现LED的呼吸灯效果(亮度渐变)。 - 使用定时器中断,产生固定频率(如1kHz)的方波。
- 在中断服务函数中,用一个变量duty_cycle控制高电平的时间。
- 逐渐改变duty_cycle的值(如从0到100再回到0),LED的亮度就会随之变化。
13 继电器控制 三极管驱动、电磁兼容 用单片机的一个I/O口控制继电器的吸合和断开,从而控制220V电器。 - 注意安全! 强弱电隔离!
- 单片机I/O口驱动能力弱,需要用一个NPN三极管(如8050)来放大电流驱动继电器线圈。
- 继电器两端并联一个续流二极管(1N4007),保护三极管不被线圈的反向电动势击穿。
14 蜂鸣器发声 无源/有源蜂鸣器、频率控制 让蜂鸣器发出不同频率的声音,甚至简单的旋律。 - 区分有源蜂鸣器(直接通电响)和无源蜂鸣器(需要PWM信号驱动)。
- 控制无源蜂鸣器发声,就是用定时器产生不同频率的方波信号。
15 串口发送数据到电脑 UART串口、波特率配置 单片机通过串口向电脑发送“Hello World!”字符串。 - 配置串口工作方式(SCON)、定时器1作为波特率发生器(TMOD)。
- 使用SBUF = 'H';发送数据,while(!TI); TI=0;等待发送完成。
- 在电脑端使用串口调试助手接收。
16 串口接收电脑指令 UART串口、中断接收 单片机接收电脑发来的单个字符(如'A'),并控制LED。 - 使能串口中断ES = 1;
- 编写void UART_interrupt() interrupt 4中断服务函数,接收数据if(RI) { RI = 0; val = SBUF; }
- 在主循环中判断val的值并执行相应操作。
17 AD0804模数转换 ADC、参考电压、时序 读取一个电位器的电压值(0-5V),并通过串口发送到电脑显示。 - 理解ADC0804的工作时序:拉低CS,拉低WR启动转换,查询INTR变低或延时后,拉低RD读取数据。
- 读取到的8位数字量0-255对应0-5V的电压。
18 DAC0832数模转换 DAC、双缓冲、参考电压 将单片机产生的数字量(如锯齿波数据)转换成模拟电压,用示波器观察。 - 理解DAC0832的三种工作方式,这里使用直通方式最简单。
- 将P0口的数据直接送给DAC0832的数据输入端,WR1XFER接地,CS接地,ILE接高电平。
- 循环送入0-255的数字量,即可在输出端看到0-Vref的锯齿波电压。
19 DS18B20温度传感器 单总线协议、时序精度 读取DS18B20的温度值,并在数码管上显示。 - 单总线协议是难点:精确实现复位脉冲、写时序(0/1)、读时序。
- 读取64位ROM序列号和暂存器中的温度数据。
- 对读取的温度数据进行处理(包括符号位和温度值转换)。
20 LCD1602字符液晶显示 LCD初始化、指令集、数据写入 在LCD1602屏幕上显示两行固定的字符串。 - 理解LCD1602的4位或8位并行通信方式。
- 严格按照时序进行初始化:设置显示模式、清屏、进入模式设置、开显示等。
- 写入数据时,RS=1, RW=0;写入指令时,RS=0, RW=0

第二部分:核心外设篇 (21-50例)

这个阶段深入掌握单片机内部和外部常用模块,如I2C、SPI、EEPROM、实时时钟等。

序号 实例名称 核心知识点 实例说明 代码解析
21 I2C协议读写AT24C02 I2C协议、模拟时序 使用软件模拟I2C时序,读写EEPROM芯片AT24C02中的数据。 - I2C是两线制(SDA, SCL)。
- 需要模拟:起始信号、停止信号、应答信号、发送字节、接收字节。
- AT24C02的器件地址是0xA0(写)和0xA1(读)。
22 SPI协议驱动AD转换器 SPI协议、模拟时序 使用软件模拟SPI时序,驱动一个SPI接口的ADC(如MCP3008)读取电压。 - SPI是四线制(MOSI, MISO, SCLK, CS)。
- 模拟:拉低CS -> 移出控制字节(通道选择) -> 移入10位数据 -> 拉高CS。
23 DS1302实时时钟 三线制串行通信、时钟芯片 读取DS1302芯片记录的年、月、日、时、分、秒,并在LCD1602上显示。 - DS1302使用I/O, SCLK, CE三根线。
- 需要严格模拟其读写时序,包括命令字节(地址+读写位)。
- 注意BCD码和十进制数的转换。
24 红外遥控解码 NEC协议、外部中断 解码常见的红外遥控器按键,并在数码管上显示对应的键值。 - 使用外部中断引脚接收红外信号。
- NEC协议有引导码、地址码、地址反码、命令码、命令反码和结束码。
- 在中断服务函数中,通过测量高电平持续时间来判断是'0'还是'1'。
25 舵机控制 PWM信号、角度控制 控制一个舵机旋转到指定的角度(如0度、90度、180度)。 - 舵机需要周期为20ms(50Hz)的PWM信号。
- 脉冲宽度(高电平时间)决定了舵机的角度:0.5ms对应0度,1.5ms对应90度,2.5ms对应180度。
- 可以使用定时器中断来精确生成这个PWM信号。
26 超声波测距 TRIG/TIOE时序、定时器 使用HC-SR04超声波模块测量与前方障碍物的距离,并在LCD上显示。 - TRIG引脚发送一个10us的高电平触发测距。
- 模块自动发送8个40kHz的方波,并等待回波。
- ECHO引脚变为高电平开始计时,变为低电平停止计时。
- 距离 = (高电平时间 * 声速) / 2。
27 矩阵键盘扫描 行列扫描、编码 读取4x4矩阵键盘的按键值,并在数码管上显示。 - 行输出低电平,列输入高电平,逐行扫描。
- 如果某列读到低电平,则说明该行该列的按键被按下。
- 可以用编码法或计数法来确定是哪个键。
28 EEPROM数据掉电保存 AT24C02、数据存储 将一个变量的值(如计数值)存入AT24C02,断电后重新上电,读取并显示该值。 - 在程序初始化时,先从AT24C02读取数据到变量。
- 在变量值改变时,及时将新值写回AT24C02。
- 实现数据的掉电不丢失功能。
29 DS18B20多点测温 ROM匹配、单总线 在总线上挂载多个DS18B20,分别读取它们的温度。 - 先发送跳过ROM命令,然后启动所有DS18B20进行温度转换。
- 再次发送跳过ROM命令,然后读取温度,此时读取的是所有器件的平均值(错误做法)。
- 正确做法:先发送复位脉冲,然后逐个读取每个DS18B20的64位ROM序列号,对目标器件进行“匹配ROM”操作,再进行单点测温。
30 DAC0832输出正弦波 查表法、数模转换 在DAC0832的输出端产生一个平滑的正弦波。 - 在程序中建立一个正弦函数值的查找表(一个0-255的数组)。
- 使用定时器中断,每隔一段时间从表中取出一个值送给DAC0832。
- 中断频率越高,正弦波频率越高,波形越平滑。
... ... ... ... ...

第三部分:综合应用篇 (51-100例)

这个阶段将多个知识点融合,完成复杂的功能,是向项目开发过渡的关键。

序号 实例名称 核心知识点 实例说明 代码解析
31 智能温控系统 DS18B20、继电器、PID算法 实时监测环境温度,当温度低于设定值时,通过继电器启动加热器。 - DS18B20负责测温。
- 继电器负责控制加热器(如电热丝)。
- 可以加入简单的阈值控制或更高级的PID算法来控制加热功率,使温度稳定在设定值。
32 电子密码锁 矩阵键盘、LCD1602、EEPROM 通过键盘输入密码,正确则开锁(点亮LED),错误则报警(蜂鸣器响),密码可修改并保存在EEPROM中。 - 矩阵键盘输入密码,LCD显示提示信息(如“请输入密码”)。
- 将输入的密码与存储在EEPROM中的正确密码进行比较。
- 实现密码修改功能,修改后存入EEPROM。
33 多功能电子钟 DS1302、矩阵键盘、LCD1602 具备时间显示、时间校准、闹钟设置功能的电子钟。 - DS1302提供精确时间。
- 矩阵键盘用于切换模式(正常/设置/闹钟)和调整数值。
- LCD1602显示当前时间、设置界面和闹钟时间。
- 到达闹钟时间,蜂鸣器响起。
34 超声波测距避小车 超声波模块、电机驱动、逻辑判断 制作一个能自动避开障碍物的小车,当超声波测距小于阈值时,小车后退并转向。 - 超声波模块作为“眼睛”。
- L298N或类似电机驱动模块控制两个直流电机。
- 主循环中不断测距,根据距离值决定前进、后退或转向的逻辑。
35 简易示波器 ADC、定时器、LCD显示 利用ADC和定时器,采集一个模拟信号的电压值,并在LCD1602上绘制出其波形。 - 定时器以固定频率触发ADC转换。
- 将ADC转换得到的数据点存储在一个数组中。
- 在LCD上,根据数组中的值计算出每个点在屏幕上的Y坐标,并画点或连线。
36 MP3播放器(模拟) VS1053模块、SPI、FAT32文件系统 通过SPI接口控制VS1053解码芯片,从SD卡中读取MP3文件并进行播放。 - 高级项目,需要掌握SPI协议、FAT32文件系统解析。
- 初始化VS1053芯片,设置其工作模式。
- 读取SD卡中的MP3文件数据,通过SPI接口将数据流发送给VS1053进行解码和播放。
37 无线数传(NRF24L01) SPI、无线通信 两块单片机通过NRF24L01模块进行无线通信,一块发送数据,另一块接收并显示在LCD上。 - SPI接口配置NRF24L01的工作频道、地址、速率等。
- 发送端:将要发送的数据打包,通过SPI写入NRF24L01的TX FIFO,然后发送。
- 接收端:不断检查RX FIFO是否有数据,有则读出并处理。
38 WiFi模块(ESP8266)控制 UART、AT指令 通过单片机向ESP8266发送AT指令,使其连接WiFi,并将传感器数据(如温度)上传到云平台。 - 单片机通过UART与ESP8266通信。
- 学习常用的AT指令:AT+RST, AT+CWMODE, AT+CWJAP, AT+CIPMUX, AT+CIPSTART, AT+CIPSEND等。
- 将传感器数据封装成HTTP或TCP数据包发送。
39 OLED屏显示图形 I2C、OLED驱动、显存 在0.96寸的OLED屏幕上绘制点、线、矩形、图片等。 - OLED通常使用I2C接口,驱动芯片为SSD1306。
- 核心是操作一个显存数组(如128x64=1024字节),每个bit对应一个像素点。
- 先在显存中修改数据,然后将整个显存一次性写入OLED驱动芯片。
40 PID电机调速 PWM、编码器、PID算法 使用PID算法控制直流电机的转速,使其稳定在设定值。 - 编码器(霍尔或光电)用于测量电机的实际转速。
- PWM信号控制电机的平均电压,从而控制转速。
- PID算法根据设定转速和实际转速的差值,计算出合适的PWM占空比,进行闭环控制。
... ... ... ... ...

学习建议与资源

  1. 官方文档这是最权威的资料! 一定要仔细阅读您所用单片机(如STC89C52、STM32F103)的数据手册(Datasheet)和参考手册(Reference Manual),里面包含了所有寄存器的详细说明和时序图。
  2. 开发板原理图:理解开发板上各个外设(LED、按键、数码管、串口等)是如何连接到单片机的引脚上的,这是硬件连接的基础。
  3. 善用调试工具:学习使用Keil C51或STM32CubeIDE等IDE的软件仿真和硬件调试功能(如单步执行、设置断点、查看变量),这能极大地提高学习效率。
  4. 从模仿到创造:先完全理解并实现上述实例,然后尝试修改它们(比如改变流水灯的速度、修改按键的功能),最后尝试自己设计一个小项目(如一个环境监测仪、一个智能台灯)。

希望这份精心整理的资源能对您的单片机C语言实训之路有所帮助!祝您学习愉快,早日成为单片机高手!

单片机c语言程序设计实训100例代码
(图片来源网络,侵删)
单片机c语言程序设计实训100例代码
(图片来源网络,侵删)
-- 展开阅读全文 --
头像
数据结构(C语言版)清华大学出版社,如何高效学习?
« 上一篇 2025-12-03
会员模型不存在?dede参数错误何解?
下一篇 » 2025-12-03

相关文章

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

目录[+]