STC89C52单片机学习——第26节: [11-2]蜂鸣器播放音乐
写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难,但我还是想去做!
本文写于:2025.03.19
51单片机学习——第26节: [11-2]蜂鸣器播放音乐
- 前言
- 开发板说明
- 引用
- 解答和科普
- 一、LED播放音乐
- 二、蜂鸣器播放音乐代码
- 问题
- 总结
前言
本次笔记是用来记录我的学习过程,同时把我需要的困难和思考记下来,有助于我的学习,同时也作为一种习惯,可以督促我学习,是一个激励自己的过程,让我们开始51单片机的学习之路。
欢迎大家给我提意见,能给我的嵌入式之旅提供方向和路线,现在作为小白,我就先学习51单片机了,就跟着B站上的江协科技开始学习了.
在这里会记录下江协科技51单片机开发板的配套视频教程所作的实验和学习笔记内容,因为我之前有一个开发板,我大概率会用我的板子模仿着来做.让我们一起加油!
另外为了增强我的学习效果:每次笔记把我不知道或者问题在后面提出来,再下一篇开头作为解答!
开发板说明
本人采用的是慧净的开发板,因为这个板子是我N年前就买的板子,索性就拿来用了。不再另外购买视频中的普中开发板了。
原理图如下
视频中的都用这个开发板来实现,如果有资源就利用起来。
仔细看了看:开发板的晶振为:11.0592Mhz;12Mhz晶振是用来给CH340G芯片外置晶振;
下图是实物图
引用
51单片机入门教程-2020版 程序全程纯手打 从零开始入门
还参考了下图中的书籍:
手把手教你学51单片机(C语言版)
STC89C52手册
解答和科普
一、LED播放音乐
1.1 播放音乐
弹钢琴时的两个要素是:1、弹哪一个钢琴按键 2、弹多长时间。弹哪一个按键就是选择音高,弹多长时间就是音长。在简谱中对应的就是写的数字是多少,还有就是拍子数。
由上一节可知,蜂鸣器的频率由计数频率,进而算出来计数周期,一个周期翻转2次,就是高电平持续半个周期,低电平持续半个周期,所以我们算出来半个周期,就是定时器定时的时间,就是半个周期是一种状态。也就是用定时器,定固定的周期,完成音高的产生。
void Timer0_Routine() interrupt 1 //1毫秒跳转到这里,T=2ms,触发中断 500hz
{ TL0 = FreqTable[FreqSelect]/256; //重新设置定时初值,根据表格算的值,计算出对应的TL0和TH0,只有我们可以设置不同的频率TH0 = FreqTable[FreqSelect]%256; //又因为总共有36个音高,是固定的只需要取数组里的值。TH0=X/256,TL0=X%256;Buzzer=!Buzzer;}
根据上节课的EXCEL表,我们可以创建一个数组:里面放的数据是用来计算重装载值,产生对应音高的重装载值。
unsigned int code FreqTable[]={0,63628,63731,63835,63928,64021,64103,64185,64260,64331,64400,64463,64528,64580,64633,64684,64732,64777,64820,64860,64898,64934,64968,65000,65030,65058,65085,65110,65134,65157,65178,65198,65217,65235,65252,65268,65283,0xFF};
如何我们在设置一个频率选择变量:FreqSelect,用来选择需要的音高。
while(1){FreqSelect++;Delay(500); //这个音高响500ms}
现在这个时候我们可以完成按着顺序弹奏给的音高。并且每个音高是500ms。
2、接下来要完成按照简谱的顺序演奏歌曲,我们就又创建了一个Music数组用来存放简谱音高的索引值,按照简谱顺序演唱的索引值。
unsigned char code Music[]={12,16,12,36,19,20};
并且创造一个MusicSelect变量用来选择,Music数组中的索引值;
while(1){FreqSelect=Music[MusicSelect]; //这个就是得到了简谱的音高的索引值,比如MusicSelect=0,去Music数组中找就是简谱第一个音高对应的索引值,如是13就是代表中音1,然后再把FreqSelect去FreqTable去找,就是64580,对应的事重装载值。MusicSelect++;Delay(500); //这个音高响500ms}
oid Timer0_Routine() interrupt 1 //1毫秒跳转到这里,T=2ms,触发中断 500hz
{ TL0 = FreqTable[FreqSelect]/256; //重新设置定时初值,根据表格算的值,计算出对应的TL0和TH0,只有我们可以设置不同的频率TH0 = FreqTable[FreqSelect]%256; //又因为总共有36个音高,是固定的只需要取数组里的值。TH0=X/256,TL0=X%256;Buzzer=!Buzzer;
}
现在这个函数完成了对简谱的音高选择,并且每个音的时间是500us。
下面是音长的设置
在这里我们采用了用最短的音符为基准设为1,比如八分音符为1,四份音符就为2,2分音符为4,全音符就为8。在这里我没有再去设数组,和数组选择位,而是把这个音长放在了Music的频率选择位后面,就这样在Music数组中形成要播放的音高,音长这么一组,一组组的数据,分别代表频率和音长。
FreqSelect=Music[MusicSelect]; //频率MusicSelect++;Delay(250*Music[MusicSelect]); //时长=基准值乘以音符的系数,如基准是16音符是1,4分音符的系数是4MusicSelect++; //取到了频率的索引值
然后完成抬手停顿的动作,每演奏一个音符把定时器关掉,这样就形成了抬手动作
TR0=0; //每演奏一个音符,就把定时器关掉Delay(5); //抬手的时间,每个音符都分开TR0=1;}
然后还有停止符,就是在频率的第一个填写了为0,这样在延迟来到蜂鸣器不发出声音,然后就是解释标志位,放在频率表后0XFF,为结束标志为。
unsigned int code FreqTable[]={**0,**63628,63731,63835,63928,64021,64103,64185,64260,64331,64400,64463,64528,64580,64633,64684,64732,64777,64820,64860,64898,64934,64968,65000,65030,65058,65085,65110,65134,65157,65178,65198,65217,65235,65252,65268,65283,**==0xFF==**};
为0的话不进入中断,也就不发声音。
void Timer0_Routine() interrupt 1 //1毫秒跳转到这里,T=2ms,触发中断 500hz
{ if(FreqTable[FreqSelect]) {TL0 = FreqTable[FreqSelect]/256; //重新设置定时初值,根据表格算的值,计算出对应的TL0和TH0,只有我们可以设置不同的频率TH0 = FreqTable[FreqSelect]%256; //又因为总共有36个音高,是固定的只需要取数组里的值。TH0=X/256,TL0=X%256;Buzzer=!Buzzer;} }
在这里如何乐谱选择的不是解释标准才执行,音高和音长的选择。
while(1){if(Music[MusicSelect]!=0xFF){FreqSelect=Music[MusicSelect]; //频率MusicSelect++;Delay(SPEED/4*Music[MusicSelect]); //时长=基准值乘以音符的系数,如基准是16音符是1,4分音符的系数是4MusicSelect++; //取到了频率的索引值TR0=0; //每演奏一个音符,就把定时器关掉Delay(5); //抬手的时间,每个音符都分开TR0=1;}else{TR0=0; while(1);}}
这样就完成了对简谱的描述,为了方便,我们给索引号定义类有含义的字母符号便于编写。
#define SPEED 500
#define P 0
#define L1 1
#define L1_ 2
#define L2 3
#define L2_ 4
#define L3 5
#define L4 6
#define L4_ 7
#define L5 8
#define L5_ 9
#define L6 10
#define L6_ 11
#define L7 12#define M1 13
#define M1_ 14
#define M2 15
#define M2_ 16
#define M3 17
#define M4 18
#define M4_ 19
#define M5 20
#define M5_ 21
#define M6 22
#define M6_ 23
#define M7 24#define H1 25
#define H1_ 26
#define H2 27
#define H2_ 28
#define H3 29
#define H4 30
#define H4_ 31
#define H5 32
#define H5_ 33
#define H6 34
#define H6_ 35
#define H7 36
这样就可以看着简谱,把频率和音长的数据编写在Music的数组中。最后结束防止结束标志位。
else{TR0=0; while(1);}
如果结束则关闭定时。结束演唱。
二、蜂鸣器播放音乐代码
1.代码
1.1main.c
#include <REGX52.H>
#include <INTRINS.H>
#include "Delay.h"
#include "Key.h"
#include "Timer0.h"
#include "LCD1602.h"
#include "Init.h"
#include "Nixie.h"sbit Buzzer = P2^3; //蜂鸣器端口
#define SPEED 500
#define P 0
#define L1 1
#define L1_ 2
#define L2 3
#define L2_ 4
#define L3 5
#define L4 6
#define L4_ 7
#define L5 8
#define L5_ 9
#define L6 10
#define L6_ 11
#define L7 12#define M1 13
#define M1_ 14
#define M2 15
#define M2_ 16
#define M3 17
#define M4 18
#define M4_ 19
#define M5 20
#define M5_ 21
#define M6 22
#define M6_ 23
#define M7 24#define H1 25
#define H1_ 26
#define H2 27
#define H2_ 28
#define H3 29
#define H4 30
#define H4_ 31
#define H5 32
#define H5_ 33
#define H6 34
#define H6_ 35
#define H7 36unsigned int code FreqTable[]={0,63628,63731,63835,63928,64021,64103,64185,64260,64331,64400,64463,64528,64580,64633,64684,64732,64777,64820,64860,64898,64934,64968,65000,65030,65058,65085,65110,65134,65157,65178,65198,65217,65235,65252,65268,65283,0xFF};
unsigned char code Music[]={ //频率、时长
P,4,
P,4,
P,4,
M6,4,
M7,4,H1,4+2,
M7,4+4,
H1,4,
H3,4,M7,4+4+4,
M3,2,
M3,2, 0xFF
}; //乐谱的音高顺序
unsigned char FreqSelect,MusicSelect; //MusicSelect乐谱的音高的顺序void main()
{Timer0_Init(); //第一次中断无关紧要DianZhengGuan(); //关闭点阵while(1){if(Music[MusicSelect]!=0xFF){FreqSelect=Music[MusicSelect]; //频率MusicSelect++;Delay(SPEED/4*Music[MusicSelect]); //时长=基准值乘以音符的系数,如基准是16音符是1,4分音符的系数是4MusicSelect++; //取到了频率的索引值TR0=0; //每演奏一个音符,就把定时器关掉Delay(5); //抬手的时间,每个音符都分开TR0=1;}else{TR0=0; while(1);}}
}void Timer0_Routine() interrupt 1 //1毫秒跳转到这里,T=2ms,触发中断 500hz
{ if(FreqTable[FreqSelect]) {TL0 = FreqTable[FreqSelect]/256; //重新设置定时初值,根据表格算的值,计算出对应的TL0和TH0,只有我们可以设置不同的频率TH0 = FreqTable[FreqSelect]%256; //又因为总共有36个音高,是固定的只需要取数组里的值。TH0=X/256,TL0=X%256;Buzzer=!Buzzer;} }
1.2Timer 0
#include <REGX52.H>void Timer0_Init(void) //1毫秒@11.0592MHz
{// TMOD不能复制,如果同时使用定时器1和0,它会覆盖淹没,TMOD &= 0xF0; //设置定时器模式TMOD |= 0x01; //设置定时器模式TL0 = 0x66; //设置定时初值TH0 = 0xFC; //设置定时初值TF0 = 0; //清除TF0标志TR0 = 1; //定时器0开始计时ET0=1;EA=1;PT0=0;
}/*
void Timer0_Routine() interrupt 1 //1毫秒跳转到这里,触发中断
{static unsigned int T0Count; //Tcount为计数值 static只有本函数使用TL0 = 0x66; //重新设置定时初值TH0 = 0xFC; //重新设置定时初值T0Count++;if(T0Count>=1000){T0Count=0;P1_0=~P1_0;}}*/
#ifndef __TIMER0_H
#define __TIMER0_Hvoid Timer0_Init(void) ;#endif
1.3Delay.c
void Delay (unsigned int xms) //@12.000MHz
{unsigned char i, j;while(xms--)
{i = 12;j = 169;do{while (--j);} while (--i);}
}
#ifndef __DELAY_H__
#define __DELAY_H__
void Delay (unsigned int xms);#endif
成品展示
好运来 三段1,2两遍,3一遍
#include <REGX52.H>
#include "Delay.h"
#include "Timer0.h"
#include "LCD1602.h"
//蜂鸣器端口定义
sbit Buzzer=P2^3 ;//播放速度,值为四分音符的时长(ms)这个
#define SPEED 500//音符与索引对应表,P:休止符,L:低音,M:中音,H:高音,下划线:升半音符号#
#define P 0
#define L1 1
#define L1_ 2
#define L2 3
#define L2_ 4
#define L3 5
#define L4 6
#define L4_ 7
#define L5 8
#define L5_ 9
#define L6 10
#define L6_ 11
#define L7 12
#define M1 13
#define M1_ 14
#define M2 15
#define M2_ 16
#define M3 17
#define M4 18
#define M4_ 19
#define M5 20
#define M5_ 21
#define M6 22
#define M6_ 23
#define M7 24
#define H1 25
#define H1_ 26
#define H2 27
#define H2_ 28
#define H3 29
#define H4 30
#define H4_ 31
#define H5 32
#define H5_ 33
#define H6 34
#define H6_ 35
#define H7 36//索引与频率对照表
unsigned int FreqTable[]={0,63628,63731,63835,63928,64021,64103,64185,64260,64331,64400,64463,64528,64580,64633,64684,64732,64777,64820,64860,64898,64934,64968,65000,65030,65058,65085,65110,65134,65157,65178,65198,65217,65235,65252,65268,65283,
};//乐谱
unsigned char code Music[]={//音符,时值,//1AM6, 4,H3, 4,H2, 4,H1, 2,M6, 2,M5, 4,H1, 2,H2, 2,M6, 4+4,M6, 4,H2, 2,H3, 2,H2, 4,H1, 2,M6, 2,//2M2, 4,M5, 2,M6, 2,M3, 4+4,//3H1,2+1,H2,1,H3,2,H3,2,H3,2,H3,2,H2,2,H1,2,M5,4,H1,4,M6,4+4+16,//4BM6,2+1,M6,1,H1,2,H1,2,M6,4+2,M6,2,M5,2,M3,2,M5,2,H1,2,M6,8,M6,2,H1,2,H1,3,H1,1,M6,4,M5,4,//5M6, 2,M5, 2,M2, 2,M5, 2,M3, 6,M3, 2,M3,2,M2,2,M1,2,M3,2,M2,6,M3,2,M6,2,M5,2,M3,2,M6,2,M5,8,//6M6,2,H1,2,H1,3,M6,1,H2,2,H2,2,H2,2,H1,2,M6,4,M5,2,H1,2,M6,16,//1A2M6, 4,H3, 4,H2, 4,H1, 2,M6, 2,M5, 4,H1, 2,H2, 2,M6, 4+4,M6, 4,H2, 2,H3, 2,H2, 4,H1, 2,M6, 2,//2M2, 4,M5, 2,M6, 2,M3, 4+4,//3H1,2+1,H2,1,H3,2,H3,2,H3,2,H3,2,H2,2,H1,2,M5,4,H1,4,M6,4+4+16,//4B2M6,2+1,M6,1,H1,2,H1,2,M6,4+2,M6,2,M5,2,M3,2,M5,2,H1,2,M6,8,M6,2,H1,2,H1,3,H1,1,M6,4,M5,4,//5M6, 2,M5, 2,M2, 2,M5, 2,M3, 6,M3, 2,M3,2,M2,2,M1,2,M3,2,M2,6,M3,2,M6,2,M5,2,M3,2,M6,2,M5,8,//6M6,2,H1,2,H1,3,M6,1,H2,2,H2,2,H2,2,H1,2,M6,4,M5,2,H1,2,M6,16,//1AM6, 4,H3, 4,H2, 4,H1, 2,M6, 2,M5, 4,H1, 2,H2, 2,M6, 4+4,M6, 4,H2, 2,H3, 2,H2, 4,H1, 2,M6, 2,//2M2, 4,M5, 2,M6, 2,M3, 4+4,//3H1,2+1,H2,1,H3,2,H3,2,H3,2,H3,2,H2,2,H1,2,M5,4,H1,4,M6,4+4+16,//1AM6, 4,H3, 4,H2, 4,H1, 2,M6, 2,M5, 4,H1, 2,H2, 2,M6, 4+4,M6, 4,H2, 2,H3, 2,H2, 4,H1, 2,M6, 2,//2M2, 4,M5, 2,M6, 2,M3, 4+4,//3H1,2+1,H2,1,H3,2,H3,2,H3,2,H3,2,H2,2,H1,2,M5,4,H1,4,M6,4+4+16,//1AM6, 4,H3, 4,H2, 4,H1, 2,M6, 2,M5, 4,H1, 2,H2, 2,M6, 4+4,M6, 4,H2, 2,H3, 2,H2, 4,H1, 2,M6, 2,//2M2, 4,M5, 2,M6, 2,M3, 4+4,//3H1,2+1,H2,1,H3,2,H3,2,H3,2,H3,2,H2,2,H1,2,M5,4,H1,4,M6,4+4+16,//1AM6, 4,H3, 4,H2, 4,H1, 2,M6, 2,M5, 4,H1, 2,H2, 2,M6, 4+4,M6, 4,H2, 2,H3, 2,H2, 4,H1, 2,M6, 2,//2M2, 4,M5, 2,M6, 2,M3, 4+4,//3H1,2+1,H2,1,H3,2,H3,2,H3,2,H3,2,H2,2,H1,2,M5,4,H1,4,M6,4+4+16,//7CH2,16,H3,16,M6,32,P,4,M5,2,M5,2,M6,8,0xFF //终止标志
};unsigned char FreqSelect,MusicSelect;void main()
{Timer0Init();LCD_Init();LCD_ShowString(1,1,"START");LCD_ShowString(2,1,"HAPPY NEW YEAR");while(1){if(Music[MusicSelect]!=0xFF) //如果不是停止标志位{FreqSelect=Music[MusicSelect]; //选择音符对应的频率MusicSelect++;Delay(SPEED/4*Music[MusicSelect]); //选择音符对应的时值MusicSelect++;TR0=0;Delay(5); //音符间短暂停顿TR0=1;}else //如果是停止标志位{TR0=0;LCD_ShowString(1,1,"END");while(1);}}
}void Timer0_Routine() interrupt 1
{if(FreqTable[FreqSelect]) //如果不是休止符{/*取对应频率值的重装载值到定时器*/TL0 = FreqTable[FreqSelect]%256; //设置定时初值TH0 = FreqTable[FreqSelect]/256; //设置定时初值Buzzer=!Buzzer; //翻转蜂鸣器IO口}
}
实验现象:
蜂鸣器播放好运来
问题
整体的编写难度很大!
总结
本节课主要学了如何用蜂鸣器来演唱音乐,主要有音高和音长着两个要素,音高的频率对应着计数器的计数频率,也就是对应的计数周期,每个音高对应一个定时器重装载值,然后进行Music数组对音高和音长一组组的存入,最后放入结束标志位,停止位不进行定时器计时(不发出声音),抬手的动作用关闭定时器5ms来表示。这样我们根据简谱把歌曲的音高和音长写入到Music数组中,这样就能演奏出音乐了。
相关文章:
STC89C52单片机学习——第26节: [11-2]蜂鸣器播放音乐
写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难,但我还是想去做! 本文写于:2025.03.19 51单片机学习——第26节: [11-2]蜂鸣器播放音乐 前言开发板说明引用解答和科普一…...
ABC396题解
A 算法标签: 模拟 问题陈述 给你一个长度为 N N N 的整数序列: A ( A 1 , A 2 , … , A N ) A (A_1, A_2, \ldots, A_N) A(A1,A2,…,AN)。 请判断在 A A A 中是否有相同元素连续出现三次或三次以上的位置。 更正式地说,请判断是否存在一个整…...
如何用Python和Selenium实现表单的自动填充与提交?
在今天的数字化时代,自动化工具可以极大地提高工作效率。很多人可能会觉得填表单是个繁琐的任务,不过你知道吗?用Python和Selenium可以轻松解决这一问题!本文将带你走进如何利用这两个强大的工具,实现表单的自动填充和…...
使用`plot_heatmap`绘制热力图时
在Python中,使用plot_heatmap绘制热力图时,颜色图例(colorbar)的定制化设置是关键步骤。以下是实现方法及优化建议: 一、基础图例绘制 自动生成颜色条 使用seaborn.heatmap()时,默认会生成颜色条࿰…...
极简桌面待办清单软件,❌不会增加工作量
工作邮件、会议安排、生活琐事……事情多到根本记不住,又怕错过重要事项,焦虑感油然而生。相信这是很多职场朋友遇到的问题,也急需一款好用的极简桌面待办清单软件来辅助我们。 今天我要给大家推荐一款拯救我们于水火的神器——好用便签&…...
QT学习笔记4
一、音视频播放(Qt Multimedia) 1. 多媒体框架架构 核心类关系 : mermaid #mermaid-svg-mwHLYcpaJDU14uFM {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-mwHLYcpaJDU14uFM .e…...
软考 中级软件设计师 考点知识点笔记总结 day06
文章目录 6、树和二叉树6.1、树的基本概念6.2、二叉树的基本概念6.3、二叉树的遍历6.4、查找二叉树(二叉排序树)BST6.5、构造霍夫曼树6.6、线索二叉树6.7、 平衡二叉树 7、 图7.1 、 存储结构 - 邻接矩阵7.2 、 存储结构 - 邻接表7.3、图的遍历7.4、拓扑…...
爬虫基础之爬取猫眼Top100 可视化
网站: TOP100榜 - 猫眼电影 - 一网打尽好电影 本次案例所需用到的模块 requests (发送HTTP请求) pandas(数据处理和分析 保存数据) parsel(解析HTML数据) pyecharts(数据可视化图表) pymysql(连接和操作MySQL数据库) lxml(数据解析模块) 确定爬取的内容: 电影名称 电影主演…...
微信小程序面试内容整理-如何使用wx.request()进行网络请求
wx.request() 是微信小程序中用于发送网络请求的 API,类似于浏览器中的 fetch 或 XMLHttpRequest。通过 wx.request(),开发者可以向服务器发送 HTTP 请求,获取数据或者提交数据。 基本用法 wx.request() 通过提供一个配置对象来进行配置,配置对象中包括请求的 URL、请求方法…...
力扣100二刷——图论、回溯
第二次刷题不在idea写代码,而是直接在leetcode网站上写,“逼”自己掌握常用的函数。 标志掌握程度解释办法⭐Fully 完全掌握看到题目就有思路,编程也很流利⭐⭐Basically 基本掌握需要稍作思考,或者看到提示方法后能解答⭐⭐⭐Sl…...
该错误是由于`KuhnMunkres`类未定义`history`属性导致的
该错误是由于KuhnMunkres类未定义history属性导致的。以下是具体分析及解决方案: 错误原因分析 属性缺失 代码中试图访问km.history,但KuhnMunkres类未在初始化或算法执行过程中定义该属性,因此触发AttributeError。动画实现逻辑不完整 用户…...
DAPO:一个开源的大规模大型语言模型LLM强化学习系统
推断扩展赋予了大型语言模型前所未有的推理能力,强化学习作为激发复杂推理的核心技术,清华大学联合字节提出了解耦片段与动态采样策略优化(DAPO)算法,并全面开源了一个最先进的大规模强化学习系统,该系统使用Qwen2.5-32B基础模型在AIME 2024上取得了50分的高分。还开源了…...
数据结构中的引用管理对象体系
数据结构中的引用管理对象体系 (注:似复刻变量即实例对象) 引用管理对象的,有引用就能管理到它所指向的对象,我们拿引用最终的目的就是管理那些我们需要管理的最终直接对象,引用也是对象,同时…...
【自学笔记】智能合约基础知识点总览-持续更新
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 智能合约基础知识点总览目录1. 智能合约简介2. 以太坊与Solidity示例代码:Hello World智能合约 3. Solidity基础语法示例代码:简单的计数器合…...
Linux的Shell编程
一、什么是Shell 1、为什么要学习Shell Linux运维工程师在进行服务器集群管理时,需要编写Shell程序来进行服务器管理。 对于JavaEE和Python程序员来说,工作的需要。Boss会要求你编写一些Shell脚本进行程序或者是服务器的维护,比如编写一个…...
【八股文】volatile关键字的底层原理是什么
volatile只能保证可见性和有序性 volatile如何保证可见性 当对volatile变量进行写操作的时候,JVM会向处理器发送一条lock前缀的命令,将这个缓存中的变量会写到系统内存中。 所以,如果一个变量被volatile所修饰,每次数据变化之后…...
一种基于大规模语言模型LLM的数据分析洞察生成方法
从复杂数据库中提取洞察对数据驱动决策至关重要,但传统手动生成洞察的方式耗时耗力,现有自动化数据分析方法生成的洞察不如人工生成的有洞察力,且存在适用场景受限等问题。下文将介绍一种新的方法,通过生成高层次问题和子问题,并使用SQL查询和LLM总结生成多表数据库中的见…...
三大供应链管理模式——解决方案与实操案例详解
库存压到喘不过气,紧急订单却总赶不上交付?这是许多企业的真实困境——推式供应链盲目备货导致积压,拉式供应链又因响应慢而丢单。供应链管理,本质上是在“计划”与“变化”之间把握平衡。上篇文章,我们系统梳理了供应…...
【C++】STL库面试常问点
STL库 什么是STL库 C标准模板库(Standard Template Libiary)基于泛型编程(模板),实现常见的数据结构和算法,提升代码的复用性和效率。 STL库有哪些组件 STL库由以下组件构成: ● 容器…...
集成学习之随机森林
目录 一、集成学习的含义 二、集成学习的代表 三、集成学习的应用 1、分类问题集成。(基学习器是分类模型) 2、回归问题集成。(基学习器是回归模型) 3、特征选取集成。 四、Bagging之随机森林 1、随机森林是有多个决策树&a…...
【SpringBatch】03步骤对象 (Step)控制与执行流程设计
目录标题 六、步骤对象 Step6.1 步骤介绍6.2 简单Tasklet6.3 chunk居于块Tasklet**ChunkTasklet 泛型** 6.4 步骤监听器6.5 多步骤执行6.6 步骤控制6.6.1 条件分支控制-使用默认返回状态6.6.2 条件分支控制-使用自定义状态值 6.7 步骤状态6.8 流式步骤 六、步骤对象 Step 前面…...
走进Java:String字符串的基本使用
❀❀❀ 大佬求个关注吧~祝您开心每一天 ❀❀❀ 目录 一、什么是String 二、如何定义一个String 1. 用双引号定义 2. 通过构造函数定义 三、String中的一些常用方法 1 字符串比较 1.1 字符串使用 1.2 字符串使用equals() 1.3 使用 equalsIgnoreCase() 1.4 cpmpareTo…...
AI如何变革亚马逊广告投放?DeepBI的智能优化解析
在亚马逊平台上,广告投放的方式正经历着从人工精细化运营到AI自动化优化的深刻变革。传统的广告投放依赖人工操作,涉及海量数据分析、手动调价、竞价策略优化等环节,既耗时又易受人为因素影响。而AI驱动的智能投放系统,如DeepBI&a…...
小程序电子画册制作,用户体验为王!
家人们,现在小程序电子画册超火,不管是展示产品还是分享故事都超实用。但在小程序电子画册制作过程中,用户体验真的得好好考量!今天就和大家唠唠这其中的门道。 1、加载速度:快才是王道 打开小程序的瞬间,…...
【商城实战(49)】解锁小程序端适配与优化,让商城飞起来
【商城实战】专栏重磅来袭!这是一份专为开发者与电商从业者打造的超详细指南。从项目基础搭建,运用 uniapp、Element Plus、SpringBoot 搭建商城框架,到用户、商品、订单等核心模块开发,再到性能优化、安全加固、多端适配…...
英伟达GTC 2025大会产品全景剖析与未来路线深度洞察分析
【完整版】3月19日,黄仁勋Nvidia GTC 2025 主题演讲|英伟达 英伟达GTC 2025大会产品全景剖析与未来路线深度洞察分析 一、引言 1.1 分析内容 本研究主要采用了文献研究法、数据分析以及专家观点引用相结合的方法。在文献研究方面,广泛收集了…...
《TCP/IP网络编程》学习笔记 | Chapter 19:Windows 平台下线程的使用
《TCP/IP网络编程》学习笔记 | Chapter 19:Windows 平台下线程的使用 《TCP/IP网络编程》学习笔记 | Chapter 19:Windows 平台下线程的使用内核对象内核对象的定义内核对象归操作系统所有 基于 Windows 的线程创建进程与线程的关系Windows 中线程的创建方…...
线性规划的基本解、基本可行解和可行解
在线性规划中,基本解、基本可行解和可行解是非常重要的概念,特别是在使用单纯形法求解时。下面详细解释这些概念,并说明如何计算它们。 1. 线性规划问题的标准形式 线性规划的标准形式为: 其中: A 是 mn 的矩阵&…...
【AVRCP】服务发现互操作性:CT 与 TG 的 SDP 协议契约解析
目录 一、服务发现的核心目标:能力画像对齐 二、控制器(CT)服务记录:控制能力的声明 2.1 必选字段:角色与协议的刚性契约 2.1.1 服务类标识(Service Class ID List) 2.1.2 协议描述列表&am…...
[从零开始学习JAVA] Stream流
前言: 本文我们将学习Stream流,他就像流水线一样,可以对我们要处理的对象进行逐步处理,最终达到我们想要的效果,是JAVA中的一大好帮手,值得我们了解和掌握。(通常和lambda 匿名内部类 方法引用相…...
K8S学习之基础三十八:Kube-static-metrics监控
Kube-static-metrics监控 kube-static-metrics组件可以通过监听apiserver生成有关资源对象的状态指标,比如Node、Pod,需要注意的是kube-state-metrics只是简单的提供一个metrics数据,并不会存储这些指标数据,所以可以使用Prom…...
JAVA-多线程join()等待一个线程
引言:更多线程的认识可以看一篇博客: JAVA-Thread类实现多线程-CSDN博客 一、join()的作用 我们知道线程是随机调度执行的,但是有时候我们需要另一个任务完成了,我们才能继续,这个时候我们就可以使用join去等待线程结束…...
HashMap 常用方法
HashMap 常用方法 方法作用示例put(K key, V value)添加键值对map.put("apple", 10);get(Object key)获取指定键的值map.get("apple"); → 10remove(Object key)删除指定键的键值对map.remove("orange");containsKey(Object key)检查是否包含指…...
LogicFlow介绍
LogicFlow介绍 LogicFlow是一款流程图编辑框架,提供了一系列流程图交互、编辑所必需的功能和灵活的节点自定义、插件等拓展机制。LogicFlow支持前端自定义开发各种逻辑编排场景,如流程图、ER图、BPMN流程等。在工作审批流配置、机器人逻辑编排、无代码平…...
Docker搭建MySQL主从服务器
一、在主机上创建MySQL配置文件——my.cnf master服务器配置文件路径:/data/docker/containers/mysql-cluster-master/conf.d/my.cnf slave服务器配置文件路径: /data/docker/containers/mysql-cluster-master/conf.d/my.cnf master服务配置文件内容 …...
计算机二级web易错点(4)-选择题
选项 A:<input type"radio"> 用于创建单选按钮,同一组单选按钮中只能选择一个选项,所以该选项不符合要求。选项 B:HTML 中没有 type"check" 这种类型,是错误的写法,不能产生复选…...
3.19学习总结
学习了Java中的面向对象的知识点 完成一道算法题,找树左下角的值,错误的以为左下角只能是最底层的左节点,但指的是最底层最左边的节点...
Swagger-告别手写文档
文章目录 1. 引言2. Swagger是什么?3. SpringBoot2.7.3集成Swagger4. 常见注解 1. 引言 在RESTful API开发中,维护准确、易读的接口文档是团队协作的核心挑战,通常接口文档分为离线的和实时的。离线的接口文档工具有 YAPI等,其中…...
LeetCode-回文数
原题链接:9. 回文数 - 力扣(LeetCode) 首先我会想到的是,将这个数字转成字符串,然后通过前后指针判断是否相等,最终返回结果是否为回文数,时间复杂度:O(n),空间复杂度&am…...
数据结构之链表(双链表)
目录 一、双向带头循环链表 概念 二、哨兵位的头节点 优点: 头节点的初始化 三、带头双向链表的实现 1.双链表的销毁 2.双链表的打印 3.双链表的尾插和头插 尾插: 头插: 4.双链表的尾删和头删 尾删: 头删: …...
硬件基础(5):(2)二极管分类
文章目录 📌 二极管的分类与详细介绍1. **整流二极管(Rectifier Diode)**特点:选型依据:补充说明: 2. **快恢复二极管(Fast Recovery Diode)**特点:选型依据:…...
MQTT 和 Modbus 的优缺点对比
MQTT和Modbus协议是物联网(IoT)躲不开的两种协议,市面上覆盖了百分之98的产品。 MQTT由IBM在1999年发布。2014年,MQTT成为OASIS(结构化信息标准促进组织)的标准,后来被ISO/IEC 20922正式采纳&a…...
Android14 系统左右声音通道设置代码
Android14 系统左右声音通道设置代码 文章目录 Android14 系统左右声音通道设置代码一、前言二、系统级设置左右声音通道分析1、各方案设置左右声音通道的主要代码(1)3588 Android13 方案的实现(2)9679 Android14 方案的实现&…...
【Golang】go如何通过atomic原子操作来确保数据一致性
✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全…...
2025年汽车加气站操作工考试精选题库
汽车加气站操作工题库中题目及答案: 单项选择题 1、按压力容器的设计压力分为( )个压力等级。 A. 3 B. 4 C. 5 答案:B 2、缓冲罐的安装位置在天然气压缩机( )。 A. 前 B. 后 C. 中间 答案&#…...
LLVM学习--外部项目
不包含于核心LLVM和Clang存储库的项目需要单独下载。在本章中,我们将介绍各种其他官方LLVM项目,并介绍如何构建和安装它们。仅仅对核心LLVM工具感兴趣的读者可以跳过本章,或者在需要的时候翻阅。 在本章中,我们将介绍以下项目安装…...
AUTOSAR_DoIP_Detailed
AUTOSAR DoIP模块详解 基于AUTOSAR标准的诊断通信协议实现 目录 架构概述通信流程消息格式配置结构详细序列总结1. 架构概述 1.1 模块架构 DoIP模块是AUTOSAR基础软件中负责诊断通信的核心组件。它通过TCP/IP网络实现诊断工具与ECU之间的通信。主要功能包括: 基础功能 基于UD…...
C语言:(大数相加版)数字阶梯求和
题目: 给定a和n,计算aaaaaaa...a(n个a)的和。 输入 测试数据有多组,输入a,n(1<a<9,1<n<100)。 输出 对于每组输入,请输出结果。 分析: 1. 方式和规定:大数相加必然越界…...
Echarts 折线图
功能 每月记录值,当数据大于600画红线,小于300画蓝线,其他在中间值为黑线。鼠标移动上去后,现在数据值。 option {tooltip: {trigger: axis, // 触发类型:坐标轴触发show: true, // 显示提示框formatter: function …...
element-plus中Dropdown下拉菜单组件的使用
1、基本使用 复制下面的代码: <!-- 选择查询类型 --> <el-dropdown trigger"click"><span class"el-dropdown-link"><span style"width:60px;color:#404040">查询类型</span><el-icon class"e…...