荔枝派nano(f1c100s)基于I2C子系统的BME280驱动

硬件环境:
1、荔枝派nano(f1c100s)
2、使用f1c100s的i2c0,PE11和PE12引脚
软件环境:
1、Linux 4.15
2、BME280使用介绍

文章目录

  • 一、I2C子系统
    • 1、应用层访问i2c设备
    • 2、驱动层访问i2c设备
      • 2.1、i2c总线设备驱动模型
      • 2.2、i2c_client 和 i2c_driver
  • 二、程序编写
    • 1、驱动程序
    • 2、i2c_client实现
    • 3、测试应用程序
  • 三、总结

一、I2C子系统

对i2c设备的访问,有两种方法:
1、在应用层直接访问i2c设备;
2、编写i2c设备的驱动程序,也就是在驱动层访问;

1、应用层访问i2c设备

在这里插入图片描述

  • 在应用层可以通过i2c-dev.c驱动程序访问芯片内部i2c控制器的驱动adapter_driver,进而实现访问i2c控制器下的i2c设备。也就是可以在应用程序中直接使用内核提供的i2c-dev.c提供的API函数对i2c设备进行读写操作,不用再去编写该设备的驱动程序。i2ctools就是基于i2c-dev.c实现的在应用层访问i2c设备的工具;

2、驱动层访问i2c设备

在这里插入图片描述

  • 所谓的驱动层访问i2c设备,就是需要我们真正编写某个i2c设备的驱动程序;

2.1、i2c总线设备驱动模型

在这里插入图片描述

  • 可以看到这很像Linux下的platform总线设备驱动模型,但platform总线设备驱动模型是虚拟的,而i2c总线设备驱动模型是真实存在的;
  • 当有新的i2c_client时,i2c总线会匹配其对应的i2c_driver;当有新的i2c_driver注册时,就会匹配还未匹配驱动的i2c_client;一旦匹配成功,i2c_driver的probe函数就被调用;

2.2、i2c_client 和 i2c_driver

  • i2c_client
    i2c_client结构体会存放设备地址(addr)、名字(name)、挂载在哪个i2c控制器下(adapter),等相关硬件信息;

  • i2c_driver
    i2c_driver结构体实现相关的probe、remove等函数;

二、程序编写

程序以访问BME280传感器为例,访问其它i2c设备也是类似的;重在框架;
本驱动程序读取BME280修正参数及温湿度值和大气压值,在应用程序计算最终的温湿度值和大气压值,BME280相关介绍可以参考BME280使用介绍;

1、驱动程序

驱动程序编写大致流程:
1、先定义i2c_driver结构体;
2、实现probe和remove函数;
3、实现file_operations结构体的open和read等函数、比如在open函数里初始化i2c设备,read函数里读寄存器;

驱动程序定义i2c_driver结构体:

static const struct of_device_id of_match_ids_bme280[] = {{ .compatible = "bosch,bme280",		.data = NULL },{ /* END OF LIST */ },
};static const struct i2c_device_id bme280_ids[] = {{ "bme280",	(kernel_ulong_t)NULL },{ /* END OF LIST */ }
};static struct i2c_driver bme280_driver = {.driver = {.name = "bme280",.of_match_table = of_match_ids_bme280,},.probe_new = bme280_probe,		//匹配成功后的probe函数.remove = bme280_remove,.id_table = bme280_ids,
};

实现probe和remove函数:

static struct file_operations bme280_ops = {.owner = THIS_MODULE,.open  = bme280_open,.read  = bme280_read,
};static int bme280_probe(struct i2c_client *client)
{printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);bme280_client = client;		//保存client,里面有设备地址,后续要用major = register_chrdev(0, "bme280", &bme280_ops);bme280_class = class_create(THIS_MODULE, "bme280_class");device_create(bme280_class, NULL, MKDEV(major, 0), NULL, "bme280"); /* /dev/bme280 */return 0;
}static int bme280_remove(struct i2c_client *client)
{	printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);device_destroy(bme280_class, MKDEV(major, 0));class_destroy(bme280_class);unregister_chrdev(major, "bme280");return 0;
}

实现open和read函数:

static ssize_t bme280_read (struct file *file, char __user *buf, size_t size, loff_t *offset)
{int err;if(size != sizeof(struct bme280_parameter))return 0;bme280_refresh();bme280_read_temp();bme280_read_press();bme280_read_humi();err = copy_to_user(buf, &bme280_para, size);return size;
}static int bme280_open (struct inode *node, struct file *file)
{/* 在open函数中初始化BME280 *//* init bme280 */i2c_smbus_write_byte_data(bme280_client, BME280_REGISTER_CTRL_MEAS, 0x55);i2c_smbus_write_byte_data(bme280_client, BME280_REGISTER_CONFIG, 0x10);/* 读取修正参数 *//* read bme280 parameter */bme280_read_parameter();printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);return 0;
}

完整的驱动程序:

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/mutex.h>
#include <linux/mod_devicetable.h>
#include <linux/bitops.h>
#include <linux/jiffies.h>
#include <linux/property.h>
#include <linux/acpi.h>
#include <linux/i2c.h>
#include <linux/nvmem-provider.h>
#include <linux/regmap.h>
#include <linux/pm_runtime.h>
#include <linux/gpio/consumer.h>
#include <linux/uaccess.h>
#include <linux/fs.h>/* BME280 REGISTER */
#define BME280_REGISTER_ID             (0xD0)
#define BME280_REGISTER_RESET          (0xE0)
#define BME280_REGISTER_STATUS         (0xF3)
#define BME280_REGISTER_CTRL_MEAS      (0xF4)
#define BME280_REGISTER_CONFIG         (0xF5)
#define BME280_REGISTER_PRESS_MSB      (0xF7)
#define BME280_REGISTER_PRESS_LSB      (0xF8)
#define BME280_REGISTER_PRESS_XLSB     (0xF9)
#define BME280_REGISTER_TEMP_MSB       (0xFA)
#define BME280_REGISTER_TEMP_LSB       (0xFB)
#define BME280_REGISTER_TEMP_XLSB      (0xFC)
#define BME280_REGISTER_HUMI_MSB       (0xFD)
#define BME280_REGISTER_HUMI_LSB       (0xFE)struct bme280_parameter{unsigned short int T1;short int T2;short int T3;unsigned short int P1;short int P2;short int P3;short int P4;short int P5;short int P6;short int P7;short int P8;short int P9;unsigned char H1;short int H2;unsigned char H3;short int H4;short int H5;unsigned char H6;int adc_T;int adc_P;int adc_H;int t_fine;
};static int major;
static struct class *bme280_class;
static struct i2c_client *bme280_client;
static struct bme280_parameter bme280_para;static void bme280_read_parameter (void)
{unsigned char tmp;//dig_T1bme280_para.T1 = i2c_smbus_read_byte_data(bme280_client, 0x89);bme280_para.T1 <<= 8;bme280_para.T1 |= i2c_smbus_read_byte_data(bme280_client, 0x88);//dig_T2bme280_para.T2 = i2c_smbus_read_byte_data(bme280_client, 0x8B);bme280_para.T2 <<= 8;bme280_para.T2 |= i2c_smbus_read_byte_data(bme280_client, 0x8A);//dig_T3bme280_para.T3 = i2c_smbus_read_byte_data(bme280_client, 0x8D);bme280_para.T3 <<= 8;bme280_para.T3 |= i2c_smbus_read_byte_data(bme280_client, 0x8C);//dig_P1bme280_para.P1 = i2c_smbus_read_byte_data(bme280_client, 0x8F);bme280_para.P1 <<= 8;bme280_para.P1 |= i2c_smbus_read_byte_data(bme280_client, 0x8E);//dig_P2bme280_para.P2 = i2c_smbus_read_byte_data(bme280_client, 0x91);bme280_para.P2 <<= 8;bme280_para.P2 |= i2c_smbus_read_byte_data(bme280_client, 0x90);//dig_P3bme280_para.P3 = i2c_smbus_read_byte_data(bme280_client, 0x93);bme280_para.P3 <<= 8;bme280_para.P3 |= i2c_smbus_read_byte_data(bme280_client, 0x92);//dig_P4bme280_para.P4 = i2c_smbus_read_byte_data(bme280_client, 0x95);bme280_para.P4 <<= 8;bme280_para.P4 |= i2c_smbus_read_byte_data(bme280_client, 0x94);//dig_P5bme280_para.P5 = i2c_smbus_read_byte_data(bme280_client, 0x97);bme280_para.P5 <<= 8;bme280_para.P5 |= i2c_smbus_read_byte_data(bme280_client, 0x96);//dig_P6bme280_para.P6 = i2c_smbus_read_byte_data(bme280_client, 0x99);bme280_para.P6 <<= 8;bme280_para.P6 |= i2c_smbus_read_byte_data(bme280_client, 0x98);//dig_P7bme280_para.P7 = i2c_smbus_read_byte_data(bme280_client, 0x9B);bme280_para.P7 <<= 8;bme280_para.P7 |= i2c_smbus_read_byte_data(bme280_client, 0x9A);//dig_P8bme280_para.P8 = i2c_smbus_read_byte_data(bme280_client, 0x9D);bme280_para.P8 <<= 8;bme280_para.P8 |= i2c_smbus_read_byte_data(bme280_client, 0x9C);//dig_P9bme280_para.P9 = i2c_smbus_read_byte_data(bme280_client, 0x9F);bme280_para.P9 <<= 8;bme280_para.P9 |= i2c_smbus_read_byte_data(bme280_client, 0x9E);//dig_H1bme280_para.H1 = i2c_smbus_read_byte_data(bme280_client, 0xA1);//dig_H2bme280_para.H2 = i2c_smbus_read_byte_data(bme280_client, 0xE2);bme280_para.H2 <<= 8;bme280_para.H2 |= i2c_smbus_read_byte_data(bme280_client, 0xE1);//dig_H3bme280_para.H3 = i2c_smbus_read_byte_data(bme280_client, 0xE3);//dig_H4bme280_para.H4 = i2c_smbus_read_byte_data(bme280_client, 0xE4);bme280_para.H4 <<= 4;tmp = i2c_smbus_read_byte_data(bme280_client, 0xE5);tmp &= 0x0f;bme280_para.H4 |= tmp;//dig_Hbme280_para.H5 = i2c_smbus_read_byte_data(bme280_client, 0xE6);bme280_para.H5 <<= 4;tmp = i2c_smbus_read_byte_data(bme280_client, 0xE5);tmp &= 0xf0;tmp >>= 4;bme280_para.H5 |= tmp;//dig_H6bme280_para.H6 = i2c_smbus_read_byte_data(bme280_client, 0xE7);
}static void bme280_refresh (void)
{int err;// refresh before read dataerr = i2c_smbus_write_byte_data(bme280_client, BME280_REGISTER_CTRL_MEAS, 0x55);msleep(45);
}static void bme280_read_temp (void)
{int ret;// read temp dataret = i2c_smbus_read_byte_data(bme280_client, BME280_REGISTER_TEMP_MSB);bme280_para.adc_T = ret;bme280_para.adc_T <<= 8;ret = i2c_smbus_read_byte_data(bme280_client, BME280_REGISTER_TEMP_LSB);bme280_para.adc_T |= ret;bme280_para.adc_T <<= 8;ret = i2c_smbus_read_byte_data(bme280_client, BME280_REGISTER_TEMP_XLSB);bme280_para.adc_T |= ret;bme280_para.adc_T >>= 4;
}static void bme280_read_press (void)
{int ret;// read press dataret = i2c_smbus_read_byte_data(bme280_client, BME280_REGISTER_PRESS_MSB);bme280_para.adc_P = ret;bme280_para.adc_P <<= 8;ret = i2c_smbus_read_byte_data(bme280_client, BME280_REGISTER_PRESS_LSB);bme280_para.adc_P |= ret;bme280_para.adc_P <<= 8;ret = i2c_smbus_read_byte_data(bme280_client, BME280_REGISTER_PRESS_XLSB);bme280_para.adc_P |= ret;bme280_para.adc_P >>= 4;
}static void bme280_read_humi (void)
{int ret;// read humi dataret = i2c_smbus_read_byte_data(bme280_client, BME280_REGISTER_HUMI_MSB);bme280_para.adc_H = ret;bme280_para.adc_H <<= 8;ret = i2c_smbus_read_byte_data(bme280_client, BME280_REGISTER_HUMI_LSB);bme280_para.adc_H |= ret;
}static ssize_t bme280_read (struct file *file, char __user *buf, size_t size, loff_t *offset)
{int err;if(size != sizeof(struct bme280_parameter))return 0;bme280_refresh();bme280_read_temp();bme280_read_press();bme280_read_humi();err = copy_to_user(buf, &bme280_para, size);return size;
}static int bme280_open (struct inode *node, struct file *file)
{/* init bme280 */i2c_smbus_write_byte_data(bme280_client, BME280_REGISTER_CTRL_MEAS, 0x55);i2c_smbus_write_byte_data(bme280_client, BME280_REGISTER_CONFIG, 0x10);/* read bme280 parameter */bme280_read_parameter();printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);return 0;
}static struct file_operations bme280_ops = {.owner = THIS_MODULE,.open  = bme280_open,.read  = bme280_read,
};static const struct of_device_id of_match_ids_bme280[] = {{ .compatible = "bosch,bme280",		.data = NULL },{ /* END OF LIST */ },
};static const struct i2c_device_id bme280_ids[] = {{ "bme280",	(kernel_ulong_t)NULL },{ /* END OF LIST */ }
};static int bme280_probe(struct i2c_client *client)
{printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);bme280_client = client;major = register_chrdev(0, "bme280", &bme280_ops);bme280_class = class_create(THIS_MODULE, "bme280_class");device_create(bme280_class, NULL, MKDEV(major, 0), NULL, "bme280"); /* /dev/bme280 */return 0;
}static int bme280_remove(struct i2c_client *client)
{	printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);device_destroy(bme280_class, MKDEV(major, 0));class_destroy(bme280_class);unregister_chrdev(major, "bme280");return 0;
}static struct i2c_driver bme280_driver = {.driver = {.name = "bme280",.of_match_table = of_match_ids_bme280,},.probe_new = bme280_probe,.remove = bme280_remove,.id_table = bme280_ids,
};static int __init bme280_driver_init(void)
{printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);return i2c_add_driver(&bme280_driver);
}static void __exit bme280_driver_exit(void)
{i2c_del_driver(&bme280_driver);
}module_init(bme280_driver_init);
module_exit(bme280_driver_exit);MODULE_AUTHOR("Cohen0415");
MODULE_LICENSE("GPL");

2、i2c_client实现

我们知道i2c_driver是靠编写程序实现,但没说i2c_client怎么实现;i2c_client也可以通过程序实现,但在这我们通过设备树来实现,i2c控制器驱动程序会自动把设备树中的i2c节点转成i2c_client(个人理解)
本次使用f1c100s的i2c0,引脚PE11(CK)、PE12(DA),只列出部分设备树的定义,如下:
suniv.dtsi:
在这里插入图片描述
在这里插入图片描述
suniv-f1c100s-licheepi-nano.dts:
在i2c节点下添加你的i2c设备
在这里插入图片描述

3、测试应用程序

应用程序比较简单,直接列出完整程序:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>struct bme280_parameter{unsigned short int T1;short int T2;short int T3;unsigned short int P1;short int P2;short int P3;short int P4;short int P5;short int P6;short int P7;short int P8;short int P9;unsigned char H1;short int H2;unsigned char H3;short int H4;short int H5;unsigned char H6;int adc_T;int adc_P;int adc_H;int t_fine;
};struct bme280_parameter bme280;float compute_temp()	//通过修正参数计算最终温度值
{int var1, var2, T;var1 = ((((bme280.adc_T>>3) - (bme280.T1<<1))) * bme280.T2) >> 11;var2 = (((((bme280.adc_T>>4)-bme280.T1) * (bme280.adc_T>>4)-bme280.T1) >> 12) * bme280.T3) >> 14;bme280.t_fine = var1 + var2;T = (bme280.t_fine * 5 + 128) >> 8;return (float)T/100;
}float compute_press()	//通过修正参数计算最终压力值,修正算法来自BME280手册
{int64_t var1, var2, p;var1 = ((int64_t)bme280.t_fine) - 128000;var2 = var1 * var1 * (int64_t)bme280.P6;var2 = var2 + ((var1 * (int64_t)bme280.P5) << 17);var2 = var2 + (((int64_t)bme280.P4) << 35);var1 = ((var1 * var1 * (int64_t)bme280.P3) >> 8) +((var1 * (int64_t)bme280.P2) << 12);var1 =(((((int64_t)1) << 47) + var1)) * ((int64_t)bme280.P1) >> 33;if (var1 == 0){return 0;}else{p = 1048576 - bme280.adc_P;p = (((p << 31) - var2) * 3125) / var1;var1 = (((int64_t)bme280.P9) * (p >> 13) * (p >> 13)) >> 25;var2 = (((int64_t)bme280.P8) * p) >> 19;p = ((p + var1 + var2) >> 8) + (((int64_t)bme280.P7) << 4);return (float)p/256;}
}float compute_humi()	//通过修正参数计算最终湿度值
{double var_H;var_H = (((double)bme280.t_fine) - 76800.00);var_H = (bme280.adc_H - (((double)bme280.H4) * 64.0 + ((double)bme280.H5) / 16384.0 * var_H)) * (((double)bme280.H2) / 65536.0 * (1.0 + ((double)bme280.H6) / 67108864.0 * var_H * (1.0 + ((double)bme280.H3) / 67108864.0 * var_H)));var_H = var_H * (1.0 - ((double)bme280.H1) * var_H / 524288.0);if(var_H > 100.0){var_H = 100.0;}else if(var_H < 0.0){var_H = 0.0;}return var_H;
}int main(int argc, char **argv)
{int fd;int len;float temp = 0, press = 0, humi = 0;fd = open("/dev/bme280", O_RDWR);if (fd == -1){printf("can not open file /dev/bme280\n");return -1;}while(1){len = read(fd, &bme280, sizeof(struct bme280_parameter));	temp = compute_temp();press = compute_press();humi = compute_humi();printf("temp=%.2f press=%.2f humi=%.2f\n", temp, press, humi);sleep(1);}close(fd);return 0;
}

三、总结

1、以上出现的专业术语或名词解释或个人理解有不妥,恳请指出!

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

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

相关文章

贪心算法Part01 455分发饼干

455分发饼干 376摆动序列 53 最大子数组和

【办公技巧】怎么批量提取文件名到excel

Excel是大家经常用来制作表格的文件&#xff0c;比如输入文件名&#xff0c;如果有大量文件需要输入&#xff0c;用张贴复制或者手动输入的方式还是很费时间的&#xff0c;今天和大家分享如何批量提取文件名。 打开需要提取文件名的文件夹&#xff0c;选中所有文件&#xff0c…

CodeWhisperer:编码世界中的声音启迪者

人烟 导语&#xff1a; 在数字化时代&#xff0c;编码已经成为了一种不可或缺的技能。而 CodeWhisperer&#xff08;编码世界中的声音启迪者&#xff09;则以其卓越的技术和深厚的知识为人们带来了独特的启发和指导。本文将介绍 CodeWhisperer 的背景和成就&#xff0c;探讨他是…

避开Python列表处理的雷区(二):从新手到专家的必看指南

文章目录 引言常见雷区汇总1. 访问列表中不存在的索引2. pop()方法索引越界 小结结尾 引言 Python列表是Python中最基础的数据结构之一&#xff0c;也是我们日常编程中经常使用的一种数据类型。然而&#xff0c;在进行列表处理时&#xff0c;许多新手和资深开发者都容易陷入一…

多家快递批量混合跟踪——跟踪物流必备份神器

先来跟大家说下我目前需要跟踪邮政、顺丰、德绑这三家快递&#xff0c;很朋友给建议是分开查询 &#xff0c;一家一家到快递官网上查询&#xff0c; 这个一种查询方法&#xff0c;这个虽然费时间&#xff0c;效率不高适合查询量少的情况&#xff0c;量多的情况下这样查起来太麻…

力扣题目学习笔记(OC + Swift)206. 反转链表

206. 反转链表 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 方法一、迭代 在遍历链表时&#xff0c;将当前节点的 next\textit{next}next 指针改为指向前一个节点。由于节点没有引用其前一个节点&#xff0c;因此必须事先存储其…

跨境电商迎来综合竞争力比拼时代 五大趋势解读跨境2024

过去几年&#xff0c;跨境电商成为外贸出口增长的一大亮点&#xff0c;随着年底国务院办公厅《关于加快内外贸一体化发展的若干措施》的发布&#xff0c;跨境电商在促进经济发展、助力内外贸一体化发展方面的价值更加凸显。 这是跨境电商变化最快的时代&#xff0c;也是跨境电…

风电机叶片表面损坏检测数据集(1万多张+txt标签)

用于深度学习模型训练。有需要的朋友可以和我私聊 数据集信息部分截图 &#xff1a;

Linux服务器搭建笔记-006:拓展/home目录容量

一、问题说明 Ubuntu服务器在使用过程中创建的新用户&#xff0c;每位用户会在/home目录下生成一个属于其个人的主文件夹。如果不限制各个用户的使用空间&#xff0c;所有的用户都会共用/home所挂载的硬盘。在这种多用户情况下&#xff0c;会很快的填满/home目录&#xff0c;导…

.json文件转为.dll文件后还能读取吗?

(只是修改了后缀名而已&#xff0c;做一个伪装&#xff09; 测试&#xff1a; QFile file(QApplication::applicationDirPath() "/config.dll");qDebug()<<QApplication::applicationDirPath() "/config.dll";if (file.open(QIODevice::ReadOnly))…

Vue: 事件修饰符, 键盘事件, 鼠标事件,计算属性

目录 事件修饰符 阻止默认事件 阻止冒泡 允许触发一次 捕获模式 self passive 键盘事件 keyup & keydown 按键别名 注意tab 注意系统按键 自定义按键 鼠标事件 简介 鼠标焦点事件 计算属性 差值语法实现 methods实现 computed实现 get() set() 总…

PLC-IoT 网关开发札记(1):存档和分发 Android App

开篇记 PLC-IoT 网关是作者开发的产品&#xff0c;根据客户需求&#xff0c;立项开发手机 App&#xff0c;为用户提供一种方便、直观、友好的设备操控方式。网关运行的是嵌入式 Linux 操作系统&#xff0c;计划通过某一种通信协议&#xff08;例如 HTTP&#xff0c;MQTT或者 T…

KMP算法的理解+板子

对kmp算法的理解中&#xff0c;很重要的一点就是next数组。 很多人不理解next数组的含义&#xff0c;是因为它同时具有两个意思&#xff0c;而且这两个意思在不同的环境下不同。 现在给你两个字符串&#xff1a; 一个是文本串 text 一个是模板串 pattern 然后定义两个指针…

react+redux+antd-mobile 之 记账本案例

1.环境搭建 //使用CRA创建项目&#xff0c;并安装必要依赖&#xff0c;包括下列基础包 //1. Redux状态管理 - reduxjs/toolkit 、 react-redux //2. 路由 - react-router-dom //3. 时间处理 - dayjs //4. class类名处理 - classnames //5. 移动端组件库 - antd-mobile //6. 请…

偏好对齐RLHF-OpenAI·DeepMind·Anthropic对比分析

OpenAI paper: InstructGPT, Training language models to follow instructions with human feedback paper: Learning to summarize from human feedback Introducing ChatGPT 解密Prompt系列4介绍了InstructGPT指令微调的部分&#xff0c;这里只看偏好对齐的部分 样本构建…

竞赛保研 基于机器学习与大数据的糖尿病预测

文章目录 1 前言1 课题背景2 数据导入处理3 数据可视化分析4 特征选择4.1 通过相关性进行筛选4.2 多重共线性4.3 RFE&#xff08;递归特征消除法&#xff09;4.4 正则化 5 机器学习模型建立与评价5.1 评价方式的选择5.2 模型的建立与评价5.3 模型参数调优5.4 将调参过后的模型重…

12.21自动售货机,单物品,多物品

自动售货机 if朴素方法 一种思路是用寄存器cnt记录已有的最小单位货币量&#xff0c;这里就是0.5 当d1时&#xff0c;cnt1;d2时&#xff0c;cnt2;d3时&#xff0c;cnt4; timescale 1ns/1ns module seller1(input wire clk ,input wire rst ,input wire d1 ,input wire d2 …

苹果CMS超级播放器专业版无授权全开源,附带安装教程

源码介绍 超级播放器专业版v1.0.8&#xff0c;内置六大主流播放器&#xff0c;支持各种格式的视频播放&#xff0c;支持主要功能在每一个播放器内核中都相同效果。 搭建教程 1.不兼容IE浏览器 2.php版本推荐7.4 支持7.1~7.4 3.框架引入不支持同时引入多个播放器 json对接教…

mfc100u.dll文件丢失了要怎么解决?修复mfc100u.dll详细指南

mfc100u.dll文件丢失了要怎么解决?首先让我们扒一扒什么是 mfc100u.dll。这玩意儿是 Microsoft Visual Studio 2010 的一部分&#xff0c;它就像一款程序生活中不可或缺的零件&#xff0c;没了它&#xff0c;程序肯定跑不起来。想想看&#xff0c;没有一个重要的零件&#xff…

【UE5蓝图】读取本地json文件修改窗口大小

效果 插件 蓝图 1.判断文件存在 2.1文件不存在&#xff0c;生成文件 {"ResolutionX":540, "ResolutionY":960} 2.2文件存在&#xff0c;直接读取 3.设置窗口大小 遇到的坑 1.分辨率太大&#xff0c;导致效果不理想&#xff0c;建议先往小填写。 2.选对…