017——DS18B20驱动开发(基于I.MX6uLL)

目录

一、 模块介绍

1.1 简介

1.2 主要特点

1.3 存储器介绍

1.4 时序

1.5 命令

1.5.1 命令大全   

1.5.2 命令使用

1.5.3 使用示例

1.6 原理图

二、 驱动程序

三、 应用程序

四、 测试


一、 模块介绍

1.1 简介

        DS18B20 温度传感器具有线路简单、体积小的特点,用来测量温度非常简单,在一根通信线上可以挂载多个 DS18B20 温度传感器。用户可以通过编程实现9~12 位的温度读数,每个 DS18B20 有唯一的 64 位序列号,保存在 rom 中,因此一条总线上可以挂载多个 DS18B20。

1.2 主要特点

■采用单总线接口仅需一个端口引脚进行通信
■每颗芯片具有全球唯一的64位的序列号
■具有多点分布式测温功能
■无需外围元器件
■可通过数据线供电;供电电压范围为2.5V∽5.5V
■测度测量范围为-55°C to +125°C(-67°F to +257°F)
■在-10°C∽70°C范围内精确度为±0.4°C
■温度分辨率9-12位可选
■最高12位精度下,温度转换速度小于400ms
■具有用户自定义的非易失性温度报警设置
■报名搜索命令识别并标识超过程序设定温度的器件
■超强静电保护能力:HBM 8000V MM 800V
■可提供贴片的MSOP8封装和3脚的TO-90封装
■应用包括温度控制、工业系统、消费品、粮情测温、温度计或任何感热系统

1.3 存储器介绍

        以前玩这个的时候都忽略这里了,就看时序图和数据帧了。

        DS18B20 内部有个 64 位只读存储器( ROM)和 64 位配置存储器( SCRATCHP)。64 位只读存储器( ROM)包含序列号等,具体格式如下图

        低八位用于 CRC 校验,中间 48 位是 DS18B20 唯一序列号,高八位是该系列产品系列号(固定为 28h)。因此,根据每个 DS18B20 唯一的序列号,可以实现一条总线上可以挂载多个 DS18B20 时,获取指定 DS18B20 的温度信息。

        64 位配置存储器( SCRATCHP)由 9 个 Byte 组成,包含温度数据、配置信息等,具体格式如下图:

⚫ Byte[0:1]:温度值。也就是当我们发出一个测量温度的命令之后,还需
要发送一个读内存的命令才能把温度值读取出来。
⚫ Byte[2:3]: TL 是低温阈值设置, TH 是高温阈值设置。当温度低于/超过
阈值,就会报警。 TL、 TH 存储在 EEPROM 中,数据在掉电时不会丢失;
⚫ Byte4:配置寄存器。用于配置温度精度为 9、 10、 11 或 12 位。配置寄存
器也存储在 EEPROM 中,数据在掉电时不会丢失;
⚫ Byte[5:7]:厂商预留;
⚫ Byte[8]: CRC 校验码。
 

1.4 时序

上面这些资料来源于这位老前辈的毕业设计翻译,翻译的挺好就是有点糊。

① ① 初始化时序
类似前面的 DHT11,主机要跟 DS18B20 通信,首先需要发出一个开始信号。
深黑色线表示由主机驱动信号,浅灰色线表示由 DS18B20 驱动信号。
最开始时引脚是高电平,想要开始传输信号,
a) 必须要拉低至少 480us,这是复位信号;
b) 然后拉高释放总线,等待 15~60us 之后,
c) 如果 GPIO 上连有 DS18B20 芯片,它会拉低 60~240us。
如果主机在最后检查到 60~240us 的低脉冲,则表示 DS18B20 初始化成功
② 写时序
⚫ 如果写 0,拉低至少 60us(写周期为 60-120us)即可;
⚫ 如果写 1,先拉低至少 1us,然后拉高,整个写周期至少为 60us 即可
③ 读时序
⚫ 主机先拉低至少 1us,随后读取电平,如果为 0,即读到的数据是 0,如果
为 1,即可读到的数据是 1。
⚫ 整个过程必须在 15us 内完成, 15us 后引脚都会被拉高
 

1.5 命令

(这块的图直接用韦东山老师的了,原来的老哥翻译的这个图片太马赛克了。但是韦老师的也不太好,后面有水印影响观感。)

1.5.1 命令大全   

     现在我们知道怎么发 1 位数据,收 1 位数据。发什么数据才能得到温度值,这需要用到“命令”。DS18B20 中有两类命令: ROM 命令、功能命令,列表如下:

1.5.2 命令使用

DS18B20 芯片手册中有 ROM 命令、功能命令的流程图,先贴出来,下一小节再举例。

1.5.3 使用示例

        总线上只一个 DS18B20 设备时,根据下表发送命令、读取数据。 因为只有一个 DS18B20,所以不需要选择设备,发出“ Skip ROM”命令。 然后发户“ ConvertT”命令启动温度转换;等待温度转换成功后,要读数据前,也要发出“ Skip ROM”命令。 下表列得很清楚:

        总线上有多个 DS18B20 设备时,根据下表发送命令、读取数据。 首先肯定是要选中指定设备:使用“ Match ROM”命令发出 ROM Code 来选择中设备; 然后发户“Convert T”命令启动温度转换; 等待温度转换成功后,要读数据前,也要发出“Match ROM”命令、 ROM Code。 下表列得很清楚:

1.6 原理图

二、 驱动程序

(今天破了一个案,dht11和ds18b20一点都不一样,以前一直没深入了解过ds18b20看来小觑它了)

#include "acpi/acoutput.h"
#include "asm-generic/errno-base.h"
#include "asm-generic/gpio.h"
#include "asm/gpio.h"
#include "asm/uaccess.h"
#include <linux/module.h>
#include <linux/poll.h>

#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/tty.h>
#include <linux/kmod.h>
#include <linux/gfp.h>
#include <linux/gpio/consumer.h>
#include <linux/platform_device.h>
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/slab.h>
#include <linux/fcntl.h>
#include <linux/timer.h>

struct gpio_desc{
	int gpio;
	int irq;
    char *name;
    int key;
	struct timer_list key_timer;
} ;

static struct gpio_desc gpios[] = {
    {115, 0, "ds18b20", },
};

/* 主设备号                                                                 */
static int major = 0;
static struct class *gpio_class;

static spinlock_t ds18b20_spinlock;


static void ds18b20_udelay(int us)
{
	u64 time = ktime_get_ns();
	while (ktime_get_ns() - time < us*1000);
}

static int ds18b20_reset_and_wait_ack(void)
{
	int timeout = 100;

	gpio_set_value(gpios[0].gpio, 0);
	ds18b20_udelay(480);

	gpio_direction_input(gpios[0].gpio);

	/* 等待ACK */
	while (gpio_get_value(gpios[0].gpio) && timeout--)
	{
		ds18b20_udelay(1);
	}

	if (timeout == 0)
		return -EIO;

	/* 等待ACK结束 */
	timeout = 300;
	while (!gpio_get_value(gpios[0].gpio) && timeout--)
	{
		ds18b20_udelay(1);
	}
	if (timeout == 0)
		return -EIO;
	
	return 0;

}

static void ds18b20_send_cmd(unsigned char cmd)
{
	int i;
	
	gpio_direction_output(gpios[0].gpio, 1);

	for (i = 0; i < 8; i++)
	{
		if (cmd & (1<<i)) 
		{
			/* 发送1 */
			gpio_direction_output(gpios[0].gpio, 0);
			ds18b20_udelay(2);
			gpio_direction_output(gpios[0].gpio, 1);
			ds18b20_udelay(60);
		}
		else
		{
			/* 发送0 */
			gpio_direction_output(gpios[0].gpio, 0);
			ds18b20_udelay(60);		
			gpio_direction_output(gpios[0].gpio, 1);
		}
	}
}

static void ds18b20_read_data(unsigned char *buf)
{
	int i;
	unsigned char data = 0;

	gpio_direction_output(gpios[0].gpio, 1);
	for (i = 0; i < 8; i++)
	{
		gpio_direction_output(gpios[0].gpio, 0);
		ds18b20_udelay(2);
		gpio_direction_input(gpios[0].gpio);
		ds18b20_udelay(15);
		if (gpio_get_value(gpios[0].gpio))
		{
			data |= (1<<i);
		}
		ds18b20_udelay(50);
		gpio_direction_output(gpios[0].gpio, 1);
	}

	buf[0] = data;
}

/********************************************************/  
/*DS18B20的CRC8校验程序*/  
/********************************************************/   
/* 参考: https://www.cnblogs.com/yuanguanghui/p/12737740.html */   
static unsigned char calcrc_1byte(unsigned char abyte)   
{   
	unsigned char i,crc_1byte;     
	crc_1byte=0;                //设定crc_1byte初值为0  
	for(i = 0; i < 8; i++)   
	{   
		if(((crc_1byte^abyte)&0x01))   
		{   
			crc_1byte^=0x18;     
			crc_1byte>>=1;   
			crc_1byte|=0x80;   
		}         
		else     
			crc_1byte>>=1;   

		abyte>>=1;         
	}   
	return crc_1byte;   
}

/* 参考: https://www.cnblogs.com/yuanguanghui/p/12737740.html */   
static unsigned char calcrc_bytes(unsigned char *p,unsigned char len)  
{  
	unsigned char crc=0;  
	while(len--) //len为总共要校验的字节数  
	{  
		crc=calcrc_1byte(crc^*p++);  
	}  
	return crc;  //若最终返回的crc为0,则数据传输正确  
}  


static int ds18b20_verify_crc(unsigned char *buf)
{
    unsigned char crc;

	crc = calcrc_bytes(buf, 8);

    if (crc == buf[8])
		return 0;
	else
		return -1;
}

static void ds18b20_calc_val(unsigned char ds18b20_buf[], int result[])
{
	unsigned char tempL=0,tempH=0;
	unsigned int integer;
	unsigned char decimal1,decimal2,decimal;

	tempL = ds18b20_buf[0]; //读温度低8位
	tempH = ds18b20_buf[1]; //读温度高8位

	if (tempH > 0x7f)      							//最高位为1时温度是负
	{
		tempL    = ~tempL;         				    //补码转换,取反加一
		tempH    = ~tempH+1;      
		integer  = tempL/16+tempH*16;      			//整数部分
		decimal1 = (tempL&0x0f)*10/16; 			//小数第一位
		decimal2 = (tempL&0x0f)*100/16%10;			//小数第二位
		decimal  = decimal1*10+decimal2; 			//小数两位
	}
	else
	{
		integer  = tempL/16+tempH*16;      				//整数部分
		decimal1 = (tempL&0x0f)*10/16; 					//小数第一位
		decimal2 = (tempL&0x0f)*100/16%10;				//小数第二位
		decimal  = decimal1*10+decimal2; 				//小数两位
	}
	result[0] = integer;
	result[1] = decimal;
}

/* 实现对应的open/read/write等函数,填入file_operations结构体                   */
static ssize_t ds18b20_read (struct file *file, char __user *buf, size_t size, loff_t *offset)
{
	unsigned long flags;
	int err;
	unsigned char kern_buf[9];
	int i;
	int result_buf[2];

	if (size != 8)
		return -EINVAL;

	/* 1. 启动温度转换 */
	/* 1.1 关中断 */
	spin_lock_irqsave(&ds18b20_spinlock, flags);

	/* 1.2 发出reset信号并等待回应 */
	err = ds18b20_reset_and_wait_ack();
	if (err)
	{
		spin_unlock_irqrestore(&ds18b20_spinlock, flags);
		printk("ds18b20_reset_and_wait_ack err\n");
		return err;
	}

	/* 1.3 发出命令: skip rom, 0xcc */
	ds18b20_send_cmd(0xcc);

	/* 1.4 发出命令: 启动温度转换, 0x44 */
	ds18b20_send_cmd(0x44);

	/* 1.5 恢复中断 */
	spin_unlock_irqrestore(&ds18b20_spinlock, flags);

	/* 2. 等待温度转换成功 : 可能长达1s */
	set_current_state(TASK_INTERRUPTIBLE);
	schedule_timeout(msecs_to_jiffies(1000));

	/* 3. 读取温度 */
	/* 3.1 关中断 */
	spin_lock_irqsave(&ds18b20_spinlock, flags);

	/* 3.2 发出reset信号并等待回应 */
	err = ds18b20_reset_and_wait_ack();
	if (err)
	{
		spin_unlock_irqrestore(&ds18b20_spinlock, flags);
		printk("ds18b20_reset_and_wait_ack second err\n");
		return err;
	}
	/* 3.3 发出命令: skip rom, 0xcc */
	ds18b20_send_cmd(0xcc);

	/* 3.4 发出命令: read scratchpad, 0xbe */
	ds18b20_send_cmd(0xbe);

	/* 3.5 读9字节数据 */
	for (i = 0; i < 9; i++)
	{
		ds18b20_read_data(&kern_buf[i]);
	}

	/* 3.6 恢复中断 */
	spin_unlock_irqrestore(&ds18b20_spinlock, flags);

	/* 3.7 计算CRC验证数据 */
	err = ds18b20_verify_crc(kern_buf);
	if (err)
	{
		printk("ds18b20_verify_crc err\n");
		return err;
	}

	/* 4. copy_to_user */
	ds18b20_calc_val(kern_buf, result_buf);
	
	err = copy_to_user(buf, result_buf, 8);
	return 8;
}


/* 定义自己的file_operations结构体                                              */
static struct file_operations gpio_key_drv = {
	.owner	 = THIS_MODULE,
	.read    = ds18b20_read,
};


/* 在入口函数 */
static int __init ds18b20_init(void)
{
    int err;
    int i;
    int count = sizeof(gpios)/sizeof(gpios[0]);
    
	printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);

	spin_lock_init(&ds18b20_spinlock);
	
	for (i = 0; i < count; i++)
	{		
		err = gpio_request(gpios[i].gpio, gpios[i].name);
		gpio_direction_output(gpios[i].gpio, 1);
	}

	/* 注册file_operations 	*/
	major = register_chrdev(0, "100ask_ds18b20", &gpio_key_drv);  /* /dev/gpio_desc */

	gpio_class = class_create(THIS_MODULE, "100ask_ds18b20_class");
	if (IS_ERR(gpio_class)) {
		printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
		unregister_chrdev(major, "100ask_ds18b20");
		return PTR_ERR(gpio_class);
	}

	device_create(gpio_class, NULL, MKDEV(major, 0), NULL, "myds18b20"); /* /dev/myds18b20 */
	
	return err;
}

/* 有入口函数就应该有出口函数:卸载驱动程序时,就会去调用这个出口函数
 */
static void __exit ds18b20_exit(void)
{
    int i;
    int count = sizeof(gpios)/sizeof(gpios[0]);
    
	printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);

	device_destroy(gpio_class, MKDEV(major, 0));
	class_destroy(gpio_class);
	unregister_chrdev(major, "100ask_ds18b20");

	for (i = 0; i < count; i++)
	{
		gpio_free(gpios[i].gpio);
	}
}


/* 7. 其他完善:提供设备信息,自动创建设备节点                                     */

module_init(ds18b20_init);
module_exit(ds18b20_exit);

MODULE_LICENSE("GPL");


三、 应用程序


#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <poll.h>
#include <signal.h>

static int fd;

/*
 * ./button_test /dev/myds18b20
 *
 */
int main(int argc, char **argv)
{
	int buf[2];
	int ret;

	int i;
	
	/* 1. 判断参数 */
	if (argc != 2) 
	{
		printf("Usage: %s <dev>\n", argv[0]);
		return -1;
	}


	/* 2. 打开文件 */
	fd = open(argv[1], O_RDWR | O_NONBLOCK);
	if (fd == -1)
	{
		printf("can not open file %s\n", argv[1]);
		return -1;
	}

	while (1) 
	{
		if (read(fd, buf, 8) == 8)
			printf("get ds18b20: %d.%d\n", buf[0], buf[1]);
		else
			printf("get ds18b20: -1\n");
		
		sleep(5);
	}
	
	close(fd);
	
	return 0;
}


四、 测试

注意一下这次设备的名字前面有个my剩下的就是老样子,暂时先直接用韦老师的后面我在按需修改。

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

mysql慢sql排查与分析

当MySQL遇到慢查询&#xff08;慢SQL&#xff09;时&#xff0c;我们可以通过以下步骤进行排查和优化&#xff1a; 标题开启慢查询日志&#xff1a; 确保MySQL的慢查询日志已经开启。通过查看slow_query_log和slow_query_log_file变量来确认。 如果没有开启&#xff0c;可以…

关于Ansible模块 ⑤

转载说明&#xff1a;如果您喜欢这篇文章并打算转载它&#xff0c;请私信作者取得授权。感谢您喜爱本文&#xff0c;请文明转载&#xff0c;谢谢。 继《关于Ansible的模块 ①》、《关于Ansible的模块 ②》与《关于Ansible的模块 ③》之后&#xff0c;继续学习ansible常用模块之…

数据结构算法题 2(力扣)——链表

1. 分割链表&#xff08;OJ链接&#xff09; 题目描述&#xff1a;给你一个链表的头节点 head 和一个特定值 x &#xff0c;请你对链表进行分隔&#xff0c;使得所有小于 x 的节点都出现在大于或等于 x 的节点之前。 本题做法是&#xff1a;遍历链表将链表分为两部分&#xf…

Discord注册教程:Discord刚注册就被封怎么办?附申诉教程!

Discord如今在海外社交媒体平台中迅速崛起&#xff0c;许多社交媒体营销人员也纷纷利用其社群特性进行推广&#xff0c;Discord注册也就成为社媒营销人员必经之路。然而&#xff0c;很多人注册Discord账号时常常会想&#xff1a;“在国内使用Discord会封号吗&#xff1f;”事实…

STC12单片机设置50Hz的PWM波驱动舵机

本文将使用STC12C5A60S2配置PWM波&#xff0c;驱动SG90舵机。 采用的开发板包括了CH340芯片&#xff0c;因此下载程序只需要使用MicroUSB转USB连接线使用STC-ISP.exe软件下载程序即可。 1 芯片资源 芯片型号STC12C5A60S2&#xff0c;增强型8051 CPU&#xff0c;1T&#xff0c…

计算机组成原理 — CPU 的结构和功能

CPU 的结构和功能 CPU 的结构和功能CPU 概述控制器概述CPU 框架图CPU 寄存器控制单元 CU 指令周期概述指令周期的数据流 指令流水概述指令流水的原理影响流水线性能的因素流水线的性能流水线的多发技术流水线结构 中断系统概述中断请求标记和中断判优逻辑中断请求标记 INTR中断…

Mysql底层原理五:如何设计、用好索引

1.索引的代价 空间上的代价 时间上的代价 每次对表中的数据进⾏增、删、改操作时&#xff0c;都需要去修改各个B树索引。⽽且我们讲过&#xff0c;B树每层节点都是按照索引列的值从⼩到⼤的顺序排序⽽组成了双 向链表。不论是叶⼦节点中的记录&#xff0c;还是内节点中的记录&a…

设计模式实践

一、工厂模式 这里只讲简单工厂模式&#xff0c;详细的可以参考Java工厂模式&#xff08;随笔&#xff09;-CSDN博客。工厂类会根据不同的参数或条件来决定创建哪种对象&#xff0c;这样客户端只需要知道自己需要什么对象&#xff0c;而不需要关心对象的创建过程&#xff01; …

Golang 开发实战day06 - Boolean Conditional

&#x1f3c6;个人专栏 &#x1f93a; leetcode &#x1f9d7; Leetcode Prime &#x1f3c7; Golang20天教程 &#x1f6b4;‍♂️ Java问题收集园地 &#x1f334; 成长感悟 欢迎大家观看&#xff0c;不执着于追求顶峰&#xff0c;只享受探索过程 Golang 教程06 - Boolean &a…

分布式锁的原子性问题

4.6 分布式锁的原子性问题 更为极端的误删逻辑说明&#xff1a; 线程1现在持有锁之后&#xff0c;在执行业务逻辑过程中&#xff0c;他正准备删除锁&#xff0c;而且已经走到了条件判断的过程中&#xff0c;比如他已经拿到了当前这把锁确实是属于他自己的&#xff0c;正准备删…

如何在CentOS安装Nexus容器无公网IP远程管理本地仓库

文章目录 1. Docker安装Nexus2. 本地访问Nexus3. Linux安装Cpolar4. 配置Nexus界面公网地址5. 远程访问 Nexus界面6. 固定Nexus公网地址7. 固定地址访问Nexus Nexus是一个仓库管理工具&#xff0c;用于管理和组织软件构建过程中的依赖项和构件。它与Maven密切相关&#xff0c;可…

数据通讯平台解决方案(Word原件获取)

1.数据通讯平台方案 1.1.系统概述 1.2.需求分析 1.3.重难点分析 1.4.重难点解决措施 2.系统架构设计 2.1.系统架构图 系统机构图 2.2.业务架构设计 (1) MQ消息服务 (2) TCP通讯服务 (3) CoAP通讯服务 (4) MQTT通讯服务 (5) 资源管理服务 2.3.主流技术架构分析 纵向设计方案 2.4…

QGraphics框架场景中图元的移除与析构

1.场景里面使用removeItem函数&#xff0c;这个函数官方给出如下解释 注意这个词remove只是移除&#xff0c;并不是delete掉&#xff0c;所以只是场景中&#xff08;显示出来的图元&#xff09;没有了&#xff0c;空间还是存在。 举个代码例子&#xff1a; void MyGraphicsV…

USACO 2024 Open Bronze铜组题解

迟到了一个月的题解...... Logical Moos: 啊这题放在铜组T1雀食有点BT...... 首先&#xff0c;我们关注l前第一和r最后那两组。如果这俩有一个是true&#xff0c;那答案肯定也是true。 否则&#xff0c;在l和r外边的都是false。那我们就只用仔细看l和r中间的玩意儿。对于l和…

三月以来的黄金暴涨 ,华尔街都看不懂

本轮黄金大幅上涨无法按照美联储政策逻辑解释&#xff0c;央行的购金需求也无法合理化金价的历史新高&#xff0c;而金价的大涨也与黄金ETF流出相背&#xff0c;推动反弹的“神秘力量”令分析师困惑不已。 黄金上涨的情况往往会出现在美联储开启降息周期后&#xff0c;如果市场…

Linux 之 定时任务调度器-crond(crontab)服务

Linux系列文章&#xff1a; Windows本地如何添加域名映射&#xff1f;&#xff08;修改hosts文件&#xff09;_本机域名映射-CSDN博客 Linux安装mysq 8.0服务端和客户端(亲测保成功&#xff09;_linux安装mysql客户端-CSDN博客 linux-man命令的使用及练习_man命令执行后无法…

微服务架构下,如何通过弱依赖原则保障系统高可用?

前言 当我初次接触高可用这个概念的时候&#xff0c;对高可用的【少依赖原则】和【弱依赖原则】的边界感模糊&#xff0c;甚至有些“傻傻分不清楚”。这两个原则都关注降低模块之间的依赖关系&#xff0c;但它们之间的确存在某些差异。 那么&#xff0c;「少依赖原则」和「弱…

Windows深度学习环境----Cuda version 10.2 pytorch3d version 0.3.0

Requirements Python version 3.8.5Pytorch version: pytorch1.6.0 torchvision0.8.2 torchaudio0.7.0 cudatoolkit10.2.89pytorch3d version 0.3.0Cuda version 10.2 感觉readme文件里的不适配&#xff0c;跟pytorch官网不同 以前的 PyTorch 版本 |PyTorch的 # CUDA 10.2 c…

面板数据回归模型(二)房价的影响因素分析

1.数据来源 本文选择我国出一线城市房价均值、新一线城市房价均值、二线城市房价均值、货币供应量和利率。选取2002-2018年的数据,共17组数据,由于数据的自然对数变换不改变原有的协整关系,并能使其趋势线性化,消除时间序列中存在的异方差现象,所以对所有数据取其自然对数…

程序员简历程序员简历.pdf

你们在制作简历时&#xff0c;是不是基本只关注两件事&#xff1a;简历模板&#xff0c;还有基本信息的填写。 当你再次坐下来更新你的简历时&#xff0c;可能会发现自己不自觉地选择了那个“看起来最好看的模板”&#xff0c;填写基本信息&#xff0c;却没有深入思考如何使简历…