tianzhendong
3 years ago
23 changed files with 1959 additions and 1188 deletions
@ -1,3 +1,3 @@ |
|||
@echo off |
|||
cd C:\hexo_blog |
|||
cd C:\Blog\hexo_blog |
|||
git pull |
@ -0,0 +1,157 @@ |
|||
--- |
|||
title: Anaconda |
|||
author: TianZD |
|||
top: true |
|||
cover: true |
|||
toc: true |
|||
mathjax: false |
|||
summary: >- |
|||
Anaconda指的是一个开源的Python发行版本,其包含了conda、Python等180多个科学包及其依赖项。Conda是一个开源的包、环境管理器,可以用于在同一个机器上安装不同版本的软件包及其依赖,并能够在不同的环境之间切换 |
|||
tags: |
|||
- python |
|||
- conda |
|||
categories: |
|||
- python |
|||
reprintPolicy: cc_by |
|||
abbrlink: 5c8e05d2 |
|||
date: 2022-04-29 14:10:50 |
|||
coverImg: |
|||
img: |
|||
password: |
|||
--- |
|||
|
|||
|
|||
# Anaconda |
|||
|
|||
|
|||
|
|||
## 介绍 |
|||
|
|||
Anaconda指的是一个开源的Python发行版本,其包含了conda、Python等180多个科学包及其依赖项。 因为包含了大量的科学包,Anaconda 的下载文件比较大(约 531 MB),如果只需要某些包,或者需要节省带宽或存储空间,也可以使用Miniconda这个较小的发行版(仅包含conda和 Python)。 |
|||
|
|||
Conda是一个开源的包、环境管理器,可以用于在同一个机器上安装不同版本的软件包及其依赖,并能够在不同的环境之间切换 |
|||
|
|||
Anaconda包括Conda、Python以及一大堆安装好的工具包,比如:numpy、pandas等 |
|||
|
|||
Miniconda包括Conda、Python |
|||
|
|||
[清华Anaconda 镜像使用帮助](https://mirror.tuna.tsinghua.edu.cn/help/anaconda/) |
|||
|
|||
## 下载、安装 |
|||
|
|||
### 下载 |
|||
|
|||
[清华镜像]( https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/) |
|||
|
|||
[官网](https://www.anaconda.com/download/) |
|||
|
|||
### 安装 |
|||
|
|||
下载后一路NEXT |
|||
|
|||
![第五步](https://gitee.com/tianzhendong/img/raw/master/images/202202181420521.png) |
|||
|
|||
第一个选项是添加环境变量,默认是没有勾选的,请务必勾选上,如果这里不勾选,后续安装完成后想要自行添加环境变量会非常麻烦。勾选完后点击 Install 安装。如果忘了勾选可以卸载重装。 |
|||
|
|||
安装完成后在开始菜单会多出一个快捷方式,也就是Anaconda下的4个子程序: |
|||
|
|||
![开始菜单](https://gitee.com/tianzhendong/img/raw/master/images/202202181421240.png) |
|||
|
|||
其中Anaconda Prompt 就是我们的cmd |
|||
|
|||
Anaconda Navigator是管理器,可以在里面通过图像化界面管理虚拟环境 |
|||
|
|||
键入`python --version` 回车,查看当前安装的python版本 |
|||
我们也可以通过键入`python` 回车进入python解释器 |
|||
|
|||
安装完成后,在**终端**输入`conda -V`注意v为大写,可以查看conda版本 |
|||
|
|||
![image-20220218142336122](https://gitee.com/tianzhendong/img/raw/master//images/202202230852094.png) |
|||
|
|||
## 更改源 |
|||
|
|||
[清华Anaconda 镜像使用帮助](https://mirror.tuna.tsinghua.edu.cn/help/anaconda/) |
|||
|
|||
各系统都可以通过修改用户目录下的 `.condarc` 文件 |
|||
|
|||
Windows 用户无法直接创建名为 `.condarc` 的文件,可先执行 `conda config --set show_channel_urls yes` 生成该文件之后再修改。 |
|||
|
|||
```bash |
|||
channels: |
|||
- defaults |
|||
show_channel_urls: true |
|||
default_channels: |
|||
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main |
|||
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r |
|||
- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2 |
|||
custom_channels: |
|||
conda-forge: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud |
|||
msys2: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud |
|||
bioconda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud |
|||
menpo: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud |
|||
pytorch: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud |
|||
pytorch-lts: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud |
|||
simpleitk: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud |
|||
``` |
|||
|
|||
即可添加 Anaconda Python 免费仓库。 |
|||
|
|||
运行 `conda clean -i` 清除索引缓存,保证用的是镜像站提供的索引。 |
|||
|
|||
运行 `conda create -n myenv numpy` 测试一下吧。 |
|||
|
|||
## 虚拟环境 |
|||
|
|||
[Anaconda创建、激活、退出、删除虚拟环境](https://blog.csdn.net/sizhi_xht/article/details/80964099?spm=1001.2101.3001.6650.6&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-6.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-6.pc_relevant_default&utm_relevant_index=11) |
|||
|
|||
方法1:通过Anaconda Navigator应用图形化方式管理,安装anaconda后自带 |
|||
|
|||
方法2:通过命令行 |
|||
|
|||
### 创建虚拟环境 |
|||
|
|||
使用 `conda create -n your_env_name python=X.X(2.7、3.6等)` |
|||
|
|||
anaconda 命令创建python版本为X.X、名字为your_env_name的虚拟环境。your_env_name文件可以在Anaconda安装目录envs文件下找到。 指定python版本为2.7,注意至少需要指定python版本或者要安装的包, 在不指定python版本时,自动安装最新python版本。 |
|||
|
|||
```bash |
|||
conda create -n env_name python=2.7 |
|||
# 同时安装必要的包 |
|||
conda create -n env_name numpy matplotlib python=2.7 |
|||
``` |
|||
|
|||
### 激活虚拟环境 |
|||
|
|||
使用如下命令即可激活创建的虚拟环境 |
|||
|
|||
Linux: `source activate your_env_name(虚拟环境名称)` |
|||
|
|||
Windows: `activate your_env_name(虚拟环境名称)` |
|||
|
|||
### 退出虚拟环境 |
|||
|
|||
使用如下命令即可退出创建的虚拟环境 |
|||
|
|||
Linux: `source deactivate your_env_name(虚拟环境名称)` |
|||
|
|||
Windows:`deactivate env_name`,也可以使用`activate root`切回root环境 |
|||
|
|||
### 虚拟环境管理 |
|||
|
|||
**删除环境:** |
|||
|
|||
使用命令`conda remove -n your_env_name(虚拟环境名称) --all`, 即可删除。 |
|||
|
|||
**删除虚拟环境中的包:** |
|||
|
|||
使用命令`conda remove --name $your_env_name $package_name(包名)` 即可。 |
|||
|
|||
|
|||
|
|||
## 常用命令 |
|||
|
|||
1. `conda list`:查看安装了哪些包。 |
|||
2. `conda install package_name(包名)`:安装包 |
|||
3. `conda env list 或 conda info -e`:查看当前存在哪些虚拟环境 |
|||
4. `conda update conda`:检查更新当前conda |
|||
|
@ -1,185 +0,0 @@ |
|||
--- |
|||
title: QT调用python代码 |
|||
date: 2022年4月28日 |
|||
author: TianZD |
|||
top: true |
|||
cover: true |
|||
toc: true |
|||
mathjax: false |
|||
summary: 在QT Creator中调用python代码 |
|||
tags: |
|||
- QT |
|||
- 编程 |
|||
categories: |
|||
- QT |
|||
abbrlink: c4a1e2a7 |
|||
reprintPolicy: cc_by |
|||
coverImg: |
|||
img: |
|||
password: |
|||
--- |
|||
[toc] |
|||
|
|||
# QT调用Python |
|||
|
|||
## 前言 |
|||
|
|||
QT上位机程序和python程序交互: |
|||
|
|||
- QT调用python代码 |
|||
- QT和python通过数据库交互 |
|||
- QT和python通过网络编程交互 |
|||
|
|||
## 环境 |
|||
|
|||
电脑:windows11 |
|||
|
|||
Anaconda中的opencv虚拟环境,python版本:3.9.7 |
|||
|
|||
Anaconda路径:`C:\ProgramData\Anaconda3` |
|||
|
|||
虚拟环境路径:`C:\Users\12038\.conda\envs\opencv\` |
|||
|
|||
## 配置 |
|||
|
|||
### QT添加python库文件 |
|||
|
|||
在pro文件中添加 |
|||
|
|||
```properties |
|||
INCLUDEPATH +=C:\Users\12038\.conda\envs\opencv\include ############# python enviroment |
|||
LIBS += -LC:\Users\12038\.conda\envs\opencv\libs\ |
|||
-l_tkinter\ |
|||
-lpython3\ |
|||
-lpython39 |
|||
``` |
|||
|
|||
python路径\include |
|||
|
|||
python路径\libs |
|||
|
|||
### 添加python文件 |
|||
|
|||
右键QT项目文件,新建python文件 |
|||
|
|||
![image-20220221182133817](https://gitee.com/tianzhendong/img/raw/master//images/202202211821926.png) |
|||
|
|||
编写python代码,这里为`test1.py` |
|||
|
|||
```python |
|||
# This Python file uses the following encoding: utf-8 |
|||
|
|||
# if __name__ == "__main__": |
|||
# pass |
|||
def hello(): |
|||
print("hello world!") |
|||
``` |
|||
|
|||
### QT调用 |
|||
|
|||
```c |
|||
#include <QCoreApplication> |
|||
#include <Python.h> //添加python |
|||
#include <iostream> |
|||
using namespace std; |
|||
int main(int argc, char *argv[]) |
|||
{ |
|||
QCoreApplication a(argc, argv); |
|||
|
|||
Py_Initialize(); //初始化 |
|||
if ( !Py_IsInitialized() ) |
|||
{ |
|||
return -1; |
|||
} |
|||
PyObject* pModule = PyImport_ImportModule("test1"); // 这里的test1就是创建的python文件 |
|||
if (!pModule) { |
|||
cout<< "Cant open python file!\n" << endl; |
|||
return -1; |
|||
} |
|||
PyObject* pFunhello= PyObject_GetAttrString(pModule,"hello"); // 这里的hellow就是python文件定义的函数 |
|||
if(!pFunhello){ |
|||
cout<<"Get function hello failed"<<endl; |
|||
return -1; |
|||
} |
|||
PyObject_CallFunction(pFunhello,NULL); //调用hello函数 |
|||
Py_Finalize(); //释放 |
|||
|
|||
return a.exec(); |
|||
} |
|||
``` |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
## 遇到的问题 |
|||
|
|||
https://blog.csdn.net/alxe_made/article/details/83382159 |
|||
|
|||
### error: C2238: 意外的标记位于“;”之前 |
|||
|
|||
出现的原因: |
|||
|
|||
**由于QT中定义了slots作为关键了,而python3中有使用slot作为变量,所以有冲突** |
|||
|
|||
解决方法: |
|||
|
|||
在python的object.h中 slots冲突,因此修改object.h |
|||
|
|||
`C:\Users\12038\.conda\envs\opencv\include\object.h` |
|||
|
|||
在`PyType_Slot *slots; `上下加上两句代码,如下 |
|||
|
|||
```python |
|||
typedef struct{ |
|||
const char* name; |
|||
int basicsize; |
|||
int itemsize; |
|||
unsigned int flags; |
|||
#undef slots //取消宏定义 |
|||
PyType_Slot *slots; /* terminated by slot==0. */ |
|||
#define slots Q_SLOTS |
|||
} PyType_Spec; |
|||
``` |
|||
|
|||
### 无法打开python39_d.lib |
|||
|
|||
修改`C:\Users\12038\.conda\envs\opencv\include\pyconfig.h`文件,将`python39_d.lib`改为`python39.lib` |
|||
|
|||
```python |
|||
#ifdef MS_COREDLL |
|||
# if !defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_BUILTIN) |
|||
/* not building the core - must be an ext */ |
|||
# if defined(_MSC_VER) |
|||
/* So MSVC users need not specify the .lib |
|||
file in their Makefile (other compilers are |
|||
generally taken care of by distutils.) */ |
|||
# if defined(_DEBUG) |
|||
# pragma comment(lib,"python39.lib") //修改后 |
|||
// # pragma comment(lib,"python39_d.lib") //修改前 |
|||
# elif defined(Py_LIMITED_API) |
|||
# pragma comment(lib,"python3.lib") |
|||
# else |
|||
# pragma comment(lib,"python39.lib") |
|||
# endif /* _DEBUG */ |
|||
# endif /* _MSC_VER */ |
|||
# endif /* Py_BUILD_CORE */ |
|||
#endif /* MS_COREDLL */ |
|||
``` |
|||
|
|||
### error: failed to get the Python codec of the filesystem encoding |
|||
|
|||
https://blog.csdn.net/qq_43302566/article/details/121537908 |
|||
|
|||
PYTHONHOME 和 PYTHONPATH 找不到路径,其实类似于JAVA的环境变量 |
|||
|
|||
**出现这种原因,我的是因为用了Anaconda的python!!!** |
|||
|
|||
**把PYTHONHOME 和 PYTHONPATH改成conda的目录即可!** |
|||
|
|||
![image-20220221162124213](https://gitee.com/tianzhendong/img/raw/master//images/202202211621272.png) |
|||
|
|||
### Cant open python file! |
|||
|
|||
把python文件手动复制到QT debug文件夹下 |
|||
|
@ -0,0 +1,527 @@ |
|||
--- |
|||
title: Linux定时执行脚本-转载 |
|||
author: TianZD |
|||
top: true |
|||
cover: true |
|||
toc: true |
|||
mathjax: false |
|||
summary: Linux环境下定时执行任务 |
|||
tags: |
|||
- linux |
|||
- 定时 |
|||
categories: |
|||
- linux |
|||
- 转载 |
|||
reprintPolicy: cc_by |
|||
abbrlink: 5177677b |
|||
date: 2022-04-29 13:32:25 |
|||
coverImg: |
|||
img: |
|||
password: |
|||
--- |
|||
|
|||
[toc] |
|||
|
|||
# Linux定时执行脚本 |
|||
转载自[CSDN博主「编程爱好者熊浪」的原创文章](https://blog.csdn.net/xionglangs/article/details/52913351) |
|||
|
|||
## 创建 |
|||
|
|||
输入: |
|||
|
|||
`sudo crontab -e` |
|||
|
|||
输入: |
|||
|
|||
```shell |
|||
5 * * * *每小时第5分钟执行 |
|||
*/5 * * * *每5分钟执行 |
|||
0 2 * * * 每天凌晨2点执行 |
|||
``` |
|||
|
|||
cron是一个linux下的定时执行工具,可以在无需人工干预的情况下运行作业。由于Cron 是Linux的内置服务,但它不自动起来,可以用以下的方法启动、关闭这个服务: |
|||
|
|||
```sh |
|||
/sbin/service crond start //启动服务 |
|||
/sbin/service crond stop //关闭服务 |
|||
/sbin/service crond restart //重启服务 |
|||
/sbin/service crond reload //重新载入配置 |
|||
``` |
|||
|
|||
你也可以将这个服务在系统启动的时候自动启动: |
|||
|
|||
```sh |
|||
vim /etc/rc.d/rc.local |
|||
#这个脚本的末尾加上: |
|||
/sbin/service crond start |
|||
``` |
|||
|
|||
现在Cron这个服务已经在进程里面了,我们就可以用这个服务了,Cron服务提供以下几种接口供大家使用: |
|||
|
|||
## 编辑 |
|||
|
|||
1、直接用crontab命令编辑 |
|||
|
|||
cron服务提供crontab命令来设定cron服务的,以下是这个命令的一些参数与说明: |
|||
|
|||
`crontab -u `//设定某个用户的cron服务,一般root用户在执行这个命令的时候需要此参数 |
|||
|
|||
```sh |
|||
#列出某个用户cron服务的详细内容,如:root查看自己的cron设置:crontab -u root -l |
|||
crontab -l |
|||
#删除某个用户的cron服务,如:root想删除fred的cron设置:crontab -u fred -r |
|||
crontab -r |
|||
#编辑某个用户的cron服务,如:crontab -u root -e |
|||
crontab -e |
|||
#在编辑cron服务时,编辑的内容有一些格式和约定,输入: |
|||
#进入vi编辑模式,编辑的内容一定要符合下面的格式:*/1 * * * * ls >> /tmp/ls.txt |
|||
``` |
|||
|
|||
这个格式的前一部分是对时间的设定,后面一部分是要执行的命令,如果要执行的命令太多,可以把这些命令写到一个脚本里面,然后在这里直接调用这个脚本就可以了,调用的时候记得写出命令的完整路径。时间的设定我们有一定的约定,前面五个*号代表五个数字,数字的取值范围和含义如下: |
|||
|
|||
```txt |
|||
分钟 (0-59) |
|||
小時 (0-23) |
|||
日期 (1-31) |
|||
月份 (1-12) |
|||
星期 (0-6)//0代表星期天 |
|||
``` |
|||
|
|||
|
|||
|
|||
除了数字还有几个个特殊的符号就是"\*"、"/"和"-"、"," |
|||
|
|||
```txt |
|||
*代表所有的取值范围内的数字, |
|||
"/"代表每的意思, |
|||
"*/5"表示每5个单位, |
|||
"-"代表从某个数字到某个数字, |
|||
","分开几个离散的数字。 |
|||
``` |
|||
|
|||
|
|||
|
|||
以下举几个例子说明问题: |
|||
|
|||
- 每天早上6点 |
|||
|
|||
0 6 * * * echo "Good morning." >> /tmp/test.txt //注意单纯echo,从屏幕上看不到任何输出,因为cron把任何输出都email到root的信箱了。 |
|||
|
|||
- 每两个小时 |
|||
|
|||
0 */2 * * * echo "Have a break now." >> /tmp/test.txt |
|||
|
|||
- 晚上11点到早上8点之间每两个小时,早上八点 |
|||
|
|||
0 23-7/2,8 * * * echo "Have a good dream:)" >> /tmp/test.txt |
|||
|
|||
- 每个月的4号和每个礼拜的礼拜一到礼拜三的早上11点 |
|||
|
|||
0 11 4 * 1-3 command line |
|||
|
|||
- 1月1日早上4点 |
|||
|
|||
0 4 1 1 * command line |
|||
|
|||
每次编辑完某个用户的cron设置后,cron自动在/var/spool/cron下生成一个与此用户同名的文件,此用户的cron信息都记录在这个文件中,这个文件是不可以直接编辑的,只可以用crontab -e 来编辑。cron启动后每过一份钟读一次这个文件,检查是否要执行里面的命令。因此此文件修改后不需要重新启动cron服务。 |
|||
|
|||
2、编辑/etc/crontab 文件配置cron |
|||
|
|||
cron服务每分钟不仅要读一次/var/spool/cron内的所有文件,还需要读一次/etc/crontab,因此我们配置这个文件也能运用 cron服务做一些事情。用crontab配置是针对某个用户的,而编辑/etc/crontab是针对系统的任务。此文件的文件格式是: |
|||
|
|||
```shell |
|||
SHELL=/bin/bash |
|||
PATH=/sbin:/bin:/usr/sbin:/usr/bin |
|||
#如果出现错误,或者有数据输出,数据作为邮件发给这个帐号 |
|||
MAILTO=root |
|||
#使用者运行的路径,这里是根目录 |
|||
HOME=/ |
|||
``` |
|||
|
|||
|
|||
|
|||
## run-parts |
|||
|
|||
```shell |
|||
#run-parts某个文件夹,根目录+文件夹+执行当前文件夹下面所有脚本 |
|||
01 * * * * root run-parts /etc/cron.hourly //每小时执行/etc/cron.hourly内的脚本 |
|||
02 4 * * * root run-parts /etc/cron.daily //每天执行/etc/cron.daily内的脚本 |
|||
22 4 * * 0 root run-parts /etc/cron.weekly //每星期执行/etc/cron.weekly内的脚本 |
|||
42 4 1 * * root run-parts /etc/cron.monthly //每月去执行/etc/cron.monthly内的脚本 |
|||
``` |
|||
|
|||
大家注意"run-parts"这个参数了,如果去掉这个参数的话,后面就可以写要运行的某个脚本名,而不是文件夹名了。 |
|||
|
|||
-------------------------------------- |
|||
|
|||
基本格式 : |
|||
|
|||
\* \* \* \* \* command |
|||
|
|||
分 时 日 月 周 命令 |
|||
|
|||
第1列表示分钟1~59 每分钟用*或者 */1表示 |
|||
第2列表示小时1~23(0表示0点) |
|||
第3列表示日期1~31 |
|||
第4列表示月份1~12 |
|||
第5列标识号星期0~6(0表示星期天) |
|||
第6列要运行的命令 |
|||
|
|||
crontab文件的一些例子: |
|||
|
|||
30 21 * * * /usr/local/etc/rc.d/lighttpd restart |
|||
上面的例子表示每晚的21:30重启lighttpd 。 |
|||
|
|||
45 4 1,10,22 * * /usr/local/etc/rc.d/lighttpd restart |
|||
上面的例子表示每月1、10、22日的4 : 45重启lighttpd 。 |
|||
|
|||
10 1 * * 6,0 /usr/local/etc/rc.d/lighttpd restart |
|||
上面的例子表示每周六、周日的1 : 10重启lighttpd 。 |
|||
|
|||
0,30 18-23 * * * /usr/local/etc/rc.d/lighttpd restart |
|||
上面的例子表示在每天18 : 00至23 : 00之间每隔30分钟重启lighttpd 。 |
|||
|
|||
0 23 * * 6 /usr/local/etc/rc.d/lighttpd restart |
|||
上面的例子表示每星期六的11 : 00 pm重启lighttpd 。 |
|||
|
|||
\* */1 * * * /usr/local/etc/rc.d/lighttpd restart |
|||
每一小时重启lighttpd |
|||
|
|||
\* 23-7/1 * * * /usr/local/etc/rc.d/lighttpd restart |
|||
晚上11点到早上7点之间,每隔一小时重启lighttpd |
|||
|
|||
0 11 4 * mon-wed /usr/local/etc/rc.d/lighttpd restart |
|||
每月的4号与每周一到周三的11点重启lighttpd |
|||
|
|||
0 4 1 jan * /usr/local/etc/rc.d/lighttpd restart |
|||
一月一号的4点重启lighttpd |
|||
|
|||
========================================= |
|||
crontab -e |
|||
|
|||
进入一个vi 编辑界面 |
|||
|
|||
在最后一行加上 |
|||
|
|||
*/30 * * * * netstat > /tmp/net.log |
|||
|
|||
表示每隔30分就执行netstat命令,并把执行结果存入net.log中。 |
|||
|
|||
Crontab是一个很方便的在unix/linux系统上定时(循环)执行某个任务的程序 |
|||
|
|||
使用cron服务,用 service crond status 查看 cron服务状态,如果没有启动则 service crond start启动它, |
|||
|
|||
cron服务是一个定时执行的服务,可以通过crontab 命令添加或者编辑需要定时执行的任务: |
|||
|
|||
crontab -u //设定某个用户的cron服务,一般root用户在执行这个命令的时候需要此参数 |
|||
|
|||
crontab -l //列出某个用户cron服务的详细内容 |
|||
|
|||
crontab -r //删除没个用户的cron服务 |
|||
|
|||
crontab -e //编辑某个用户的cron服务 |
|||
|
|||
比如说root查看自己的cron设置:crontab -u root -l |
|||
|
|||
再例如,root想删除fred的cron设置:crontab -u fred -r |
|||
|
|||
在编辑cron服务时,编辑的内容有一些格式和约定,输入:crontab -u root -e |
|||
|
|||
进入vi编辑模式,编辑的内容一定要符合下面的格式:*/1 * * * * ls >> /tmp/ls.txt |
|||
|
|||
编辑/etc/crontab文件,在末尾加上一行: 30 5 * * * root init 6 这样就将系统配置为了每天早上5点30自动重新启动。 |
|||
|
|||
需要将crond设置为系统启动后自动启动的服务,可以在/etc/rc.d/rc.local 中,在末尾加上 |
|||
|
|||
service crond start |
|||
|
|||
如果还需要在系统启动十加载其他服务,可以继续加上其他服务的启动命令。 |
|||
|
|||
比如: service mysqld start |
|||
|
|||
基本用法: |
|||
|
|||
1. crontab -l |
|||
|
|||
列出当前的crontab任务 |
|||
|
|||
2. crontab -d |
|||
|
|||
删除当前的crontab任务 |
|||
|
|||
3. crontab -e (solaris5.8上面是 crontab -r) |
|||
|
|||
编辑一个crontab任务,ctrl_D结束 |
|||
|
|||
4. crontab filename |
|||
|
|||
以filename做为crontab的任务列表文件并载入 |
|||
|
|||
crontab file的格式: |
|||
|
|||
crontab 文件中的行由 6 个字段组成,不同字段间用空格或 tab 键分隔。前 5 个字段指定命令要运行的时间 |
|||
|
|||
分钟 (0-59) |
|||
|
|||
小时 (0-23) |
|||
|
|||
日期 (1-31) |
|||
|
|||
月份 (1-12) |
|||
|
|||
星期几(0-6,其中 0 代表星期日) |
|||
|
|||
第 6 个字段是一个要在适当时间执行的字符串 |
|||
|
|||
例子: |
|||
|
|||
#MIN HOUR DAY MONTH DAYOFWEEK COMMAND |
|||
|
|||
#每天早上6点10分 |
|||
|
|||
10 6 * * * date |
|||
|
|||
#每两个小时 |
|||
|
|||
0 */2 * * * date (solaris 5.8似乎不支持此种写法) |
|||
|
|||
#晚上11点到早上8点之间每两个小时,早上8点 |
|||
|
|||
0 23-7/2,8 * * * date |
|||
|
|||
#每个月的4号和每个礼拜的礼拜一到礼拜三的早上11点 |
|||
|
|||
0 11 4 * mon-wed date |
|||
|
|||
#1月份日早上4点 |
|||
|
|||
0 4 1 jan * date |
|||
|
|||
补充:在使用crontab的时候,要特别注意的是运行脚本中能够访问到的环境变量和当前测试环境中的环境变量未必一致,一个比较保险的做法是在运行的脚本程序中自行设置环境变量(export) |
|||
|
|||
(1)先建一个文件crond.txt如下, 每天早上5点36分重新启动 |
|||
|
|||
36 5 * * * reboot |
|||
|
|||
(2)上传到/opt目录 |
|||
|
|||
(3)运行命令 |
|||
|
|||
crontab /opt/crond.txt |
|||
|
|||
crontab -l |
|||
|
|||
让配置文件生效:如果让配置文件生效,还得重新启动cron,切记,既然每个用户下的cron配置文件修改后。也要重新启动cron服务器。 |
|||
|
|||
在Fedora 和RedHat中,我们应该用; |
|||
|
|||
[root@localhost ~]# /etc/init.d/crond restart |
|||
|
|||
如果让crond 在开机时运行,应该改变其运行级别; |
|||
|
|||
[root@localhost ~]# chkconfig --levels 35 crond on |
|||
|
|||
service crond status 查看 cron服务状态,如果没有启动则 service crond start启动它, cron服务是一个定时执行的服务,可以通过crontab 命令添加或者编辑需要定时执行的任务 |
|||
|
|||
Crontab文件的每一行由六个域(minutes、hours、day of month、month、day of week、 command)组 成,域之间用空格或Tab分开,其中: |
|||
|
|||
minutes: 分钟域,值的范围是0到59 |
|||
|
|||
hours: 小时域,值的范围是0到23 |
|||
|
|||
day of month: 日期,值的范围是1到31 |
|||
|
|||
month: 月份,值的范围是1到12 |
|||
|
|||
day of week: 星期,值的范围是0到6,星期日值为0 |
|||
|
|||
command: 所要运行的命令 |
|||
|
|||
如果一个域是*,表明命令可以在该域所有可能的取值范围内执行。 |
|||
|
|||
如果一个域是由连字符隔开的两个数字,表明命令可以在两个数字之间的范围内执行(包括两个数字 本身)。 |
|||
|
|||
如果一个域是由逗号隔开的一系列值组成的,表明命令可以在这些值组成的范围内执行。 |
|||
|
|||
如果日期域和星期域都有值,则这两个域都有效。 |
|||
|
|||
编写一个文件,用以启动自动备份进程。 |
|||
|
|||
cd /opt |
|||
|
|||
touch reboot.txt |
|||
|
|||
在reboot.txt中添加一下内容: |
|||
|
|||
0 4 * * * reboot |
|||
|
|||
crontab /opt/reboot.txt |
|||
|
|||
用crontab -e编辑定时操作,例如加入下行命令: |
|||
|
|||
用crontab -l命令来查看 |
|||
|
|||
注意:需要启动服务(添加在rc.local中) |
|||
|
|||
重启crond任务 |
|||
|
|||
/etc/init.d/cron restart (Ubuntu下) |
|||
|
|||
第一种 在Fedora或Redhat 等以RPM包管理的系统中; |
|||
|
|||
[root@localhost ~]# /etc/init.d/crond start |
|||
|
|||
[root@localhost ~]# /etc/init.d/crond stop |
|||
|
|||
[root@localhost ~]# /etc/init.d/crond restart |
|||
|
|||
/etc/rc.d/init.d/crond restart |
|||
|
|||
命令简介 |
|||
|
|||
crontab-操作每个用户的守护程序和该执行的时间表。 |
|||
|
|||
部分参数说明 |
|||
|
|||
crontab file [-u user]-用指定的文件替代目前的crontab。 |
|||
|
|||
crontab-[-u user]-用标准输入替代目前的crontab. |
|||
|
|||
crontab-1[user]-列出用户目前的crontab. |
|||
|
|||
crontab-e[user]-编辑用户目前的crontab. |
|||
|
|||
crontab-d[user]-删除用户目前的crontab. |
|||
|
|||
crontab-c dir- 指定crontab的目录。 |
|||
|
|||
crontab文件的格式:M H D m d cmd. |
|||
|
|||
M: 分钟(0-59)。 |
|||
|
|||
H:小时(0-23)。 |
|||
|
|||
D:天(1-31)。 |
|||
|
|||
m: 月(1-12)。 |
|||
|
|||
d: 一星期内的天(0~6,0为星期天)。 |
|||
|
|||
cmd要运行的程序,程序被送入sh执行,这个shell只有USER,HOME,SHELL这三个环境变量。 |
|||
|
|||
下面是一个例子文件: |
|||
|
|||
#MIN HOUR DAY MONTH DAYOFWEEK COMMAND |
|||
|
|||
#每天早上6点 |
|||
|
|||
106* * * date |
|||
|
|||
#每两个小时 |
|||
|
|||
0*/2* * * date |
|||
|
|||
#晚上11点到早上8点之间每两个小时,早上部点 |
|||
|
|||
0 23-7/2,8* * * date |
|||
|
|||
#每个月的4号和每个礼拜的礼拜一到礼拜三的早上11点 |
|||
|
|||
0 11 4* mon-wed date |
|||
|
|||
#1月份日早上4点 |
|||
|
|||
0 4 1 jan* date |
|||
|
|||
范例 |
|||
|
|||
lark:~>crontab-1 列出用户目前的crontab. |
|||
|
|||
#MIN HOUR DAY MONTH DAYOFWEEK COMMAND |
|||
|
|||
10 6* * * date |
|||
|
|||
0*/2* * * date |
|||
|
|||
0 23-7/2,8 * * * date |
|||
|
|||
lark:~> |
|||
|
|||
使用权限 : root用户和crontab文件的所有者 |
|||
|
|||
语法 : |
|||
|
|||
crontab [-e [UserName]|-l [UserName]|-r [UserName]|-v [UserName]|File ] |
|||
|
|||
重启:sudo /etc/init.d/cron restart |
|||
|
|||
说明 : |
|||
|
|||
crontab 是用来让使用者在固定时间或固定间隔执行程式之用,换句话说,也就是类似使用者的时程表。-u user 是指设定指定 user 的时程表,这个前提是你必须要有其权限(比如说是 root)才能够指定他人的时程表。如果不使用 -u user 的话,就是表示设定自己的时程表。 |
|||
|
|||
参数 : |
|||
|
|||
-e [UserName]: 执行文字编辑器来设定时程表,内定的文字编辑器是 VI,如果你想用别的文字编辑器,则请先设定 VISUAL 环境变数来指定使用那个文字编辑器(比如说 setenv VISUAL joe) |
|||
|
|||
-r [UserName]: 删除目前的时程表 |
|||
|
|||
-l [UserName]: 列出目前的时程表 |
|||
|
|||
-v [UserName]:列出用户cron作业的状态 |
|||
|
|||
时程表的格式如下 : |
|||
|
|||
f1 f2 f3 f4 f5 program |
|||
|
|||
其中 f1 是表示分钟,f2 表示小时,f3 表示一个月份中的第几日,f4 表示月份,f5 表示一个星期中的第几天。 |
|||
|
|||
program 表示要执行的程式,就是在终端写入的命令。 |
|||
|
|||
当 f1 为 * 时表示每分钟都要执行 program,f2 为 * 时表示每小时都要执行程式,其余类推 |
|||
|
|||
当 f1 为 a-b 时表示从第 a 分钟到第 b 分钟这段时间内要执行,f2 为 a-b 时表示从第 a 到第 b 小时都要执行,其余类推 |
|||
|
|||
当 f1 为 \*/n 时表示每 n 分钟个时间间隔执行一次,f2 为 \*/n 表示每 n 小时个时间间隔执行一次,其余类推 |
|||
|
|||
当 f1 为 a, b, c,... 时表示第 a, b, c,... 分钟要执行,f2 为 a, b, c,... 时表示第 a, b, c...个小时要执行,其余类推 |
|||
|
|||
使用者也可以将所有的设定先存放在档案 file 中,用 crontab file 的方式来设定时程表。 |
|||
|
|||
由于unix版本不一样,所以部分语法有差别,例如在hp unix aix 中设定间隔执行如果采用*/n 方式将出现语法错误,在这类unix中 ,间隔执行只能以列举方式,详请见例子。 |
|||
|
|||
使用方法: |
|||
|
|||
用VI编辑一个文件 cronfile,然后在这个文件中输入格式良好的时程表。编辑完成后,保存并退出。 |
|||
|
|||
在命令行输入 |
|||
|
|||
$: crontab cronfile |
|||
|
|||
这样就将cronfile文件提交给c r o n进程,同时,新创建cronfile的一个副本已经被放在/ v a r / s p o o l / c r o n目录中,文件名就是用户名。 |
|||
|
|||
例子 : |
|||
|
|||
每月每天每小时的第 0 分钟执行一次 /bin/ls : |
|||
|
|||
0 * * * * /bin/ls |
|||
|
|||
在 12 月内, 每天的早上 6 点到 12 点中,每隔 20 分钟执行一次 /usr/bin/backup : |
|||
|
|||
*/20 6-12 * 12 * /usr/bin/backup |
|||
|
|||
周一到周五每天下午 5:00 寄一封信给 alex@domain.name : |
|||
|
|||
0 17 * * 1-5 mail -s "hi" alex@domain.name < /tmp/maildata |
|||
|
|||
每月每天的午夜 0 点 20 分, 2 点 20 分, 4 点 20 分....执行 echo "haha" |
|||
|
|||
20 0-23/2 * * * echo "haha" |
|||
|
|||
晚上11点到早上8点之间每两个小时,早上8点 |
|||
|
|||
0 23-7/2,8 * * * date |
|||
|
|||
> 在hp unix,中,每20分钟执行一次,表示为:0,20,40 * * * * 而不能采用*/n方式,否则出现语法错误 |
|||
|
|||
版权声明:本文为CSDN博主「编程爱好者熊浪」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 |
|||
原文链接:https://blog.csdn.net/xionglangs/article/details/52913351 |
@ -0,0 +1,85 @@ |
|||
--- |
|||
title: SSH免密码连接-转载 |
|||
author: TianZD |
|||
top: true |
|||
cover: true |
|||
toc: true |
|||
mathjax: false |
|||
summary: ssh免密码连接配置 |
|||
tags: |
|||
- SSH |
|||
categories: |
|||
- 转载 |
|||
- linux |
|||
reprintPolicy: cc_by |
|||
abbrlink: 7f5b723e |
|||
date: 2022-04-29 13:35:05 |
|||
coverImg: |
|||
img: |
|||
password: |
|||
--- |
|||
|
|||
# SSH免密连接(转载) |
|||
|
|||
[toc] |
|||
|
|||
转自[VS code 连接远程服务器 免密登录设置](https://blog.csdn.net/weixin_38665694/article/details/115692316) |
|||
|
|||
## 客户端(连接端)生成密钥 |
|||
|
|||
一般是windows |
|||
|
|||
打开命令行 |
|||
|
|||
输入: |
|||
|
|||
```bash |
|||
ssh-keygen -t rsa -b 4096 |
|||
``` |
|||
|
|||
连续点击三次回车,生成密钥(如果已经生成,跳过) |
|||
|
|||
![在这里插入图片描述](https://gitee.com/tianzhendong/img/raw/master/images/202204191700953.png) |
|||
|
|||
2、进入C:\User\用户名/.ssh此处为C:\User\20202/.ssh目录可以看到生成了id_rsa和id_rsa.pub两个文件 |
|||
|
|||
![image-20220419170136752](https://gitee.com/tianzhendong/img/raw/master/images/202204191701807.png) |
|||
|
|||
3、用记事本打开id_rsa.pub,并复制里面的内容 |
|||
|
|||
## 服务器被连接端 |
|||
|
|||
一般为linux |
|||
|
|||
1、通过命令编辑authorized_keys文件。 |
|||
|
|||
```sh |
|||
vim ~/.ssh/authorized_keys |
|||
``` |
|||
|
|||
2、在win10系统中,用记事本打开id_rsa.pub,并复制里面的内容到authorized_keys文件中。 |
|||
|
|||
3、切换到这个.ssh目录, 并ls 确保生成authorized_keys文件。 |
|||
|
|||
```sh |
|||
cd ~/.ssh |
|||
``` |
|||
|
|||
4、修改authorized_keys文件权限。 |
|||
|
|||
```sh |
|||
sudo chmod 600 authorized_keys |
|||
``` |
|||
|
|||
5、修改~/.ssh文件夹权限。 |
|||
|
|||
```sh |
|||
sudo chmod 700 ~/.ssh |
|||
``` |
|||
|
|||
6、重启SSH便大功告成 |
|||
|
|||
```sh |
|||
sudo service sshd restart |
|||
``` |
|||
|
@ -0,0 +1,121 @@ |
|||
--- |
|||
title: linux更换源-转载 |
|||
author: TianZD |
|||
top: true |
|||
cover: true |
|||
toc: true |
|||
mathjax: false |
|||
summary: linux更换国内源,提升软件下载速度 |
|||
tags: |
|||
- linux |
|||
categories: |
|||
- linux |
|||
- 转载 |
|||
reprintPolicy: cc_by |
|||
abbrlink: 28825a1e |
|||
date: 2022-04-29 13:36:19 |
|||
coverImg: |
|||
img: |
|||
password: |
|||
--- |
|||
|
|||
# 【Linux教程】Ubuntu Linux 更换源教程 |
|||
|
|||
[blog.csdn.net](https://blog.csdn.net/weixin_43876206/article/details/100924378) |
|||
|
|||
> 因为Ubuntu自带的源已经老旧,下载速度慢,而且不稳定- |
|||
> 本教程告诉大家如何更换Ubuntu源到国内几个比较好的源 |
|||
|
|||
更换源步骤如下: |
|||
|
|||
1. 备份源列表 |
|||
|
|||
`sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak` |
|||
|
|||
2. 命令行打开sources.list文件 |
|||
|
|||
`sudo gedit /etc/apt/sources.list` |
|||
|
|||
3. 修改sources,list文件【本例更改为阿里镜像源】 |
|||
|
|||
# 阿里镜像源 |
|||
|
|||
```bash |
|||
deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse |
|||
deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse |
|||
|
|||
deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse |
|||
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse |
|||
|
|||
deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse |
|||
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse |
|||
|
|||
deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse |
|||
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse |
|||
|
|||
deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse |
|||
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse |
|||
``` |
|||
|
|||
4. 更新并升级 |
|||
|
|||
`sudo apt-get update && sudo apt-get upgrade` |
|||
|
|||
5. 等待更新并升级完成即可 |
|||
|
|||
【注意】更新过程中可能会有询问是否下载包的提示,输入y,按回车即可。 |
|||
|
|||
【注意!注意!注意】更新时一定要把Linux的网络连接检查是否已经连接上网络,不然会出错,我之前试一直不成功,困了好久,才发现是虚拟机的网络没有连接。。。 |
|||
|
|||
更新好后就可以用命令行进行安装软件或者插件了 |
|||
|
|||
> 如何用命令行安装gcc 和 g++ 参考文章:- |
|||
> [Linux下安装gcc 和 g++运行C程序](https://blog.csdn.net/weixin_43876206/article/details/100923785) |
|||
|
|||
最后再分享几个国内比较好的镜像源: |
|||
|
|||
``` |
|||
# 中科大镜像源 |
|||
deb https://mirrors.ustc.edu.cn/ubuntu/ bionic main restricted universe multiverse |
|||
deb-src https://mirrors.ustc.edu.cn/ubuntu/ bionic main restricted universe multiverse |
|||
deb https://mirrors.ustc.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse |
|||
deb-src https://mirrors.ustc.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse |
|||
deb https://mirrors.ustc.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse |
|||
deb-src https://mirrors.ustc.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse |
|||
deb https://mirrors.ustc.edu.cn/ubuntu/ bionic-security main restricted universe multiverse |
|||
deb-src https://mirrors.ustc.edu.cn/ubuntu/ bionic-security main restricted universe multiverse |
|||
deb https://mirrors.ustc.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse |
|||
deb-src https://mirrors.ustc.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse |
|||
|
|||
``` |
|||
|
|||
``` |
|||
# 清华镜像源 |
|||
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse |
|||
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse |
|||
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse |
|||
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse |
|||
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse |
|||
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse |
|||
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse |
|||
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse |
|||
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse |
|||
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse |
|||
|
|||
``` |
|||
|
|||
``` |
|||
# 163镜像源 |
|||
deb http://mirrors.163.com/ubuntu/ bionic main restricted universe multiverse |
|||
deb http://mirrors.163.com/ubuntu/ bionic-security main restricted universe multiverse |
|||
deb http://mirrors.163.com/ubuntu/ bionic-updates main restricted universe multiverse |
|||
deb http://mirrors.163.com/ubuntu/ bionic-proposed main restricted universe multiverse |
|||
deb http://mirrors.163.com/ubuntu/ bionic-backports main restricted universe multiverse |
|||
deb-src http://mirrors.163.com/ubuntu/ bionic main restricted universe multiverse |
|||
deb-src http://mirrors.163.com/ubuntu/ bionic-security main restricted universe multiverse |
|||
deb-src http://mirrors.163.com/ubuntu/ bionic-updates main restricted universe multiverse |
|||
deb-src http://mirrors.163.com/ubuntu/ bionic-proposed main restricted universe multiverse |
|||
deb-src http://mirrors.163.com/ubuntu/ bionic-backports main restricted universe multiverse |
|||
``` |
|||
|
|||
[查看原网页: blog.csdn.net](https://blog.csdn.net/weixin_43876206/article/details/100924378) |
@ -0,0 +1,99 @@ |
|||
--- |
|||
title: Labview打包程序-转载 |
|||
author: TianZD |
|||
top: true |
|||
cover: true |
|||
toc: true |
|||
mathjax: false |
|||
summary: labview打包程序,用于在没有安装labview环境的电脑上运行程序 |
|||
tags: |
|||
- labview |
|||
- 上位机 |
|||
- 打包程序 |
|||
categories: |
|||
- 上位机 |
|||
- labview |
|||
- 转载 |
|||
reprintPolicy: cc_by |
|||
abbrlink: 2c2d93c9 |
|||
date: 2022-04-29 13:42:18 |
|||
coverImg: |
|||
img: |
|||
password: |
|||
--- |
|||
|
|||
# Labview |
|||
|
|||
## 用LabVIEW打包EXE应用文件和打包程序安装文件的方法【转】 |
|||
|
|||
原文链接[blog.csdn.net](https://blog.csdn.net/weixin_41692285/article/details/87079330) |
|||
|
|||
我同学现在单位也要从事LabVIEW的编程学习,他们想把编写的软件放到另外的电脑上执行。网上搜索了一些,但是没有一个系统的归纳和汇总。借此机会,我把几种打包方案和区别整理一下发布在这里,欢迎大家批评指正,互相学习。 |
|||
|
|||
### 打包方式比对表 |
|||
|
|||
表1 打包方式比对 |
|||
|
|||
![image-20220218162532787](https://gitee.com/tianzhendong/img/raw/master//images/202202181625844.png) |
|||
|
|||
|
|||
|
|||
### 对应打包方式的具体方法 |
|||
|
|||
第1种VI打包方式,这里就不赘述了,拿个U盘拷贝一下就可以了。 |
|||
|
|||
### 应用文件打包 |
|||
|
|||
首先,必须在工程模式下,也就是打开名为“拟\*.lvproj”的文件。如果刚开始的时候,不是用创建工程的方式创建项目,然后一步步新建VI来编程的同学,也不用担心,打开VI,工具栏依次点击“**工具->通过VI生成应用程序(EXE)...**”,会弹出让你创建工程的提示,如图1所示,可以根据需要,确定工程的保存目录以及工程名称; |
|||
|
|||
![img](https://gitee.com/tianzhendong/img/raw/master//images/202202181625076.png) |
|||
|
|||
图1 通过VI生成应用程序提醒界面 |
|||
|
|||
点击“**继续**”后,就会自动打开lvproj工程文件,并开始新建应用程序流程。我们这里不着急往下。如果我们通过新建工程在创建VI进行编程,那么我们打开工程后**右击**其中的“程序生成规范”选择“**新建->应用程序(EXE)**”便可得到应用程序生成配置界面,该界面用户通过VI生成应用程序中点击“**继续**”按钮后的界面相同,配置界面如图3所示。 |
|||
|
|||
![img](https://gitee.com/tianzhendong/img/raw/master//images/202202181626273.png) |
|||
|
|||
图2 工程中新建应用程序选择界面 |
|||
|
|||
![img](https://gitee.com/tianzhendong/img/raw/master//images/202202181626357.png) |
|||
|
|||
图3 生成应用程序配置界面-初始 |
|||
|
|||
![img](https://gitee.com/tianzhendong/img/raw/master//images/202202181626523.png) |
|||
|
|||
图4 生成应用程序配置界面-源文件 |
|||
|
|||
1. 信息:修改应用程序目标文件的名称和保存路径; |
|||
2. 源文件:选择需要生成应用程序的源VI文件,单击选中后,点击最上的向右箭头,启动VI设置为程序的第一个VI,其他子VI(若有),则放置在“始终包括”栏中,如图4所示; |
|||
3. 其他设置可以根据需要,自行修改,单击生成即可在指定未知生成\*.exe文件。此时本地电脑中是有LabVIEW的,可以打开保存目录,查看一下.exe文件是否好用,保存目录截图如图5所示; |
|||
|
|||
![img](https://gitee.com/tianzhendong/img/raw/master//images/202202181626257.png) |
|||
|
|||
图5 应用程序保存文件 |
|||
|
|||
到此,应用程序打包结束; |
|||
|
|||
### 安装程序打包 |
|||
|
|||
安装程序打包同应用程序打包的流程类似。**首先必须在工程下新建应用程序!**非常重要;否则没有生成安装程序的源应用程序文件! |
|||
|
|||
安装程序的配置界面与图3类似,不再赘述,在源文件配置时,应当选择之前保存的应用程序文件,添加到程序文件对应目录中,如图6所示,选中后,点击亮起的向右箭头即可; |
|||
|
|||
![img](https://gitee.com/tianzhendong/img/raw/master//images/202202181632690.png) |
|||
|
|||
图6 安装程序配置界面-源文件 |
|||
|
|||
附加安装程序选择需要的核心程序文件即可,我的电脑中只有2013版,所以只有一个引擎可选,如图7。剩余选项根据自己的需要,自行定制。 |
|||
|
|||
![img](https://gitee.com/tianzhendong/img/raw/master//images/202202181626616.png) |
|||
|
|||
图7 安装程序配置界面-附加安装程序 |
|||
|
|||
点击生成,即可生成对应应用程序的安装程序。 |
|||
|
|||
到此为止,应用程序的打包和对应的安装程序打包均已演示完毕。如果有不对的地方,欢迎大家批评指正。 |
|||
|
|||
谢谢。 |
|||
|
|||
[查看原网页: blog.csdn.net]( |
@ -1,993 +0,0 @@ |
|||
--- |
|||
title: 文字背景粒子特效 |
|||
author: Luckey |
|||
coverImg: /medias/banner/7.jpg |
|||
top: false |
|||
cover: false |
|||
toc: true |
|||
mathjax: false |
|||
summary: '一款jQuery+CSS3的文字背景粒子动画特效,一共6种粒子效果,每种文字背景的粒子效果都不同,有漂浮的有坠落的等等。 ' |
|||
tags: |
|||
- jQuery+CSS3 |
|||
- 粒子特效 |
|||
- 转载 |
|||
categories: |
|||
- Luckey博客篇 |
|||
abbrlink: 4b3510a4 |
|||
reprintPolicy: cc_by |
|||
date: 2020-03-27 00:00:00 |
|||
img: |
|||
password: |
|||
--- |
|||
|
|||
### 前言 |
|||
|
|||
一款jQuery+CSS3的文字背景粒子动画特效,一共6种粒子效果,每种文字背景的粒子效果都不同,有漂浮的有坠落的等等。 |
|||
|
|||
### 0x001 特效演示 |
|||
|
|||
--- |
|||
|
|||
<div style="width: 100%;text-align: center; height: 120px; position: relative; bottom: 0px;" ><span class="particletext fire" style="font-size:48px;position: relative;">This is fires</span></div> |
|||
|
|||
|
|||
<div style="width: 100%;text-align: center; height: 120px; position: relative; bottom: 0px;" > <span class="particletext lines" style="font-size:48px; position: relative;">This is lines</span> |
|||
</div> |
|||
|
|||
<div style="width: 100%;text-align: center; height: 120px; position: relative; bottom: 0px;" ><span class="particletext hearts" style="font-size:48px; position: relative;">This is hearts</span></div> |
|||
|
|||
<div style="width: 100%;text-align: center; height: 120px; position: relative; bottom: 0px;" > <span class="particletext bubbles" style="font-size:48px; position: relative;">This is bubbles</span> |
|||
</div> |
|||
|
|||
<div style="width: 100%;text-align: center; height: 120px; position: relative; bottom: 0px;" > <span class="particletext confetti" style="font-size:48px; position: relative;">This is confetti</span> |
|||
</div> |
|||
|
|||
<div style="width: 100%;text-align: center; height: 120px; position: relative; bottom: 0px;" > <span class="particletext sunbeams" style="font-size:48px; position: relative;">This is sunbeams</span> |
|||
</div> |
|||
|
|||
<style> |
|||
|
|||
.particletext { |
|||
|
|||
} |
|||
|
|||
.fire > .particle { |
|||
position: absolute; |
|||
background-color: rgba(255, 193, 7, 0.5); |
|||
border-radius: 40px; |
|||
border-top-right-radius: 0px; |
|||
-webkit-animation: fires 0.8s linear infinite; |
|||
animation: fires 0.8s linear infinite; |
|||
-webkit-transform: rotate(-45deg); |
|||
transform: rotate(-45deg); |
|||
opacity: 0; |
|||
} |
|||
/*css keyframes 动画*/ |
|||
@-webkit-keyframes fires { |
|||
0% { |
|||
-webkit-transform: rotate(-70deg) translateY(0%); |
|||
transform: rotate(-70deg) translateY(0%); |
|||
} |
|||
25% { |
|||
-webkit-transform: rotate(-20deg) translateY(-5%); |
|||
transform: rotate(-20deg) translateY(-5%); |
|||
opacity: 1; |
|||
} |
|||
50% { |
|||
-webkit-transform: rotate(-70deg) translateY(-10%); |
|||
transform: rotate(-70deg) translateY(-10%); |
|||
} |
|||
75% { |
|||
-webkit-transform: rotate(-20deg) translateY(-20%); |
|||
transform: rotate(-20deg) translateY(-20%); |
|||
} |
|||
100% { |
|||
-webkit-transform: rotate(-70deg) translateY(-40%); |
|||
transform: rotate(-70deg) translateY(-40%); |
|||
opacity: 1; |
|||
} |
|||
} |
|||
@keyframes fires { |
|||
0% { |
|||
-webkit-transform: rotate(-70deg) translateY(0%); |
|||
transform: rotate(-70deg) translateY(0%); |
|||
} |
|||
25% { |
|||
-webkit-transform: rotate(-20deg) translateY(-5%); |
|||
transform: rotate(-20deg) translateY(-5%); |
|||
opacity: 1; |
|||
} |
|||
50% { |
|||
-webkit-transform: rotate(-70deg) translateY(-10%); |
|||
transform: rotate(-70deg) translateY(-10%); |
|||
} |
|||
75% { |
|||
-webkit-transform: rotate(-20deg) translateY(-20%); |
|||
transform: rotate(-20deg) translateY(-20%); |
|||
} |
|||
100% { |
|||
-webkit-transform: rotate(-70deg) translateY(-40%); |
|||
transform: rotate(-70deg) translateY(-40%); |
|||
opacity: 1; |
|||
} |
|||
} |
|||
</style> |
|||
|
|||
|
|||
<script type="text/javascript" src="https://code.jquery.com/jquery-3.1.1.min.js"></script> |
|||
<script> |
|||
function fire() { |
|||
$.each($(".particletext.fire"), function(){ |
|||
var firecount = ($(this).width()/50)*20; |
|||
for(var i = 0; i <= firecount; i++) { |
|||
var size = $.rnd(8,12); |
|||
$(this).append('<span class="particle" style="top:' + $.rnd(40,70) + '%; left:' + $.rnd(-10,100) + '%;width:' + size + 'px; height:' + size + 'px;animation-delay: ' + ($.rnd(0,20)/10) + 's;"></span>'); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
</script> |
|||
|
|||
<style> |
|||
.lines > .particle { |
|||
position: absolute; |
|||
background-color: rgba(244, 67, 54, 0.5); |
|||
-webkit-animation: lines 3s linear infinite; |
|||
animation: lines 3s linear infinite; |
|||
} |
|||
@-webkit-keyframes lines { |
|||
0%, 50%, 100% { |
|||
-webkit-transform: translateY(0%); |
|||
transform: translateY(0%); |
|||
} |
|||
25% { |
|||
-webkit-transform: translateY(100%); |
|||
transform: translateY(100%); |
|||
} |
|||
75% { |
|||
-webkit-transform: translateY(-100%); |
|||
transform: translateY(-100%); |
|||
} |
|||
} |
|||
@keyframes lines { |
|||
0%, 50%, 100% { |
|||
-webkit-transform: translateY(0%); |
|||
transform: translateY(0%); |
|||
} |
|||
25% { |
|||
-webkit-transform: translateY(100%); |
|||
transform: translateY(100%); |
|||
} |
|||
75% { |
|||
-webkit-transform: translateY(-100%); |
|||
transform: translateY(-100%); |
|||
} |
|||
} |
|||
</style> |
|||
|
|||
<script> |
|||
function lines() { |
|||
$.each($(".particletext.lines"), function(){ |
|||
var linecount = ($(this).width()/50)*10; |
|||
for(var i = 0; i <= linecount; i++) { |
|||
$(this).append('<span class="particle" style="top:' + $.rnd(-30,30) + '%; left:' + $.rnd(-10,110) + '%;width:' + $.rnd(1,3) + 'px; height:' + $.rnd(20,80) + '%;animation-delay: -' + ($.rnd(0,30)/10) + 's;"></span>'); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
</script> |
|||
|
|||
<style> |
|||
.hearts > .particle { |
|||
opacity: 0; |
|||
position: absolute; |
|||
background-color: #cc2a5d; |
|||
-webkit-animation: hearts 3s ease-in infinite; |
|||
animation: hearts 3s ease-in infinite; |
|||
} |
|||
.hearts > .particle:before,.hearts > .particle:after { |
|||
position: absolute; |
|||
content: ''; |
|||
border-radius: 100px; |
|||
top: 0px; |
|||
left: 0px; |
|||
width: 100%; |
|||
height: 100%; |
|||
background-color: #cc2a5d; |
|||
} |
|||
.hearts > .particle:before { |
|||
-webkit-transform: translateX(-50%); |
|||
transform: translateX(-50%); |
|||
} |
|||
.hearts > .particle:after { |
|||
-webkit-transform: translateY(-50%); |
|||
transform: translateY(-50%); |
|||
} |
|||
@-webkit-keyframes hearts { |
|||
0% { |
|||
opacity: 0; |
|||
-webkit-transform: translate(0, 0%) rotate(45deg); |
|||
transform: translate(0, 0%) rotate(45deg); |
|||
} |
|||
20% { |
|||
opacity: 0.8; |
|||
-webkit-transform: translate(0, -20%) rotate(45deg); |
|||
transform: translate(0, -20%) rotate(45deg); |
|||
} |
|||
100% { |
|||
opacity: 0; |
|||
-webkit-transform: translate(0, -1000%) rotate(45deg); |
|||
transform: translate(0, -1000%) rotate(45deg); |
|||
} |
|||
} |
|||
@keyframes hearts { |
|||
0% { |
|||
opacity: 0; |
|||
-webkit-transform: translate(0, 0%) rotate(45deg); |
|||
transform: translate(0, 0%) rotate(45deg); |
|||
} |
|||
20% { |
|||
opacity: 0.8; |
|||
-webkit-transform: translate(0, -20%) rotate(45deg); |
|||
transform: translate(0, -20%) rotate(45deg); |
|||
} |
|||
100% { |
|||
opacity: 0; |
|||
-webkit-transform: translate(0, -1000%) rotate(45deg); |
|||
transform: translate(0, -1000%) rotate(45deg); |
|||
} |
|||
} |
|||
</style> |
|||
|
|||
|
|||
|
|||
|
|||
<script> |
|||
function hearts() { |
|||
$.each($(".particletext.hearts"), function(){ |
|||
var heartcount = ($(this).width()/50)*5; |
|||
for(var i = 0; i <= heartcount; i++) { |
|||
var size = ($.rnd(60,120)/10); |
|||
$(this).append('<span class="particle" style="top:' + $.rnd(20,80) + '%; left:' + $.rnd(0,95) + '%;width:' + size + 'px; height:' + size + 'px;animation-delay: ' + ($.rnd(0,30)/10) + 's;"></span>'); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
</script> |
|||
|
|||
<style> |
|||
.bubbles > .particle { |
|||
opacity: 0; |
|||
position: absolute; |
|||
background-color: rgba(33, 150, 243, 0.5); |
|||
-webkit-animation: bubbles 3s ease-in infinite; |
|||
animation: bubbles 3s ease-in infinite; |
|||
border-radius: 100%; |
|||
} |
|||
@-webkit-keyframes bubbles { |
|||
0% { |
|||
opacity: 0; |
|||
} |
|||
20% { |
|||
opacity: 1; |
|||
-webkit-transform: translate(0, -20%); |
|||
transform: translate(0, -20%); |
|||
} |
|||
100% { |
|||
opacity: 0; |
|||
-webkit-transform: translate(0, -1000%); |
|||
transform: translate(0, -1000%); |
|||
} |
|||
} |
|||
|
|||
@keyframes bubbles { |
|||
0% { |
|||
opacity: 0; |
|||
} |
|||
20% { |
|||
opacity: 1; |
|||
-webkit-transform: translate(0, -20%); |
|||
transform: translate(0, -20%); |
|||
} |
|||
100% { |
|||
opacity: 0; |
|||
-webkit-transform: translate(0, -1000%); |
|||
transform: translate(0, -1000%); |
|||
} |
|||
} |
|||
</style> |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
<script> |
|||
function bubbles() { |
|||
$.each($(".particletext.bubbles"), function(){ |
|||
var bubblecount = ($(this).width()/50)*10; |
|||
for(var i = 0; i <= bubblecount; i++) { |
|||
var size = ($.rnd(40,80)/10); |
|||
$(this).append('<span class="particle" style="top:' + $.rnd(20,80) + '%; left:' + $.rnd(0,95) + '%;width:' + size + 'px; height:' + size + 'px;animation-delay: ' + ($.rnd(0,30)/10) + 's;"></span>'); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
</script> |
|||
|
|||
<style> |
|||
.confetti > .particle { |
|||
opacity: 0; |
|||
position: absolute; |
|||
-webkit-animation: confetti 3s ease-in infinite; |
|||
animation: confetti 3s ease-in infinite; |
|||
} |
|||
.confetti > .particle.c1 { |
|||
background-color: rgba(76, 175, 80, 0.5); |
|||
} |
|||
.confetti > .particle.c2 { |
|||
background-color: rgba(156, 39, 176, 0.5); |
|||
} |
|||
@-webkit-keyframes confetti { |
|||
0% { |
|||
opacity: 0; |
|||
-webkit-transform: translateY(0%) rotate(0deg); |
|||
transform: translateY(0%) rotate(0deg); |
|||
} |
|||
10% { |
|||
opacity: 1; |
|||
} |
|||
35% { |
|||
-webkit-transform: translateY(-800%) rotate(270deg); |
|||
transform: translateY(-800%) rotate(270deg); |
|||
} |
|||
80% { |
|||
opacity: 1; |
|||
} |
|||
100% { |
|||
opacity: 0; |
|||
-webkit-transform: translateY(2000%) rotate(1440deg); |
|||
transform: translateY(2000%) rotate(1440deg); |
|||
} |
|||
} |
|||
@keyframes confetti { |
|||
0% { |
|||
opacity: 0; |
|||
-webkit-transform: translateY(0%) rotate(0deg); |
|||
transform: translateY(0%) rotate(0deg); |
|||
} |
|||
10% { |
|||
opacity: 1; |
|||
} |
|||
35% { |
|||
-webkit-transform: translateY(-800%) rotate(270deg); |
|||
transform: translateY(-800%) rotate(270deg); |
|||
} |
|||
80% { |
|||
opacity: 1; |
|||
} |
|||
100% { |
|||
opacity: 0; |
|||
-webkit-transform: translateY(2000%) rotate(1440deg); |
|||
transform: translateY(2000%) rotate(1440deg); |
|||
} |
|||
} |
|||
</style> |
|||
|
|||
|
|||
|
|||
|
|||
<script> |
|||
function confetti() { |
|||
$.each($(".particletext.confetti"), function(){ |
|||
var confetticount = ($(this).width()/50)*10; |
|||
for(var i = 0; i <= confetticount; i++) { |
|||
$(this).append('<span class="particle c' + $.rnd(1,2) + '" style="top:' + $.rnd(10,50) + '%; left:' + $.rnd(0,100) + '%;width:' + $.rnd(6,8) + 'px; height:' + $.rnd(3,4) + 'px;animation-delay: ' + ($.rnd(0,30)/10) + 's;"></span>'); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
</script> |
|||
|
|||
<style> |
|||
.sunbeams > .particle { |
|||
position: absolute; |
|||
background-color: rgba(253, 216, 53, 0.5); |
|||
-webkit-animation: sunbeams 3s linear infinite; |
|||
animation: sunbeams 3s linear infinite; |
|||
} |
|||
@-webkit-keyframes sunbeams { |
|||
0% { |
|||
-webkit-transform: translateY(40%) rotate(0deg); |
|||
transform: translateY(40%) rotate(0deg); |
|||
} |
|||
50% { |
|||
-webkit-transform: translateY(-40%) rotate(180deg); |
|||
transform: translateY(-40%) rotate(180deg); |
|||
} |
|||
100% { |
|||
-webkit-transform: translateY(40%) rotate(360deg); |
|||
transform: translateY(40%) rotate(360deg); |
|||
} |
|||
0%,14%,17%,43%,53%,71%,80%,94%,100% { |
|||
opacity: 0; |
|||
} |
|||
6%,15%,24%,28%,48%,55%,78%,82%,99% { |
|||
opacity: 1; |
|||
} |
|||
} |
|||
@keyframes sunbeams { |
|||
0% { |
|||
-webkit-transform: translateY(40%) rotate(0deg); |
|||
transform: translateY(40%) rotate(0deg); |
|||
} |
|||
50% { |
|||
-webkit-transform: translateY(-40%) rotate(180deg); |
|||
transform: translateY(-40%) rotate(180deg); |
|||
} |
|||
100% { |
|||
-webkit-transform: translateY(40%) rotate(360deg); |
|||
transform: translateY(40%) rotate(360deg); |
|||
} |
|||
0%,14%,17%,43%,53%,71%,80%,94%,100% { |
|||
opacity: 0; |
|||
} |
|||
6%,15%,24%,28%,48%,55%,78%,82%,99% { |
|||
opacity: 1; |
|||
} |
|||
} |
|||
</style> |
|||
|
|||
<script> |
|||
function sunbeams() { |
|||
$.each($(".particletext.sunbeams"), function(){ |
|||
var linecount = ($(this).width()/50)*10; |
|||
for(var i = 0; i <= linecount; i++) { |
|||
$(this).append('<span class="particle" style="top:' + $.rnd(-50,00) + '%; left:' + $.rnd(0,100) + '%;width:' + $.rnd(1,3) + 'px; height:' + $.rnd(80,160) + '%;animation-delay: -' + ($.rnd(0,30)/10) + 's;"></span>'); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
</script> |
|||
|
|||
<script type="text/javascript"> |
|||
function initparticles() { |
|||
bubbles(); |
|||
hearts(); |
|||
lines(); |
|||
confetti(); |
|||
fire(); |
|||
sunbeams(); |
|||
} |
|||
jQuery.rnd = function(m,n) { |
|||
m = parseInt(m); |
|||
n = parseInt(n); |
|||
return Math.floor( Math.random() * (n - m + 1) ) + m; |
|||
} |
|||
initparticles(); |
|||
</script> |
|||
|
|||
### 0x002 Fires 特效 |
|||
|
|||
#### 1. JS 代码 |
|||
|
|||
```javascript |
|||
<script> |
|||
function fire() { |
|||
$.each($(".particletext.fire"), function(){ |
|||
var firecount = ($(this).width()/50)*20; |
|||
for(var i = 0; i <= firecount; i++) { |
|||
var size = $.rnd(8,12); |
|||
$(this).append('<span class="particle" style="top:' + $.rnd(40,70) + '%; left:' + $.rnd(-10,100) + '%;width:' + size + 'px; height:' + size + 'px;animation-delay: ' + ($.rnd(0,20)/10) + 's;"></span>'); |
|||
} |
|||
}); |
|||
} |
|||
jQuery.rnd = function(m,n) { |
|||
m = parseInt(m); |
|||
n = parseInt(n); |
|||
return Math.floor( Math.random() * (n - m + 1) ) + m; |
|||
} |
|||
fire(); |
|||
</script> |
|||
``` |
|||
|
|||
#### 2. CSS 代码 |
|||
|
|||
```css |
|||
<style> |
|||
.fire > .particle { |
|||
position: absolute; |
|||
background-color: rgba(255, 193, 7, 0.5); |
|||
border-radius: 40px; |
|||
border-top-right-radius: 0px; |
|||
-webkit-animation: fires 0.8s linear infinite; |
|||
animation: fires 0.8s linear infinite; |
|||
-webkit-transform: rotate(-45deg); |
|||
transform: rotate(-45deg); |
|||
opacity: 0; |
|||
} |
|||
|
|||
@-webkit-keyframes fires { |
|||
0% { |
|||
-webkit-transform: rotate(-70deg) translateY(0%); |
|||
transform: rotate(-70deg) translateY(0%); |
|||
} |
|||
25% { |
|||
-webkit-transform: rotate(-20deg) translateY(-5%); |
|||
transform: rotate(-20deg) translateY(-5%); |
|||
opacity: 1; |
|||
} |
|||
50% { |
|||
-webkit-transform: rotate(-70deg) translateY(-10%); |
|||
transform: rotate(-70deg) translateY(-10%); |
|||
} |
|||
75% { |
|||
-webkit-transform: rotate(-20deg) translateY(-20%); |
|||
transform: rotate(-20deg) translateY(-20%); |
|||
} |
|||
100% { |
|||
-webkit-transform: rotate(-70deg) translateY(-40%); |
|||
transform: rotate(-70deg) translateY(-40%); |
|||
opacity: 1; |
|||
} |
|||
} |
|||
@keyframes fires { |
|||
0% { |
|||
-webkit-transform: rotate(-70deg) translateY(0%); |
|||
transform: rotate(-70deg) translateY(0%); |
|||
} |
|||
25% { |
|||
-webkit-transform: rotate(-20deg) translateY(-5%); |
|||
transform: rotate(-20deg) translateY(-5%); |
|||
opacity: 1; |
|||
} |
|||
50% { |
|||
-webkit-transform: rotate(-70deg) translateY(-10%); |
|||
transform: rotate(-70deg) translateY(-10%); |
|||
} |
|||
75% { |
|||
-webkit-transform: rotate(-20deg) translateY(-20%); |
|||
transform: rotate(-20deg) translateY(-20%); |
|||
} |
|||
100% { |
|||
-webkit-transform: rotate(-70deg) translateY(-40%); |
|||
transform: rotate(-70deg) translateY(-40%); |
|||
opacity: 1; |
|||
} |
|||
} |
|||
</style> |
|||
``` |
|||
|
|||
#### 3. HTML 代码 |
|||
|
|||
```html |
|||
<div style="width: 100%;text-align: center; height: 120px; position: relative; bottom: 0px;" > |
|||
<span class="particletext fire" style="font-size:48px;position: relative;">This is fires</span> |
|||
</div> |
|||
``` |
|||
|
|||
### 0x003 Lines 特效 |
|||
|
|||
#### 1. JS 代码 |
|||
|
|||
```javascript |
|||
<script> |
|||
function lines() { |
|||
$.each($(".particletext.lines"), function(){ |
|||
var linecount = ($(this).width()/50)*10; |
|||
for(var i = 0; i <= linecount; i++) { |
|||
$(this).append('<span class="particle" style="top:' + $.rnd(-30,30) + '%; left:' + $.rnd(-10,110) + '%;width:' + $.rnd(1,3) + 'px; height:' + $.rnd(20,80) + '%;animation-delay: -' + ($.rnd(0,30)/10) + 's;"></span>'); |
|||
} |
|||
}); |
|||
} |
|||
jQuery.rnd = function(m,n) { |
|||
m = parseInt(m); |
|||
n = parseInt(n); |
|||
return Math.floor( Math.random() * (n - m + 1) ) + m; |
|||
} |
|||
lines(); |
|||
</script> |
|||
``` |
|||
|
|||
#### 2. CSS 代码 |
|||
|
|||
```css |
|||
<style> |
|||
.lines > .particle { |
|||
position: absolute; |
|||
background-color: rgba(244, 67, 54, 0.5); |
|||
-webkit-animation: lines 3s linear infinite; |
|||
animation: lines 3s linear infinite; |
|||
} |
|||
@-webkit-keyframes lines { |
|||
0%, 50%, 100% { |
|||
-webkit-transform: translateY(0%); |
|||
transform: translateY(0%); |
|||
} |
|||
25% { |
|||
-webkit-transform: translateY(100%); |
|||
transform: translateY(100%); |
|||
} |
|||
75% { |
|||
-webkit-transform: translateY(-100%); |
|||
transform: translateY(-100%); |
|||
} |
|||
} |
|||
@keyframes lines { |
|||
0%, 50%, 100% { |
|||
-webkit-transform: translateY(0%); |
|||
transform: translateY(0%); |
|||
} |
|||
25% { |
|||
-webkit-transform: translateY(100%); |
|||
transform: translateY(100%); |
|||
} |
|||
75% { |
|||
-webkit-transform: translateY(-100%); |
|||
transform: translateY(-100%); |
|||
} |
|||
} |
|||
</style> |
|||
``` |
|||
|
|||
#### 3. HTML 代码 |
|||
|
|||
```html |
|||
<div style="width: 100%;text-align: center; height: 120px; position: relative; bottom: 0px;" > |
|||
<span class="particletext lines" style="font-size:48px; position: relative;">This is lines</span> |
|||
</div> |
|||
``` |
|||
|
|||
### 0x004 Hearts 特效 |
|||
|
|||
#### 1. JS 代码 |
|||
|
|||
```javascript |
|||
<script> |
|||
function hearts() { |
|||
$.each($(".particletext.hearts"), function(){ |
|||
var heartcount = ($(this).width()/50)*5; |
|||
for(var i = 0; i <= heartcount; i++) { |
|||
var size = ($.rnd(60,120)/10); |
|||
$(this).append('<span class="particle" style="top:' + $.rnd(20,80) + '%; left:' + $.rnd(0,95) + '%;width:' + size + 'px; height:' + size + 'px;animation-delay: ' + ($.rnd(0,30)/10) + 's;"></span>'); |
|||
} |
|||
}); |
|||
} |
|||
jQuery.rnd = function(m,n) { |
|||
m = parseInt(m); |
|||
n = parseInt(n); |
|||
return Math.floor( Math.random() * (n - m + 1) ) + m; |
|||
} |
|||
hearts(); |
|||
</script> |
|||
``` |
|||
|
|||
#### 2. CSS 代码 |
|||
|
|||
```css |
|||
<style> |
|||
.hearts > .particle { |
|||
opacity: 0; |
|||
position: absolute; |
|||
background-color: #cc2a5d; |
|||
-webkit-animation: hearts 3s ease-in infinite; |
|||
animation: hearts 3s ease-in infinite; |
|||
} |
|||
.hearts > .particle:before, .hearts > .particle:after { |
|||
position: absolute; |
|||
content: ''; |
|||
border-radius: 100px; |
|||
top: 0px; |
|||
left: 0px; |
|||
width: 100%; |
|||
height: 100%; |
|||
background-color: #cc2a5d; |
|||
} |
|||
.hearts > .particle:before { |
|||
-webkit-transform: translateX(-50%); |
|||
transform: translateX(-50%); |
|||
} |
|||
.hearts > .particle:after { |
|||
-webkit-transform: translateY(-50%); |
|||
transform: translateY(-50%); |
|||
} |
|||
@-webkit-keyframes hearts { |
|||
0% { |
|||
opacity: 0; |
|||
-webkit-transform: translate(0, 0%) rotate(45deg); |
|||
transform: translate(0, 0%) rotate(45deg); |
|||
} |
|||
20% { |
|||
opacity: 0.8; |
|||
-webkit-transform: translate(0, -20%) rotate(45deg); |
|||
transform: translate(0, -20%) rotate(45deg); |
|||
} |
|||
100% { |
|||
opacity: 0; |
|||
-webkit-transform: translate(0, -1000%) rotate(45deg); |
|||
transform: translate(0, -1000%) rotate(45deg); |
|||
} |
|||
} |
|||
@keyframes hearts { |
|||
0% { |
|||
opacity: 0; |
|||
-webkit-transform: translate(0, 0%) rotate(45deg); |
|||
transform: translate(0, 0%) rotate(45deg); |
|||
} |
|||
20% { |
|||
opacity: 0.8; |
|||
-webkit-transform: translate(0, -20%) rotate(45deg); |
|||
transform: translate(0, -20%) rotate(45deg); |
|||
} |
|||
100% { |
|||
opacity: 0; |
|||
-webkit-transform: translate(0, -1000%) rotate(45deg); |
|||
transform: translate(0, -1000%) rotate(45deg); |
|||
} |
|||
} |
|||
</style> |
|||
``` |
|||
|
|||
#### 3. HTML 代码 |
|||
|
|||
```html |
|||
<div style="width: 100%;text-align: center; height: 120px; position: relative; bottom: 0px;" > |
|||
<span class="particletext hearts" style="font-size:48px; position: relative;">This is hearts</span> |
|||
</div> |
|||
``` |
|||
|
|||
### 0x005 Bubbles 特效 |
|||
|
|||
#### 1. JS 代码 |
|||
|
|||
```javascript |
|||
<script> |
|||
function bubbles() { |
|||
$.each($(".particletext.bubbles"), function(){ |
|||
var bubblecount = ($(this).width()/50)*10; |
|||
for(var i = 0; i <= bubblecount; i++) { |
|||
var size = ($.rnd(40,80)/10); |
|||
$(this).append('<span class="particle" style="top:' + $.rnd(20,80) + '%; left:' + $.rnd(0,95) + '%;width:' + size + 'px; height:' + size + 'px;animation-delay: ' + ($.rnd(0,30)/10) + 's;"></span>'); |
|||
} |
|||
}); |
|||
} |
|||
jQuery.rnd = function(m,n) { |
|||
m = parseInt(m); |
|||
n = parseInt(n); |
|||
return Math.floor( Math.random() * (n - m + 1) ) + m; |
|||
} |
|||
bubbles(); |
|||
</script> |
|||
``` |
|||
|
|||
#### 2. CSS 代码 |
|||
|
|||
```css |
|||
<style> |
|||
<style> |
|||
.bubbles > .particle { |
|||
opacity: 0; |
|||
position: absolute; |
|||
background-color: rgba(33, 150, 243, 0.5); |
|||
-webkit-animation: bubbles 3s ease-in infinite; |
|||
animation: bubbles 3s ease-in infinite; |
|||
border-radius: 100%; |
|||
} |
|||
@-webkit-keyframes bubbles { |
|||
0% { |
|||
opacity: 0; |
|||
} |
|||
20% { |
|||
opacity: 1; |
|||
-webkit-transform: translate(0, -20%); |
|||
transform: translate(0, -20%); |
|||
} |
|||
100% { |
|||
opacity: 0; |
|||
-webkit-transform: translate(0, -1000%); |
|||
transform: translate(0, -1000%); |
|||
} |
|||
} |
|||
|
|||
@keyframes bubbles { |
|||
0% { |
|||
opacity: 0; |
|||
} |
|||
20% { |
|||
opacity: 1; |
|||
-webkit-transform: translate(0, -20%); |
|||
transform: translate(0, -20%); |
|||
} |
|||
100% { |
|||
opacity: 0; |
|||
-webkit-transform: translate(0, -1000%); |
|||
transform: translate(0, -1000%); |
|||
} |
|||
} |
|||
</style> |
|||
``` |
|||
|
|||
#### 3. HTML 代码 |
|||
|
|||
```html |
|||
<div style="width: 100%;text-align: center; height: 120px; position: relative; bottom: 0px;" > |
|||
<span class="particletext bubbles" style="font-size:48px; position: relative;">This is bubbles</span> |
|||
</div> |
|||
``` |
|||
|
|||
### 0x006 Confetti 特效 |
|||
|
|||
#### 1. JS 代码 |
|||
|
|||
```javascript |
|||
<script> |
|||
function confetti() { |
|||
$.each($(".particletext.confetti"), function(){ |
|||
var confetticount = ($(this).width()/50)*10; |
|||
for(var i = 0; i <= confetticount; i++) { |
|||
$(this).append('<span class="particle c' + $.rnd(1,2) + '" style="top:' + $.rnd(10,50) + '%; left:' + $.rnd(0,100) + '%;width:' + $.rnd(6,8) + 'px; height:' + $.rnd(3,4) + 'px;animation-delay: ' + ($.rnd(0,30)/10) + 's;"></span>'); |
|||
} |
|||
}); |
|||
} |
|||
jQuery.rnd = function(m,n) { |
|||
m = parseInt(m); |
|||
n = parseInt(n); |
|||
return Math.floor( Math.random() * (n - m + 1) ) + m; |
|||
} |
|||
confetti(); |
|||
</script> |
|||
``` |
|||
|
|||
#### 2. CSS 代码 |
|||
|
|||
```css |
|||
<style> |
|||
.confetti > .particle { |
|||
opacity: 0; |
|||
position: absolute; |
|||
-webkit-animation: confetti 3s ease-in infinite; |
|||
animation: confetti 3s ease-in infinite; |
|||
} |
|||
.confetti > .particle.c1 { |
|||
background-color: rgba(76, 175, 80, 0.5); |
|||
} |
|||
.confetti > .particle.c2 { |
|||
background-color: rgba(156, 39, 176, 0.5); |
|||
} |
|||
@-webkit-keyframes confetti { |
|||
0% { |
|||
opacity: 0; |
|||
-webkit-transform: translateY(0%) rotate(0deg); |
|||
transform: translateY(0%) rotate(0deg); |
|||
} |
|||
10% { |
|||
opacity: 1; |
|||
} |
|||
35% { |
|||
-webkit-transform: translateY(-800%) rotate(270deg); |
|||
transform: translateY(-800%) rotate(270deg); |
|||
} |
|||
80% { |
|||
opacity: 1; |
|||
} |
|||
100% { |
|||
opacity: 0; |
|||
-webkit-transform: translateY(2000%) rotate(1440deg); |
|||
transform: translateY(2000%) rotate(1440deg); |
|||
} |
|||
} |
|||
@keyframes confetti { |
|||
0% { |
|||
opacity: 0; |
|||
-webkit-transform: translateY(0%) rotate(0deg); |
|||
transform: translateY(0%) rotate(0deg); |
|||
} |
|||
10% { |
|||
opacity: 1; |
|||
} |
|||
35% { |
|||
-webkit-transform: translateY(-800%) rotate(270deg); |
|||
transform: translateY(-800%) rotate(270deg); |
|||
} |
|||
80% { |
|||
opacity: 1; |
|||
} |
|||
100% { |
|||
opacity: 0; |
|||
-webkit-transform: translateY(2000%) rotate(1440deg); |
|||
transform: translateY(2000%) rotate(1440deg); |
|||
} |
|||
} |
|||
</style> |
|||
``` |
|||
|
|||
#### 3. HTML 代码 |
|||
|
|||
```html |
|||
<div style="width: 100%;text-align: center; height: 120px; position: relative; bottom: 0px;" > |
|||
<span class="particletext confetti" style="font-size:48px; position: relative;">This is confetti</span> |
|||
</div> |
|||
``` |
|||
|
|||
### 0x007 Sunbeams 特效 |
|||
|
|||
#### 1. JS 代码 |
|||
|
|||
```javascript |
|||
<script> |
|||
function sunbeams() { |
|||
$.each($(".particletext.sunbeams"), function(){ |
|||
var linecount = ($(this).width()/50)*10; |
|||
for(var i = 0; i <= linecount; i++) { |
|||
$(this).append('<span class="particle" style="top:' + $.rnd(-50,00) + '%; left:' + $.rnd(0,100) + '%;width:' + $.rnd(1,3) + 'px; height:' + $.rnd(80,160) + '%;animation-delay: -' + ($.rnd(0,30)/10) + 's;"></span>'); |
|||
} |
|||
}); |
|||
} |
|||
jQuery.rnd = function(m,n) { |
|||
m = parseInt(m); |
|||
n = parseInt(n); |
|||
return Math.floor( Math.random() * (n - m + 1) ) + m; |
|||
} |
|||
sunbeams(); |
|||
</script> |
|||
``` |
|||
|
|||
#### 2. CSS 代码 |
|||
|
|||
```css |
|||
<style> |
|||
.sunbeams > .particle { |
|||
position: absolute; |
|||
background-color: rgba(253, 216, 53, 0.5); |
|||
-webkit-animation: sunbeams 3s linear infinite; |
|||
animation: sunbeams 3s linear infinite; |
|||
} |
|||
@-webkit-keyframes sunbeams { |
|||
0% { |
|||
-webkit-transform: translateY(40%) rotate(0deg); |
|||
transform: translateY(40%) rotate(0deg); |
|||
} |
|||
50% { |
|||
-webkit-transform: translateY(-40%) rotate(180deg); |
|||
transform: translateY(-40%) rotate(180deg); |
|||
} |
|||
100% { |
|||
-webkit-transform: translateY(40%) rotate(360deg); |
|||
transform: translateY(40%) rotate(360deg); |
|||
} |
|||
0%,14%,17%,43%,53%,71%,80%,94%,100% { |
|||
opacity: 0; |
|||
} |
|||
6%,15%,24%,28%,48%,55%,78%,82%,99% { |
|||
opacity: 1; |
|||
} |
|||
} |
|||
@keyframes sunbeams { |
|||
0% { |
|||
-webkit-transform: translateY(40%) rotate(0deg); |
|||
transform: translateY(40%) rotate(0deg); |
|||
} |
|||
50% { |
|||
-webkit-transform: translateY(-40%) rotate(180deg); |
|||
transform: translateY(-40%) rotate(180deg); |
|||
} |
|||
100% { |
|||
-webkit-transform: translateY(40%) rotate(360deg); |
|||
transform: translateY(40%) rotate(360deg); |
|||
} |
|||
0%,14%,17%,43%,53%,71%,80%,94%,100% { |
|||
opacity: 0; |
|||
} |
|||
6%,15%,24%,28%,48%,55%,78%,82%,99% { |
|||
opacity: 1; |
|||
} |
|||
} |
|||
</style> |
|||
``` |
|||
|
|||
#### 3. HTML 代码 |
|||
|
|||
```html |
|||
<div style="width: 100%;text-align: center; height: 120px; position: relative; bottom: 0px;" > |
|||
<span class="particletext sunbeams" style="font-size:48px; position: relative;">This is sunbeams</span> |
|||
</div> |
|||
``` |
@ -0,0 +1,269 @@ |
|||
--- |
|||
title: IEEE754标准的浮点数存储格式-转载 |
|||
author: TianZD |
|||
top: true |
|||
cover: true |
|||
toc: true |
|||
mathjax: false |
|||
summary: IEEE754标准的浮点数存储格式-转载 |
|||
tags: |
|||
- 浮点数 |
|||
- 数据格式 |
|||
categories: |
|||
- 通信 |
|||
- 转载 |
|||
reprintPolicy: cc_by |
|||
abbrlink: 8cc8b422 |
|||
date: 2022-04-29 13:38:14 |
|||
coverImg: |
|||
img: |
|||
password: |
|||
--- |
|||
|
|||
[TOC] |
|||
|
|||
|
|||
|
|||
# IEEE754标准的浮点数存储格式【转载】 |
|||
|
|||
转载自[查看原网页: www.cnblogs.com](https://www.cnblogs.com/MikeZhang/p/IEEE754FloatEncode20180117.html) |
|||
|
|||
|
|||
|
|||
基本存储格式(从高到低) : Sign + Exponent + Fraction |
|||
|
|||
Sign : 符号位 |
|||
|
|||
Exponent : 阶码 |
|||
|
|||
Fraction : 有效数字 |
|||
|
|||
[在线转换网址](http://www.speedfly.cn/tools/hexconvert/) |
|||
|
|||
## 32位浮点数存储格式解析 |
|||
|
|||
Sign : 1 bit(第31个bit) |
|||
|
|||
Exponent :8 bits (第 30 至 23 共 8 个bits) |
|||
|
|||
Fraction :23 bits (第 22 至 0 共 23 个bits) |
|||
|
|||
32位非0浮点数的真值为(python语法) : |
|||
|
|||
(-1) \*\*Sign \* 2 \*\*(Exponent-127) \* (1 + Fraction) |
|||
|
|||
示例如下: |
|||
|
|||
a = 12.5 |
|||
|
|||
1、求解符号位 |
|||
|
|||
a大于0,则 Sign 为 0 ,用二进制表示为: 0 |
|||
|
|||
2、求解阶码 |
|||
|
|||
a表示为二进制为: 1100.0 |
|||
|
|||
小数点需要向左移动3位,则 Exponent 为 130 (127 + 3),用二进制表示为: 10000010 |
|||
|
|||
3、求解有效数字 |
|||
|
|||
有效数字需要去掉最高位隐含的1,则有效数字的整数部分为 : 100 |
|||
|
|||
将十进制的小数转换为二进制的小数的方法为将小数\*2,取整数部分,则小数部分为: 1 |
|||
|
|||
后面补0,则a的二进制可表示为: 01000001010010000000000000000000 |
|||
|
|||
即 : 0100 0001 0100 1000 0000 0000 0000 0000 |
|||
|
|||
用16进制表示 : 0x41480000 |
|||
|
|||
4、还原真值 |
|||
|
|||
``` |
|||
Sign = bin(0) = 0 |
|||
Exponent = bin(10000010) = 130 |
|||
Fraction = bin(0.1001) = 2 ** (-1) + 2 ** (-4) = 0.5625 |
|||
``` |
|||
|
|||
真值: |
|||
|
|||
(-1) \*\*0 \* 2 \*\*(130\-127) \* (1 + 0.5625) = 12.5 |
|||
|
|||
32位浮点数二进制存储解析代码(c++): |
|||
|
|||
[https://github.com/mike-zhang/cppExamples/blob/master/dataTypeOpt/IEEE754Relate/floatTest1.cpp](https://github.com/mike-zhang/cppExamples/blob/master/dataTypeOpt/IEEE754Relate/floatTest1.cpp) |
|||
|
|||
运行效果: |
|||
|
|||
``` |
|||
[root@localhost floatTest1]# ./floatToBin1 |
|||
sizeof(float) : 4 |
|||
sizeof(int) : 4 |
|||
a = 12.500000 |
|||
showFloat : 0x 41 48 00 00 |
|||
UFP : 0,82,480000 |
|||
b : 0x41480000 |
|||
showIEEE754 a = 12.500000 |
|||
showIEEE754 varTmp = 0x00c00000 |
|||
showIEEE754 c = 0x00400000 |
|||
showIEEE754 i = 19 , a1 = 1.000000 , showIEEE754 c = 00480000 , showIEEE754 b = 0x41000000 |
|||
showIEEE754 i = 18 , a1 = 0.000000 , showIEEE754 b = 0x41000000 |
|||
showIEEE754 i = 17 , a1 = 0.000000 , showIEEE754 b = 0x41000000 |
|||
showIEEE754 i = 16 , a1 = 0.000000 , showIEEE754 b = 0x41000000 |
|||
showIEEE754 i = 15 , a1 = 0.000000 , showIEEE754 b = 0x41000000 |
|||
showIEEE754 i = 14 , a1 = 0.000000 , showIEEE754 b = 0x41000000 |
|||
showIEEE754 i = 13 , a1 = 0.000000 , showIEEE754 b = 0x41000000 |
|||
showIEEE754 i = 12 , a1 = 0.000000 , showIEEE754 b = 0x41000000 |
|||
showIEEE754 i = 11 , a1 = 0.000000 , showIEEE754 b = 0x41000000 |
|||
showIEEE754 i = 10 , a1 = 0.000000 , showIEEE754 b = 0x41000000 |
|||
showIEEE754 i = 9 , a1 = 0.000000 , showIEEE754 b = 0x41000000 |
|||
showIEEE754 i = 8 , a1 = 0.000000 , showIEEE754 b = 0x41000000 |
|||
showIEEE754 i = 7 , a1 = 0.000000 , showIEEE754 b = 0x41000000 |
|||
showIEEE754 i = 6 , a1 = 0.000000 , showIEEE754 b = 0x41000000 |
|||
showIEEE754 i = 5 , a1 = 0.000000 , showIEEE754 b = 0x41000000 |
|||
showIEEE754 i = 4 , a1 = 0.000000 , showIEEE754 b = 0x41000000 |
|||
showIEEE754 i = 3 , a1 = 0.000000 , showIEEE754 b = 0x41000000 |
|||
showIEEE754 i = 2 , a1 = 0.000000 , showIEEE754 b = 0x41000000 |
|||
showIEEE754 i = 1 , a1 = 0.000000 , showIEEE754 b = 0x41000000 |
|||
showIEEE754 : 0x41480000 |
|||
[root@localhost floatTest1]# |
|||
``` |
|||
|
|||
## 64位浮点数存储格式解析 |
|||
|
|||
Sign : 1 bit(第31个bit) |
|||
|
|||
Exponent :11 bits (第 62 至 52 共 11 个bits) |
|||
|
|||
Fraction :52 bits (第 51 至 0 共 52 个bits) |
|||
|
|||
64位非0浮点数的真值为(python语法) : |
|||
|
|||
```(-1) **Sign * 2 **(Exponent-1023) * (1 + Fraction)``` |
|||
|
|||
示例如下: |
|||
|
|||
a = 12.5 |
|||
|
|||
1、求解符号位 |
|||
|
|||
a大于0,则 Sign 为 0 ,用二进制表示为: 0 |
|||
|
|||
2、求解阶码 |
|||
|
|||
a表示为二进制为: 1100.0 |
|||
|
|||
小数点需要向左移动3位,则 Exponent 为 1026 (1023 + 3),用二进制表示为: 10000000010 |
|||
|
|||
3、求解有效数字 |
|||
|
|||
有效数字需要去掉最高位隐含的1,则有效数字的整数部分为 : 100 |
|||
|
|||
将十进制的小数转换为二进制的小数的方法为将小数\*2,取整数部分,则小数部分为: 1 |
|||
|
|||
后面补0,则a的二进制可表示为: |
|||
|
|||
0100000000101001000000000000000000000000000000000000000000000000 |
|||
|
|||
即 : 0100 0000 0010 1001 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 |
|||
|
|||
用16进制表示 : 0x4029000000000000 |
|||
|
|||
4、还原真值 |
|||
|
|||
``` |
|||
Sign = bin(0) = 0 |
|||
Exponent \= bin(10000000010) = 1026 |
|||
Fraction \= bin(0.1001) = 2 \*\* (-1) + 2 \*\* (-4) = 0.5625 |
|||
``` |
|||
|
|||
真值: |
|||
|
|||
```(-1) **0 * 2 **(1026-1023) * (1 + 0.5625) = 12.5``` |
|||
|
|||
64位浮点数二进制存储解析代码(c++): |
|||
|
|||
[https://github.com/mike-zhang/cppExamples/blob/master/dataTypeOpt/IEEE754Relate/doubleTest1.cpp](https://github.com/mike-zhang/cppExamples/blob/master/dataTypeOpt/IEEE754Relate/doubleTest1.cpp) |
|||
|
|||
运行效果: |
|||
|
|||
``` |
|||
[root@localhost t1]# ./doubleToBin1 |
|||
sizeof(double) : 8 |
|||
sizeof(long) : 8 |
|||
a = 12.500000 |
|||
showDouble : 0x 40 29 00 00 00 00 00 00 |
|||
UFP : 0,402,0 |
|||
b : 0x0 |
|||
showIEEE754 a = 12.500000 |
|||
showIEEE754 logLen = 3 |
|||
showIEEE754 c = 4620693217682128896(0x4020000000000000) |
|||
showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 varTmp = 0x8000000000000 |
|||
showIEEE754 c = 0x8000000000000 |
|||
showIEEE754 i = 48 , a1 = 1.000000 , showIEEE754 c = 9000000000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 47 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 46 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 45 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 44 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 43 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 42 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 41 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 40 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 39 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 38 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 37 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 36 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 35 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 34 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 33 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 32 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 31 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 30 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 29 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 28 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 27 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 26 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 25 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 24 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 23 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 22 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 21 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 20 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 19 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 18 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 17 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 16 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 15 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 14 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 13 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 12 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 11 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 10 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 9 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 8 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 7 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 6 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 5 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 4 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 3 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 2 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 i = 1 , a1 = 0.000000 , showIEEE754 b = 0x4020000000000000 |
|||
showIEEE754 : 0x4029000000000000 |
|||
[root@localhost t1]# |
|||
``` |
|||
|
|||
|
|||
|
|||
好,就这些了,希望对你有帮助。 |
|||
|
|||
本文github地址: |
|||
|
|||
[https://github.com/mike-zhang/mikeBlogEssays/blob/master/2018/20180117\_IEEE754标准的浮点数存储格式.rst- |
|||
|
|||
](https://github.com/mike-zhang/mikeBlogEssays/blob/master/2018/20180117_IEEE754%E6%A0%87%E5%87%86%E7%9A%84%E6%B5%AE%E7%82%B9%E6%95%B0%E5%AD%98%E5%82%A8%E6%A0%BC%E5%BC%8F.rst) |
|||
|
|||
欢迎补充 |
|||
|
|||
[查看原网页: www.cnblogs.com](https://www.cnblogs.com/MikeZhang/p/IEEE754FloatEncode20180117.html) |
@ -0,0 +1,500 @@ |
|||
--- |
|||
title: ModbusTcp |
|||
author: TianZD |
|||
top: true |
|||
cover: true |
|||
toc: true |
|||
mathjax: false |
|||
summary: ModbusTcp通讯相关学习笔记,参考多篇博文,其中有些已经找不到原文链接 |
|||
tags: |
|||
- modbus |
|||
- 学习笔记 |
|||
categories: |
|||
- Modbus |
|||
- 转载 |
|||
reprintPolicy: cc_by |
|||
abbrlink: c7022bb7 |
|||
date: 2022-04-29 13:49:25 |
|||
coverImg: |
|||
img: |
|||
password: |
|||
--- |
|||
|
|||
\[toc\] |
|||
|
|||
# ModBusTCP |
|||
|
|||
## 术语 |
|||
|
|||
### 寄存器 |
|||
|
|||
> 寄存器的功能是存储[二进制代码](https://baike.baidu.com/item/%E4%BA%8C%E8%BF%9B%E5%88%B6%E4%BB%A3%E7%A0%81/4879654),它是由具有存储功能的[触发器](https://baike.baidu.com/item/%E8%A7%A6%E5%8F%91%E5%99%A8/193146)组合起来构成的。一个触发器可以存储1位二进制代码,故存放n位二进制代码的寄存器,需用n个触发器来构成。 |
|||
|
|||
PLC中**输入寄存器**和**输出寄存器**均为16位,2个字节 |
|||
|
|||
00:一个字节:0 |
|||
|
|||
00 0A:两个字节:10 |
|||
|
|||
### 校验码 |
|||
|
|||
校验码是由前面的数据通过某种算法得出的,用以检验该组数据的正确性。代码作为数据在向计算机或其它设备进行输入时,容易产生输入错误,为了减少这种输入错误,编码专家发明了各种校验检错方法,并依据这些方法设置了校验码。 |
|||
|
|||
常用的校验有:累加和校验SUM、字节异或校验XOR、纵向冗余校验LRC、循环冗余校验CRC…… |
|||
|
|||
### 离散量输入 |
|||
|
|||
主要用来读取单个位的数据,如IO的状态 |
|||
|
|||
### 线圈 |
|||
|
|||
开关输出信号,主要用来写入单个位的数据,与离散量构成组成对位的操作; |
|||
|
|||
## ModBus |
|||
|
|||
### 概述 |
|||
|
|||
一种**应用层协议** |
|||
|
|||
Modbus通信协议,是Modicon PLC所制定的资料交换通信接口标准,于1979年首先制定串行通信标准(含Modbus异步及Modbus Plus同步),于1997年制定网络通信标准(Modbus/TCP)。是属于OSI所定义的通信层的第七层应用层(Application Layer)。是为**Client/Server**或称为 **Master/Slave**型式的通信协议。由于Modbus的通信协议简单容易设计,结果广被许多控制设备或外围信号设备所采用,因此无形中成为自控业界的标准。Modbus异步的硬件架构简单,被使用的比率最高。Modbus Plus同步的协议可以提供高速的通信速度,适合主控制设备间大量资料交换。Modbus/TCP则是因应Ethernet网络的架构,近年来被大量使用的通信协议,也因为其速度及资料传送量远比Modbus Plus更快更大,所以已渐渐取代其功能。 |
|||
|
|||
Modbus通信协议基本上是遵循MasterandSlave的通信步骤,有一方扮演**Master角色采取主动询问方式**,送出QueryMessage给Slave方,然后由Slave方依据接到的QueryMessage内容准备ResponseMessage回传给Master。即使目前硬件通信已经可以达到双方互相主动通信的能力,但是于Modbus通信协议的规定,必须一方为Master,另一方为Slave不能互换角色。一般使用上,**监控系统(HMI)都为Maste**r,**PLC、电表、仪表等都为Slave**,HMI系统一直PollingSlave的各种relayandregister最新数值,然后做显示及各种逻辑计算及控制调整等处理。 |
|||
|
|||
Modbus大家庭,有三个兄弟:大哥(Modbus-RTU协议)、二哥(Modbus-ASCII协议)和ModbutTcp,都活跃在工业通信领域。大哥和二哥擅长串行通信,比如基于RS485或者RS232的通信,而ModbutTcp则擅长基于以太网的通信。由于底层所使用的结构不同,应用数据单元(Application Data Unit,ADU)有所不同。 |
|||
|
|||
### Modbus协议的数据模型 |
|||
|
|||
[深入理解Modbus协议的数据模型和地址模型](https://zhuanlan.zhihu.com/p/164885080) |
|||
|
|||
数据模型是对可访问数据的一种抽象,Modbus协议的数据模型定义了四种可访问的数据,分别是: |
|||
|
|||
- 离散量输入(Discrete Input); |
|||
|
|||
- 线圈(Coils); |
|||
|
|||
- 输入寄存器(Input registers); |
|||
|
|||
- 保持寄存器(Holding registers); |
|||
|
|||
其中,离散量输入和线圈只支持以**位(bit)的方式进行访问,输入寄存器和保持寄存器只支持以**字(WORD)**的方式进行访问;离散量输入和输入寄存器只支持以**只读的方式进行访问,而线圈和保持寄存器既可以读也可以写; |
|||
|
|||
数据模型中成员的特点如下面的表格: |
|||
|
|||
![image-20220126154248046](https://gitee.com/tianzhendong/img/raw/master//images/202201261542152.png) |
|||
|
|||
既然数据模型是一种抽象,在实际使用时必须将其映射到真实的物理存储区才能被访问。 |
|||
|
|||
Modbus协议允许设备将四种数据分别映射到**不同的存储区块**中,各个区块之间相互独立,使用不同的功能码可读取到不同的数值,如下图所示: |
|||
|
|||
![image-20220126154419939](https://gitee.com/tianzhendong/img/raw/master//images/202201261544060.png) |
|||
|
|||
Modbus协议也允许设备将四种数据映射到同一存储区块中,这样通过不同的功能码读取数据可能会得到相同的数据(比如:输入寄存器和保持寄存器为同一物理区块),如下图所示: |
|||
|
|||
![image-20220126154513588](https://gitee.com/tianzhendong/img/raw/master//images/202201261545716.png) |
|||
|
|||
数据模型中的每一种数据都最多允许有65536个元素(编号1~65536),元素的地址编号从0开始,因此地址的范围为:0~65535; |
|||
|
|||
*需要说明的是:65536只是协议允许的最大元素范围,但并不要求全部实现。Modbus协议允许设备根据自己的实际情况实现部分元素,甚至不要求实现模型中全部四种数据;* |
|||
|
|||
### Modbus协议的地址模型 |
|||
|
|||
为了简化数据模型与设备存储区的对应关系,引入了一种地址模型。该模型通过编号的方式对不同类型数据进行区分,各数据的地址编号请看下面的表格: |
|||
|
|||
![image-20220126154701232](https://gitee.com/tianzhendong/img/raw/master//images/202201261547313.png) |
|||
|
|||
Modbus地址模型的编号从1开始。 |
|||
|
|||
由于每一种数据都最大支持65536个元素,因此理论上, |
|||
|
|||
对于线圈型数据来说,其地址范围为:000001\~065536; |
|||
|
|||
类似的, |
|||
|
|||
离散量输入,其地址范围为:100001\~165536; |
|||
|
|||
输入寄存器,其地址范围为:300001\~365536; |
|||
|
|||
保持寄存器,其地址范围为:400001\~465536; |
|||
|
|||
由于65536是比较大的数值,实际应用一般不需要这么大的存储区,因此PLC厂家普遍采用的是10000以内的地址范围,即: |
|||
|
|||
线圈地址范围:00001\~09999; |
|||
|
|||
离散量输入地址范围:10001\~19999; |
|||
|
|||
输入寄存器地址范围:30001\~39999; |
|||
|
|||
保持寄存器地址范围:40001\~49999; |
|||
|
|||
有了该地址模型,我们就可以从Modbus寄存器的地址判断要访问的区块的类型。比如本文开头提到到地址40001就是保持存储器的第一个值的地址,而10001就是离散量输入的第一个值的地址;要注意的是,保持寄存器和输入寄存器的每个值的大小为16bits(字),而线圈和离散量输入每个值的大小为1bit(位); |
|||
|
|||
各PLC厂家根据PLC的实际情况,将Modbus的地址模型映射到实际的存储区。一般来说,线圈对应过程输出映像区(Q);离散量输入对应过程输入映像区(I);输入寄存器对应模拟量输入(AI);保持寄存器对应数据块或V存储区或M存储区。 |
|||
|
|||
### 协议数据单元(Protocol Data Unit,PDU) |
|||
|
|||
协议数据单元由功能码+数据构成,如下面这张图: |
|||
|
|||
![img](https://pic4.zhimg.com/80/v2-4994ae96e27d20fd6617ff86e997975b_1440w.jpg) |
|||
|
|||
**功能码**的长度为**1个字节**,它表示要执行的功能。比如常见的:**01读取线圈;02读取离散量输入值;03读取保持寄存器值;05写单个线圈等**; |
|||
|
|||
**数据**部分的长度为0\~252个字节,它表示要读的地址或者要写入的值,不同的功能码对应的数据有所不同。比如01功能码,其数据为4个字节,其中前两个字节表示要读取的线圈的地址,后两个字节表示要读取线圈的数量;而对于05功能码,其数据也是4个字节,前两个字节表示要写入线圈的地址,后面两字节表示要写入的值。 |
|||
|
|||
协议数据单元有三种类型:**请求型协议数据单元(Request PDU)**、**应答型协议数据单元(Response PDU)**、及**异常应答型协议数据单元(Exception Response PDU)** |
|||
|
|||
协议数据单元是家族的**通用数据结构**,它**与底层物理结构无关**,三兄弟都使用相同的协议数据单元。 |
|||
|
|||
Modbus协议定义了一个与基础通信层无关的简单协议数据单元(PDU)。特定总线或网线路上的Modbus协议映射能够在应用数据单元(ADU)上引入一些附加域。 |
|||
|
|||
![img](https://gitee.com/tianzhendong/img/raw/master//images/202201261523783.png) |
|||
|
|||
### Modbus常用功能码 |
|||
|
|||
https://zhuanlan.zhihu.com/p/145546574 |
|||
|
|||
https://blog.csdn.net/sgmcumt/article/details/87435191?spm=1001.2014.3001.5502 |
|||
|
|||
**功能码**的长度为**1个字节**,它表示要执行的功能。比如常见的:**01读取线圈;02读取离散量输入值;03读取保持寄存器值;05写单个线圈等**; |
|||
|
|||
![image-20220126163451792](https://gitee.com/tianzhendong/img/raw/master//images/202201261634907.png) |
|||
|
|||
#### 01(0x01)读线圈 |
|||
|
|||
1)功能:读取从站(远程设备)的1\~2000个连续线圈的状态数值;读取采用起始地址+线圈数量的方式; |
|||
2)操作方式:位操作; |
|||
3)说明:Modbus1号线圈的地址为0,2号线圈的地址为1,以此类推;因此,假设要读取1~10号线圈的值,其寄存器地址范围为:0~9;(相对地址??) |
|||
4)发送指令示例: |
|||
假设从站地址为0x03,要读取编号从33~42的10个连续线圈的状态值,其寄存器地址范围为:0x0020~0x0029,则发送指令下图所示: |
|||
|
|||
![image-20220126155544480](https://gitee.com/tianzhendong/img/raw/master//images/202201261555531.png) |
|||
|
|||
5)应答格式: |
|||
应答数据包括:从站地址+功能码+返回字节数+数据值+校验码 |
|||
其中,线圈的状态以位的形式返回。状态为ON时,其值为1;状态为OFF时,其值为0; |
|||
数据以小端(Little Endian)的形式进行组织。即先存放LSB(最低权重位),再存放MSB。 |
|||
每8个位组成一个字节,**当线圈的数量不是8的倍数时,剩余的位数添0补位。** |
|||
本例程读取**10个线圈,10/8商1余2,因此需要2个字节存放应答数据。** |
|||
字节1存放线圈编号33\~40的数值(小端字节序,线圈40的值存放在bit7,线圈33的值存放在bit0); |
|||
字节2存放线圈编号41\~42的数值,剩余位数添0补位; |
|||
假设线圈状态及数值如下面两张图所示: |
|||
|
|||
![image-20220126155705332](https://gitee.com/tianzhendong/img/raw/master//images/202201261557403.png) |
|||
|
|||
则,应答字节1的值为:11001011=0xCB; |
|||
应答字节2的值为:10=0x02 |
|||
应答消息帧下图所示: |
|||
|
|||
![image-20220126155736705](https://gitee.com/tianzhendong/img/raw/master//images/202201261557805.png) |
|||
|
|||
#### 02(0x02)读离散量输入 |
|||
|
|||
1)功能:读取从站1\~2000个连续离散量输入的状态值;读取采用起始地址+通道数量的方式; |
|||
2)操作方式:位操作; |
|||
3)离散量输入通道地址编号从1开始,寄存器地址编号从0开始; |
|||
4)发送指令示例: |
|||
假设要读取从站地址为0x03的第110\~119个数字量输入通道的数值,则发送指令如下图所示: |
|||
|
|||
![image-20220126155950411](https://gitee.com/tianzhendong/img/raw/master//images/202201261559467.png) |
|||
|
|||
5)应答:应答格式与功能码01H类似 |
|||
应答数据包括:从站地址+功能码+返回字节数+数据值+校验码 |
|||
假设应答字节1的数据如下图所示: |
|||
|
|||
![image-20220126160101013](https://gitee.com/tianzhendong/img/raw/master//images/202201261601073.png) |
|||
|
|||
应答字节2的内容如下图所示: |
|||
|
|||
![image-20220126160117915](https://gitee.com/tianzhendong/img/raw/master//images/202201261601955.png) |
|||
|
|||
应答消息帧如下图所示: |
|||
|
|||
![image-20220126160140799](https://gitee.com/tianzhendong/img/raw/master//images/202201261601880.png) |
|||
|
|||
#### 03(0x03)读保持寄存器 |
|||
|
|||
1)功能:读取远程从站若干个保持寄存器(Holding Register)的数值; |
|||
2)操作方式:每个保持存储器的数值以字(2个字节)的形式进行应答; |
|||
3)发送指令: |
|||
假设要读取从机地址0x03的108~110保持存储器的数值,其寄存器地址范围为:0x006B~0x006D,指令格式如下图所示: |
|||
|
|||
![image-20220126160219357](https://gitee.com/tianzhendong/img/raw/master//images/202201261602407.png) |
|||
|
|||
4)应答: |
|||
从站应答数据包括:从站地址+功能码+应答字节数+寄存器1高字节+寄存器1低字节+...+寄存器N高字节+寄存器N低字节 |
|||
假设编号108\~110保持寄存器的数值如下图所示: |
|||
|
|||
![image-20220126160302415](C:/Users/12038/AppData/Roaming/Typora/typora-user-images/image-20220126160302415.png) |
|||
|
|||
#### 04(0x04)读输入寄存器 |
|||
|
|||
1)功能:读1\~125个连续输入寄存器(Input Register)的数值; |
|||
2)操作方式:每个输入寄存器存储器的数值以字(2个字节)的形式进行应答; |
|||
3)发送指令: |
|||
假设要读取从机地址0x03的9-10号输入存储器的数值,其寄存器地址范围为:0x0008\~0x0009,指令格式如下图所示: |
|||
|
|||
![image-20220126160421236](https://gitee.com/tianzhendong/img/raw/master//images/202201261604282.png) |
|||
|
|||
4)应答: |
|||
从站应答数据包括:从站地址+功能码+应答字节数+寄存器1高字节+寄存器1低字节+...+寄存器N高字节+寄存器N低字节(与功能码03H类似) |
|||
假设寄存器的数据如下图所示: |
|||
|
|||
![image-20220126160435075](https://gitee.com/tianzhendong/img/raw/master//images/202201261604181.png) |
|||
|
|||
#### 05(0x05)写单个线圈 |
|||
|
|||
1)功能:对单个线圈进行写操作。线圈编号从1开始,地址从0开始。写值0xFF00表示将线圈置为ON,写值0x0000表示将线圈置为OFF,其它值是无效的; |
|||
2)操作方式:位操作 |
|||
3)发送指令: |
|||
假设要将从站地址0x03的第33个线圈(地址:0x0020)的值设置ON,指令如下图所示: |
|||
|
|||
![image-20220126160554223](https://gitee.com/tianzhendong/img/raw/master//images/202201261605273.png) |
|||
|
|||
4)应答: |
|||
从站应答数据包括:从站地址+功能码+寄存器地址+写入值 |
|||
如果数据成功写入,则应答数据与请求数据一样,如下图所示: |
|||
|
|||
![image-20220126160827485](https://gitee.com/tianzhendong/img/raw/master//images/202201261608569.png) |
|||
|
|||
#### 06(0x06)写单个寄存器 |
|||
|
|||
**写单个寄存器** |
|||
|
|||
在一个远程设备中,使用该功能码写单个保持寄存器。 |
|||
|
|||
请求 PDU 说明了被写入寄存器的地址。从零开始寻址寄存器。因此,寻址寄存器 1 为 0。 |
|||
|
|||
正常响应是请求的应答,在写入寄存器内容之后返回这个正常响应。 |
|||
|
|||
![image-20220126163833967](https://gitee.com/tianzhendong/img/raw/master//images/202201261638049.png) |
|||
|
|||
这是一个请求将十六进制 00 03 写入寄存器2的实例: |
|||
|
|||
![image-20220126163905446](https://gitee.com/tianzhendong/img/raw/master//images/202201261639508.png) |
|||
|
|||
![img](https://gitee.com/tianzhendong/img/raw/master//images/202201261617490.jpeg) |
|||
|
|||
#### 15 (0x0F) 写多个线圈 |
|||
|
|||
在一个远程设备中,使用该功能码强制线圈序列中的每个线圈为 ON 或 OFF。请求 PDU 说明了强制的线圈参考。从零开始寻址线圈。因此,寻址线圈 1 为 0。 |
|||
|
|||
请求数据域的内容说明了被请求的 ON/OFF 状态。域比特位置中的逻辑“1”请求相应输出为ON。域比特位置中的逻辑“0”请求相应输出为 OFF。 |
|||
|
|||
正常响应返回功能码、起始地址和强制的线圈数量。 |
|||
|
|||
![image-20220126163712250](https://gitee.com/tianzhendong/img/raw/master//images/202201261637349.png) |
|||
|
|||
这是一个请求从线圈 20 开始写入 10 个线圈的实例: |
|||
|
|||
请求的数据内容为两个字节:十六进制 CD 01 (二进制 1100 1101 0000 0001)。使用下列方法,二进制比特对应输出。 |
|||
|
|||
![image-20220126163753361](https://gitee.com/tianzhendong/img/raw/master//images/202201261637405.png) |
|||
|
|||
传输的第一字节(十六进制 CD)寻址为输出 27-20,在这种设置中,最低有效比特寻址为最低输出(20)。 |
|||
|
|||
传输的下一字节(十六进制 01)寻址为输出 29-28,在这种设置中,最低有效比特寻址为最低输出(28)。 |
|||
|
|||
应该用零填充最后数据字节中的未使用比特。 |
|||
|
|||
![image-20220126163810606](https://gitee.com/tianzhendong/img/raw/master//images/202201261638684.png) |
|||
|
|||
#### 16 (0x10) 写多个寄存器 |
|||
|
|||
在一个远程设备中,使用该功能码写连续寄存器块(1 至约 120 个寄存器)。 |
|||
|
|||
在请求数据域中说明了请求写入的值。每个寄存器将数据分成两字节。 |
|||
|
|||
正常响应返回功能码、起始地址和被写入寄存器的数量。 |
|||
|
|||
![image-20220126163612204](https://gitee.com/tianzhendong/img/raw/master//images/202201261636296.png) |
|||
|
|||
![image-20220126163641740](https://gitee.com/tianzhendong/img/raw/master//images/202201261636854.png) |
|||
|
|||
#### 23 (0x17) 读/写多个寄存器 |
|||
|
|||
在一个单独 MODBUS 事务中,这个功能码实现了一个读操作和一个写操作的组合。从零开始寻址保持寄存器。因此,寻址保持寄存器 1-16为0-15。 |
|||
|
|||
请求说明了起始地址、被读取的保持寄存器号和起始地址、保持寄存器号以及被写入的数据。在写数据域中,字节数说明随后的字节号。 |
|||
|
|||
正常响应包括被读出的寄存器组的数据。在读数据域中,字节数域说明随后的字节数量。 |
|||
|
|||
![img](https://gitee.com/tianzhendong/img/raw/master//images/202201261624713.jpeg) |
|||
|
|||
这是一个请求从寄存器4开始读六个寄存器并且从寄存器15开始读三个寄存器的实例: |
|||
|
|||
![img](https://gitee.com/tianzhendong/img/raw/master//images/202201261625666.jpeg) |
|||
|
|||
## ModBusTCP |
|||
|
|||
### 初识 |
|||
|
|||
#### 概述 |
|||
|
|||
> MODBUS/TCP 使MODBUS_RTU协议运行于以太网,MODBUS TCP使用TCP/IP和以太网在站点间传送**MODBUS报文**,MODBUS TCP结合了以太网物理网络和网络标准TCP/IP以及以MODBUS作为应用协议标准的数据表示方法。MODBUS TCP通信报文被封装于以太网TCP/IP数据包中。与传统的串口方式,MODBUS TCP插入一个标准的MODBUS报文到TCP报文中,不再带有数据校验和地址。 |
|||
|
|||
简单的理解一下[Modbus](https://so.csdn.net/so/search?q=Modbus&spm=1001.2101.3001.7020) TCP/IP协议的内容,就是**去掉了**modbus协议本身的**CRC校验**,**增加了MBAP 报文头**。TCP/IP上的MODBUS的请求/响应如下图所示: |
|||
|
|||
![TCPIPmodbus请求和响应](https://gitee.com/tianzhendong/img/raw/master//images/202201261523410.jpeg) |
|||
|
|||
--- |
|||
|
|||
#### 网络模型 |
|||
|
|||
通讯使用的以太网参考模型: |
|||
|
|||
Modbus TCP传输过程中使用了TCP/IP以太网参考模型的5层: |
|||
|
|||
第一层:物理层,提供设备物理接口,与市售介质/网络适配器相兼容 |
|||
|
|||
第二层:数据链路层,格式化信号到源/目硬件址数据帧 |
|||
|
|||
第三层:网络层,实现带有32位IP址IP报文包 |
|||
|
|||
第四层:传输层,实现可靠性连接、传输、查错、重发、端口服务、传输调度 |
|||
|
|||
第五层:应用层,Modbus协议报文 |
|||
|
|||
在网络通信中,通常需要写明IP地址和端口号,为什么ADU中没有相关的内容呢? |
|||
|
|||
其实这是因为是一个应用层的协议,而IP地址和端口号属于传输层/网络层的协议。看图: |
|||
|
|||
![image-20220126161301250](https://gitee.com/tianzhendong/img/raw/master//images/202201261613326.png) |
|||
|
|||
逻辑上是在TCP层上的。在发送数据的时候,应用数据单元首先向下传送给传输层,加上TCP协议的报文;再传送给网络层,加上IP协议的报文;再向下传送给数据链路层及物理层;接收的过程正好相反,从物理层一层一层的去掉相应层的报文,最终到达应用层。所以在进行数据传输的时候,是要配合TCP/IP协议来使用的。通常如果你使用电脑编程,就要用到SOCKET技术;如果是使用PLC编程,通常厂家已经把底层通信封装成库指令了,你只要直接调用就好了。比如西门子S7-200 SMART/1200/1500等PLC都有现成的Modbus-TCP指令库。 |
|||
|
|||
--- |
|||
|
|||
在Modbus服务器中按缺省协议使用Port 502 通信端口,在Modbus客户器程序中设置任意通信端口,为避免与其他通讯协议的冲突一般建议2000开始可以使用。 |
|||
|
|||
#### 通讯过程举例 |
|||
|
|||
在读寄存器的过程中,以Modbus TCP请求报文为例,具体的数据传输过程如下: |
|||
|
|||
\\1) Modbus TCP客户端实况,用Connect()命令建立目标设备TCP 502端口连接数据通信过程; |
|||
|
|||
\\2) 准备Modbus报文,包括7个字节MBAP内请求; |
|||
|
|||
\\3) 使用send()命令发送; |
|||
|
|||
\\4) 同一连接等待应答; |
|||
|
|||
\\5) 同recv()读报文,完成一次数据交换过程; |
|||
|
|||
\\6) 当通信任务结束时,关闭TCP连接,使服务器可以为其他服务。 |
|||
|
|||
### MBAP报文 |
|||
|
|||
MBAP是英文"ModBus APlication"的缩写,即"应用数据单元"的意思。 |
|||
|
|||
首先来看一下,MBAP 报文头都包括了哪些信息和内容 |
|||
|
|||
![image-20220126152436499](https://gitee.com/tianzhendong/img/raw/master//images/202201261524563.png) |
|||
|
|||
* **事务元标识符(2个字节):用于事务处理配对**。在响应中,MODBUS服务器复制请求的事务处理标识符。这里在以太网传输中存在一个问题,就是先发后至,我们可以利用这个事务处理标识符做一个**TCP序列号**,来防止这种情况所造成的数据收发错乱(这里我们先不讨论这种情况,这个事务处理标识符我们统一使用0x00,0x01) |
|||
|
|||
* **协议标识符(2个字节)**:modbus协议标识符为0x00,0x00 |
|||
|
|||
* **长度(2个字节)**:长度域是下一个域的字节数,包括单元标识符和数据域。 |
|||
|
|||
* **单元标识符(1个字节)**:该设备的编号。(可以使用PLC的IP地址标识)。 |
|||
|
|||
**对 TCP/IP 来说,利用IP地址寻址MODBUS服务器;因此,MODBUS单元标识符是无用的。必需使用值0xFF。** |
|||
|
|||
**注:0也可以用作与MODBUS/TCP设备直接通信。** |
|||
|
|||
### 请求和响应 |
|||
|
|||
#### MODBUS请求的生成 |
|||
|
|||
在收到来自用户应用的需求后,客户端必须生成一个MODBUS请求,并发送到TCP管理。下表显示MODBUS请求ADU编码: |
|||
|
|||
![image-20220126163209642](https://gitee.com/tianzhendong/img/raw/master//images/202201261632744.png) |
|||
|
|||
#### MODBUS响应的生成 |
|||
|
|||
一旦处理请求,MODBUS 服务器必须使用适当的MODBUS服务器事务处理生成一个响应,并且必须将响应发送到TCP管理组件。 |
|||
|
|||
根据处理结果,可以生成两类响应: |
|||
|
|||
* 肯定的MODBUS响应: |
|||
|
|||
* 响应功能码 = 请求功能码 |
|||
|
|||
* MODBUS异常响应: |
|||
|
|||
* 目的是为客户机提供与处理过程检测到的错误相关的信息 |
|||
|
|||
* 响应功能码 = 请求功能码+0x80 |
|||
|
|||
* 提供异常码来表明出错的原因。 |
|||
|
|||
![image-20220126163326097](https://gitee.com/tianzhendong/img/raw/master//images/202201261633205.png) |
|||
|
|||
### SIMATIC S7-1200/S7-1500存储区寻址 |
|||
|
|||
| 存储区 | Modbus 设备中应用层的地址 | 传输报文中 Modbus 地址(数据链路层) | |
|||
| -------------------- | ---------------------------------------------- | ------------------------------------ | |
|||
| 线圈(输出) | 1 to 9999 | 0 to 9998 | |
|||
| 离散输入(输入) | 10001 to 19999 | 0 to 9998 | |
|||
| 输入寄存器(输入字) | 30001 to 39999 | 0 to 9998 | |
|||
| 保持寄存器(输出字) | 40001 to 49999 400001 to 465536 扩展的地址空间 | 0 to 9998 0 to 65535 | |
|||
|
|||
### 实例 |
|||
|
|||
![image-20220214153310475](https://gitee.com/tianzhendong/img/raw/master//images/202202141533546.png) |
|||
|
|||
*注意:MB_HOLD_REG中的数量不能大于数据块中数据的数量* |
|||
|
|||
保持性寄存器示例如下,有word(两个字节,16位)类型和Real(4个字节,32位)两种组成, |
|||
|
|||
注意:一个保持性寄存器为16位,两个字节,因此一个**real类型**占用**两个保持性寄存器** |
|||
|
|||
![image-20220214151538122](https://gitee.com/tianzhendong/img/raw/master//images/202202141515294.png) |
|||
|
|||
发送读取请求,需要从0位(00 00)开始,读取15(00 0f)个保持性寄存器: |
|||
|
|||
发送请求: |
|||
|
|||
``` |
|||
00 00 00 00 00 06 FF 03 00 00 00 0f |
|||
``` |
|||
|
|||
收到回复: |
|||
|
|||
``` |
|||
00 00 00 00 00 21 FF 03 1E 00 01 00 02 00 03 00 04 00 05 40 D3 33 33 40 F6 66 66 41 0C CC CD 41 1E 66 66 BF 80 00 00 |
|||
``` |
|||
|
|||
其中a1-a5为word类型,分别占用一个保持性寄存器,两个字节表示,如a1(1)表示为:00 01 |
|||
|
|||
a6-a10为real类型,占用了两个保持性寄存器,用4个字节表示,如a6(6.6)表示为:40 D3 33 33,a10(-1.0)表示为:BF 80 00 00 |
|||
|
|||
注意:浮点数表示遵循[IEEE 754标准](https://www.cnblogs.com/MikeZhang/p/IEEE754FloatEncode20180117.html),在线转换:http://www.speedfly.cn/tools/hexconvert/ |
|||
|
|||
## ModbusTCP QT编程 |
|||
|
|||
### QModBusTcpClient类 |
|||
|
|||
QModBusTcpClient类>>QModbusClient>>QModbusDevice>>QObject |
|||
|
|||
#### 信号 |
|||
|
|||
| 信号 | | |
|||
| ------------- | ------------------------------------------------------------ | |
|||
| errorOccurred | 有错误时发出 | |
|||
| stateChanged | 每当设备的状态发生变化时,就会发出这个信号。新状态由状态表示。 | |
|||
| finished() | 该信号在应答完成处理时发出。回复可能仍然返回了一个错误。在发出此信号后,应答的数据将不再有更新。 | |
|||
|
|||
#### 函数 |
|||
|
|||
| | | |
|||
| ------------------------------ | ------------------------------------------------------------ | |
|||
| Error error() | 返回设备的错误状态 | |
|||
| QString errorString() | 返回设备错误的描述性错误文本。 | |
|||
| void disconnectDevice() | 断开连接的设备。 | |
|||
| setConnectionParameter() | | |
|||
| setTimeout() | | |
|||
| setNumberOfRetries() | | |
|||
| bool connectDevice() | 用于设备接入Modbus网络。成功时返回true;否则错误。 | |
|||
| QMODBUSREPLY sendReadRequest() | 发送读请求 | |
|||
| sendWriteRequest() | 发送一个读取read所指向数据的内容的请求。如果没有错误发生,返回一个新的有效的QModbusReply对象,否则为nullptr。Modbus网络可以有多个服务器,每个服务器都有唯一的serverAddress。 | |
|||
| bool isFinished() | 当回复完成或中止时返回true。 | |
@ -0,0 +1,179 @@ |
|||
--- |
|||
title: 通讯数据格式转换 |
|||
author: TianZD |
|||
top: true |
|||
cover: true |
|||
toc: true |
|||
mathjax: false |
|||
summary: >- |
|||
modubusTCP在传输时,通过读写保持性寄存器位进行数据传输,一个保持性寄存器占有2个byte,16个bite,传输的数据常为float型(4个byte,32位),需要进行转换 |
|||
tags: |
|||
- 数据格式 |
|||
- modbus |
|||
categories: |
|||
- 通讯 |
|||
reprintPolicy: cc_by |
|||
abbrlink: fffca2d8 |
|||
date: 2022-04-29 13:47:36 |
|||
coverImg: |
|||
img: |
|||
password: |
|||
--- |
|||
|
|||
\[toc\] |
|||
|
|||
# 通讯数据格式转换(float/real-word-byte) |
|||
|
|||
## 前言 |
|||
|
|||
在上位机和下位机进行通讯的时候,通常要进行数据转换为字节(8位)或者word(16位)进行传输 |
|||
|
|||
modubusTCP在传输时,通过**读写保持性寄存器**位进行数据传输,一个保持性寄存器占有**2个byte**,**16个bite**,传输的数据常为**float型(4个byte,32位)**,需要进行转换 |
|||
|
|||
浮点数的表示通常采用**IEEE 754浮点数标准**,可以参考文章[IEEE754标准的浮点数存储格式](https://www.cnblogs.com/MikeZhang/p/IEEE754FloatEncode20180117.html) |
|||
|
|||
IEEE754转换:[在线转换网址](http://www.speedfly.cn/tools/hexconvert/) |
|||
|
|||
## 数据在内存中的存储格式 |
|||
|
|||
### 大端模式 |
|||
|
|||
大端模式是指数据的高字节保存在内存的低地址单元中,而数据的低字节保存在内存的高地址单元中,这样的存储模式有点类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;这和我们的阅读习惯一致。 |
|||
|
|||
### 小端模式 |
|||
|
|||
小端模式是指数据的高字节保存在内存的高地址单元中,而数据的低字节保存在内存的低地址单元中。 |
|||
|
|||
## 转换 |
|||
|
|||
其中float-byte、byte-float代码转自CSDN文章:[float型数据与4字节之间的转换,作者tutu-hu](https://blog.csdn.net/weixin_42700740/article/details/103236885?share_token=7af34e32-1bce-4b09-9225-afa6e02006f6) |
|||
|
|||
### float-byte(32位浮点数转4个8位) |
|||
|
|||
**2进制,与运算,左移运算** |
|||
|
|||
```c++ |
|||
/*将浮点数f转化为4个字节数据存放在byte[4]中*/ |
|||
unsigned char* Float_to_Byte(float f) |
|||
{ |
|||
float float_data = 0; |
|||
unsigned long longdata = 0; |
|||
longdata = *(unsigned long*)&f; //注意,会丢失精度 |
|||
byte[0] = (longdata & 0xFF000000) >> 24; |
|||
byte[1] = (longdata & 0x00FF0000) >> 16; |
|||
byte[2] = (longdata & 0x0000FF00) >> 8; |
|||
byte[3] = (longdata & 0x000000FF); |
|||
return byte; |
|||
} |
|||
``` |
|||
|
|||
### float-word(32位浮点数转2个16位) |
|||
|
|||
```c++ |
|||
unsigned int* Float_to_word(float f) |
|||
{ |
|||
unsigned long longdata = 0; |
|||
longdata = *(unsigned long*)&f; //注意,会丢失精度 |
|||
word[0] = (longdata & 0xFFFF0000) >> 16; |
|||
word[1] = (longdata & 0x0000FFFF); |
|||
return word; |
|||
} |
|||
``` |
|||
|
|||
### byte-float(4个8位转1个32位浮点数) |
|||
|
|||
#### 方法1 |
|||
|
|||
把四个字节存储好之后,再把这个**存储区域的首地址强制转换为float指针类型**,这样就可以提取出这个浮点数了。 |
|||
|
|||
```c |
|||
/*将4个字节数据byte[4]转化为浮点数存放在*f中*/ |
|||
float Byte_to_Float(unsigned char *p) |
|||
{ |
|||
float float_data=0; |
|||
unsigned long longdata = 0; |
|||
longdata = (*p<< 24) + (*(p+1) << 16) + (*(p + 2) << 8) + (*(p + 3) << 0); |
|||
float_data = *(float*)&longdata; |
|||
return float_data; |
|||
} |
|||
``` |
|||
|
|||
#### 方法2 |
|||
|
|||
把四个字节存储好之后,再把这个**存储区域的首地址强制转换为float指针类型**,这样就可以提取出这个浮点数了。 |
|||
|
|||
这个和方法1类似 |
|||
|
|||
```c |
|||
/** |
|||
*作用:把u8四字节数组转为float |
|||
*note:低地址放float的低字节 |
|||
**/ |
|||
float U8_to_Float(u8* str) |
|||
{ |
|||
float data; |
|||
data = *((float*)str); |
|||
return data; |
|||
} |
|||
``` |
|||
|
|||
#### 方法3 |
|||
|
|||
定义一个float变量,然后定义u8类型指针数组指向float变量地址,Modbus协议解析的时候只管向地址指向的存储单元填充数据,需要用浮点数的时候直接拿过来用就可以了。 |
|||
|
|||
```c |
|||
#include <stdio.h> |
|||
#include <stdlib.h> |
|||
#include <string.h> |
|||
|
|||
int main(void) |
|||
{ |
|||
float freq; |
|||
char recv[4] = {0x41, 0xbc, 0x00, 0x00}; //接收到的数据,高字节到低字节排列 |
|||
char *Modbus_HoldReg[4]; //定义保持寄存器指针数组 |
|||
|
|||
//第一步:指针初始化 |
|||
Modbus_HoldReg[0] = ((char*)(&freq)) + 3; //低地址指向高位 |
|||
Modbus_HoldReg[1] = ((char*)(&freq)) + 2; |
|||
Modbus_HoldReg[2] = ((char*)(&freq)) + 1; |
|||
Modbus_HoldReg[3] = ((char*)(&freq)) + 0; //高地址指向低位 |
|||
|
|||
//第二步:给地址指定的内存单元赋值(对应Modbus协议中的数据解析) |
|||
*Modbus_HoldReg[0] = recv[0]; |
|||
*Modbus_HoldReg[1] = recv[1]; |
|||
*Modbus_HoldReg[2] = recv[2]; |
|||
*Modbus_HoldReg[3] = recv[3]; |
|||
printf("%f\r\n", freq); |
|||
|
|||
return 0; |
|||
} |
|||
``` |
|||
|
|||
### word-float(2个16位合成1个32位浮点数) |
|||
|
|||
```c |
|||
float Byte_to_Float(unsigned char *p) |
|||
{ |
|||
float float_data=0; |
|||
unsigned long longdata = 0; |
|||
longdata = (*p<< 16) + (*(p+1) << 0); |
|||
float_data = *(float*)&longdata; |
|||
return float_data; |
|||
} |
|||
``` |
|||
|
|||
### byte-word(2个8位合成1个16位) |
|||
|
|||
两个8位数如何转化为16位数? |
|||
|
|||
```c |
|||
int data = (a<<8) & b; |
|||
``` |
|||
|
|||
```c |
|||
char a;//高位 |
|||
char b;//低位 |
|||
.... |
|||
int data = (a<<8)&0xFF00; |
|||
data &= b; |
|||
``` |
@ -1,5 +1,5 @@ |
|||
@echo off |
|||
cd C:\hexo_blog |
|||
cd C:\Blog\hexo_blog |
|||
git add . |
|||
git commit -m "Auto commit." |
|||
git push origin master |
|||
|
@ -1,5 +1,5 @@ |
|||
@echo off |
|||
cd C:\hexo_blog |
|||
cd C:\Blog\hexo_blog |
|||
hexo cl && hexo d |
|||
|
|||
pause |
Loading…
Reference in new issue