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

news2024/11/16 23:51:45

点击链接获取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/497825.html

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

相关文章

JVM内存模型和结构介绍

什么是JVM JVM是Java Virtual Machine&#xff08;Java虚拟机&#xff09;的缩写&#xff0c;JVM是一个虚构出来的计算机&#xff0c;有着自己完善的硬件架构&#xff0c;如处理器、堆栈等。 为什么需要JVM&#xff1f; Java语言使用Java虚拟机屏蔽了与具体平台相关的信息&…

执行网格中有特定数量节点的传感器网络部署(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 ​无线传感器网络是通过大量分布的传感器节点作为终端来协同感知和自主地监测外部世界,以多跳、自组织或协作的方式进行通信和…

Java 基础进阶篇(十二)—— Arrays 与 Collections 工具类

文章目录 一、Arrays工具类1.1 Arrays 类常用方法1.2 对于 Comparator 比较器的支持1.3 Arrays 的综合应用1.3.1 应用一&#xff1a;数组的降序排序1.3.2 应用二&#xff1a;根据学生年龄进行排序 二、Collections工具类2.1 Collections 类常用方法2.2 Collections 排序相关 AP…

哈希表相关知识总结

一、哈希表的定义 散列表&#xff08;Hash table&#xff0c;也叫哈希表&#xff09;&#xff0c;是根据键&#xff08;Key&#xff09;而直接访问在内存存储位置的数据结构。也就是说&#xff0c;它通过计算一个关于键值的函数&#xff0c;将所需查询的数据映射到表中一个位置…

C++相比于C语言增加的8个特性(详解)

C相比于C语言增加的8个特性&#xff08;详解&#xff09; 文章目录 C相比于C语言增加的8个特性&#xff08;详解&#xff09;一、命名空间二、C输入和输出三、缺省参数四、函数重载五、引用六、内联函数七、auto关键字八、指针空值nullptr总结 一、命名空间 c的命名空间是为了…

【刷题之路】LeetCode 21. 合并两个有序链表

【刷题之路】LeetCode 21. 合并两个有序链表 1、题目描述二、解题1、方法1——直接合并1.1、思路分析1.2、代码实现 2、方法2——递归2.1、思路分析2.2、代码实现 1、题目描述 原题连接&#xff1a; 21. 合并两个有序链表 题目描述&#xff1a; 将两个升序链表合并为一个新的 …

Camtasia Studio2023Mac最新电脑版屏幕录像软件

Camtasia Studio2023提供了强大的屏幕录像、视频的剪辑和编辑、视频菜单制作、视频剧场和视频播放功能等。它能在任何颜色模式下轻松地记录屏幕动作&#xff0c;包括影像、音效、鼠标移动的轨迹&#xff0c;解说声音等等&#xff0c;另外&#xff0c;它还具有及时播放和编辑压缩…

数字化转型导师坚鹏:美的集团数字化转型案例研究

美的集团数字化转型案例研究 课程背景&#xff1a; 很多企业存在以下问题&#xff1a; 不清楚企业数字化转型能否成功&#xff1f; 不知道其它企业数字化转型的实际做法&#xff1f; 不知道其它企业的数字化转型战略是如何演变的&#xff1f; 课程特色&#xff1a; 用…

汽车架构-工作流程 以及相关协议解读

全车架构&#xff08;E/E&#xff09; 车载测试阶段&#xff1a; 台架测试 HIL测试&#xff08;硬件在环测试&#xff09; ADAS智能辅助驾驶测试 OTA测试&#xff08;远程升级测试&#xff09; 测试工具&#xff1a; Can协议工具&#xff1a;Canoe Pcan Zcanpro 辅助工具…

【Stable Diffusion】ControlNet基本教程(三)

接上篇【Stable Diffusion】ControlNet基本教程&#xff08;二&#xff09;&#xff0c;本篇再介绍两个ControlNet常见的基本用法&#xff0c;更多用法欢迎关注博主&#xff0c;博主还会更新更多有趣的内容。 3.3更换物体皮肤 有时&#xff0c;我们不想改变物体的轮廓&#xff…

毫米波雷达系列 | 传统CFAR检测(均值类)

毫米波雷达系列 | 传统CFAR检测&#xff08;均值类&#xff09; 文章目录 毫米波雷达系列 | 传统CFAR检测&#xff08;均值类&#xff09;1.CA-CFAR算法2.SO-CFRA算法3.GO-CFAR算法4.仿真对比 CFAR检测器主要用于检测背景杂波环境中的雷达目标&#xff0c;常见的均值类CFAR检测…

数据结构之队列的详解

文章目录 一.什么是队列二.队列的使用2.1 队列的基本操作2.2 队列的基本使用 三.队列的模拟实现3.1 数组实现队列3.2 链表实现队列 四.队列的应用4.1 设计循环队列4.2 设计双端队列4.3 队列实现栈4.4 栈实现队列 五.总结 一.什么是队列 队列是一种先入先出(FIFO)的线性表数据结…

点评项目导入

文章目录 开篇导读项目地址导入SQL项目架构介绍后端项目导入前端项目导入 开篇导读 实战篇我们要学习以下内容 短信登录 这一块我们会使用redis共享session来实现 商户查询缓存 通过本章节&#xff0c;我们会理解缓存击穿&#xff0c;缓存穿透&#xff0c;缓存雪崩等问题&…

力扣刷题Day12

239. 滑动窗口最大值 (此题逻辑真心牛皮&#xff09; 做此题之前&#xff0c;首先明确此题的目的。我最开始没搞明白此题目的&#xff0c;看代码的时候卡死。 copy他人代码&#xff1a; from collections import dequeclass MyQueue: #单调队列&#xff08;从大到小def __ini…

6.S081——陷阱部分(一文读懂Xv6系统调用)——xv6源码完全解析系列(5)

0.briefly speaking 这篇博客将要开始尝试阅读和研究与Xv6陷阱机制相关的代码&#xff0c;主要有以下文件&#xff0c;最重要的是结合Xv6 book将Xv6处理陷阱的相关逻辑和流程弄透。在Xv6的语境中所谓陷阱的触发有以下三种情况&#xff1a; 系统调用严重错误&#xff08;比如除…

windows守护进程工具--nssm使用

一、nssm简介 nssm是一个服务封装程序&#xff0c;它可以将普通exe程序封装成服务&#xff0c;实现开机自启动&#xff0c;同类型的工具还有微软自己的srvany&#xff0c;不过nssm更加简单易用&#xff0c;并且功能强大。 它的特点如下&#xff1a; 支持普通exe程序(控制台程序…

每天看一个fortran文件(7)之寻找cesm边界层高度计算代码

自从我把我的代码移到了单独的F90 中&#xff0c;从tphysac.F90中调用后。我发现有很多的变量我没办法调用了&#xff0c;特别是边界层中原先已经算好的变量&#xff0c;比如说我想调用原来模式中的pblh,但是那是在vertical diffusion.F90中计算的&#xff0c;在tphysac中根本调…

基于springcloud实现的医院信息系统

访问【WRITE-BUG数字空间】_[内附完整源码和文档] 医疗信息就诊系统&#xff0c;系统主要功能按照数据流量、流向及处理过程分为临床诊疗、药品管理、财务管理、患者管理。诊疗活动由各工作站配合完成&#xff0c;并将临床信息进行整理、处理、汇总、统计、分析等。本系统包括以…

以前以为去流量大的部门是好事,能学技术,现在才知道,流量大的部门狗都不去!晚上9点才下班,一天到晚都是监控告警!...

流量大的部门好&#xff0c;还是流量小的部门好&#xff1f; 一位网友说&#xff0c;工作以前以为去流量大的部门是好事&#xff0c;能学技术&#xff1b;工作后才知道&#xff0c;流量大的部门和组&#xff0c;狗都不去&#xff01;待在流量大的组&#xff0c;晚上9点起步才下…

p71 内网安全-域横向网络传输应用层隧道技术

数据来源 必备知识点&#xff1a; 1、代理和隧道技术区别? 代理&#xff1a;只是解决网络的访问问题&#xff08;如&#xff1a;有些内网访问不到&#xff0c;可以用代理实现&#xff09; 隧道&#xff1a;隧道不仅是解决网络的通信问题&#xff0c;更大的作用是绕过过滤&…