51单片机(STC89C52RC版本)学习笔记(更新中...)
文章目录
- 参考资料
- 1. 准备工作
- 1.1 win10配置51单片机开发环境
- 1.1 Ubuntu配置51单片机开发环境
- 问题1:`mcs51/8051.h`依赖于`mcs51/lint.h`
- 问题2:提示找不到头文件`mcs51/8051.h`
- 2. 认识51单片机
- 2.1 STC89C52单片机
- 2.2 管脚图
- 2.3 原理图
- 2.4 按键抖动
- 2.5 头文件说明
- 2.6 模块化函数
- 2.6.1 延时函数
- 2.6.2 矩阵键盘
- 3. LED模块
- 3.1 原理图
- 实验1:点亮LED灯D1
- 实验2:LED灯D8闪烁
- 实验3:LED流水灯
- 4. 独立按键模块
- 4.1 原理图
- 实验1:独立按键控制LED灯D1
- 5. 动态数码管模块
- 5.1 原理图
- 实验1:数码管LED3显示2
- 实验2:数码管LED8 ~ LED1分别显示0 ~ 8
- 6. LCD1602接口
- 6.1 原理图
- 7. 矩阵按键模块
- 7.1 原理图
- 实验1:在LCD1602显示按下的键码(1 ~ 16)
- 实验2:4位密码锁
- 8. 定时器与中断
- 8.1 原理图
- 实验1:实现一个电子时钟
- 9. 串口通信
- 9.1 原理图
参考资料
51单片机入门教程-2020版 程序全程纯手打 从零开始入门
江协科技资料下载
51单片机(STC89C52RC)系统性学习笔记
1. 准备工作
1.1 win10配置51单片机开发环境
- 51单片机
正在重新握手 ... 成功 [0.578"]
当前的波特率: 115200
正在擦除目标区域 ... 完成 ! [0.328"]
正在下载用户代码 ... 完成 ! [0.141"]
正在设置硬件选项 ... 完成 ! [0.031"]更新后的硬件选项为:. 当前的时钟频率: 11.088MHz. 系统频率为12T(单倍速)模式. 振荡器的放大增益不降低. 当看门狗启动后,任何复位都可停止看门狗. MCU内部的扩展RAM可用. ALE脚的功能选择仍然为ALE功能脚. P1.0和P1.1与下次下载无关. 下次下载用户程序时,不擦除用户EEPROM区单片机型号: STC89C52RC/LE52RC固件版本号: 6.6.4C
-
编程工具
Keil5 C51
新建项目时选择AT89C51RC2
-
将程序载入到51单片机的工具
STC-ISP
-
51单片机接入电脑,并配置驱动CH340_CH341
1.1 Ubuntu配置51单片机开发环境
- 编辑器 VS Code 安装教程
- 安装VS Code插件
C/C++ Extension Pack
- 安装编译工具
sudo apt-get install sdcc
- 程序编译
sdcc 1_LED_1.c
将编译生成的文件输出到out目录,需要先通过sudo mkdir out
创建out目录
sdcc 1_LED_1.c -o out/
问题1:mcs51/8051.h
依赖于mcs51/lint.h
#include <mcs51/lint.h>
#include <mcs51/8051.h>
问题2:提示找不到头文件mcs51/8051.h
8051.h
是安装sdcc
后产生的,请先确保sdcc
已经安装,sudo find / -name 8051.h
搜索一下头文件8051.h
所在的目录
这里目录是/usr/share/sdcc/include
,将该路径配置到includepath
,先点击Quick Fix
再点击Edit “includePath” setting
添加/usr/share/sdcc/include
到Include path
2. 认识51单片机
2.1 STC89C52单片机
- 所属系列:51单片机系列
- 公司:STC公司
- 位数:8位
- RAM:512字节
- ROM:8K(Flash)
- 工作频率:12MHz(本开发板使用)
2.2 管脚图
2.3 原理图
高清PDF可从这里下载江协科技资料下载
2.4 按键抖动
对于机械开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开,所以在开关闭合及断开的瞬间会伴随一连串的抖动。
因此,需要进行防抖处理,如下:
// 这是一个检测独立按键K1是否按下,并控制LED模块的简化代码
if(P3_1==0) // 如果K1按键按下,P3_1的值会变为0
{Delay(20); // 延时20毫秒消抖while(P3_1==0); // 死循环空转,直到K1按键松开,P3_1变为1,跳出循环Delay(20); // 延时20毫秒消抖P2_0=~P2_0; // LED1的亮灭情况
}
2.5 头文件说明
#include <mcs51/lint.h>
#include <mcs51/8051.h>
#include <REGX52.H>
2.6 模块化函数
2.6.1 延时函数
#ifndef __DELAY_H__
#define __DELAY_H__void Delayms(unsigned char k);#endif
#include <INTRINS.H>// 延时k ms
void Delayms(unsigned char k) //@11.0592MHz
{unsigned char i, j;while (k --) {_nop_();i = 2;j = 199;do{while (--j);} while (--i);}
}
2.6.2 矩阵键盘
#ifndef __MATRIXKEYBOARD_H__
#define __MATRIXKEYBOARD_H__unsigned int matrixKeyboard();#endif
#include <at89c51RC2.h>
#include "Delay.h"
// 反回键码(1 ~ 16),行优先遍历
// 按列扫描矩阵键盘
// 如果按行的话,P1_5和蜂鸣器冲突,会导致其发声
unsigned int matrixKeyboard() {unsigned int keyNum = 0;P1 = 0xFF;P1_3 = 0; // 第一列if (P1_7 == 0) {Delayms(20); while (P1_7 == 0); Delayms(20); keyNum = 1;}if (P1_6 == 0) {Delayms(20); while (P1_6 == 0); Delayms(20); keyNum = 5;}if (P1_5 == 0) {Delayms(20); while (P1_5 == 0); Delayms(20); keyNum = 9;}if (P1_4 == 0) {Delayms(20); while (P1_4 == 0); Delayms(20); keyNum = 13;}P1 = 0xFF;P1_2 = 0; // 第二列if (P1_7 == 0) {Delayms(20); while (P1_7 == 0); Delayms(20); keyNum = 2;}if (P1_6 == 0) {Delayms(20); while (P1_6 == 0); Delayms(20); keyNum = 6;}if (P1_5 == 0) {Delayms(20); while (P1_5 == 0); Delayms(20); keyNum = 10;}if (P1_4 == 0) {Delayms(20); while (P1_4 == 0); Delayms(20); keyNum = 14;}P1 = 0xFF;P1_1 = 0; // 第三列if (P1_7 == 0) {Delayms(20); while (P1_7 == 0); Delayms(20); keyNum = 3;}if (P1_6 == 0) {Delayms(20); while (P1_6 == 0); Delayms(20); keyNum = 7;}if (P1_5 == 0) {Delayms(20); while (P1_5 == 0); Delayms(20); keyNum = 11;}if (P1_4 == 0) {Delayms(20); while (P1_4 == 0); Delayms(20); keyNum = 15;}P1 = 0xFF;P1_0 = 0; // 第四列if (P1_7 == 0) {Delayms(20); while (P1_7 == 0); Delayms(20); keyNum = 4;}if (P1_6 == 0) {Delayms(20); while (P1_6 == 0); Delayms(20); keyNum = 8;}if (P1_5 == 0) {Delayms(20); while (P1_5 == 0); Delayms(20); keyNum = 12;}if (P1_4 == 0) {Delayms(20); while (P1_4 == 0); Delayms(20); keyNum = 16;}return keyNum;
}
3. LED模块
3.1 原理图
LED等的左侧接入VCC正极,若要使灯亮,则右侧需要接入负极,也就是对应的寄存器位需要赋值为0。
实验1:点亮LED灯D1
#include <AT89C51RC2.h>
/*** 点亮LED灯D1
*/
void main() {P2 = 0xFF; // 将所有灯熄灭P2_0 = 0; // D1灯亮起while (1); // 程序始终保持运行
}
实验2:LED灯D8闪烁
#include <AT89C51RC2.h>
#include <INTRINS.H>/*** LED灯D8闪烁
*/
void main() {P2 = 0xFF; while (1){P2_7 = 0; // D8灯亮Delayms(1000); // 延迟1000ms = 1sP2_7 = 1; // D8灯灭Delayms(1000); // 延迟1000ms = 1s}
}
实验3:LED流水灯
#include <AT89C51RC2.h>
#include "Delay.h"/*** LED灯D1 ~ D8按顺序点亮,每次只有一个灯亮
*/
void main() {// 1111 1110// 1111 1101// 1111 1011// ...// 1111 1110// =》 其实就是实现循环左移P2 = 0xFE;while (1){P2 <<= 1;if (P2 != 0xFE) P2 |= 0x01;Delayms(1000); // 延迟1000ms = 1s}
}
4. 独立按键模块
4.1 原理图
实验1:独立按键控制LED灯D1
#include <AT89C51RC2.h>
#include "Delay.h"/*** 独立按键K1控制LED灯D1* 按下按键并松开后,变换灯D1的状态
*/
void main() {while (1){// 注意控制K1的是P3_1,控制K2的是P3_0// 当值为0是代表按键按下if (P3_1 == 0) {Delay(20); // 消除按键抖动while (P3_1 == 0); // 一直保持按下的状态则卡在这Delay(20); // 消除按键抖动P2_0 = ~P2_0; // 状态取反}}
}
5. 动态数码管模块
5.1 原理图
LED1 ~ LED8的亮灭(位选)由P24, P23, P22三位决定,P24位高位,当这三个位表示数据n时,Yn对应的灯亮,Y0对应LED1
P0_0 ~ P0_6分别控制a ~ g晶体管,P0_7控制dp晶体管,为1代表选中。(P0_7是最高位,P0_0是最低位)
实验1:数码管LED3显示2
#include <AT89C51RC2.h>/*** 数码管LED3显示2
*/
void main() {// 选中数码管LED3,对应Y2 P2_4 P2_3 P2_2 = 0 1 0P2_4 = 0;P2_3 = 1;P2_2 = 0;// a b c d e f g dp// 0 1 2 3 4 5 6 7// a b c d e f g dp// 1 1 0 1 1 0 1 0 => 0101 1011 = 0x5B// 数字2,需要点亮 a b g e dP0 = 0x5B;while (1);
}
实验2:数码管LED8 ~ LED1分别显示0 ~ 8
// 对应数字 0 ~ 9 的段码
unsigned char NixieTable[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};
// 在LED-loc 显示num
void Nixie(unsigned char loc, unsigned char num) { P2_4 = 0; P2_3 = 0; P2_2 = 0; // 1110 0011 = 0xE3 P2 &= 0xE3if ((loc & 0x01) == 1) P2_2 = 1;if ((loc & 0x02) == 2) P2_3 = 1;if ((loc & 0x04) == 4) P2_4 = 1;P0 = NixieTable[num];// 消影,数字清零,防止上一个位置的数字显示到下一个位置Delayms(1);P0 = 0x00;
}/*** 数码管LED8 ~ LED1分别显示0 ~ 8
**/
void main() {unsigned char i;while (1) {for (i = 0; i <= 7; i ++) {Nixie(7 - i, i);}}
}
6. LCD1602接口
6.1 原理图
7. 矩阵按键模块
7.1 原理图
实验1:在LCD1602显示按下的键码(1 ~ 16)
#include <at89c51RC2.h>
#include "Delay.h"
// 反回键码(1 ~ 16),行优先遍历
// 没有按下任何键则返回0
// 按列扫描矩阵键盘
// 如果按行的话,P1_5和蜂鸣器冲突,会导致其发声
unsigned int matrixKeyboard() {unsigned int keyNum = 0;P1 = 0xFF;P1_3 = 0; // 第一列if (P1_7 == 0) {Delayms(20); while (P1_7 == 0); Delayms(20); keyNum = 1;}if (P1_6 == 0) {Delayms(20); while (P1_6 == 0); Delayms(20); keyNum = 5;}if (P1_5 == 0) {Delayms(20); while (P1_5 == 0); Delayms(20); keyNum = 9;}if (P1_4 == 0) {Delayms(20); while (P1_4 == 0); Delayms(20); keyNum = 13;}P1 = 0xFF;P1_2 = 0; // 第二列if (P1_7 == 0) {Delayms(20); while (P1_7 == 0); Delayms(20); keyNum = 2;}if (P1_6 == 0) {Delayms(20); while (P1_6 == 0); Delayms(20); keyNum = 6;}if (P1_5 == 0) {Delayms(20); while (P1_5 == 0); Delayms(20); keyNum = 10;}if (P1_4 == 0) {Delayms(20); while (P1_4 == 0); Delayms(20); keyNum = 14;}P1 = 0xFF;P1_1 = 0; // 第三列if (P1_7 == 0) {Delayms(20); while (P1_7 == 0); Delayms(20); keyNum = 3;}if (P1_6 == 0) {Delayms(20); while (P1_6 == 0); Delayms(20); keyNum = 7;}if (P1_5 == 0) {Delayms(20); while (P1_5 == 0); Delayms(20); keyNum = 11;}if (P1_4 == 0) {Delayms(20); while (P1_4 == 0); Delayms(20); keyNum = 15;}P1 = 0xFF;P1_0 = 0; // 第四列if (P1_7 == 0) {Delayms(20); while (P1_7 == 0); Delayms(20); keyNum = 4;}if (P1_6 == 0) {Delayms(20); while (P1_6 == 0); Delayms(20); keyNum = 8;}if (P1_5 == 0) {Delayms(20); while (P1_5 == 0); Delayms(20); keyNum = 12;}if (P1_4 == 0) {Delayms(20); while (P1_4 == 0); Delayms(20); keyNum = 16;}return keyNum;
}// 在LCD1602显示按下的键码(1 ~ 16)
void main() {unsigned int num = 0, newNum = 0;LCD_Init();while (1) {newNum = matrixKeyboard();if (newNum != 0) {num = newNum;}LCD_ShowNum(1, 1, num, 2); // 第一行第一列显示,占两个位置}
}
实验2:4位密码锁
// 10为0,11为确认,12为清空
void main() {// num,保存当前输入的密码// keyNum,记录矩阵键盘按下的键码// count,记录当前已经输入多少个数字unsigned int num = 0, keyNum = 0, count = 0;// LCD1602初始化LCD_Init();// 在第一行的前9个输入固定显示输入提示符LCD_ShowString(1, 1, "PASSWORD:");while (1) {// 第10个字符显示当前输入的密码LCD_ShowNum(1, 10, num, 4);// 获取当前矩阵键盘的键码(没有按下任何键则返回0)keyNum = matrixKeyboard();if (keyNum >= 1 && keyNum <= 9 && count < 4) {num = num * 10 + keyNum;count ++;} else if (keyNum == 11 && count == 4) {if (num == 1234) {LCD_ShowString(2, 1, "OK");} else {LCD_ShowString(2, 1, "ERR");}} else if (keyNum == 12) {num = 0;count = 0;LCD_ShowString(2, 1, " ");}}
}
8. 定时器与中断
定时器介绍:51单片机的定时器属于单片机的内部资源,其电路的连接和运转均在单片机内部完成
定时器作用︰
(1)用于计时系统,可实现软件计时,或者使程序每隔一固定时间完成一项操作
(2)替代长时间的Delay,提高CPU的运行效率和处理速度(…)
8.1 原理图
TL0和TH0发生溢出时(达到65535),TF0标志位被置位1,从而引发中断。
- 生成定时器初始化代码
void Timer0Init(void) //1毫秒@11.0592MHz
{AUXR &= 0x7F; //定时器时钟12T模式TMOD &= 0xF0; //设置定时器模式TMOD |= 0x01; //设置定时器模式TL0 = 0x66; //设置定时初值TH0 = 0xFC; //设置定时初值TF0 = 0; //清除TF0标志TR0 = 1; //定时器0开始计时// 这两个开关配置需要自己加一下ET0 = 1; // 打开定时器0EA = 1; // 打开总开关
}
实验1:实现一个电子时钟
void Timer0Init() //1毫秒@11.0592MHz
{AUXR &= 0x7F; //定时器时钟12T模式TMOD &= 0xF0; //设置定时器模式TMOD |= 0x01; //设置定时器模式TL0 = 0x66; //设置定时初值 TH0 = 0xFC; //设置定时初值TF0 = 0; //清除TF0标志TR0 = 1; //定时器0开始计时ET0 = 1; // 打开定时器0EA = 1; // 打开总开关
}unsigned int count = 0;
// 设置时钟为 23:59:45 方便调试
unsigned int second = 45;
unsigned int minute = 59;
unsigned int hour = 23;void main() {
// // TMOD不可位寻址, M0给1 => 0x01
// // TMOD = 0x01; // 配置定时器0
// // 防止对定时器1的配置产生影响,使用与或赋值法
// TMOD &= 0xF0; // 清空定时器0的配置
// TMOD |= 0x01; // 配置定时器0
//
// // TCON可位寻址,TF0 = 0, TR0 = 1
// TF0 = 0;
// TR0 = 1;
//
// // 64635 到 65535 相差1000,也就是1ms会发生中断
// TH0 = 64535 / 256; // 取高8位
// TL0 = 54535 % 256; // 取低8位
//
// // 定时器开关
// ET0 = 1; // 打开定时器0
// EA = 1; // 打开总开关
PT0 = 0;Timer0Init();LCD_Init();LCD_ShowChar(1, 3, ':');LCD_ShowChar(1, 6, ':');while (1) {if (second == 60) {second = 0;minute ++;}if (minute == 60) {minute = 0;hour ++;}if (hour == 24) {hour = 0;}LCD_ShowNum(1, 1, hour, 2);LCD_ShowNum(1, 4, minute, 2);LCD_ShowNum(1, 7, second, 2);}
}// 发生时钟中断时,会触发该函数,中断号为1
void Timer0_Routube() interrupt 1 {TL0 = 0x66; //设置定时初值TH0 = 0xFC; //设置定时初值count ++;if (count == 1000) {second ++;count = 0;// 中断程序应该尽量简短
// if (second == 60) {
// second = 0;
// minute ++;
// if (minute == 60) {
// minute = 0;
// hour ++;
// if (hour == 24) {
// hour = 0;
// }
// }
// }}
}
9. 串口通信
9.1 原理图
相关文章:

51单片机(STC89C52RC版本)学习笔记(更新中...)
文章目录 参考资料1. 准备工作1.1 win10配置51单片机开发环境1.1 Ubuntu配置51单片机开发环境问题1:mcs51/8051.h依赖于mcs51/lint.h问题2:提示找不到头文件mcs51/8051.h 2. 认识51单片机2.1 STC89C52单片机2.2 管脚图2.3 原理图2.4 按键抖动2.5 头文件说…...
七:仪表盘安装-controller node
一:工具、环境准备-controller node 二:OpenStack环境准备-controller node 三:安装服务-controller node 四:工具、环境准备-compute node 五:OpenStack环境准备-compute node 六:安装服务-compute node 七…...

C++设计模式之外观模式
动机 下图中左边方案的问题在于组件的客户和组件中各种复杂的子系统有了过多的耦合,随着外部客户程序和各子系统的演化,这种过多的耦合面临很多变化的挑战。 如何简化外部客户程序和系统间的交互接口?如何将外部客户程序的演化和内部子系统…...
显卡(Graphics Processing Unit,GPU)比特币挖矿
1. 比特币挖矿基本原理 比特币挖矿是通过参与比特币网络的共识机制——工作量证明(Proof of Work, PoW) 来完成的。具体来说,矿工通过不断尝试不同的哈希值,以解决一个难度逐渐增大的数学问题,从而验证交易并获得比特…...

【SARL】单智能体强化学习(Single-Agent Reinforcement Learning)《纲要》
📢本篇文章是博主强化学习(RL)领域学习时,用于个人学习、研究或者欣赏使用,并基于博主对相关等领域的一些理解而记录的学习摘录和笔记,若有不当和侵权之处,指出后将会立即改正,还望谅…...

CSS 动画效果实现:图片展示与交互
🌈个人主页:前端青山 🔥系列专栏:Css篇 🔖人终将被年少不可得之物困其一生 依旧青山,本期给大家带来Css篇专栏内容:CSS 动画效果实现:图片展示与交互 前言 在现代网页设计中,动态效果能够显著…...

【机器学习】—Transformers的扩展应用:从NLP到多领域突破
好久不见!喜欢就关注吧~ 云边有个稻草人-CSDN博客 目录 引言 一、Transformer架构解析 (一)、核心组件 (二)、架构图 二、领域扩展:从NLP到更多场景 1. 自然语言处理(NLP) 2…...

Linux权限机制深度解读:系统安全的第一道防线
文章目录 前言‼️一、Linux权限的概念‼️二、Linux权限管理❕2.1 文件访问者的分类(人)❕2.2 文件类型和访问权限(事物属性)✔️1. 文件类型✔️2. 基本权限✔️3. 权限值的表示方法 ❕2.3 文件访问权限的相关设置方法✔️1. ch…...

NineData云原生智能数据管理平台新功能发布|2024年11月版
本月发布 8 项更新,其中重点发布 2 项、功能优化 6 项。 重点发布 数据库 Devops - 数据生成支持多个数据源 NineData 支持在数据库中自动生成符合特定业务场景的随机数据,用于模拟实际生产环境中的数据情况,帮助用户在不使用真实数据的情况…...
Vue中控制组件的挂载位置
在 Vue 中,append-to-body“true” 主要用于一些第三方组件(如 Element UI 或 Ant Design Vue 中的弹出框、下拉菜单等)来控制组件的挂载位置。具体来说,当你设置 append-to-body“true” 时,它会将该组件的 DOM 元素插…...
查看docker容器日志
容器里面的服务运行报错了,要查看容器的日志 要查看 Docker 容器的日志,可以使用 docker logs 命令。以下是一些常见的使用方法: 基本用法 docker logs <container_name_or_id> 查看最近的日志 docker logs --tail 100 <contai…...

Apache Commons工具类库使用整理
文章目录 Apache Commons工具类库分类- commons-lang3字符串工具:StringUtils日期工具:DateUtils数值工具:NumberUtils对象工具:ObjectUtils数组工具:ArrayUtils异常工具:ExceptionUtils枚举工具࿱…...
力扣第89题 格雷编码
题目描述 格雷编码序列是一个二进制数字序列,其中的每两个相邻的数字只有一个二进制位不同。给定一个整数 n,表示格雷编码的位数,要求返回 n 位的格雷编码序列。 示例 1 输入: n 2输出: [0, 1, 3, 2]解释&#x…...

Linux C/C++编程中的多线程编程基本概念
【图书推荐】《Linux C与C一线开发实践(第2版)》_linux c与c一线开发实践pdf-CSDN博客《Linux C与C一线开发实践(第2版)(Linux技术丛书)》(朱文伟,李建英)【摘要 书评 试读】- 京东图书 (jd.com…...

解决Tomcat运行时错误:“Address localhost:1099 is already in use”
目录 背景: 过程: 报错的原因: 解决的方法: 总结: 直接结束Java.exe进程: 使用neststat -aon | findstr 1099 命令: 选择建议: 背景: 准备运行Tomcat服务器调试项目时,程序下…...
C/C++中的调用约定
在C/C编程中,调用约定(calling conventions)是一组指定如何调用函数的规则。主要在你调用代码之外的函数(例如OS API,操作系统应用程序接口)或OS调用你(如WinMain的情况)时起作用。如果编译器不知道正确的调用约定,那么你很可能会遇到非常奇怪…...

微信创建小程序码 - 数量不受限制
获取小程序码:小程序码为圆图,且不受数量限制。 目录 文档 接口地址 请求方式 功能描述 注意事项 获取 scene 值 请求参数 返回参数 对接 请求方法 获取小程序码 调用获取小程序码 总结 文档 接口地址 https://api.weixin.qq.com/wxa/get…...
springboot/ssm美食分享系统Java代码web项目美食烹饪笔记分享交流
springboot/ssm美食分享系统ava美食烹饪笔记分享交流系统web美食源码 基于springboot(可改ssm)vue项目 开发语言:Java 框架:springboot/可改ssm vue JDK版本:JDK1.8(或11) 服务器:tomcat 数据库&#…...

【Redis篇】 List 列表
在 Redis 中,List 是一种非常常见的数据类型,用于表示一个有序的字符串集合。与传统的链表结构类似,Redis 的 List 支持在两端进行高效的插入和删除操作,因此非常适合实现队列(Queue)和栈(Stack…...

多级IIR滤波效果(BIQUAD),system verilog验证
MATLAB生成IIR系数 采用率1k,截止频率30hz,Matlab生成6阶对应的biquad3级系数 Verilog测试代码 // fs1khz,fc30hz initial beginreal Sig_Orig, Noise_white, Mix_sig;real fs 1000;Int T 1; //周期int N T*fs; //1s的采样点数// 数组声明…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
省略号和可变参数模板
本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...

Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)
引言 工欲善其事,必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后,我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集,就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...
32单片机——基本定时器
STM32F103有众多的定时器,其中包括2个基本定时器(TIM6和TIM7)、4个通用定时器(TIM2~TIM5)、2个高级控制定时器(TIM1和TIM8),这些定时器彼此完全独立,不共享任何资源 1、定…...
CppCon 2015 学习:Time Programming Fundamentals
Civil Time 公历时间 特点: 共 6 个字段: Year(年)Month(月)Day(日)Hour(小时)Minute(分钟)Second(秒) 表示…...
深度解析:etcd 在 Milvus 向量数据库中的关键作用
目录 🚀 深度解析:etcd 在 Milvus 向量数据库中的关键作用 💡 什么是 etcd? 🧠 Milvus 架构简介 📦 etcd 在 Milvus 中的核心作用 🔧 实际工作流程示意 ⚠️ 如果 etcd 出现问题会怎样&am…...