51单片机教程(五)- LED灯闪烁
1 项目分析
- 让输入/输出口的P1.0或P1.0~P1.7连接的LED灯闪烁。
2 技术准备
1、C语言知识点
1 运算符
1 算术运算符 
#include <stdio.h>int main(){// 算术运算符int a = 13;int b = 6;printf("%d\n", a+b); printf("%d\n", a-b); printf("%d\n", a*b); printf("%d\n", a/b); printf("%d\n", a%b); // 后续应用:将数的十位、个位取出来,分别记录下来用于显示在不同的数码管printf("1: %d\n", a/10);printf("3: %d\n", a%10);return 0;
}
2 自增/自减运算符
-
自增运算符为
++,其功能是使变量的值自增1 -
自减运算符为
--,其功能是使变量值自减1。

#include <stdio.h>int main(){// 自增、自减运算符 --》 计数int a = 10;printf("%d\n", a++); // ++ 在后,表示先用后加 ++a; // ++ 在前,表示用先加后用 printf("%d\n", a);return 0;
}
3 关系运算符

- 关系表达式的值是
真和假,在C程序用整数1和0表示。
#include <stdio.h>int main(){// 关系运算符 --> if语句中使用 int a = 13;int b = 6;printf("%d\n", a>=b); printf("%d\n", a==b); printf("%d\n", a!=b);return 0;
}
5 逻辑运算符

#include <stdio.h>int main(){// 逻辑运算符 --> if语句中使用:条件关系的判断 int mathScore = 90;int englishScore = 60;int stu1_mathScore = 99;int stu1_englishScore = 66;printf("%d\n", (stu1_mathScore > 60) && (); printf("%d\n", a||b); printf("%d\n", !b);return 0;
}
6 位运算符和位表达式

#include <stdio.h>int main()
{int a = 10; // 二进制为:1010int b = 6; // 二进制为:0110printf("&:%d\n", a & b); // 2 --> 0010printf("|:%d\n", a | b); // 14 --> 1110// int在计算机中是以补码形式存储printf("~:%d\n", ~a); // -11 --> 0101 (32位:0101,最高位为1表示为负,补码:取反后 +1)printf("^:%d\n", a ^ b); // 1100 --> 12printf("<<: %d\n", a << 2); // 1010 00 --> 40 低位补0,高位丢失printf(">>: %d\n", b >> 3); // 0000 00 --> 0 高位补0,低位丢失return 0;
}

7 赋值运算符
-
格式
- 变量名 = 表达式;
#include <stdio.h>int main()
{int number = 10; char letter = 'a';printf("int:%d\n", a); printf("char:%c\n", letter); return 0;
}
8 复合赋值运算符
- 将变量计算的结果重新赋值给该变量

#include <stdio.h>int main()
{int a = 13;int b = 6;//a = a +b;a += b; printf("%d\n", a); return 0;
}
9 三目运算符
表达式1 ? 表达式2 : 表达式3;
#include <stdio.h>int main()
{int a = 10; int b = 6; printf("结果为:%d", a > b ? a : b); // a 大于 b,返回a,否则返回breturn 0;
}
2 选择与循环语句
1 if 语句
if(表达式)
语句;if(表达式){语句列表1
}
else{语句列表2;
}//多分支
if(表达式1){语句列表1;
}
else if(表达式2){语句列表2;
}
else{语句列表3;
}
#include <stdio.h>int main()
{// if 语句 --> 存在多个范围判断 int a = 4;if(a > 0){printf("a 是正数");} else if(a < 0){printf("a 是负数");} else{printf("a 是零");}return 0;
}
2 switch语句
- 使用:用于多分支的情况,可以简化多重if语句嵌套的情况。
switch(表达式A){case 常量表达式1:语句1;break;case 常量表达式2:语句2;break;……case 常量表达式n:语句n;break;default:语句n+1; break;
}
#include <stdio.h>int main()
{// switch-case --> 对变量的有限个取值判断 int a = 1;switch(a){case 1:// 无break:case穿透 printf("选项1");case 2:printf("选项2");break;case 3:printf("选项3");break;default:printf("无效选择");} return 0;
}
3 while语句
while(表达式){循环语句;
}
#include <stdio.h>int main()
{// while循环 --> 已知或未知循环次数 int a = 1;while(a < 6){printf("%d\n", a);a++;} return 0;
}
4 do-while语句
do{循环语句;
}while(表达式);
5 for语句
for(表达式1;表达式2;表达式3){循环语句;
}
#include <stdio.h>int main()
{// while循环 --> 已知或未知循环次数 int a = 1;while(a < 6){printf("%d\n", a);a++;} return 0;
}
6 死循环
// 死循环 --> 主要用于未知循环次数
while(1){} for(;;){}
3 函数
1)函数的定义
void 函数名()
{语句块;
}
2)函数的返回
类型 函数名(形参1,形参2,形参3,……)
{……return 数据;
}
3)形式参数与实际参数。
void(类型形参1,类型形参2,……)
{
}函数名(实参1;实参2;实参3;……);
4)函数的调用方式
函数名();
#include <stdio.h>// 函数定义位置
// 1 在main函数之前
int max(int a, int b){if(a >b){return a;} else{return b;}
} int main()
{// 调用函数int c=max(4, 7); printf("最大值:%d\n", c);int d=max1(40, 7); printf("最大值:%d\n", d); return 0;
}// 2 在main函数之后
int max1(int a, int b){if(a >b){return a;} else{return b;}
}
4 reg52.h
-
介绍
- 用于80C52和80C32微控制器的通用头文件。
- 其中定义了各种特殊字节寄存器,如P0口、P1口、P2口、P3口、程序状态字寄存器、累加器、B特殊寄存器、堆栈指针寄存器和数字指针(低位/高位)等。
- 该头文件还定义了一些与定时器/计数器和电源控制相关的寄存器。
-
导入
#include "reg52.h" -
区别:引入方式 “” 与 <>
- “”
- 使用双引号来包含头文件时,编译器会首先在当前文件所在的目录下搜索指定的头文件。
- 如果在这个目录下找不到文件,编译器会继续在编译器的标准库路径中查找。
- 这种机制允许开发者包含项目中自定义的头文件。
- <>
- 当使用尖括号时,编译器只在编译器的标准库路径中查找指定的文件。
- 意味着尖括号主要用于包含标准库头文件,如
<stdio.h>、<stdlib.h>等。
- “”
-
内容
- 点击到 “reg52.h” 处,右击选择 Open Document <reg52.h>

3 项目实现
实验1 点亮LED
-
基本结构:main.c 文件
#include "reg52.h"sbit LED = P1^4; void main() {while (1){LED = 0; // 点亮LED1} }- 注意:一个程序里有且只有一个main函数。
-
释义
- **sbit LED = P0^4; ** 定义P0.4引脚赋值给变量LED(sbit 是定义特殊功能寄存器的位变量)。
实验2 实现LED闪烁
-
延迟函数
void Delay(unsigned int t) {while(--t); } -
说明
- 通过一个空 while 循环来延迟执行,让CPU在循环中忙等待,直到变量 t 的值从传入的值递减到0。
- 大约是 0.1 毫秒(ms)或 0.0001 秒。
-
缺点
- 效率低下:CPU在这段时间内无法执行其他任务,导致资源浪费。
- 不可预测性:延迟的时间长度高度依赖于执行代码的CPU的速度。在更快的CPU上,同样的循环次数会更快地完成,导致延迟时间更短。
- 不可移植性:由于延迟时间依赖于CPU速度,因此代码在不同硬件上的表现可能会有很大差异。
-
代码
#include <reg52.h> //头文件包含特殊功能寄存器的定义sbit LED0=P1^0; // 用sbit 关键字 定义 LED到P1.0端口,void Delay(unsigned int t); //函数声明/*------------------------------------------------主函数 ------------------------------------------------*/ void main (void) {while (1) //主循环{LED0=0; //将P1.0口赋值 0,对外输出低电平Delay(10000); //调用延时程序;更改延时数字可以更改延时长度;LED0=1; //将P1.0口赋值 1,对外输出高电平Delay(10000);} }/*------------------------------------------------延时函数,含有输入参数 unsigned int t,无返回值unsigned int 是定义无符号整形变量,其值的范围是0~65535 ------------------------------------------------*/ void Delay(unsigned int t) {while(--t); }
-
方式2:for循环延迟
#include "reg52.h"sbit LED = P1^4; void delay();void main() {while (1){LED = 0; // 点亮LED1delay(); // 延时1sLED = 1; // 熄灭LED1delay(); // 延时1s } } -
实现delay函数
void delay() {unsigned int i, j;for(i=0; i<183; i++){for(j=0; j<1000;j++); } }
实验3 LED灯先快闪,再慢闪,循环闪烁
#include<reg52.h> //头文件包含特殊功能寄存器的定义sbit LED0 = P1 ^ 0; // 用sbit 关键字 定义 LED到P1.0端口,void Delay(unsigned int t); //函数声明/*------------------------------------------------主函数
------------------------------------------------*/
void main()
{unsigned char i; //定义一个无符号字符型局部变量 i 取值范围 0~255while (1) { //主循环for (i = 0; i < 10; i++) { //加入 for循环,表明for循环大括号中的程序循环执行10次LED0 = 0; //将P1.0口赋值 0,对外输出低电平Delay(5000); //调用延时程序;更改延时数字可以更改延时长度;LED0 = 1; //将P1.0口赋值 1,对外输出高电平Delay(5000);}for (i = 0; i < 10; i++) {LED0 = 0; //将P1.0口赋值 0,对外输出低电平Delay(60000); //用于改变闪烁频率LED0 = 1; //将P1.0口赋值 1,对外输出高电平Delay(60000);}}
}/*------------------------------------------------延时函数,含有输入参数 unsigned int t,无返回值unsigned int 是定义无符号整形变量,其值的范围是0~65535
------------------------------------------------*/
void Delay(unsigned int t)
{while (--t);
}
实验4 不同频率让多个LED灯闪烁
#include<reg52.h>sbit LED0 = P1 ^ 0;
sbit LED1 = P1 ^ 1;
sbit LED2 = P1 ^ 2;
sbit LED3 = P1 ^ 3;
sbit LED4 = P1 ^ 4;
sbit LED5 = P1 ^ 5;
sbit LED6 = P1 ^ 6;
sbit LED7 = P1 ^ 7;void Delay(unsigned int t); //函数声明/*------------------------------------------------主函数
------------------------------------------------*/
void main()
{unsigned char i; //定义一个无符号字符型局部变量 i 取值范围 0~255while (1) {for (i = 0; i < 10; i++) { //程序循环执行10次LED0 = 0; //将P1.0口赋值 0,对外输出低电平LED2 = 1;LED4 = 0;Delay(5000);LED0 = 1; //将P1.0口赋值1,对外输出高电平LED2 = 0;LED4 = 1;Delay(5000);}for (i = 0; i < 10; i++) {LED0 = 0; //将P1.0口赋值 0,对外输出低电平LED2 = 1;LED4 = 0;Delay(60000);LED0 = 1; //将P1.0口赋值 1,对外输出高电平LED2 = 0;LED4 = 1;Delay(60000);}}
}/*------------------------------------------------延时函数,含有输入参数 unsigned int t,无返回值unsigned int 是定义无符号整形变量,其值的范围是 0~65535
------------------------------------------------*/
void Delay(unsigned int t)
{while (--t);
}
4 格式化代码
-
下载并安装AStyle
-
访问AStyle的官方网站(https://astyle.sourceforge.net/)下载最新版本的AStyle。

-
解压下载的文件,并记住解压后的路径,特别是
Astyle.exe文件的路径。
-
-
在Keil 5中加载AStyle
-
打开Keil 5软件,选择
Tools->Customize Tools Menu...,点击“新建”按钮,创建一个新的菜单项,命名为“formatCode”, -
在 “Command” 栏中选择上述解压的绝对路径(选择到 astyle.exe)
-
在 “Arguments” 栏中输入:
!E --style=1tbs --indent-col1-comments --break-blocks --pad-oper --pad-comma --pad-header --unpad-paren --delete-empty-lines --align-pointer=name --break-one-line-headers --add-braces --max-code-length=120。 -
点击“OK”保存设置。

-
-
设置 代码格式化 快捷键
- 点击菜单栏中的 【Edit】选择【 Configuration…】,切换到【Shortcut Keys】,在 Select a Command 中找到:【Tools: formatCode】,点击 【Create Shortcut】,设置快捷键(按下对应的按键,如:Ctrl + Q),点击【OK】

相关文章:
51单片机教程(五)- LED灯闪烁
1 项目分析 让输入/输出口的P1.0或P1.0~P1.7连接的LED灯闪烁。 2 技术准备 1、C语言知识点 1 运算符 1 算术运算符 #include <stdio.h>int main(){// 算术运算符int a 13;int b 6;printf("%d\n", ab); printf("%d\n", a-b); printf("%…...
VUE3中Element table表头动态展示合计信息(不是表尾合计)
一、背景 原型上需要对两个字段动态合计,输出摘要信息 原先想到是的Element的 :summary-method,发现不是动态,所以换监听来实现 二、vue代码 <el-table v-model"loading" :data"itemList"><el-table-column la…...
git重置的四种类型(Git Reset)
git区域概念 1.工作区:IDEA中红色显示文件为工作区中的文件 (还未使用git add命令加入暂存区) 2.暂存区:IDEA中绿色(本次还未提交的新增的文件显示为绿色)或者蓝色(本次修改的之前版本提交的文件但本次还未提交的文件显示为蓝色)显示的文件为暂存区中的文件(使用了…...
【Java集合面试1】说说Java中的HashMap原理?
Java中的HashMap是一种基于哈希表的Map接口实现,它存储的内容是键值对(key-value)映射。HashMap允许空键(null)和空值(null),并且它的键值对没有顺序。以下是HashMap的一些关键工作原…...
万字长文解读机器学习——决策树
🌺历史文章列表🌺 机器学习——损失函数、代价函数、KL散度机器学习——特征工程、正则化、强化学习机器学习——常见算法汇总机器学习——感知机、MLP、SVM机器学习——KNN机器学习——贝叶斯机器学习——决策树机器学习——随机森林、Bagging、Boostin…...
内网环境,基于k8s docer 自动发包
背景:生产环境是内网,无法连接外部git环境,需要上传tar包打成镜像,然后发布。 简单写了个脚本,记录下方便复用。 将tar包和脚本拷贝到同一个目录下。 使用方式: tar 包名称格式:服务名-版本号…...
【HCIP园区网综合拓扑实验】配置步骤与详解(已施工完毕)
一、实验要求 实验拓扑图如上图所示 1、按照图示的VLAN及IP地址需求,完成相关配置 2、要求SW1为VLAN 2/3的主根及主网关 SW2为vlan 20/30的主根及主网关 SW1和SW2互为备份 3、可以使用super vlan(本实验未使用) 4、上层…...
Qt 编写插件plugin,支持接口定义信号
https://blog.csdn.net/u014213012/article/details/122434193?spm1001.2014.3001.5506 本教程基于该链接的内容进行升级,在编写插件的基础上,支持接口类定义信号。 环境:Qt5.12.12 MSVC2017 一、创建项目 新建一个子项目便于程序管理【…...
Qt中 QWidget 和 QMainWindow 区别
QWidget 用来构建简单窗口 QMainWindow 用来构建更复杂的窗口,QMainWindow 继承自QWidget,在QWidget 的基础上提供了菜单栏、工具栏、状态栏等功能 菜单栏(QMenuBar)工具栏(QToolBar)状态栏(Q…...
Kafka集群中数据的存储是按照什么方式存储的?
1)Topic 数据的存储机制 Topic是逻辑上的概念,而partition是物理上的概念,每个partition对应于一个log文件,该log文件中存储的就是Producer生产的数据。Producer生产的数据会被不断追加到该log文件末端,为防止log文件…...
中断的硬件框架
往期内容 本专栏往期内容,interrtupr子系统: 深入解析Linux内核中断管理:从IRQ描述符到irq domain的设计与实现Linux内核中IRQ Domain的结构、操作及映射机制详解中断描述符irq_desc成员详解Linux 内核中断描述符 (irq_desc) 的初始化与动态分…...
数据备份策略:企业防御的关键
数据备份是保护数据免受网络攻击的重要步骤。在从恶意软件或勒索软件攻击中恢复时,公司可以使用保存的备份将其恢复到之前的状态。但是,为了确保数据的完全安全,任何公司的备份策略都应该在其总体策略中包含多种解决方案。 根据关于创建、消…...
Baget 私有化nuget
Baget下载 1、下载运行 方法一:cmd运行 dotnet BaGet.dll --urls http://*:8002 http://localhost:8002 方法二:bat脚本运行Baget 创建Start.bat dotnet BaGet.dll --urls http://*:8002 运行Start.bat 方法三:部署成Window服务 NSSM部…...
前端函数的参数都有哪些?
在前端开发中,函数的分类可以根据不同的标准进行。以下是一些常见的函数分类方式,并附有相应的例子: 按传递方式分类: 按值传递:JavaScript 中的基本类型(如数字、字符串、布尔值)都是按值传递的…...
【CSS】什么是BFC?
块级格式化上下文(Block Formatting Context,简称BFC)是CSS布局中的一种重要概念,它决定了块级盒子如何在其容器内排列,以及浮动元素对其周围元素的影响。理解BFC可以帮助解决许多常见的网页布局问题,比如清…...
HCIP小型园区网拓扑实验
1.拓扑以及需求 2.需求分析 需要的核心技术 1、虚拟局域网(VLAN) 2、链路聚合(E-trunk) 3、多生成树协议(MSTP) 4、VLANIF三层逻辑接口 5、虚拟路由冗余协议(VRRP) 6、动态主…...
GRR测量系统的重复性和再现性
GRR(GaugeRepeatabilityandReproducibility)即测量系统的重复性和再现性,是用于评估测量系统性能的一个重要指标。以下是对GRR的详细解释: 一、定义 • 重复性(Repeatability):在相同条件下&…...
133.鸿蒙基础01
鸿蒙基础 1.自定义构建函数1. 构建函数-[Builder ](/Builder )2. 构建函数-传参传递(单向)3. 构建函数-传递参数(双向)4. 构建函数-传递参数练习5. 构建函数-[BuilderParam ](/BuilderParam ) 传递UI 2.组件状态共享1. 状态共享-父子单向2. 状态共享-父子双向3. 状态共享-后代组…...
科技查新小知识
首先科技查新是什么? 科技查新是文献检索和情报调研相结合的情报研究工作,它以文献为基础,以文献检索和情报调研为手段,以检出结果为依据,通过综合分析,对查新项目的新颖性进行情报学审查,写出有…...
docker安装portainer
1、拉取镜像 docker pull portainer/portainer-ce:latest2、执行 docker run -d --restartalways --name portainer -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock -v /data/portainer/data:/data -v /data/portainer/public:/public portainer/portain…...
老码农和你一起学AI系列:ELECTRA
ELECTRA(Efficiently Learning an Encoder that Classifies Token Replacements Accurately)是Google Research在2020年提出的一种自监督预训练方法。它不像BERT那样做“完形填空”,而是让模型扮演一个“作弊检测员”,通过判别输入…...
tkinter表格神器tkintertable实战:5分钟搞定可拖拽编辑的数据表格(附完整代码)
tkinter表格神器tkintertable实战:5分钟搞定可拖拽编辑的数据表格(附完整代码) 在Python GUI开发中,表格控件一直是刚需但实现起来又颇为棘手的组件。传统tkinter自带的Treeview虽然能勉强实现表格功能,但在交互体验上…...
Stable Diffusion像素艺术工作站:Pixel Fashion Atelier支持LoRA在线热切换
Stable Diffusion像素艺术工作站:Pixel Fashion Atelier支持LoRA在线热切换 1. 像素时装锻造坊简介 Pixel Fashion Atelier是一款基于Stable Diffusion与Anything-v5的图像生成工作站,专为像素艺术创作而设计。与传统AI工具不同,它采用了复…...
VitePress 博客主题定制与美化实战
1. VitePress主题美化的核心思路 很多开发者在使用VitePress搭建博客时,都会遇到一个共同的问题:默认主题虽然简洁,但缺乏个性。我在实际项目中发现,通过CSS变量覆盖、自定义组件和插件扩展这三个维度,可以打造出极具辨…...
9大核心优势!Outfit字体全方位应用指南:从安装到精通
9大核心优势!Outfit字体全方位应用指南:从安装到精通 【免费下载链接】Outfit-Fonts The most on-brand typeface 项目地址: https://gitcode.com/gh_mirrors/ou/Outfit-Fonts Outfit字体作为一款专业开源无衬线字体,凭借9种完整字重体…...
Phi-4-Reasoning-Vision应用场景:法律文书配图证据链推理系统
Phi-4-Reasoning-Vision应用场景:法律文书配图证据链推理系统 1. 法律文书配图证据链推理系统概述 在法律实务中,证据链的构建往往需要处理大量图文混合材料。传统人工分析方式存在效率低下、主观性强、容易遗漏细节等问题。基于Phi-4-Reasoning-Visio…...
全球蛋白质组学数据共享核心平台升级
摘要 ProteomeXchange蛋白质组学资源联盟(http://www.proteomexchange.org)的建立旨在标准化基于质谱(MS)的蛋白质组学领域开放数据实践。本文介绍了ProteomeXchange在过去3年的主要进展。该联盟的6个成员数据库分布于࿱…...
利用快马ai快速生成流水线plc控制逻辑原型,无硬件也能验证思路
最近在做一个自动化流水线的小项目,需要设计PLC控制逻辑。传统方式需要先搭建硬件环境才能调试,但通过InsCode(快马)平台的AI辅助,我实现了无硬件环境下的快速原型验证,分享下这个实用经验。 项目背景与需求分析 这个流水线控制系…...
Qwen3.5-4B-Claude-Opus保姆级教程:Web界面响应延迟归因与优化路径
Qwen3.5-4B-Claude-Opus保姆级教程:Web界面响应延迟归因与优化路径 1. 模型与部署环境概览 Qwen3.5-4B-Claude-4.6-Opus-Reasoning-Distilled-GGUF是基于Qwen3.5-4B的推理蒸馏模型,特别强化了结构化分析、分步骤回答以及代码与逻辑类问题的处理能力。该…...
Vivado仿真踩坑实录:PR模式不支持仿真的快速解决方案(附详细步骤)
Vivado仿真避坑指南:PR模式不支持仿真的深度解析与实战方案 刚接触FPGA开发的朋友们,不知道你们是否遇到过这样的场景:在Vivado中精心设计了一个工程,准备进行仿真验证时,突然弹出一个令人困惑的错误提示——"Sim…...
