【单片机】DS1302时钟/蜂鸣器

news2024/9/28 11:23:32


目录

一、DS1302时钟

1、DS1302时钟的介绍

2、DS1302时钟寄存器

3、DS1302时序图

4、BCD码

5、写一个时钟

6、写一个可调时钟

二、蜂鸣器

1、蜂鸣器的介绍​编辑

2、三极管放大驱动蜂鸣器

2.1NPN三极管工作原理(基极电流和发射电流均流向集电区)

2.2PNP三极管工作原理(发射电流分别流向基极和集电极)

3、集成电路驱动蜂鸣器

4、按下按键后蜂鸣器播发声

5、蜂鸣器利用定时器循环播放小星星


一、DS1302时钟

1、DS1302时钟的介绍

DS1302具有涓细电流充电能力的低功耗实时时钟芯片。掉电后能够切换为备用电池。

RTC:实时时钟,是一种集成电路,通常称为时钟芯片。

翻一下51单片机的配套原理图,可以发现DS1302模块的VCC1口引脚并没有连接电源,所以单片机掉电后,并没有备用电源为DS1302时钟供电。

2、DS1302时钟寄存器

第一张小图已经详细列寄存器对应的读写信息了,直接用就行。原理是图二的地址/命令字。

3、DS1302时序图

写入时序步骤

读出时序步骤

步骤1:将CE置为1并开启时钟;

步骤2:将命令字的最低位设置到IO口上;

步骤3:时钟给个上升沿,此时命令字的最低位就会被写入单片机;

步骤4:将时钟重置为0;

步骤5:重复2-4步骤,每次压入一个比特数据,直到命令字和写入字节全部写入

步骤6:将CE置为0并关闭时钟。

步骤1:将CE置为1并开启时钟;

步骤2:将命令字的最低位设置到IO口上;

步骤3:时钟给个上升沿,此时命令字的最低位就会被写入单片机;

步骤4:将时钟重置为0;

步骤5:重复2-4步骤,每次压入一个比特数据,直到命令字全部写入。命令字写入完毕后的第一个下降沿开始,每个下降沿读出数据

步骤6:将CE置为0并关闭时钟。

在写读/写函数时,要注意时钟上升沿向时钟写入数据,下降沿时钟数据读出至IO口,跳变有效。当时钟上升与下降时,均会发生数据的写/读,读写情况可以参照上图。总结:读模块要利用上升沿向时钟写入数据,再写下降沿,看图可知,这个下降沿并不影响IO口,处理得就很微妙。写模块也同理。

4、BCD码

调用写/读函数可以发现数字从9直接跳到了16。因为DS1302内部并不是以二进制存储数据,而是使用BCD码。

BCD码:用四个二进制数表示一个十进制数。所以9的BCD码是0000 1001,10的BCD码是0001 0000。但是解码读取到的并不是BCD码,而是16进制,所以会从9突变到16的现象。

BCD码转10进制:DEC=BCD/16*10+BCD%16;(两位BCD)

十进制转BCD码:BCD=DEC/10*16+DEC%10;(两位BCD)

5、写一个时钟

1、DS1302.h

#ifndef __DS1302_H__
#define __DS1302_H__
#include <REGX52.H>
sbit DS1302_SCLK =P3^6;
sbit DS1302_IO=P3^4;
sbit DS1302_CE=P3^5;
#define DS1302_SECOND 0x80
#define DS1302_MINUTE 0X82
#define DS1302_HOUR   0X84
#define DS1302_DATE   0X86//日
#define DS1302_MONTH  0X88
#define DS1302_DAY    0X8A//星期
#define DS1302_YEAR   0X8C
#define DS1302_WP     0X8E
extern unsigned char DS1302Time[];
unsigned char DS1302Name[];//外部声明变量必须加extern,数组函数可加可不加
void DS1302SetTime();//设置初始时间
void DS1302ReadTime();//不断更新时间
void DS1302_Init();//初始化
void DS1302WriteByte(unsigned char Command,unsigned char Data);//单字节写入时钟
unsigned char DS1302ReadByte(unsigned char Command);//单字节从时钟读出
#endif

2、DS1302.c

#include "DS1302.h"
#include "delay.h"
unsigned char DS1302Time[]={22,12,15,18,27,55,4};
unsigned char DS1302Name[]={
DS1302_YEAR,DS1302_MONTH,DS1302_DATE,DS1302_HOUR,DS1302_MINUTE,DS1302_SECOND,DS1302_DAY
};
//设置初始时间
void DS1302SetTime()
{
	unsigned char i=0;
	DS1302WriteByte(DS1302_WP,0X00);//关闭写保护位
	for(i=0;i<7;++i)
	{
		DS1302WriteByte(DS1302Name[i],DS1302Time[i]/10*16+DS1302Time[i]%10);
	}
	
	DS1302WriteByte(DS1302_WP,0X80);//开启写保护位
}
//不断更新时间
void DS1302ReadTime()
{
	unsigned char Tmp,i=0;
	for(i=0;i<7;++i)
	{
		Tmp=DS1302ReadByte(DS1302Name[i]);//读出来的是BCD码
		DS1302Time[i]=Tmp/16*10+Tmp%16;//更新数组
	}
}
void DS1302_Init()
{
	DS1302_CE=0;//因为P3^5引脚默认是高电平,先初始化成低电平
	DS1302_SCLK=0;//同上
	
}
//单字节写
void DS1302WriteByte(unsigned char Command,unsigned char Data)
{
	unsigned char i=0;
	DS1302_CE=1;
	//向时钟写入命令字
	for(;i<8;++i)
	{
		DS1302_IO=(Command>>i)&1;//取出命令字的最低位
		DS1302_SCLK=1;//此处完成时钟从低到高跳变,向时钟写入IO口数据
		//时钟置零,注意时钟从高到低是需要时间的,必要时可以加个延时(不同状态下的延时时间见产品手册)
		DS1302_SCLK=0;//同时此处完成高电平到低电平的跳变,IO口重新被赋值为刚才写入的数据
	}
	//上方for循环结束后时钟是低电平
	//向时钟继续写入Data
	for(i=0;i<8;++i)
	{
		DS1302_IO=(Data>>i)&1;//取出写入字节的最低位
		DS1302_SCLK=1;//低->高跳变,向时钟写入IO口数据
		DS1302_SCLK=0;//跳变
	}
	DS1302_CE=0;//关闭CE
}
//单字节读
unsigned char DS1302ReadByte(unsigned char Command)
{
	unsigned char i=0,Data=0;
	Command|=1;//读的最低位是1,传进来的是写的地址,需要与上1
	DS1302_CE=1;
	//IO口读入命令字
	for(;i<8;++i)
	{
		DS1302_IO=(Command>>i)&1;
		DS1302_SCLK=0;//为了出循环时钟是1,时钟先给0
		DS1302_SCLK=1;//低->高跳变,向时钟写入IO口数据。循环中先给0再给1,保证出循环后时钟是1,时钟是1,下一个0马上可以读出数据
	}
	//上方for循环结束后时钟是高电平
	//读出时钟里的数据
	for(i=0;i<8;++i)
	{
		DS1302_SCLK=1;
		DS1302_SCLK=0;//从高->低跳变,数据从时钟读出至IO口
		if(DS1302_IO==1)
		{
			Data|=(1<<i);
		}
	}
	DS1302_CE=0;
	DS1302_IO=0;//将IO口置0
	return Data;
}

3、main.c

#include "LCD1602.h"
#include "DS1302.h"
#include "delay.h"
void main()
{	
	LCD_Init();
	DS1302_Init();
	
	DS1302SetTime();
	while(1)
	{
		DS1302ReadTime();
		LCD_ShowNum(1,1,DS1302Time[0],2);
		LCD_ShowString(1,3,"-");
		LCD_ShowNum(1,4,DS1302Time[1],2);
		LCD_ShowString(1,6,"-");
		LCD_ShowNum(1,7,DS1302Time[2],2);
		LCD_ShowNum(2,1,DS1302Time[3],2);
		LCD_ShowString(2,3,":");
		LCD_ShowNum(2,4,DS1302Time[4],2);
		LCD_ShowString(2,6,":");
		LCD_ShowNum(2,7,DS1302Time[5],2);
	}
}

6、写一个可调时钟

1、DS1302.h

#ifndef __DS1302_H__
#define __DS1302_H__
#include <REGX52.H>
#include "Timer0.h"
#include "key.h" 
#include "LCD1602.h"
#include "delay.h"
sbit DS1302_SCLK =P3^6;
sbit DS1302_IO=P3^4;
sbit DS1302_CE=P3^5;
#define DS1302_SECOND 0x80
#define DS1302_MINUTE 0X82
#define DS1302_HOUR   0X84
#define DS1302_DATE   0X86//日
#define DS1302_MONTH  0X88
#define DS1302_DAY    0X8A//星期
#define DS1302_YEAR   0X8C
#define DS1302_WP     0X8E
extern unsigned char KeyNum,MODE,TimeSetSelect,TimeSetFlashFlag;
extern unsigned char DS1302Time[];
unsigned char DS1302Name[];//外部声明变量必须加extern,数组函数可加可不加
void DS1302SetTime();//设置初始时间
void DS1302ReadTime();//不断更新时间
void DS1302_Init();//初始化
void DS1302WriteByte(unsigned char Command,unsigned char Data);//单字节写入时钟
unsigned char DS1302ReadByte(unsigned char Command);//单字节从时钟读出
void TimeShow();//模式0,显示时间
void TimeSet();//模式1,修改时间
void LegalDate();//合法日期判断
#endif

2、DS1302.c 

#include "DS1302.h"
unsigned char KeyNum,MODE,TimeSetSelect,TimeSetFlashFlag;
unsigned char DS1302Time[]={22,12,15,18,27,55,4};
unsigned char DS1302Name[]={
DS1302_YEAR,DS1302_MONTH,DS1302_DATE,DS1302_HOUR,DS1302_MINUTE,DS1302_SECOND,DS1302_DAY
};

//设置初始时间
void DS1302SetTime()
{
	unsigned char i=0;
	DS1302WriteByte(DS1302_WP,0X00);//关闭写保护位
	for(i=0;i<7;++i)
	{
		DS1302WriteByte(DS1302Name[i],DS1302Time[i]/10*16+DS1302Time[i]%10);
	}
	
	DS1302WriteByte(DS1302_WP,0X80);//开启写保护位
}
//不断更新时间
void DS1302ReadTime()
{
	unsigned char Tmp,i=0;
	for(i=0;i<7;++i)
	{
		Tmp=DS1302ReadByte(DS1302Name[i]);//读出来的是BCD码
		DS1302Time[i]=Tmp/16*10+Tmp%16;//更新数组
	}
}
void DS1302_Init()
{
	DS1302_CE=0;//因为P3^5引脚默认是高电平,先初始化成低电平
	DS1302_SCLK=0;//同上
	
}
//单字节写
void DS1302WriteByte(unsigned char Command,unsigned char Data)
{
	unsigned char i=0;
	DS1302_CE=1;
	//向时钟写入命令字
	for(;i<8;++i)
	{
		DS1302_IO=(Command>>i)&1;//取出命令字的最低位
		DS1302_SCLK=1;//此处完成时钟从低到高跳变,向时钟写入IO口数据
		//时钟置零,注意时钟从高到低是需要时间的,必要时可以加个延时(不同状态下的延时时间见产品手册)
		DS1302_SCLK=0;//同时此处完成高电平到低电平的跳变,IO口重新被赋值为刚才写入的数据
	}
	//上方for循环结束后时钟是低电平
	//向时钟继续写入Data
	for(i=0;i<8;++i)
	{
		DS1302_IO=(Data>>i)&1;//取出写入字节的最低位
		DS1302_SCLK=1;//低->高跳变,向时钟写入IO口数据
		DS1302_SCLK=0;//跳变
	}
	DS1302_CE=0;//关闭CE
}
//单字节读
unsigned char DS1302ReadByte(unsigned char Command)
{
	unsigned char i=0,Data=0;
	Command|=1;//读的最低位是1,传进来的是写的地址,需要与上1
	DS1302_CE=1;
	//IO口读入命令字
	for(;i<8;++i)
	{
		DS1302_IO=(Command>>i)&1;
		DS1302_SCLK=0;//为了出循环时钟是1,时钟先给0
		DS1302_SCLK=1;//低->高跳变,向时钟写入IO口数据。循环中先给0再给1,保证出循环后时钟是1,时钟是1,下一个0马上可以读出数据
	}
	//上方for循环结束后时钟是高电平
	//读出时钟里的数据
	for(i=0;i<8;++i)
	{
		DS1302_SCLK=1;
		DS1302_SCLK=0;//从高->低跳变,数据从时钟读出至IO口
		if(DS1302_IO==1)
		{
			Data|=(1<<i);
		}
	}
	DS1302_CE=0;
	DS1302_IO=0;//将IO口置0
	return Data;
}

void TimeShow()
{
	DS1302ReadTime();
	LCD_ShowNum(1,1,DS1302Time[0],2);
	LCD_ShowString(1,3,"-");
	LCD_ShowNum(1,4,DS1302Time[1],2);
	LCD_ShowString(1,6,"-");
	LCD_ShowNum(1,7,DS1302Time[2],2);
	LCD_ShowNum(2,1,DS1302Time[3],2);
	LCD_ShowString(2,3,":");
	LCD_ShowNum(2,4,DS1302Time[4],2);
	LCD_ShowString(2,6,":");
	LCD_ShowNum(2,7,DS1302Time[5],2);
}
void TimeSet()
{
	if(KeyNum==2)
	{
		++TimeSetSelect;
		TimeSetSelect%=6;//如果TimeSetSelect大于等于5,对TimeSetSelect清零
	}
	if(KeyNum==3)
	{
		++DS1302Time[TimeSetSelect];
		if(DS1302Time[0]>99){DS1302Time[0]=0;}//年越界判断
		if(DS1302Time[1]>12){DS1302Time[1]=1;}//月越界判断
		if( DS1302Time[1]==1 || DS1302Time[1]==3 || DS1302Time[1]==5 || DS1302Time[1]==7 || 
			DS1302Time[1]==8 || DS1302Time[1]==10 || DS1302Time[1]==12)//日越界判断
		{
			if(DS1302Time[2]>31){DS1302Time[2]=1;}//大月
		}
		else if(DS1302Time[1]==4 || DS1302Time[1]==6 || DS1302Time[1]==9 || DS1302Time[1]==11)
		{
			if(DS1302Time[2]>30){DS1302Time[2]=1;}//小月
		}
		else if(DS1302Time[1]==2)
		{
			if(DS1302Time[0]%4==0)
			{
				if(DS1302Time[2]>29){DS1302Time[2]=1;}//闰年2月
			}
			else
			{
				if(DS1302Time[2]>28){DS1302Time[2]=1;}//平年2月
			}
		}
		if(DS1302Time[3]>23){DS1302Time[3]=0;}//时越界判断
		if(DS1302Time[4]>59){DS1302Time[4]=0;}//分越界判断
		if(DS1302Time[5]>59){DS1302Time[5]=0;}//秒越界判断
	}
	if(KeyNum==4)
	{
		--DS1302Time[TimeSetSelect];
		if(DS1302Time[0]<0){DS1302Time[0]=99;}//年越界判断
		if(DS1302Time[1]<1){DS1302Time[1]=12;}//月越界判断
		if( DS1302Time[1]==1 || DS1302Time[1]==3 || DS1302Time[1]==5 || DS1302Time[1]==7 || 
			DS1302Time[1]==8 || DS1302Time[1]==10 || DS1302Time[1]==12)//日越界判断
		{
			if(DS1302Time[2]<1){DS1302Time[2]=31;}//大月
			if(DS1302Time[2]>31){DS1302Time[2]=1;}
		}
		else if(DS1302Time[1]==4 || DS1302Time[1]==6 || DS1302Time[1]==9 || DS1302Time[1]==11)
		{
			if(DS1302Time[2]<1){DS1302Time[2]=30;}//小月
			if(DS1302Time[2]>30){DS1302Time[2]=1;}
		}
		else if(DS1302Time[1]==2)
		{
			if(DS1302Time[0]%4==0)
			{
				if(DS1302Time[2]<1){DS1302Time[2]=29;}//闰年2月
				if(DS1302Time[2]>29){DS1302Time[2]=1;}
			}
			else
			{
				if(DS1302Time[2]<1){DS1302Time[2]=28;}//平年2月
				if(DS1302Time[2]>28){DS1302Time[2]=1;}
			}
		}
		if(DS1302Time[3]<0){DS1302Time[3]=23;}//时越界判断
		if(DS1302Time[4]<0){DS1302Time[4]=59;}//分越界判断
		if(DS1302Time[5]<0){DS1302Time[5]=59;}//秒越界判断
	}
	//利用中断更新显示
	if(TimeSetSelect==0&&TimeSetFlashFlag==1){LCD_ShowString(1,1,"  ");}
	else{LCD_ShowNum(1,1,DS1302Time[0],2);}
	LCD_ShowString(1,3,"-");
	
	if(TimeSetSelect==1&&TimeSetFlashFlag==1){LCD_ShowString(1,4,"  ");}
	else{LCD_ShowNum(1,4,DS1302Time[1],2);}
	LCD_ShowString(1,6,"-");
	
	if(TimeSetSelect==2&&TimeSetFlashFlag==1){LCD_ShowString(1,7,"  ");}
	else{LCD_ShowNum(1,7,DS1302Time[2],2);}
	
	if(TimeSetSelect==3&&TimeSetFlashFlag==1){LCD_ShowString(2,1,"  ");}
	else{LCD_ShowNum(2,1,DS1302Time[3],2);}
	LCD_ShowString(2,3,":");
	
	if(TimeSetSelect==4&&TimeSetFlashFlag==1){LCD_ShowString(2,4,"  ");}
	else{LCD_ShowNum(2,4,DS1302Time[4],2);}
	LCD_ShowString(2,6,":");
	
	if(TimeSetSelect==5&&TimeSetFlashFlag==1){LCD_ShowString(2,7,"  ");}
	else{LCD_ShowNum(2,7,DS1302Time[5],2);}
	
	LCD_ShowNum(2,10,TimeSetSelect,2);
}

3、main.c

#include "DS1302.h"
void main()
{	
	LCD_Init();
	DS1302_Init();
	Timer0_Init();
	
	DS1302SetTime();
	while(1)
	{
		KeyNum=Key();
		if(KeyNum==1)
		{
			MODE=!MODE;//模式切换,这里要取非,不能取反,因为1的反是1111 1110,并不是0
			LCD_ShowNum(1,10,MODE,2);
			if(MODE==0)
			{
				DS1302SetTime();//将数组中的时间重新写入时钟
				LCD_ShowString(2,10,"  ");
			}	
		}
		switch(MODE)
		{
			case 0:
				TimeShow();
				break;
			case 1:
				TimeSet();
				break;
		}
	}
}
void Timer0_Routine() interrupt 1
{
	static unsigned int T0Count;//函数栈帧结束后保留T0Count
	TH0=64535/256;//每次进中断函数后,让这两个寄存器重新回到初值
	TL0=64535%256;
	T0Count++;//每中断一次T0Count++
	if(T0Count>=(500/(12/11)))//达到了定时0.5秒的作用(晶振11.0592)
	{
		T0Count=0;//重置为0
		TimeSetFlashFlag=!TimeSetFlashFlag;
	}
}

可调时钟修改某一位时间,通过定时器中断达到0.5秒闪烁功能。

二、蜂鸣器

1、蜂鸣器的介绍

蜂鸣器是一种将电信号转化为声音信号的器件。按驱动方式可以分为有源蜂鸣器和无源蜂鸣器。

有源蜂鸣器:内部自带振荡源,将正负极接上直流电压即可持续发音,频率固定。

无源蜂鸣器:内部不带振荡源,需要控制器提供振荡脉冲才可发声,调整振荡频率,可发出不同频率的声音。51系列单片机用的就是无源蜂鸣器,无源蜂鸣器仅限振荡发声,切忌长时间连续导通,防止线圈烧坏。

用蜂鸣器之前需要先知道这个蜂鸣器是有源还是无源的。

2、三极管放大驱动蜂鸣器

51单片机的蜂鸣器所需功率比LED大,不能直接用引脚驱动蜂鸣器。这和数码管的74HC245一样,需要驱动电路,引脚的电平将被当成一种控制信号而不是运行蜂鸣器的能量。

2.1NPN三极管工作原理(基极电流和发射电流均流向集电区)

NPN三级管导通要求:BE电压大于导通电压。(图上就是基极电压大于三极管的管压降即可导通)

基区做得很薄是为了能让发射区的电子更容易进入集电区,浓度很低是为了形成更小的基极电流,这样才能有更多的自由电子进入集电区。而发射区电子浓度高是为了确保有足够多的自由电子进入基区和集电区。

为什么右侧电路图中蜂鸣器接VCC端而不是接GND端?如果蜂鸣器接GND端,一旦蜂鸣器自身电阻过大,基区电压可能驱使不了蜂鸣器(基区电压小于(管压降+蜂鸣器压降),电路不通);但是蜂鸣器接VCC端,只要基区电压大于三级管的管压降,电路即可导通。

2.2PNP三极管工作原理(发射电流分别流向基极和集电极)

PNP三极管信号电流给低电平导通。

PNP三级管导通要求:EB电压大于导通电压。(VCC>基区电压+管压降即可导通)

所以蜂鸣器不接VCC端,如果接VCC端,蜂鸣器电阻一旦过大,三极管可能不导通。

3、集成电路驱动蜂鸣器

51系列单片机使用集成电路来驱动蜂鸣器。

4、按下按键后蜂鸣器播发声

1、Buzzer.h

#ifndef __BUZZER_H__
#define __BUZZER_H__
//调用这个函数,蜂鸣器就响多少秒
void Buzzer_Time(unsigned int ms);
#endif

2、Buzzer.c

#include "Buzzer.h"
#include <REGX52.H>
#include "delay.h"
#include <INTRINS.H>
sbit Buzzer=P2^5;
void Buzzer_Delay500us()		//@11.0592MHz
{
	unsigned char i;

	_nop_();
	i = 227;
	while (--i);
}

//调用这个函数,蜂鸣器就响多少秒
void Buzzer_Time(unsigned int ms)
{
	unsigned int i;
	for(i=0;i<ms*2;++i)
	{
		Buzzer=!Buzzer;
		Buzzer_Delay500us();//必须要有延时,保证高低电平维持0.5ms(几字波形)
	}	
}

3、main.c

#include <REGX52.H>
#include "key.h"
#include "Nixie.h"
#include "Buzzer.h"
#include "delay.h"
unsigned char KeyNum;
void main()
{
	Nixie(1,0);
	while(1)
	{
		KeyNum=Key();
		if(KeyNum!=0)
		{
			Buzzer_Time(100);//蜂鸣器发声100ms 	
			Nixie(1,KeyNum);
		}
	}
}

5、蜂鸣器利用定时器循环播放小星星

反转两次电平,为两个发声周期,对应一个完整周期,计一个数。部分音符对应的定时器重装值。

#include <REGX52.H>
#include "delay.h"
#include "Timer0.h"
#define SPEED 500
sbit Buzzer=P2^5;
unsigned char FreqSelect,MusicSelect;//频率下标/音色顺序
unsigned int FreqTable[]={
	0,
	63465,63577,63691,63792,63892,63981,64070,64152,64229,64303,64372,64442,
	64499,64557,64612,64664,64713,64759,64803,64844,64883,64919,64954,64987,
	65017,65047,65074,65100,65124,65148,65169,65190,65209,65228,65245,65261,
};
//假设16分音符为1
unsigned char Music[]={
13,4,
13,4,
20,4,
20,4,
22,4,
22,4,
20,4+4,
0,4,//停止符
18,4,
18,4,
17,4,
17,4,
15,4,
15,4,
13,4+4
};
void main()
{
	Timer0_Init();
	while(1)
	{
		if(MusicSelect>=sizeof(Music))//判断越界
		{
			MusicSelect=0;
		}
		FreqSelect=Music[MusicSelect++];
		delay_ms(SPEED/4*Music[MusicSelect++]);//根据音符的不同,进行不同的延时
		TR0=0;//让每一个音间隔开来,关闭定时器0
		delay_ms(5);
		TR0=1;
	}
}
void Timer0_Routine() interrupt 1
{

	TH0=FreqTable[FreqSelect]/256;//每次进中断函数后,让这两个寄存器重新回到初值
	TL0=FreqTable[FreqSelect]%256;
	//频率不为0时,蜂鸣器才振荡
	if(FreqTable[FreqSelect])
	{
		Buzzer=!Buzzer;
	}	
}

根据乐谱频率,设定定时器重装值,并对蜂鸣器电平进行改变,蜂鸣器就能根据指定的电平信号发出不同频率的声音。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/97019.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python图像识别实战(二):实现批量图像读取和像素转换(附源码和实现效果)

前面我介绍了可视化的一些方法以及机器学习在预测方面的应用&#xff0c;分为分类问题&#xff08;预测值是离散型&#xff09;和回归问题&#xff08;预测值是连续型&#xff09;&#xff08;具体见之前的文章&#xff09;。 从本期开始&#xff0c;我将做一个关于图像识别的…

Dubbo 3 Dubbo 快速入门 3.2 Dubbo 快速入门 3.2.3 服务消费者

Dubbo 【黑马程序员Dubbo快速入门&#xff0c;Java分布式框架dubbo教程】 3 Dubbo 快速入门 文章目录Dubbo3 Dubbo 快速入门3.2 Dubbo 快速入门3.2.3 服务消费者3.2 Dubbo 快速入门 3.2.3 服务消费者 OK&#xff0c;之前我们 已经完成了 服务提供 者的改造 现在来改造 服务…

智能电网中采用博弈论的方法(Python代码实现)

目录 1 概述 2 系统模型 2.1 单价模型 2.2 效用模型和 能源消费者&#xff08;EC&#xff09; 的目标 2.3 成本模型和 中央电站&#xff08;CPS&#xff09; 的目标 2.4 优化问题 3 优化的能源管理模型 4 模型的特性 4.1 均衡的存在 4.2 决策过程 5 算法 6 数值的…

vector详解(不定长数组)

目录 什么是vector vector的介绍 模板的声明方式 vector的基本操作 push_back insert erase 遍历vector 小明爱数列-练习题 思路 什么是vector vector的介绍 和我一样,我猜你们看到题目时心里都会产生一个疑问"什么是vector?(大佬除外)".vector其实是…

一起Talk Android吧(第四百四十四回:UI控件之DatePicker)

文章目录概念介绍使用方法内容总结各位看官们大家好&#xff0c;上一回中咱们说的例子是"UI控件之NumberPicker",这一回中说的例子是"UI控件之DatePicker"。闲话休提&#xff0c;言归正转&#xff0c;让我们一起Talk Android吧&#xff01; 概念介绍 看官…

CSS实现文字扫光特效

上大学的玩 ae 的时候&#xff0c;就曾遇到过这个特效。偶然在百度看到了类似特效&#xff0c;没想到竟然能用 css 实现&#xff0c;所以就研究了一下&#xff0c;文字扫光效果如下&#xff1a; 实现思路&#xff1a; 光效移动效果&#xff0c;可以通过 background-image 设置…

RCNN网络源码解读(Ⅲ) --- finetune训练过程

目录 0.回顾 1.finetune二分类代码解释&#xff08;finetune.py&#xff09; 1.1 load_data&#xff08;定义获取数据的方法&#xff09; 1.2 CustomFineTuneDataset类 1.3 custom_batch_sampler类&#xff08; custom_batch_sampler.py&#xff09; 1.4 训练train_mod…

JVM.......未完待续

一、了解 JVM JVM ( Java Virtual Machine )&#xff0c;又称之为 Java虚拟机。JVM 的运行与操作系统无关&#xff0c;能够实现跨平台&#xff0c;只要是安装了JVM的机器&#xff0c;都能运行Java程序&#xff0c;Java语言最重要的特点 "跨平台运行"&#xff0c;也…

关于应用形态数轴方法的一点展望

“既然目前物理化学关于物质世界的最高理论成果&#xff0c;即所谓由量子力学和统计力学组成的第一原理&#xff0c;只能求算物质无生命的性质&#xff0c;而药物设计关心的却是有生命的性质.那么是否第一原理对药物设计就无所作为呢&#xff1f;不是的.也就是说&#xff0c;尽…

设备资产管理系统有什么用?

在PC时代&#xff0c;电脑、打印设备的那个已经成为当代企业的必备资产&#xff0c;生产型企业还有生产设备等资产&#xff0c;企业规模越大资产就越多&#xff0c;就越难管理&#xff0c;因此设备资产管理系统成为诸多企业数字化管理的重要组成之一。设备管理系统的应用不仅能…

算法基础篇-10-动态规划

1. 简介 动态规划是一种算法思想&#xff1b; 动态规划递归式子问题 1.1 案例1&#xff1a; 斐波那契数列 斐波那契数列&#xff1a;FnFn-1Fn-2 代码演示&#xff1a; 使用递归和非递归的方法来求解斐波那契数列的第n项&#xff1b; 递归的方法&#xff1a; public static…

uniapp实战仿写网易云音乐(二)—视频页面(scroll-view组件实现横线滑动,mescroll-uni实现视频列表,向下滑动刷新当前页面)

文章目录前言顶部导航条的实现视频列表的展示部分CSS部分最后前言 接着上篇文章继续完成剩下的部分&#xff0c;本篇文章是完成第二个页面——视频页面的部分&#xff0c;视频还是没有做播放的效果&#xff0c;主要是做展示效果。下面附上两篇文章链接&#xff0c;没看过的同学…

【概率论】正态分布

前导知识&#xff1a; 概率密度函数&#xff08;密度函数&#xff09;&#xff1a;描述一个随机变量的在某个确定的取值点附近的可能性的函数。 随机变量的取值落在某个区域内的概率为概率密度函数在这个区域上的积分。 性质&#xff1a; f(x)>0 数学期望 又称均值&am…

vue组件

9.Vue组件 组件&#xff08;Component&#xff09;是 Vue.js 最强大的功能之一。 组件可以扩展 HTML 元素&#xff0c;封装可重用的代码。 组件系统让我们可以用独立可复用的小组件来构建大型应用&#xff0c;几乎任意类型的应用的界面都可以抽象为一个组件树&#xff1a; 9…

SpringBoot 自定义starter yaml提示失效问题

自定义starter yaml提示失效问题自定义starter yaml提示失效问题问题场景解决办法自定义starter yaml提示失效问题 问题场景 在自定义starter后&#xff0c;必不可少会有properties配置参数需要指定&#xff0c;而在有时又不知道为什么出现这个问题。官方 Configuration Meta…

玩以太坊链上项目的必备技能(OOP-抽象合约-Solidity之旅十)

抽象合约&#xff08;abstract contract&#xff09; 前文在讲合约继承的基类构造函数的参数时&#xff0c;有提到抽象合约&#xff0c;也就是说&#xff0c;如果派生合约未能给其继承的基合约指定构造函数参数时&#xff0c;那么&#xff0c;该派生合约必须声明为抽象合约&am…

ubuntu中安装tippecanoe并切片

概述 本文是一片”水文”&#xff0c;记录一下如何在ubuntu中用tippecanoe制作矢量切片。 实现操作 本示例中ubuntu是在VMware虚拟机中&#xff0c;安装的是18.04.6的版本&#xff0c;你可通过我兰的镜像下载&#xff0c;速度杠杠的。 1.安装git sudo apt install git2.cl…

探索SpringMVC-HandlerMapping之RequestMappingHandlerMapping

前言 上回我们知道HandlerMapping是用来寻找Handler的&#xff0c;并不与Handler的类型或者实现绑定&#xff0c;而是根据需要定义的。那么为什么要单独给RequestMapping实现一个HandlerMapping&#xff1f;这次咱们就来专门看看这个RequestMappingHandlerMapping。 RequestM…

Educational Codeforces Round 139 (Rated for Div. 2)(A~E)

A. Extremely Round 定义一个数中仅存在一位非0&#xff0c;它是extremely round&#xff0c;计算1~n中有几个满足条件的数。 思路&#xff1a;直接计算即可。 AC Code&#xff1a; #include <bits/stdc.h>typedef long long ll; const int N 1e5 5; int t, n;int c…

高手必备10大难题:Mysql如何实现RR级隔离时,不会幻读?

文章很长&#xff0c;而且持续更新&#xff0c;建议收藏起来&#xff0c;慢慢读&#xff01;疯狂创客圈总目录 博客园版 为您奉上珍贵的学习资源 &#xff1a; 免费赠送 :《尼恩Java面试宝典》 持续更新 史上最全 面试必备 2000页 面试必备 大厂必备 涨薪必备 免费赠送 经典…