【51单片机DS1302时钟芯片读取数码管显示打造小成本高品质】2022-12-23

news2024/11/24 1:42:00

缘由https://ask.csdn.net/questions/7867303

/*写回复缘由https://ask.csdn.net/questions/7867303*/
#include "reg52.h"
sbit RST=P3^5;//DS1302允许(读/写)当RST为高电平时,所有的数据传送被初始化,允许对DS1302进行操作。如果在传送过程中RST置为低电平,则会终止此次数据传送,I/O引脚变为高阻态。RST必须保持低电平。只有在SCLK为低电平时,才能将RST置为高电平。
sbit SCLK=P3^6;//DS1302的SCLK为时钟输入端。在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从低位即位0开始。同样,在紧跟8位的控制指令字后的下一个SCLK脉冲的下降沿读出DS1302的数据,读出数据时从低位0位到高位7。在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从低位即位0开始。同样,在紧跟8位的控制指令字后的下一个SCLK脉冲的下降沿读出DS1302的数据,读出数据时从低位0位到高位7。
sbit IO=P3^7;//DS1302数据传递(读/写)秒寄存器80H写81H读/分寄存器82H写83H读/时寄存器84H写85H读/天寄存器86H写87H读/月寄存器88H写89H读/周寄存器8AH写8BH读/年寄存器8CH写8DH读,存放的数据位为BCD码形式。
sbit L1=P2^2;
sbit L2=P2^3;
sbit L3=P2^4;
sbit beep=P2^5;
bit smk=0,bek=0;
unsigned char code ShuMaGuan[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00,0X80,64};//0~9隐.小数点-号
unsigned char Nbcd=0,Ybcd=0,Tbcd=0,Sbcd=0,Fbcd=0,Mbcd=0,Zbcd=0,SJ=0;//年月天时分秒周
void ShuMaXianShi(unsigned char s,unsigned char w,unsigned char d)
{
	unsigned char YanShi=0;
	P0=255;
		switch(w)
		{
			case 2:{L1=0;L2=L3=1;}break;//011
			case 3:{L2=0;L1=L3=1;}break;//101
			case 4:{L1=L2=0;L3=1;}break;//001
			case 5:{L1=L2=1;L3=0;}break;//110
			case 6:{L1=L3=0;L2=1;}break;//010
			case 7:{L1=1;L2=L3=0;}break;//100
			case 8:{L1=L2=L3=0;}break;//000
			case 1:{L1=L2=L3=1;}break;//111
			default:{L1=L2=L3=0;}break;
		}
		P0=ShuMaGuan[s]|ShuMaGuan[d];//d显示小数点11,10关闭
		while(++YanShi);
}
void XianShi()
{
		ShuMaXianShi(Sbcd/10,1,10);
		ShuMaXianShi(Sbcd%10,2,10);
		ShuMaXianShi(12,3,10);
		ShuMaXianShi(Fbcd/10,4,10);
		ShuMaXianShi(Fbcd%10,5,10);
		ShuMaXianShi(12,6,10);
		ShuMaXianShi(Mbcd/10,7,10);
		ShuMaXianShi(Mbcd%10,8,10);	
}
void XK_1302(unsigned char SD)
{
	unsigned char cs=8,zh=1;
	RST=SCLK=0;
	RST=1;
	xf:if(cs--)
	{
		IO=SD&0x01;//低位起16进制
		SCLK=1;//上升沿写数据
		SD>>=1;//右移
		SCLK=0;//为下次上升沿准备时钟
		goto xf;
	}//发送命令时不能RST=0表示结束
}
unsigned char Du_1302(unsigned char Dz)
{
	unsigned char cs=8,zh=1,sj=0;
	XK_1302(Dz);//读地址命令
	SJ=SCLK=0;
	xf:if(cs--)
	{
		SJ+=IO*zh;//位为BCD码形式
		SCLK=1;//为下次下降沿准备时钟
		zh*=2;//直接转化为10进制数据
		if(cs==4){sj=SJ;SJ=0;zh=1;}
		SCLK=0;//下降沿读数据
		goto xf;
	}
	RST=0;
	return SJ*10+sj;
}
void main()
{
	unsigned char hm=0;
	while(1)
	{
		Mbcd=Du_1302(0x81);
		Fbcd=Du_1302(0x83);
		Sbcd=Du_1302(0x85);
		if(bek&&(Fbcd==0&&Mbcd<9||Fbcd==30&&Mbcd<5))beep=~beep;else beep=0;
		if(hm!=Mbcd%10){hm=Mbcd%10;bek=!bek;}
		XianShi();
	}
}
/*止回复*/

 发送命令IO可以编程软件仿真可以看到,然读取数据IO无法看到,只有在仿真电路中才能用示波器看到IO的全部,暂时只写了读取秒钟在数码管显示。之上蜂鸣器周期约10MS之下蜂鸣器周期约40US。

//缘由https://ask.csdn.net/questions/7867303
#include "reg52.h"
sbit RST=P3^5;//DS1302允许(读/写)当RST为高电平时,所有的数据传送被初始化,允许对DS1302进行操作。如果在传送过程中RST置为低电平,则会终止此次数据传送,I/O引脚变为高阻态。RST必须保持低电平。只有在SCLK为低电平时,才能将RST置为高电平。
sbit SCLK=P3^6;//DS1302的SCLK为时钟输入端。在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从低位即位0开始。同样,在紧跟8位的控制指令字后的下一个SCLK脉冲的下降沿读出DS1302的数据,读出数据时从低位0位到高位7。在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从低位即位0开始。同样,在紧跟8位的控制指令字后的下一个SCLK脉冲的下降沿读出DS1302的数据,读出数据时从低位0位到高位7。
sbit IO=P3^7;//DS1302数据传递(读/写)秒寄存器80H写81H读/分寄存器82H写83H读/时寄存器84H写85H读/天寄存器86H写87H读/月寄存器88H写89H读/周寄存器8AH写8BH读/年寄存器8CH写8DH读,存放的数据位为BCD码形式。
sbit L1=P2^2;
sbit L2=P2^3;
sbit L3=P2^4;
sbit beep=P2^5;
bit smk=0,bek=0;
unsigned char code ShuMaGuan[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00,0X80,64};//0~9隐.小数点-号
unsigned char Nbcd=0,Ybcd=0,Tbcd=0,Sbcd=0,Fbcd=0,Mbcd=0,Zbcd=0,SJ=0;//年 月 天 时 分 秒 周 数据
void ShuMaXianShi(unsigned char s,unsigned char w,unsigned char d)
{
	P0=255;
	switch(w)
	{
		case 2:{L1=0;L2=L3=1;}break;//011
		case 3:{L2=0;L1=L3=1;}break;//101
		case 4:{L1=L2=0;L3=1;}break;//001
		case 5:{L1=L2=1;L3=0;}break;//110
		case 6:{L1=L3=0;L2=1;}break;//010
		case 7:{L1=1;L2=L3=0;}break;//100
		case 8:{L1=L2=L3=0;}break;//000
		case 1:{L1=L2=L3=1;}break;//111
		default:{L1=L2=L3=0;}break;
	}
	P0=ShuMaGuan[s]|ShuMaGuan[d];//d显示小数点11,10关闭
}
void XianShi(unsigned char w)
{
	switch(w)
	{
		case 0:ShuMaXianShi(Sbcd/10,1,10);break;
		case 1:ShuMaXianShi(Sbcd%10,2,10);break;
		case 2:ShuMaXianShi(12,3,10);break;
		case 3:ShuMaXianShi(Fbcd/10,4,10);break;
		case 4:ShuMaXianShi(Fbcd%10,5,10);break;
		case 5:ShuMaXianShi(12,6,10);break;
		case 6:ShuMaXianShi(Mbcd/10,7,10);break;
		case 7:ShuMaXianShi(Mbcd%10,8,10);break;
		default:break;
	}
}
void XK_1302(unsigned char SD)
{
	unsigned char cs=8,zh=1;
	RST=SCLK=0;
	RST=1;
	xf:if(cs--)
	{
		IO=SD&0x01;//低位起16进制
		SCLK=1;//上升沿写数据
		SD>>=1;//右移
		SCLK=0;//为下次上升沿准备时钟
		goto xf;
	}//发送命令时不能RST=0表示结束
}
unsigned char Du_1302(unsigned char Dz)
{
	unsigned char cs=8,zh=1,sj=0;
	XK_1302(Dz);//读地址命令
	SJ=SCLK=0;
	xf:if(cs--)
	{
		SJ+=IO*zh;//位为BCD码形式
		SCLK=1;//为下次下降沿准备时钟
		zh*=2;//直接转化为10进制数据
		if(cs==4){sj=SJ;SJ=0;zh=1;}
		SCLK=0;//下降沿读数据
		goto xf;
	}
	RST=0;
	return SJ*10+sj;
}
void main()
{
	unsigned char hm=0,smys=0,w=0,m=0;
	Mbcd=Du_1302(0x81);Fbcd=Du_1302(0x83);Sbcd=Du_1302(0x85);
	while(1)
	{
		if(++smys>174)
		{
			XianShi(w);
			if(++w>7)
			{
				w=0;
				Mbcd=Du_1302(0x81);
				if(Mbcd==0)Fbcd=Du_1302(0x83);
				if(Mbcd==0&&Fbcd==0)Sbcd=Du_1302(0x85);
			}
			smys=0;
		}
		if(++m>9)
        {
            if(bek&&(Fbcd==0&&Mbcd<9||Fbcd==30&&Mbcd<5))beep=~beep;
            else beep=0;
            m=0;
        }
		if(hm!=Mbcd%10){hm=Mbcd%10;bek=!bek;}
	}
}

可以这样说,以贴出来的电路和只读取1302的时分秒送8位数码管显示,并有整点4响半点2响为功能,并在主函数while(1)内用beep=!beep;仿真测试整个代码响应时间为目标,且不得使用循环语句包括GOTO在内构成的独占循环计数延时,也不开定时器的,即这次把数码管显示中的while计数延时也去掉了,从而提高了程序整体响应时间含动态最小响应时间,从之前的10ms提高到了约40us,这就意味着整个程序还有充足的时间去响应其它更多事件安排。各位高手可以尽情展现优秀算法,尽量使得beep的周期最小,我目前能做到beep的周期不到40us,既然“大家”们说得那么有把握,我很想开开眼界,相信有很多人也期待着。
通过我提供的测试图片一看就知道单片机的时间都到哪去了,也就知道优化该从何处下手了,我之所以说我的程序还能进一步优化,指的是读取芯片的频次可以进一步减少而不会明显影响显示精度,按目前图片的时间约50毫秒的频次显然有很多次去读取是不必要的,因此是可以继续优化的,至于多少次或说多少时间去读取一次合理,就值得探讨了,各位高手不妨畅言高论。
之前代码是秒分时频繁都去读取,其实没必要,因此修改后的代码就是按条件限制的读取秒分时天月年信息。在不开定时器情况下也可以比较精准控制只读一次秒信息精度控制在毫秒以下,因为上述说过了的6毫秒和40毫秒周期,因此可以比较精准控制去读秒信息一次足够,而不需要无谓的多次读取,同样道理读天月年也可以按条件读取,只是不开定时器情况下按我的思路是实现所有功能代码后再进行比较精准的控制读秒信息,因为不同功能的程序周期也不同,就比如6毫秒和40毫秒周期一般道理。

void main()
{
	unsigned char hm=0,smys=0,w=0,ys=0,m=0;
	Mbcd=Du_1302(0x81);Fbcd=Du_1302(0x83);Sbcd=Du_1302(0x85);
	while(1)
	{
		if(++smys>147)
		{
			XianShi(w);
			if(++w>7)
			{
				w=0;//之下调整秒读时间
				if(++m>4){Mbcd=Du_1302(0x81);
				if(Mbcd==0){Fbcd=Du_1302(0x83);
				if(Fbcd==0)Sbcd=Du_1302(0x85);}m=0;}
			}
			smys=0;
		}
		if(++ys>10){if(bek&&(Fbcd==0&&Mbcd<9||Fbcd==30&&Mbcd<5))beep=~beep;else beep=0;ys=0;}
		if(hm!=Mbcd%10){hm=Mbcd%10;bek=!bek;}
	}
}

我家一台旭日红外热水器无线控制器每周都快1小时多,比如时间是6点看它屏幕走时已经是7点多了,每次都要去调整时间,否则计算峰谷的时间就不准确了!非常麻烦,是很差劲的产品质量,可以断定是很差劲的程序代码,所以莫要小看简单的程序提高效率问题,所谓见微知著,简单的功能都不能注重效率的话,可知复杂功能是很有问题的。经过几次试验目前把读秒信号压缩到每秒4次左右基本察觉不到太大差别可以接受的程度,调整后蜂鸣器音调频率也发生变化能听出区别来。

void XianShi(unsigned char w,unsigned char x)
{
	switch(w)
	{
		case 0:ShuMaXianShi((x?Nbcd:Sbcd)/10,1,10);break;
		case 1:ShuMaXianShi((x?Nbcd:Sbcd)%10,2,10);break;
		case 2:ShuMaXianShi(12,3,10);break;
		case 3:ShuMaXianShi((x?Ybcd:Fbcd)/10,4,10);break;
		case 4:ShuMaXianShi((x?Ybcd:Fbcd)%10,5,10);break;
		case 5:ShuMaXianShi(12,6,10);break;
		case 6:ShuMaXianShi((x?Tbcd:Mbcd)/10,7,10);break;
		case 7:ShuMaXianShi((x?Tbcd:Mbcd)%10,8,10);break;
		default:break;
	}
}
void main()
{
	unsigned char hm=0,smys=0,w=0,m=0,dm=0;bit x=0;
	Mbcd=Du_1302(0x81);Fbcd=Du_1302(0x83);Sbcd=Du_1302(0x85);
	Nbcd=Du_1302(0x8D);Ybcd=Du_1302(0x89);Tbcd=Du_1302(0x87);
	while(1)
	{
		if(++smys>174)//数码管延时
		{
			XianShi(w,x);
			if(++w>7)//数码管位循环+读时钟延时
			{
				w=0;
				if(++dm>4){Mbcd=Du_1302(0x81);//第三级读秒延时
				if(Mbcd==0){Fbcd=Du_1302(0x83);
				if(Fbcd==0){Sbcd=Du_1302(0x85);
				if(Sbcd==0){Tbcd=Du_1302(0x87);
				if(Tbcd==1){Ybcd=Du_1302(0x89);
				if(Ybcd==1)Nbcd=Du_1302(0x8D);}}}}
				dm=0;}
			}
			smys=0;
		}
		if(++m>9)//蜂鸣器频率控制
		{
			if(Fbcd==0&&Mbcd<9||Fbcd==30&&Mbcd<5||(Fbcd==15||Fbcd==45)&&Mbcd<2)
			{x=1;if(bek)beep=~beep;} else x=beep=0;
			m=0;//每15分钟1响30分钟2响整点4响并报时期间显示日期
		}
		if(hm!=Mbcd%10){hm=Mbcd%10;bek=!bek;}//状态秒反转
	}
}
再优化
void main()
{
	unsigned char hm=0,smys=0,w=0,m=0,dm=0;bit x=0;
	Mbcd=Du_1302(0x81);Fbcd=Du_1302(0x83);Sbcd=Du_1302(0x85);
	Nbcd=Du_1302(0x8D);Ybcd=Du_1302(0x89);Tbcd=Du_1302(0x87);
	while(1)
	{
		if(++smys>174)//数码管延时
		{
			XianShi(w,x);
			if(++w>7)//数码管位循环+读时钟延时
			{
				w=0;
				if(++dm>7){Mbcd=Du_1302(0x81);//第三级读秒延时
				if(Mbcd==0){Fbcd=Du_1302(0x83);
				if(Fbcd==0){Sbcd=Du_1302(0x85);
				if(Sbcd==0){Tbcd=Du_1302(0x87);
				if(Tbcd==1){Ybcd=Du_1302(0x89);
				if(Ybcd==1)Nbcd=Du_1302(0x8D);}}}}
				if(hm!=Mbcd%10){hm=Mbcd%10;bek=!bek;}//状态秒反转
				dm=0;}
			}
			smys=0;
		}
		if(++m>14)//蜂鸣器频率控制
		{
			if(Fbcd==0&&Mbcd<9||Fbcd==30&&Mbcd<5||(Fbcd==15||Fbcd==45)&&Mbcd<2)
			{x=1;if(bek)beep=~beep;} else x=beep=0;
			m=0;//每15分钟1响30分钟2响整点4响并报时期间显示日期
		}
	}
}

那就抛砖引玉看看我主函数实现的询问式延时和安排的功能,蜂鸣器频率还在可控范围;如果程序复杂到无法再控制蜂鸣器频率满足要求的情况时才考虑蜂鸣器用其他办法产生频率或使用有源蜂鸣器;整体代码是不开定时器和使用独占计数延时的,除了发送命令和读取的8+8独占循环。还可以再优化到颠覆常规思维,依据的就是仿真观察取反周期来决定和调节;从优化后的代码对比可以看到延时值也发生了变化可调范围增大。

void main()
{
	unsigned char hm=0,smys=0,w=0,m=0,dm=0;bit x=0;
	Mbcd=Du_1302(0x81);Fbcd=Du_1302(0x83);Sbcd=Du_1302(0x85);
	Nbcd=Du_1302(0x8D);Ybcd=Du_1302(0x89);Tbcd=Du_1302(0x87);
	while(1)
	{
		if(++m>25)//蜂鸣器频率控制
		{
			if(Fbcd==0&&Mbcd<8||Fbcd==30&&Mbcd<4||(Fbcd==15||Fbcd==45)&&Mbcd<2)
			{x=1;if(bek)beep=~beep;} else x=beep=0;
			m=0;//每15分钟1响30分钟2响整点4响并报时期间显示日期
			if(++smys>12)//数码管延时
			{
				XianShi(w,x);
				if(++w>7)//数码管位循环+读时钟延时
				{
					w=0;
					if(++dm>7){Mbcd=Du_1302(0x81);//第三级读秒延时
					if(Mbcd==0){Fbcd=Du_1302(0x83);
					if(Fbcd==0){Sbcd=Du_1302(0x85);
					if(Sbcd==0){Tbcd=Du_1302(0x87);
					if(Tbcd==1){Ybcd=Du_1302(0x89);
					if(Ybcd==1)Nbcd=Du_1302(0x8D);}}}}
					if(hm!=Mbcd%10){hm=Mbcd%10;bek=!bek;}//状态秒反转
					dm=0;}
				}
				smys=0;
			}
		}
	}
}

从优化后的代码可以看到实现了4级询问式延时,延时值也发生了变化可调范围继续增大,4级延时内各级都有可调范围,可安排其他功能;按键可以安排在延时内也可以安排在延时外。

void main()
{
	unsigned char hm=0,smys=0,w=0,m=0,dm=0;bit x=0;
	Mbcd=Du_1302(0x81);Fbcd=Du_1302(0x83);Sbcd=Du_1302(0x85);
	Nbcd=Du_1302(0x8D);Ybcd=Du_1302(0x89);Tbcd=Du_1302(0x87);
	while(1)
	{
		if(++m>47)//蜂鸣器频率控制
		{
			if(x&&bek)beep=~beep;
			m=0;//每15分钟1响30分钟2响整点4响并报时期间显示日期
			if(++smys>12)//数码管延时
			{
				XianShi(w,x);smys=0;
				if(++w>7)//数码管位循环+读时钟延时
				{
					w=0;
					if(++dm>4){Mbcd=Du_1302(0x81);//第四级读秒延时
					if(Mbcd==0){Fbcd=Du_1302(0x83);
					if(Fbcd==0){Sbcd=Du_1302(0x85);
					if(Sbcd==0){Tbcd=Du_1302(0x87);
					if(Tbcd==1){Ybcd=Du_1302(0x89);
					if(Ybcd==1)Nbcd=Du_1302(0x8D);}}}}
					if(hm!=Mbcd%10){hm=Mbcd%10;bek=!bek;}//状态秒反转
					if(Fbcd==0&&Mbcd<8||Fbcd==30&&Mbcd<4||(Fbcd==15||Fbcd==45)&&Mbcd<2)
						x=1; else x=beep=0;
					dm=0;}
				}}}}
}

最后优化到十几微妙周期,经过以上数次优化,可以看出单片机时间都跑哪去了,以及如何下手优化。

#include "reg52.h"
sbit RST=P2^5;//DS1302允许(读/写)当RST为高电平时,所有的数据传送被初始化,允许对DS1302进行操作。如果在传送过程中RST置为低电平,则会终止此次数据传送,I/O引脚变为高阻态。RST必须保持低电平。只有在SCLK为低电平时,才能将RST置为高电平。
sbit SCLK=P2^6;//DS1302的SCLK为时钟输入端。在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从低位即位0开始。同样,在紧跟8位的控制指令字后的下一个SCLK脉冲的下降沿读出DS1302的数据,读出数据时从低位0位到高位7。在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从低位即位0开始。同样,在紧跟8位的控制指令字后的下一个SCLK脉冲的下降沿读出DS1302的数据,读出数据时从低位0位到高位7。
sbit IO=P2^7;//DS1302数据传递(读/写)秒寄存器80H写81H读/分寄存器82H写83H读/时寄存器84H写85H读/天寄存器86H写87H读/月寄存器88H写89H读/周寄存器8AH写8BH读/年寄存器8CH写8DH读,存放的数据位为BCD码形式,8EH+0x00/0x80取消/恢复写保护。
sbit L1=P2^2;
sbit L2=P2^3;
sbit L3=P2^4;
sbit beep=P2^1;
sbit k1=P3^0;
bit smk=0,bek=0;
unsigned char code ShuMaGuan[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00,0X80,64};//0~9隐.小数点-号
unsigned char Nbcd=0,Ybcd=0,Tbcd=0,Sbcd=0,Fbcd=0,Mbcd=0,Zbcd=0,SJ=0;//年 月 天 时 分 秒 周 数据
void ShuMaXianShi(unsigned char s,unsigned char w,unsigned char d)
{
	P0=255;
	switch(w)
	{
		case 2:{L1=0;L2=L3=1;}break;//011
		case 3:{L2=0;L1=L3=1;}break;//101
		case 4:{L1=L2=0;L3=1;}break;//001
		case 5:{L1=L2=1;L3=0;}break;//110
		case 6:{L1=L3=0;L2=1;}break;//010
		case 7:{L1=1;L2=L3=0;}break;//100
		case 8:{L1=L2=L3=0;}break;//000
		case 1:{L1=L2=L3=1;}break;//111
		default:P0=255;break;
	}
	P1=ShuMaGuan[s]|ShuMaGuan[d];//d显示小数点11,10关闭
}
void XianShi(unsigned char w,unsigned char x)
{
	switch(w)
	{
		case 0:ShuMaXianShi((x?Nbcd:Sbcd)/10,1,10);break;
		case 1:ShuMaXianShi((x?Nbcd:Sbcd)%10,2,(x?11:10));break;
		case 2:ShuMaXianShi((x?Ybcd/10:10),3,10);break;
		case 3:ShuMaXianShi((x?Ybcd%10:Fbcd/10),4,(x?11:10));break;
		case 4:ShuMaXianShi((x?Tbcd/10:Fbcd%10),5,10);break;
		case 5:ShuMaXianShi((x?Tbcd%10:10),6,(x?11:10));break;
		case 6:ShuMaXianShi((x?10:Mbcd/10),7,10);break;
		case 7:ShuMaXianShi((x?Zbcd?Zbcd:8:Mbcd%10),8,10);break;
		default:P0=255;break;
	}
}
void XK_1302(unsigned char SD, bit k)
{
	unsigned char cs=8,zh=1;
	if(k){RST=SCLK=0;RST=1;}
	xf:if(cs--)
	{
		IO=SD&0x01;//低位起16进制
		SCLK=1;//上升沿写数据
		SD>>=1;//右移
		SCLK=0;//为下次上升沿准备时钟
		goto xf;
	}//发送命令时不能RST=0表示结束
	if(!k){SCLK=1;RST=0;}
}
unsigned char Du_1302(unsigned char Dz)
{
	unsigned char cs=8,zh=1,sj=0;
	XK_1302(Dz,1);//读地址命令
	SJ=SCLK=0;
	xf:if(cs--)
	{
		SJ+=IO*zh;//位为BCD码形式
		SCLK=1;//为下次下降沿准备时钟
		zh*=2;//直接转化为10进制数据
		//if(cs==4){sj=SJ;SJ=0;zh=1;}
		SCLK=0;//下降沿读数据
		goto xf;
	}
	RST=0;
	return SJ/16*10+SJ%16;//SJ*10+sj;
}
void Xie_1302(unsigned char Dz,unsigned char Sj)
{
	XK_1302(0x8e,1);XK_1302(0x00,0);//取消写保护
	XK_1302(Dz,1);XK_1302(Sj,0);//写入数据
	XK_1302(0x8e,1);XK_1302(0x80,0);
}
void main()
{
	unsigned char hm=0,smys=0,w=0,m=0,dm=0,xd=0;bit x=0;
	Mbcd=Du_1302(0x81);Fbcd=Du_1302(0x83);Sbcd=Du_1302(0x85);
	Nbcd=Du_1302(0x8D);Ybcd=Du_1302(0x89);Tbcd=Du_1302(0x87);Zbcd=Du_1302(0x8B)-1;
	while(1)
	{
		if(++m>47)//蜂鸣器频率控制
		{
			if(x&&bek)beep=~beep;
			m=0;//每15分钟1响30分钟2响整点4响并报时期间显示日期
			if(++smys>10)//数码管延时
			{
				XianShi(w,x);smys=0;if(!k1||!k2)bek=1;
				if(++w>7)//数码管位循环+读时钟延时
				{
					w=0;
					if(++dm>7){Mbcd=Du_1302(0x81);//第四级读秒延时
					if(Mbcd==0){Fbcd=Du_1302(0x83);
					if(Fbcd==0){Sbcd=Du_1302(0x85);
					if(Sbcd==0){Tbcd=Du_1302(0x87);Zbcd=Du_1302(0x8B)-1;
					if(Tbcd==1){Ybcd=Du_1302(0x89);
					if(Ybcd==1)Nbcd=Du_1302(0x8D);}}}}
					if(k1&&k2&&hm!=Mbcd%10){hm=Mbcd%10;bek=!bek;}//状态秒反转
					if(Fbcd==0&&Mbcd<8||Fbcd==30&&Mbcd<4||(Fbcd==15||Fbcd==45)&&Mbcd<2)
						x=1; else x=beep=0;
					if(!k1&&!k2&&bek)Xie_1302(0x80,0);//直接十进制转十六进制写信息每秒分钟步进
					if(k1==0&&bek)
					{
						if(++Fbcd<60)Xie_1302(0x82,Fbcd/10*16+Fbcd%10);
						else {Fbcd=0;
						if(++Sbcd<24)Xie_1302(0x84,Sbcd/10*16+Sbcd%10);else Sbcd=0;}
					bek=!bek;}
					if(k2==0&&bek)
					{if(Fbcd>0)--Fbcd;else {Fbcd=59;
					if(Sbcd>0){--Sbcd;Xie_1302(0x84,Sbcd/10*16+Sbcd%10);}else Sbcd=23;}
						Xie_1302(0x82,Fbcd/10*16+Fbcd%10);
					bek=!bek;}
					dm=0;}
				}}}
	}
}

中断+计数的1毫秒间隔或200微妙能做多少事还真的没什么案例,本案例旨在说明询问式计数延时相比独占计数延时的优越且灵活调节和设置,属于高级分析思维模式,而非入门级别独占计数延时一直套用引发种种疑难。

#include "reg52.h"
sbit RST=P3^5;//DS1302允许(读/写)当RST为高电平时,所有的数据传送被初始化,允许对DS1302进行操作。如果在传送过程中RST置为低电平,则会终止此次数据传送,I/O引脚变为高阻态。RST必须保持低电平。只有在SCLK为低电平时,才能将RST置为高电平。
sbit SCLK=P3^6;//DS1302的SCLK为时钟输入端。在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从低位即位0开始。同样,在紧跟8位的控制指令字后的下一个SCLK脉冲的下降沿读出DS1302的数据,读出数据时从低位0位到高位7。在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从低位即位0开始。同样,在紧跟8位的控制指令字后的下一个SCLK脉冲的下降沿读出DS1302的数据,读出数据时从低位0位到高位7。
sbit IO=P3^7;//DS1302数据传递(读/写)秒寄存器80H写81H读/分寄存器82H写83H读/时寄存器84H写85H读/天寄存器86H写87H读/月寄存器88H写89H读/周寄存器8AH写8BH读/年寄存器8CH写8DH读,存放的数据位为BCD码形式。
sbit L1=P2^2;
sbit L2=P2^3;
sbit L3=P2^4;
sbit beep=P2^5;
sbit k1=P3^0;
sbit k2=P3^1;
bit smk=0,bek=1,x=0;
unsigned char code ShuMaGuan[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00,0X80,64};//0~9隐.小数点-号
unsigned char code ZhouShuMa[]={121,79,64,64,9,9,73,73,63,63,79,77,81,69};//用数码管显示每周的值:一二三四五六日。
unsigned char Nbcd=0,Ybcd=0,Tbcd=0,Sbcd=0,Fbcd=0,Mbcd=0,Zbcd=0,SJ=0;//年 月 天 时 分 秒 周 数据
void ShuMaXianShi(unsigned char s,unsigned char w,unsigned char d)
{
	P0=L1=L2=L3=0;
	switch(w)
	{
		case 2:{L1=0;L2=L3=1;}break;//011
		case 3:{L2=0;L1=L3=1;}break;//101
		case 4:{L1=L2=0;L3=1;}break;//001
		case 5:{L1=L2=1;L3=0;}break;//110
		case 6:{L1=L3=0;L2=1;}break;//010
		case 7:{L1=1;L2=L3=0;}break;//100
		case 8:{L1=L2=L3=0;}break;//000
		case 1:{L1=L2=L3=1;}break;//111
		default:{L1=L2=L3=0;}break;
	}//d显示小数点11,10关闭
	P0=w>6&&x?ZhouShuMa[s]:ShuMaGuan[s]|ShuMaGuan[d];
}
void XianShi(unsigned char w,unsigned char x)
{
	switch(w)
	{
		case 0:ShuMaXianShi((x?Nbcd:Sbcd)/10,1,10);break;
		case 1:ShuMaXianShi((x?Nbcd:Sbcd)%10,2,(x?11:10));break;
		case 2:ShuMaXianShi((x?Ybcd/10:10),3,10);break;
		case 3:ShuMaXianShi((x?Ybcd%10:Fbcd/10),4,(x?11:10));break;
		case 4:ShuMaXianShi((x?Tbcd/10:Fbcd%10),5,10);break;
		case 5:ShuMaXianShi((x?Tbcd%10:10),6,(x?11:10));break;
		case 6:ShuMaXianShi((x?Zbcd:Mbcd/10),7,10);break;
		case 7:ShuMaXianShi((x?Zbcd+1:Mbcd%10),8,10);break;
		default:P0=L1=L2=L3=0;break;
	}
}
void XK_1302(unsigned char SD, bit k)
{
	unsigned char cs=8,zh=1;
	if(k){RST=SCLK=0;RST=1;}
	xf:if(cs--)
	{
		IO=SD&0x01;//低位起16进制
		SCLK=1;//上升沿写数据
		SD>>=1;//右移
		SCLK=0;//为下次上升沿准备时钟
		goto xf;
	}//发送命令时不能RST=0表示结束
	if(!k){SCLK=1;RST=0;}
}
unsigned char Du_1302(unsigned char Dz)
{
	unsigned char cs=8,zh=1,sj=0;
	XK_1302(Dz,1);//读地址命令
	SJ=SCLK=0;
	xf:if(cs--)
	{
		SJ+=IO*zh;//位为BCD码形式
		SCLK=1;//为下次下降沿准备时钟
		zh*=2;//直接转化为10进制数据
//		if(cs==4){sj=SJ;SJ=0;zh=1;}
		SCLK=0;//下降沿读数据
		goto xf;
	}
	RST=0;//十六进制转十进制
	return SJ/16*10+SJ%16;//SJ*10+sj;
}
void Xie_1302(unsigned char Dz,unsigned char Sj)
{
	XK_1302(0x8e,1);XK_1302(0x00,0);//取消写保护
	XK_1302(Dz,1);XK_1302(Sj,0);//写入数据
	XK_1302(0x8e,1);XK_1302(0x80,0);
}
void main()
{
	unsigned char hm=0,smys=0,w=0,m=0,dm=0,xd=0;
	Mbcd=Du_1302(0x81);Fbcd=Du_1302(0x83);Sbcd=Du_1302(0x85);
	Nbcd=Du_1302(0x8D);Ybcd=Du_1302(0x89);Tbcd=Du_1302(0x87);Zbcd=(Du_1302(0x8B)-1)*2;
	while(1)
	{
		if(++m>47)//蜂鸣器频率控制
		{
			if(x&&bek)beep=~beep;
			m=0;//每15分钟1响30分钟2响整点4响并报时期间显示日期
			if(++smys>10)//数码管延时
			{
				XianShi(w,x);smys=0;
				if(++w>7)//数码管位循环+读时钟延时
				{
					w=0;
					if(++dm>7){Mbcd=Du_1302(0x81);//第四级读秒延时
					if(Mbcd==0){Fbcd=Du_1302(0x83);
					if(Fbcd==0){Sbcd=Du_1302(0x85);
					if(Sbcd==0){Tbcd=Du_1302(0x87);Zbcd=(Du_1302(0x8B)-1)*2;
					if(Tbcd==1){Ybcd=Du_1302(0x89);
					if(Ybcd==1)Nbcd=Du_1302(0x8D);}}}}
					if(k1&&k2&&hm!=Mbcd%10){hm=Mbcd%10;bek=!bek;}//状态秒反转
					if(Fbcd==0&&Mbcd<8||Fbcd==30&&Mbcd<4||(Fbcd==15||Fbcd==45)&&Mbcd<2)
						x=1; else x=beep=0;
					if(!k1&&!k2)Xie_1302(0x80,0);//复合按键
					if(k1==0&&bek)
					{//直接十进制转十六进制写信息每秒分钟步进
						if(++Fbcd<60)Xie_1302(0x82,Fbcd/10*16+Fbcd%10);
						else {Fbcd=0;
						if(++Sbcd<24)Xie_1302(0x84,Sbcd/10*16+Sbcd%10);else Sbcd=0;}
					bek=0;}
					if(k2==0&&bek)
					{if(Fbcd>0)--Fbcd;else {Fbcd=59;
					if(Sbcd>0){--Sbcd;Xie_1302(0x84,Sbcd/10*16+Sbcd%10);}else Sbcd=23;}
						Xie_1302(0x82,Fbcd/10*16+Fbcd%10);
					bek=0;}
					dm=0;}if(!k1||!k2)bek=1;//调节快进速度控制
				}}}
	}
}

 第一电路图对应代码,按键代码也可以安排在其他延时层,修改dek的变化速度,实现比秒更快的调值。
不断优化就是对逻辑思维的验证,从而实现卖油翁的过程,只有了然于胸才能驾轻就熟;其实不然我认为频繁读取对精度有所影响,就好比开定时器中断应该说没什么影响,然而实践告诉人们,轻便的程序对定时器计时精度没多大影响,而复杂的程序对定时器计时精度就有影响,中断也要获得响应时间的,电路也是一样的总要拨点时间去处理其他事件;如果能够把程序打造得轻便即可用定时器中断实现比较精准的计时,抛却时钟芯片降低成本目标,毕竟兆赫兹的精度比千赫兹提高了一个数量级别,而且可以使用无源蜂鸣器,不用被逼选择有源蜂鸣器,有源蜂鸣器和无源蜂鸣器是有差价的,也充分体现了程序员的价值和水平。

#include "reg52.h"
sbit RST=P3^5;//DS1302允许(读/写)当RST为高电平时,所有的数据传送被初始化,允许对DS1302进行操作。如果在传送过程中RST置为低电平,则会终止此次数据传送,I/O引脚变为高阻态。RST必须保持低电平。只有在SCLK为低电平时,才能将RST置为高电平。
sbit SCLK=P3^6;//DS1302的SCLK为时钟输入端。在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从低位即位0开始。同样,在紧跟8位的控制指令字后的下一个SCLK脉冲的下降沿读出DS1302的数据,读出数据时从低位0位到高位7。在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从低位即位0开始。同样,在紧跟8位的控制指令字后的下一个SCLK脉冲的下降沿读出DS1302的数据,读出数据时从低位0位到高位7。
sbit IO=P3^7;//DS1302数据传递(读/写)秒寄存器80H写81H读/分寄存器82H写83H读/时寄存器84H写85H读/天寄存器86H写87H读/月寄存器88H写89H读/周寄存器8AH写8BH读/年寄存器8CH写8DH读,存放的数据位为BCD码形式。
sbit L1=P2^2;
sbit L2=P2^3;
sbit L3=P2^4;
sbit beep=P2^5;
sbit k1=P3^0;
sbit k2=P3^1;
bit smk=0,bek=1,x=0;
unsigned char code ShuMaGuan[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00,0X80,64};//0~9隐.小数点-号
unsigned char code ZhouShuMa[]={121,79,64,64,9,9,73,73,63,63,79,77,81,69};//用数码管显示每周的值:一二三四五六日。
unsigned char Nbcd=0,Ybcd=0,Tbcd=0,Sbcd=0,Fbcd=0,Mbcd=0,Zbcd=0,SJ=0,Js;//年 月 天 时 分 秒 周 数据
void ShuMaXianShi(unsigned char s,unsigned char w,unsigned char d)
{
	P0=L1=L2=L3=0;
	switch(w)
	{
		case 2:{L1=0;L2=L3=1;}break;//011
		case 3:{L2=0;L1=L3=1;}break;//101
		case 4:{L1=L2=0;L3=1;}break;//001
		case 5:{L1=L2=1;L3=0;}break;//110
		case 6:{L1=L3=0;L2=1;}break;//010
		case 7:{L1=1;L2=L3=0;}break;//100
		case 8:{L1=L2=L3=0;}break;//000
		case 1:{L1=L2=L3=1;}break;//111
		default:{L1=L2=L3=0;}break;
	}//d显示小数点11,10关闭
	P0=w>6&&x?ZhouShuMa[s]:ShuMaGuan[s]|ShuMaGuan[d];
}
void XianShi(unsigned char w,unsigned char x)
{
	switch(w)
	{
		case 0:ShuMaXianShi((x?Nbcd:Sbcd)/10,1,10);break;
		case 1:ShuMaXianShi((x?Nbcd:Sbcd)%10,2,(x?11:10));break;
		case 2:ShuMaXianShi((x?Ybcd/10:10),3,10);break;
		case 3:ShuMaXianShi((x?Ybcd%10:Fbcd/10),4,(x?11:10));break;
		case 4:ShuMaXianShi((x?Tbcd/10:Fbcd%10),5,10);break;
		case 5:ShuMaXianShi((x?Tbcd%10:10),6,(x?11:10));break;
		case 6:ShuMaXianShi((x?Zbcd:Mbcd/10),7,10);break;
		case 7:ShuMaXianShi((x?Zbcd+1:Mbcd%10),8,10);break;
		default:P0=L1=L2=L3=0;break;
	}
}
void XK_1302(unsigned char SD, bit k)
{
	unsigned char cs=8,zh=1;
	if(k){RST=SCLK=0;RST=1;}
	xf:if(cs--)
	{
		IO=SD&0x01;//低位起16进制
		SCLK=1;//上升沿写数据
		SD>>=1;//右移
		SCLK=0;//为下次上升沿准备时钟
		goto xf;
	}//发送命令时不能RST=0表示结束
	if(!k){SCLK=1;RST=0;}
}
unsigned char Du_1302(unsigned char Dz)
{
	unsigned char cs=8,zh=1,sj=0;
	XK_1302(Dz,1);//读地址命令
	SJ=SCLK=0;
	xf:if(cs--)
	{
		SJ+=IO*zh;//位为BCD码形式
		SCLK=1;//为下次下降沿准备时钟
		zh*=2;//直接转化为10进制数据
//		if(cs==4){sj=SJ;SJ=0;zh=1;}
		SCLK=0;//下降沿读数据
		goto xf;
	}
	RST=0;//十六进制转十进制
	return SJ/16*10+SJ%16;//SJ*10+sj;
}
void Xie_1302(unsigned char Dz,unsigned char Sj)
{
	XK_1302(0x8e,1);XK_1302(0x00,0);//取消写保护
	XK_1302(Dz,1);XK_1302(Sj,0);//写入数据
	XK_1302(0x8e,1);XK_1302(0x80,0);
}
char NYT(unsigned char n,unsigned char y)
{
	if (y == 2){ if ((!(2000+n % 4) && 2000+n % 100) || !(2000+n % 400)) return 29; else return 28; }
	else if ((y <= 7 && y % 2) || (y > 7 && !(y % 2)))return 31; else return 30;
}
void JiShi(/*时间计算*/)
{
	if(Js==100)
	{
		Js=0;
		if(++Mbcd==60){Mbcd=0;++Fbcd;
		if(Fbcd==60){Fbcd=0;++Sbcd;
		if(Sbcd==24){Sbcd=0;++Tbcd;++Zbcd;
		if(Zbcd>6)Zbcd=0;if(Tbcd>NYT(Nbcd,Ybcd)){Tbcd=1;++Ybcd;
		if(Ybcd>12){Ybcd=1;++Nbcd;}}}}}
		bek=!bek;
	}
}
void ZhongDuanSheZhi()
{
	TH0+=(65536-9216)/256;/*定时器赋初值,定时10ms触发中断,自动补偿方式*/
	TL0+=(65536-9216)%256; /*11.0592MHz/12=921600Hz就是1秒921600次机器周期*/
	TMOD=0X01;
	TR0=1; 
	ET0=1; //开启定时器
	EA=1; //全局中断开关
}
void ZhongDuan() interrupt 1
{
	++Js;//快+慢-
	TH0+=(65536-(9216))/256;/*定时器赋初值,定时10ms触发中断,自动补偿方式*/
	TL0+=(65536-(9216))%256; /*11.0592MHz/12=921600Hz就是1秒921600次机器周期*/       
}
void main()
{
	unsigned char hm=0,smys=0,w=0,m=0,dm=0,xd=0;
	Mbcd=Du_1302(0x81);Fbcd=Du_1302(0x83);Sbcd=Du_1302(0x85);
	Nbcd=Du_1302(0x8D);Ybcd=Du_1302(0x89);Tbcd=Du_1302(0x87);Zbcd=(Du_1302(0x8B)-1)*2;
	ZhongDuanSheZhi();
	while(1)
	{
		if(++m>47)//蜂鸣器约1千赫兹频率控制
		{
			if(x&&bek)beep=~beep;
			m=0;//每15分钟1响30分钟2响整点4响并报时期间显示日期
			if(++smys>10)//数码管延时
			{
				JiShi();XianShi(w,x);smys=0;
				if(++w>7)//数码管位循环+读时钟延时
				{
					w=0;
					if(Fbcd==0&&Mbcd<8||Fbcd==30&&Mbcd<4||(Fbcd==15||Fbcd==45)&&Mbcd<2)
						x=1; else x=beep=0;
					if(k1==0&&bek)
					{//直接十进制转十六进制写信息每秒分钟步进
						if(++Fbcd<60)Xie_1302(0x82,Fbcd/10*16+Fbcd%10);
						else {Fbcd=0;
						if(++Sbcd<24)Xie_1302(0x84,Sbcd/10*16+Sbcd%10);else Sbcd=0;}
					bek=0;}
					if(k2==0&&bek)
					{if(Fbcd>0)--Fbcd;else {Fbcd=59;
					if(Sbcd>0){--Sbcd;Xie_1302(0x84,Sbcd/10*16+Sbcd%10);}else Sbcd=23;}
						Xie_1302(0x82,Fbcd/10*16+Fbcd%10);
					bek=0;}
				}}}
	}
}

已经全部描述示例完毕,能否学到手,看各人自己了。之下记录了定时器10毫秒计时运行9个半小时后依然同系统保持一致,在WIN7系统7.8SP2仿真情况下。

void ShuMaXianShi(unsigned char s,unsigned char w,unsigned char d)
{
	P0=L1=L2=L3=0;
//	switch(w)
//	{
//		case 2:{L1=0;L2=L3=1;}break;//011=24
//		case 3:{L2=0;L1=L3=1;}break;//101=20
//		case 4:{L1=L2=0;L3=1;}break;//001=16
//		case 5:{L1=L2=1;L3=0;}break;//110=12
//		case 6:{L1=L3=0;L2=1;}break;//010=8
//		case 7:{L1=1;L2=L3=0;}break;//100=4
//		case 8:{L1=L2=L3=0;}break;//000=0
//		case 1:{L1=L2=L3=1;}break;//111=28
//		default:{L1=L2=L3=0;}break;
//	}//d显示小数点11,10关闭
	P2=w;//虽然可以操作整组IO实现但是运算时间会增加
	P0=w>6&&x?ZhouShuMa[s]:ShuMaGuan[s]|ShuMaGuan[d];
}

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

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

相关文章

不用PS也能抠图?点哪抠哪,简直是职场人的最强助手

抠图你还在用 PS 一点点抠吗&#xff1f; 不仅费时费力&#xff0c;还常常达不到理想效果&#xff0c;真的太让人崩溃了 但别担心&#xff0c;我找到了一个超棒的工具——千鹿设计助手的AI智能抠图插件。它就像你的私人设计小助手&#xff0c;能快速帮你把想要的元素抠出来&…

Mendix 创客访谈录|Mendix 如何化解工业企业数字化转型的复杂性

本期创客 田月萍 西门子 Advanta研发部门 大家好&#xff0c;我是田月萍&#xff0c;来自西门子Advanta的研发部门&#xff0c;专注于工业数字化转型。在我的职业生涯中&#xff0c;参与了多个关键项目的开发&#xff0c;涵盖了制造执行系统&#xff08;MES&#xff09;的实施&…

ECMA6Script学习笔记(六)

【摘要】 本文是对自己学习ES6的学习笔记回顾,后面是概要:文章深入探讨了ES6模块化处理&#xff0c;强调模块化在提高代码可维护性、可复用性和可扩展性方面的重要性。介绍了ES6模块化的三种导出方式&#xff1a;分别导出、统一导出和默认导出&#xff0c;并通过具体的代码示例…

3.特征工程-特征抽取、特征预处理、特征降维

文章目录 环境配置&#xff08;必看&#xff09;头文件引用1.数据集: sklearn代码运行结果 2.字典特征抽取: DictVectorizer代码运行结果稀疏矩阵 3.文本特征抽取(英文文本): CountVectorizer()代码运行结果 4.中文文本分词(中文文本特征抽取使用)代码运行结果 5.中文文本特征抽…

一款功能强大且免费的Windows系统优化工具

TweakPower是一款功能强大的Windows系统优化工具&#xff0c;旨在帮助用户提升电脑性能、清理垃圾文件、备份数据以及修复系统问题。该软件提供了多种实用功能&#xff0c;包括内存管理、垃圾清理、数据备份、数据擦除、硬盘维护和性能调度调整等。 TweakPower的主要界面或仪表…

如意玲珑支持发行版再添新成员,openEuler安装使用如意玲珑操作指南

查看原文 如意玲珑&#xff08;Linyaps&#xff09;项目已与开放原子开源基金会完成捐赠协议签署&#xff0c;目前如意玲珑已成为基金会的正式孵化期项目。 如意玲珑是开源软件包格式&#xff0c;用于替代 deb、rpm等包管理工具&#xff0c;实现应用包管理、分发、容器、集成开…

数据产品价值评估体系搭建

00前言 随着数据在企业的重要性越来越高&#xff0c;数据赋予的价值和意义在企业内部也深入人心&#xff0c;不仅纳入到了企业战略中去&#xff0c;在日常的工作中&#xff0c;各个业务部门也会不断的提出五花八门的数据需求&#xff08;数据分析、数据治理、数据应用等等&…

qt-01安装

qt5.15安装 版本链接5.15Qt5.15.2镜像QTCreater Launching Debugger 错误 版本链接5.15 https://download.qt.io/archive/online_installers/4.5/ Qt5.15.2镜像 https://mirrors.tuna.tsinghua.edu.cn/qt/online/qtsdkrepository/windows_x86/desktop/qt5_5152/ https://m…

插入数据优化 ---大批量数据插入建议使用load

一.insert优化 1.批量插入 2.手动提交事务 3.主键顺序插入 二.大批量插入数据 如果一次性需要插入大批量数据,使用insert语句插入性能较低,此时可以使用MySQL数据库提供的load指令进行插入。操作如下 1.客户端连接服务端时,加入参数 --local-infine mysql --local-infine…

AllReduce通信库;Reduce+LayerNorm+Broadcast 算子;LayerNorm(层归一化)和Broadcast(广播)操作;

目录 AllReduce通信库 一、定义与作用 二、常见AllReduce通信库 三、AllReduce通信算法 四、总结 Reduce+LayerNorm+Broadcast 算子 1. Reduce 算子 2. LayerNorm 算子 3. Broadcast 算子 组合作用 LayerNorm(层归一化)和Broadcast(广播)操作 提出的创新方案解析 优点与潜在…

私有化部署 Dify+Ollama并使用qwen2快速搭建 AI 应用

私有化部署 DifyOllama并使用qwen2快速搭建 AI 应用 Dify 是一款开源的大语言模型(LLM) 应用开发平台。它融合了后端即服务&#xff08;Backend as Service&#xff09;和 LLMOps 的理念&#xff0c;使开发者可以快速搭建生产级的生成式 AI 应用。即使你是非技术人员&#xff…

5.8软件工程基础知识-项目管理

项目管理 范围管理产品范围和项目范围管理过程WBS练习题 进度管理基本原则过程活动资源估算 软件规模估算方法进度安排关键路径法练习题 成本管理过程成本的类型练习题 软件配置管理配置项配置基线配置数据库练习题 质量管理过程质量模型软件评审软件容错技术练习题 风险管理宏…

java基础概念10-数组

一、什么是数组 二、数组的定义和初始化 2-1、数组的定义 2-2、数组的初始化 初始化&#xff1a;就是在内存中&#xff0c;为数组容器开辟空间&#xff0c;并将数据存入容器中的过程。 1、静态初始化 【注意】&#xff1a; 数字一旦初始化后&#xff0c;数组的长度不可改变&a…

Python 如何进行Web抓取(BeautifulSoup, Scrapy)

Web抓取&#xff08;Web Scraping&#xff09;是一种从网站提取数据的技术。Python有许多用于Web抓取的库&#xff0c;其中最常用的是BeautifulSoup和Scrapy。 BeautifulSoup BeautifulSoup是一个用于解析HTML和XML文档的Python库&#xff0c;适合处理简单的Web抓取任务。它将…

Occlusion in Augmented Reality

1.Occlusion in Augmented Reality 笔记来源&#xff1a; 1.Occlusion handling in Augmented Reality context 2.Occlusion in Augmented Reality 3.Real-Time Occlusion Handling in Augmented Reality Based on an Object Tracking Approach 4.Occlusion Matting: Realisti…

SQLTools插件下载与使用说明

SQLTools是一个专注于SQL优化与管理的plsql developer插件&#xff0c;目的是把一些常用的SQL收集在一起&#xff0c;方便快速解决问题&#xff0c;提高工作效率。 当在SQL或PACKAGE窗口,或者选中表时&#xff0c;会有两个右键菜单&#xff1a; SQLTools聚焦在SQL方面&#xf…

unity 程序做一个折叠菜单

第一次遇到这种需求&#xff0c;本来以为很难&#xff0c;没想到试了一下以后没啥难度&#xff0c;所以记录一下 首先新建一个scroll view&#xff0c;然后在content里面添加vertical layout group和content size fitter这两个组件。&#xff08;vertical layout group 的 spac…

前端常用的性能优化方案

目录 性能分析工具lighthouseWebpack Bundle分析 开发阶段按需引入路由懒加载 打包阶段打包配置减少包体积配置压缩分包 资源预加载/预请求 部署阶段开启http2静态资源缓存gzip压缩 性能优化主要在三个阶段进行&#xff1a;开发阶段、开发结束后的打包阶段、项目部署上线阶段 首…

动态规划例题

目录 A.小红组比赛 B.小红升装备 A.小红组比赛 思路 &#xff1a;经典的多重背包问题&#xff0c;这里将dp[ i ][ j ]定义为前 i 场比赛的难度 j 是否可能&#xff0c;所以dp只需用0 1 表示&#xff0c;然后遍历dp[ n ][ j ]即可。 代码&#xff1a; void solve() { cin&g…

TRANSFORMERS FOR IMAGE RECOGNITION AT SCALE(Transformer 在图像中的应用)翻译

摘要 虽然Transformer架构已成为自然语言处理任务的实际标准&#xff0c;但其在计算机视觉领域的应用仍然有限。在计算机视觉中&#xff0c;注意力机制要么与卷积网络结合使用&#xff0c;要么用于替换卷积网络的某些组件&#xff0c;同时保持其整体结构不变。我们证明了这种对…