基于AT89C51单片机的电子钟设计与仿真

news2024/10/5 17:16:19

点击链接获取Keil源码与Project Backups仿真图:
https://download.csdn.net/download/qq_64505944/87759735?spm=1001.2014.3001.5503
在这里插入图片描述

源码获取
主要内容:
设计一个电子钟,实现对时、分、秒的显示的控制,电路采用24小时计时方式。另一个功能是秒表功能,从零开始读秒,可以暂停,二者可以通过一个按键进行互换,并具备时间校准功能。
基本要求:
1、原理分析;
2、keil建立工程;
3、代码实现;
4、通过Proteus仿真;
5、设计总结
主要参考资料:
[1]张俊谟.单片机中级教程—原理与应用[第2版].北京航空航天大学出版社,2006.
[2]周润景、张丽娜.基于PROTEUS的电路及单片机系统设计与仿真.北京航空航天大学出版社,2006.
[3]全国大学生电子设计竞赛组委会.全国大学生电子设计竞赛获奖作品选编[M].北京理工大学出版社.2007.
[4]雷志勇、江建尧.数字存贮示波器的随机采样原理.西安工业学院学报.1997,(5)
[5]黄智伟.全国大学生电子设计竞赛电路设计.北京航空航天大学出版社,2006.

           完  成  期  限:   月  日  -  月  日  
        指导教师签名:                    
           课程负责人签名:                         

摘 要
本次课程设计是电子钟的设计,对时、分、秒的显示的控制,电路采用24小时计时方式。另一个功能是秒表功能,从零开始读秒,可以暂停,二者可以通过一个按键进行互换,并具备时间校准功能。
最常见的电子钟通常使用单片机模块控制,一种用单片机原理实现时、分、秒计时的装置,与机械式时钟相比具有更高的准确性和直观性,且无机械装置,具有硬件成本低、计时准确、更长的使用寿命特点,因此得到了广泛的使用。
本次设计通过用单片机为主控制 ,通过电路仿真而实现 。首先使用 Proteus软件进行绘制硬件电路图,用 keil 软件进行编程与调试,最终生成 hex文件,传入单片机内部,从而实现仿真效果。
关键词:电子钟;仿真;单片机

目 录
摘 要 I
目 录 II
1.设计要求 1
1.1介绍 1
1.2基本功能 1
1.3扩展功能 1
2.工作原理 2
2.1LCD1602液晶显示屏原理 2
2.2按键原理 2
2.3单片机核心模块的时钟电路原理 2
2.4使用说明 3
3.仿真设计 4
3.1显示时间与温度 4
3.2实现秒表功能 5
4 程序 6
4.1程序结构 6
4.2代码 6
5.设计总结 18
参考文献 19

1.设计要求
1.1介绍
电子钟是一种利用数字电路来显示秒、分、时的计时装置,与传统的机械钟相比,它具有走时准确、显 示直观、无机械传动装置等优点,因而得到广泛应用。同时电子钟可以集成诸多功能,如秒表、温度测量、水平检测等功能。
1.2基本功能
1、电子钟可显示时、分、秒;
2、可手动校时,待校时的时间闪烁;
1.3扩展功能
1、可当作秒表使用;
2、可测量当前环境温度;
3、通过LCD1602液晶屏显示数据及特殊图形;

2.工作原理
2.1LCD1602液晶显示屏原理
LCD1602液晶显示的原理是利用液晶的物理特性,通过电压对其显示区域进行控制,有电就有显示,这样即可以显示出图形。它是由字符型液晶显示屏(LCD)、控制驱动主电路HD44780及其扩展驱动电路HD44100,以及少量电阻、电容元件和结构件等装配在PCB板上而组成。
LCD1602液晶屏由板载5V电压供电;VO引脚连接可调电阻,因此可以通过调节电阻阻值大小控制背光亮度;LCD RS、LCD WR、LCD EN分别连接单片机的P2.6、P2.5、P2.7,控制数据与命令的传输;LCD D0~LCD D7连接单片机P0口,作为单片机与模块之间的数据传送通道。
2.2按键原理
在这里插入图片描述

图2-1 独立按键模块
由图2-1可知,4位独立按键K1K4分别连接单片机P3.1P3.3,只有按键按下时读引脚才可以得到高电平1。因此可以通过对引脚值电平进行分析,进而判断有无按键按下。
2.3单片机核心模块的时钟电路原理
单片机时钟信号的产生采用内部震荡方式,外接12MHZ晶振,得到频率为12MHZ的时钟信号。在AT89C52芯片内部有一个高增益反相放大器,其输入端为芯片引脚XTAL1,输出端为引脚XTAL2。把放大器与作为反馈元件的晶体振荡器和陶瓷电容相连,就构成了自激振荡器。
主机和从机通信使用单总线,即使用单线进行数据的发送和接收。首先需要判断总线上是否存在设备,确定有设备存在后在进行读/写操作,查找芯片手册中的寄存器地址与操作提示可以设置温度检测精度与温度值读取。
2.4使用说明
使用K1、K2、K3共3个按键
(1)功能切换:单击K3,用于切换时间、温度显示和秒表功能菜单间切换
(2)时间校准:长按K3 进入/退出时间调整菜单,当菜单为时间调整时,单击K3 切换选择时/分/秒进行调整,待调整的时间会闪烁,单击K1,当前调整的时间值+1,单击K2则-1。时间调整完毕后,长按K2保存当前时间值,LED灯闪烁一次时,则表示校时成功。
(3)秒表功能:当菜单为秒表时,单击K实现开/关秒表,长按K1秒表清0。

图2-2菜单描述

3.仿真设计
3.1显示时间与温度
在这里插入图片描述

3-1时间和温度显示图

3.2实现秒表功能
在这里插入图片描述

3-2秒表功能图

4 程序
4.1程序结构

在这里插入图片描述

图4-1KEIL工程目录
KEIL工程目录如图13所示,共有5个程序文件,其文件内容如下表所示。
表4-1KEIL工程目录
main.c 主函数
lcd1602.c 液晶屏驱动
delay.c 延时函数集合
timer0.c 定时器0初始化
ds18.c 温度传感器驱动
4.2代码

(*)main.c
#include <main.h>
#include <lcd1602.h>
#include <delay.h>
#include <timer0.h>
#include <ds18.h>
unsigned char MenuSelect,LastKey,NowKey;
unsigned char	MenuChange= 1;
unsigned char T0Count = 0;
unsigned int  T1Count = 0;
unsigned int  T2Count = 0;
unsigned char	SCount = 0;
unsigned char	KeyNumber = 0;
unsigned long	time_value =0;
unsigned long	time_change_value =0;
unsigned char str[12];
unsigned char S_Flag = 0;
unsigned long	second_value =0;
unsigned char	h_m_s=0;
long temp; //不是无符号数
int DS_int; 
unsigned char Dsdata[7] ="_______";
bit  fg=1;//用于判断温度正负
//读取温度
int ReadTemperature(void)
{
	unsigned char a=0;//低8位
	unsigned char b=0;//高8位
	unsigned int  t=0;
	Init_DS18B20();
	WriteOneChar(0xCC); // 跳过读序号列号的操作
	WriteOneChar(0x44); // 启动温度转换
	delay_18B20(100); //至少750ms
	Init_DS18B20();
	WriteOneChar(0xCC); //跳过读序号列号的操作
	WriteOneChar(0xBE); //读取温度寄存器
	a=ReadOneChar();
	b=ReadOneChar();
	if((b&0xf8)==0xf8) //位为1 时温度是负
	{
		b=~b;
		a=~a+1; //补码转换,取反加一
		if(a==0)b++;//如果发生进位
		fg=0; //读取温度为负时fg=0
	}
	else{
		fg=1;//正数
	}
	  t=((b*256+a)*25)>>2;//合成整数
		return(t);
}
//对读取到的温度数据进行处理
void Tran(int temp)
{
	unsigned char k=0;  
  Dsdata[1] = ' ';Dsdata[2] = '0';Dsdata[3] = '0';Dsdata[4] = '0';Dsdata[5] = '0';//清缓存
	if(fg){
		Dsdata[0] = ' ';
	}
	else{
		Dsdata[0] = '-';
	}
	do
  {
   Dsdata[4-k]=temp%10 + '0';//取最后一位
   k++;
  }while(temp/=10);
		Dsdata[5]=Dsdata[4];Dsdata[4]=Dsdata[3];Dsdata[3]='.';//后移2位数据,加上小数点
	Dsdata[6]='\0';//END
}
//按键扫描
void Scan_Key()
{
	unsigned char KEY_Temp = 0;
	if(KEY_1==0){KEY_Temp=1;}
	if(KEY_2==0){KEY_Temp=2;}
	if(KEY_3==0){KEY_Temp=3;}
	if(KEY_4==0){KEY_Temp=4;}
	LastKey	=	NowKey;
	NowKey	= KEY_Temp;
}
//根据扫描结果判断有无按键按下,可以实现长按检测
unsigned char Judge_Key(){
	if(NowKey!= 0 ){
		T2Count++;
	}else if(LastKey!=0 && NowKey==0){//边沿检测
		
			if(T2Count>25){
				KeyNumber=LastKey+4;
			}else{
				KeyNumber=LastKey;
			}
			T2Count=0;
	}
}
//长整数转换成时间(模60)
unsigned char IntergerToTime(long dat,unsigned char*str){
	//中间变量
	unsigned char i = 0;
	unsigned char h = 0;
	unsigned char m = 0;
	unsigned char s = 0;
	unsigned char buff[11];
    h = dat/ 3600;
    m = dat% 3600 / 60;
    s = dat% 60;
		buff[i]=s%10 + '0';
		i++;
		buff[i]=s/10 + '0';
		i++;
		buff[i]=m%10 + '0';
		i++;
		buff[i]=m/10 + '0';
		i++;
		buff[i]=h%10 + '0';
		i++;
		buff[i]=h/10 + '0';
		i++;
	while(i-- > 0){
		*str = buff[i];
		str++;
	}
	*str='\0';//取内容	
	return 1;
}
//秒表计数值转换
unsigned char MsecondToTime(long dat,unsigned char*str){
	//中间变量
	unsigned char i = 0;
	unsigned char h = 0;
	unsigned char m = 0;
	unsigned char s = 0;
	unsigned char buff[11];
    h = dat/ 6000;
    m = (dat-h*6000)/100;
    s = dat-h*6000-m*100;
		buff[i]=s%10 + '0';
		i++;
		buff[i]=s/10 + '0';
		i++;
		buff[i]=m%10 + '0';
		i++;
		buff[i]=m/10 + '0';
		i++;
		buff[i]=h%10 + '0';
		i++;
		buff[i]=h/10 + '0';
		i++;	
	while(i-- > 0){
		*str = buff[i];
		str++;
	}
	*str='\0';//取内容
	
	return 1;
}
//主菜单
void Main_menu(){
	LCD_Show_String(0,0,"Time:");
	LCD_Show_CHAR(6,0,str[0]);
	LCD_Show_CHAR(7,0,str[1]);
	LCD_Show_CHAR(8,0,':');
	LCD_Show_CHAR(9,0,str[2]);
	LCD_Show_CHAR(10,0,str[3]);
	LCD_Show_CHAR(11,0,':');
	LCD_Show_CHAR(12,0,str[4]);
	LCD_Show_CHAR(13,0,str[5]);
	LCD_Show_String(0,1,"Temp:");//温度
	Tran(DS_int);
	LCD_Show_String(5,1,Dsdata);
	//LCD_Show_CHAR(7,1, '0');
}
//秒表菜单
void Second_menu(){
	LCD_Show_String(0,0,"Stopwatch:");
	LCD_Show_CHAR(6,1,str[0]);
	LCD_Show_CHAR(7,1,str[1]);
	LCD_Show_CHAR(8,1,':');
	LCD_Show_CHAR(9,1,str[2]);
	LCD_Show_CHAR(10,1,str[3]);
	LCD_Show_CHAR(11,1,':');
	LCD_Show_CHAR(12,1,str[4]);
	LCD_Show_CHAR(13,1,str[5]);
}
//时间调整菜单
void Change_menu(){
	LCD_Show_String(0,0,"Change Time");
	if(h_m_s == 0){
		LCD_Show_CHAR(0,1,'H');
	}else if(h_m_s == 1){
		LCD_Show_CHAR(0,1,'M');
	}else if(h_m_s == 2){
		LCD_Show_CHAR(0,1,'S');
	}
	LCD_Show_CHAR(6,1,str[0]);
	LCD_Show_CHAR(7,1,str[1]);
	LCD_Show_CHAR(8,1,':');
	LCD_Show_CHAR(9,1,str[2]);
	LCD_Show_CHAR(10,1,str[3]);
	LCD_Show_CHAR(11,1,':');
	LCD_Show_CHAR(12,1,str[4]);
	LCD_Show_CHAR(13,1,str[5]);
}
void main(){
	delayx10ms(1);
	LcdInit();
	LCD_CGRAM();
	LCD_Start();
	Timer0_Init();
	//循环
	while(1){
		if(KeyNumber){
			if(KeyNumber == 1){
				if(MenuSelect == 1){
					if(S_Flag == 1){
						S_Flag = 0;
					}else{
						S_Flag = 1;
					}
				}
				if(MenuSelect==2){
					switch(h_m_s){
						case 0 : 
							temp = time_change_value + 60*60;
							if(temp<86400-1){
								time_change_value = temp;
							}break;
						case 1 : 
							temp = time_change_value + 60;
							if(temp<86400-1){
								time_change_value = temp;
							}break;
						case 2 : 
							temp = time_change_value + 1;
							if(temp<86400-1){
								time_change_value = temp;
							}break;
					}
				}
			}else if(KeyNumber == 2){
				if(MenuSelect==2){
					switch(h_m_s){
						case 0 : 
							temp = time_change_value - 60*60;
							if(temp>=0){
								time_change_value = temp;
							}break;
						case 1 : 

							temp = time_change_value - 60;
							if(temp>=0){
								time_change_value = temp;
							}break;
						case 2 : 

							temp = time_change_value - 1;
							if(temp>=0){
								time_change_value = temp;
							}break;
					}
				}
			}
			else if(KeyNumber == 3){//3键切换菜单
					if(MenuSelect<2){
							MenuSelect++;
							MenuChange=1;
							if(MenuSelect>1){
								MenuSelect=0;
							}
					}else if(MenuSelect==2){
							h_m_s++;
							if(h_m_s>=3){
								h_m_s=0;
							}
					}
			}else if(KeyNumber == 5){
						if(MenuSelect == 1){
							//清零计数值
							second_value=0;
						}
						//LED_2 = ~LED_2;
			}else if(KeyNumber == 6){
						if(MenuSelect == 2){
							//确定校时
							time_value=time_change_value;
							//--
							LED_2 = ~LED_2;//LED闪烁表示 效时成功了哦
							//--
						}
			}else if(KeyNumber == 7){
					if(MenuSelect != 2){
						MenuChange=1;
						//time_change_value=time_value;
						time_change_value=0;
						MenuSelect=2;
					}else{
						MenuChange=1;
						MenuSelect=0;
					}
			}
			KeyNumber=0;
		}
		//清屏命令,防止重复清屏,卡哎
		if(MenuChange==1){
			WriteCmd(0x01);//清屏
			MenuChange = 0;
		}
		//切换菜单
		switch(MenuSelect){
			case 0 :	IntergerToTime(time_value,str);Main_menu();break;
			case 1 :	MsecondToTime(second_value,str);Second_menu();break;
			case 2 :	IntergerToTime(time_change_value,str);Change_menu();
								if(h_m_s==0){
									Delay(260);
									LCD_Show_CHAR(6,1,' ');
									LCD_Show_CHAR(7,1,' ');
									Delay(260);
								}else if(h_m_s==1){
									Delay(260);
									LCD_Show_CHAR(9,1,' ');
									LCD_Show_CHAR(10,1,' ');
									Delay(260);
								}else if(h_m_s==2){
									Delay(260);
									LCD_Show_CHAR(12,1,' ');
									LCD_Show_CHAR(13,1,' ');
									Delay(260);
								}break;
			}
	}
}
//计数器0用于按键扫描(不要加delay延时!)同时实现计数
void Timer0_interrupt() interrupt 1
{
	TL0 = 0x18;		
	TH0 = 0xFC;		
	T0Count++;T1Count++;
	if(T0Count>=20)					//每20ms扫描一次按键
	{
		T0Count=0;
		SCount++;
		Scan_Key();
		Judge_Key();
	}
	if(T1Count>=10){
		T1Count=0;
		if(S_Flag==1){
			if(second_value<60001){
				second_value++;
			}else{
				second_value=0;
			}
		}
	}
	if(SCount >= 50 ){
		SCount=0;
		if(time_value >86400-1){
					time_value=0;
			}else{
					time_value++;
				//---
					DS_int = ReadTemperature();//读取温度
				//---
			}
	}
}

5.设计总结
在课程设计,将理论用于实践,实践又将丰富理论,对单片机的掌握更加深刻,收获颇丰。在制作过程中也遇到了许多问题,如LCD1602因为操作时序不正确导致无响应,因为清屏指令不合适造成屏幕闪烁明显;对读取DS18B20的高8位和低8位数据进行整合处理时遇到的难题;按键单击与长按复用功能的实现,消抖的细节处理等。通过查找CSDN与B站上的资源,与同学交流,问题最后得到了解决。但由于自己能力有限,做出来的成品只能尽自己所能做到最好。
单片机的型号千千万万,随着时代的发展,单片机更新迭代,只有掌握了基本的单片机原理与学习方法,有了坚实的基础才可以对任何单片机的开发水到渠成,应一步一步慢慢来。
总之这次电路的设计和仿真,基本上达到了设计的功能要求。在以后的实践中,我将继续努力学习电路设计方面的理论知识,并理论联系实际,争取在电路设计方面能有所提升。

参考文献
[1]张俊谟.单片机中级教程—原理与应用[第2版].北京航空航天大学出版社,2006.
[2]周润景、张丽娜.基于PROTEUS的电路及单片机系统设计与仿真.北京航空航天大学出版社,2006.
[3]全国大学生电子设计竞赛组委会.全国大学生电子设计竞赛获奖作品选编[M].北京理工大学出版社.2007.
[4]雷志勇、江建尧.数字存贮示波器的随机采样原理.西安工业学院学报.1997,(5)
[5]黄智伟.全国大学生电子设计竞赛电路设计.北京航空航天大学出版社,2006.

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

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

相关文章

mysql : name like “%name“; 索引一定失效吗?

场景如下&#xff1a; MySQL版本如下&#xff1a; 表结构如下&#xff1a;索引结构如下&#xff1a; 查询语句以及执行计划如下&#xff1a; 第一条查询语句&#xff1a; select name from em where name like ‘%b’; 可以发现使用了name 字段创建的索引 第二条查询语句&…

02-Java基础编程

Java基础编程 Java 基础语法Java 标识符变量变量的类型Java 基本数据类型基本数据类型转换 运算符常见运算符运算符的优先级 程序流程控制分支语句循环结构常用的循环结构循环的嵌套break 和 continue 关键字 数组一维数组多维数组的使用Arrays 工具类的使用数组中常见的异常 J…

AcWing——方格迷宫(有点不一样的迷宫问题)

4943. 方格迷宫 - AcWing题库 1、题目 给定一个 n 行 m 列的方格矩阵。 行从上到下依次编号为 1∼n&#xff0c;列从左到右依次编号为 1∼m。 第 i 行第 j 列的方格表示为 (i,j)。 矩阵中的方格要么是空地&#xff08;用 . 表示&#xff09;&#xff0c;要么是陷阱&#xf…

前后端身份认证:session身份认证,JWT认证

文章目录 前后端身份认证1、概述2、不同开发模式下的身份认证3、关于HTTP协议的无状态性4、Cookie4.1 介绍4.2 cookie特点4.3 cookie分类4.4 Cookie在session身份认证中的作用4.5 Cookie不具有安全性 5、Session认证5.1 Session认证过程5.2 Session认证原理图5.3 Session认证的…

【Linux】多线程 --- 线程概念 控制 封装

从前种种&#xff0c;譬如昨日死。从后种种&#xff0c;往如今日生。 文章目录 一、线程概念1.重新理解用户级页表1.1 进程资源如何进行分配呢&#xff1f;&#xff08;地址空间页表&#xff09;1.2 虚拟地址如何转换到物理地址&#xff1f;&#xff08;页目录页表项&#xff0…

11 KVM虚拟机配置-配置虚拟设备(存储)

11 KVM虚拟机配置-配置虚拟设备(存储) 文章目录 11 KVM虚拟机配置-配置虚拟设备(存储)11.1 存储设备概述11.2 存储设备元素介绍11.3 存储设备配置示例 11.1 存储设备概述 虚拟机XML配置文件使用devices元素配置虚拟设备&#xff0c;包括存储设备、网络设备、总线、鼠标等。 X…

【LeetCode】494. 目标和

494. 目标和 思路 首先&#xff0c;将这道题想成 0-1背包问题&#xff0c;我们最终要输出的结果是最多的方法数&#xff0c;因此 dp 数组需要记录具体的方法数。 状态定义 按照 0-1 背包问题的套路&#xff0c;我们将状态定义为 &#xff1a;dp[i][j] &#xff0c;表示「前 …

YOLOv5测距+碰撞检测

YOLOv5测距碰撞检测 1. 相关配置2. 测距原理3. 标定和测距4. 碰撞检测4.1 相关代码4.2 主代码 5. 实验效果 相关链接 1. YOLOV5 单目测距&#xff08;python&#xff09; 2. YOLOV7 单目测距&#xff08;python&#xff09; 3. 具体实现效果已在Bilibili发布&#xff0c;点击…

string的介绍

string是c中表示字符串的字符串类&#xff0c;要使用需要包头文件&#xff1a;#include<string> 先了解一下string的一些信息 string看起来是一个类&#xff0c;但实际上是typedef的模板。 在cplusplus.com网站上&#xff0c;string的相关信息 模板的实例化结果有以下几个…

【unity小创意】相机的正反操作实现场景的二维跳跃

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;uni…

Spring的第十二阶段(01):Spring实现AOP的简单使用

1、使用Spring实现AOP简单切面编程 需要导入工程的jar包 Spring的核心包 spring-beans-4.0.0.RELEASE.jar spring-context-4.0.0.RELEASE.jar spring-core-4.0.0.RELEASE.jar spring-expression-4.0.0.RELEASE.jarSpring的测试包 spring-test-4.0.0.RELEASE.jarSpring日记相…

【网络安全】这套面试题,让你提前预判面试官的预判!

最近这个帖子的点赞和收藏变高起来了&#xff0c;许多小伙伴在问我安全大厂的面试题没有&#xff0c;我准备利用一些时间把这套面试宝典整理一下&#xff01; 今天有同学拿着他准备的面试问题清单给我看&#xff0c;看还有没有遗漏的&#xff0c;我看了下&#xff0c;觉得还是…

Spring-Bean管理-注解

组件注册 Component/Controller/Service/Repostory :注册自定义组件到容器中 加上约定的注解。 在Configuration注解的类中配置包扫描器 ComponentScan(vlaue "cn.shaoxiongdu") Configuration: 标注配置类 Scope &#xff1a; 配置是否为单实例 prototype: 多实…

JVM与GC

Java:跨平台的语言 write once, run anywhere JVM&#xff1a;跨语言的平台 Java虚拟机根本不关心运行在其内部的程序到底是使用何种编程语言编写的&#xff0c;它只关心“字节码”文件。 Java不是最强大的语言&#xff0c;但是JVM是最强大的虚拟机。 JVM的整体结构 这个架构…

Java基础学习(12)

Java基础学习 一、不可变集合二、Stream流2.1 Stream流数据添加2.2 Stream流的中间方法2.3 Stream终结方法 三、 方法引用3.1 方法引用的基本概念3.2 方法引用的分类3.2.1 引用静态方法 3.2.2 引用成员方法3.2.3 引用构造方法3.2.4 使用类名引用成员方法3.2.5 引用数组的构造方…

PyQt5 基础篇(一)-- 安装与环境配置

1 PyQt5 图形界面开发工具 Qt 库是跨平台的 C 库的集合&#xff0c;是最强大的 GUI 库之一&#xff0c;可以实现高级 API 来访问桌面和移动系统的各种服务。PyQt5 是一套 Python 绑定 Digia QT5 应用的框架。PyQt5 实现了一个 Python模块集&#xff0c;有 620 个类&#xff0c;…

MATLAB 点云非均匀体素下采样 (8)

MATLAB 点云非均匀体素下采样的不同参数效果测试 (8) 一、实现效果二、算法介绍三、函数说明3.1 函数3.2 参数四、实现代码(详细注释!)五、与固定步长采样法比较5.1 代码5.2 效果一、实现效果 不同参数调整下的非均匀体素下采样结果如下图所示,后续代码复制黏贴即可: 可…

入职6个月,被裁了...

我跟大多数人不大一样&#xff0c;从来没有说要等公司主动裁员拿补偿&#xff0c;我看自己没有什么价值或者是公司不行了&#xff0c;我都会主动离职。但是这次也太突然了。公司很大已上市&#xff0c;并不是不行了&#xff0c;总结原因就是&#xff0c;一是领导无能&#xff0…

【STM32CubeMX】F103ADC获取

前言 本文记录了我学习STM32CubeMX的过程&#xff0c;方便以后回忆。我们使用的开发板是基于STM32F103C6T6的。本章记录了基本的ADC值的获取流程&#xff0c;只单纯地记录了ADC端口的配置&#xff0c;没有加配像串口之类的调试&#xff0c;以简化流程。下面的流程是使用串口调试…

版本控制系统Git - 配置与基本使用

Git 1 Git简介1 Git概述2 Git的作用2.1 项目版本管理2.2 多人协同开发2.3 Git 的结构2.4 Git的工作原理 2 Git安装1 下载Git2 安装Git3 配置环境变量4 测试git是否安装成功5 安装git桌面工具(可以不安装) 3 Git基本操作1 设置Git用户2 新建仓库3 查看仓库状态4 添加到暂存文件5…