【智能家居项目】裸机版本——设备子系统(LED Display 风扇)
🐱作者:一只大喵咪1201
🐱专栏:《智能家居项目》
🔥格言:你只管努力,剩下的交给时间!
输入子系统中目前仅实现了按键输入,剩下的网络输入和标准输入在以后会逐步实现,今天先来实现设备子系统,包含LED设备(GPIO控制),风扇设备,OLED设备。
目录
- 🍛设计思路
- 🍛LED设备
- 🍚设备层
- 🍚内核抽象层
- 🍚芯片抽象层
- 🍚硬件操作
- 🍚单元测试
- 🍛显示设备
- 🍚管理及设备层
- 🍚内核抽象层
- 🍚芯片抽象层及硬件操作
- 🍚单元测试
- 🍛风扇设备
- 🍚设备层
- 🍚内核抽象层
- 🍚芯片抽象层
- 🍚硬件操作
- 🍚单元测试
🍛设计思路
不同内核下是访问设备的方式是不同的:
- 裸机里怎么访问设备?
对于ST芯片可以使用HAL库访问设备,对于一些国产芯片可以使用厂家自己封装的库,甚至自己编写代码直接访问寄存器来访问设备。
- FreeRTOS怎么访问设备?
FreeRTOS中并没有驱动程序框架,它访问设备时方法和裸机一样。
- RT-Thread怎么访问设备?
RT-Thread可以使用两种方法访问设备:
- 像裸机一样访问
- 使用RT-Thread的驱动程序框架
如上图便是RT-Thread
驱动程序框架的示意图,所谓驱动框架就是事先定义好的接口函数,无论是访问设备还是添加新设备,直接调用这些接口函数即可。
所以我们要做的就是实现这些接口函数好让应用层去直接调用,这样做的好处是,无论硬件怎么修改,驱动程序的接口并不会改变,上层的应用程序也就不需要改变。
如上图所示是RT-Thread
驱动框架下“I/O设备管理”的接口,应用程序通过标准的接口来访问设备:
rt_device_find
:查找设备rt_device_open
:打开设备rt_device_read
:从设备中读取数据rt_device_write
:向设备中写数据
- Linux下怎么访问设备?
Linux系统中,和驱动程序严格分离开,应用程序无法直接读写寄存器,应用程序必须通过驱动程序访问设备,应用程序使用的接口只有open/read/write/ioctl等。
如上图所示,APP就是应用程序,在Linux下一切皆文件,所以设备在Linux内核中都被抽象成了一个文件,所以应用层必须通过系统调用接口通过文件系统来访问设备。
再来看我们要实现的设备子系统,目前暂时将其分为两层,虚线之上写出统一的应程序接口,虚线之下根据不同的系统,调用不同的函数,这样一来就统一了设备的访问方式。
对于开发应用程序的人,他不关心LED使用哪个GPIO引脚,GPIO是输出高还是低来控制LED,open的是什么设备、read/write的又是什么设备,也不用去看原理图,芯片手册,以及研究HAL库,RT-Thread,或者Linux的驱动函数怎么调用。
甚至不用理解我们抽象出来的设备结构体,只需要关心结构体中的Init
和Contral
两个函数指针怎么使用即可,其他的一概不用关心,所以非常有必要提供更高层的API接口。
以LCD的使用为例,可以分为三层:
如上图,其中设备驱动层中的驱动程序负责提供像素操作的功能,但是显示什么字符、显示多大、在哪显示,不用关心。
文字/图像显示层中包含库函数/函数功能,提供显示字符、显示图片功能的接口,但是显示什么字符、显示多大、在哪显示,不用关心。
应用程序则通过库函数来显示字符以及图片,并且决定显示什么字符,显示在哪里,显示多大等问题,但是并不用关心驱动程序。
- 驱动只提供功能,不提供策略,应用程序只提供策略,不提供功能的实现。
- 不同的层要各司其职不要越界,实现不同专业知识的隔离。
在实现设备子系统的时候,使用面向对象的思想,对于每一种设备,抽象出一个结构体,结构体里有设备相关的函数指针,不同设备,不强求统一,不强求用一个结构体类型来支持所有设备。
编写函数时要注意:
- 头文件:这些函数是面向应用程序开发者,假设他们对硬件一无所知。
- C文件:函数内部,再根据不同系统、不同芯片,调用其他函数。
🍛LED设备
如上图所示,我们把LED设备分为4层,接下来就是一层一层来实现。
🍚设备层
LED设备的功能:
- LED的开和关
- 设置LED的颜色
- 设置LED的亮度
虽然本喵使用的LED灯并不支持设置颜色和直接设置亮度,但是有一些高级的LED灯是支持的,这里我们为了以后更好的维护和扩展,所以在抽象LED设备结构体的时候都考虑上:
如上图所示,抽象出来的LEDDevice
结构体就是用来描述LED设备的,包含LED编号,初始化和控制方法,以及设置颜色和亮度的方法,还需要在LED的设备层提供一个获取LED设备的方法。
如上图所示,因为LED设备只有三个,所以通过一个全局的LEDDevice
数组来管理LED设备,对每一个LED设备进行了初始化,实现了LED设备的初始化函数以及控制函数,为了达到分层的目的,在函数内部调用内核抽象层的初始化和控制函数。
至于设置颜色和亮度的函数并没有实现,因为本喵使用的LED灯并不支持这两种功能,还实现了一个获取LED设备的函数,在上层使用访问LED设备的时候,必须先调用该函数获取LED设备。
🍚内核抽象层
如上图,无论是访问LED设备还是控制LED设备,甚至初始化LED设备,在内核抽象都有不同的方式,这里定义一个配置文件,用来控制是使用哪种方式:
如上图所示,用到哪种内核就定义相应的标识符常量。
如上图所示头文件,提供了内核抽象层对LED设备初始化和控制的函数声明。
如上图所示内核抽象层源文件,提供了LED设备初始化和控制函数的实现,通过宏开关来控制调用对应内核下的LED初始化和控制函数。
其中对于RT-Thread
和Linux
下的LED设备初始化和控制函数本喵在这里并不会实现,这里仅仅是为了给大家演示本喵的代码架构写的。
- 对于裸机和FreeRTOS,LED设备的初始化和控制函数都是一样的。
🍚芯片抽象层
如上图,在真正访问芯片的时候,不同类型的芯片支持不同的库,同样可以通过宏开关来控制使用哪种库来访问芯片:
#define CONFIG_SUPPORT_HAL 0x10
//#define CONFIG_SUPPORT_OTHER 0x20
将这部分代码加入到config.h
中去。
如上图头文件代码,提供了芯片抽象层LED设备初始化和控制的函数声明。
如上图源文件代码,提供了芯片抽象层LED设备初始化和控制函数的实现,对于HAL库,调用对应的HAL库对应的初始化和控制函数,对应其他库则调用其他方式。
🍚硬件操作
本喵使用的是ST的芯片,所以使用HAL库来操作硬件:
如上图所示头文件,提供了LED设备的GPIO信息以及初始化和控制的函数声明。
如上图所示源文件,提供了初始化和控制函数的实现,在控制函数中,switch
通过LEDDevice
结构体中的LED编号操作具体的LED设备。
🍚单元测试
LED设备从设备层到操作硬件共五层已经实现了,下面就进行单元测试,看是否符合预期:
如上图所示LED设备的测试函数,其中LED点亮和熄灭中间的延时,为了应用层和HAL库的解耦,本喵只是通过循环进行了一个大概的循环,有兴趣的小伙伴可以按照五层的框架,在最底层调用HAL_Delay()
自己实现一下。
如上图,白蓝绿三个灯在不停闪烁。
🍛显示设备
为了让这里的代码更加容易维护和扩展,适用于多种类型的显示设备,本喵通过LCD显示的原理来抽象出一个具有普适性的显示设备结构体,虽然本喵最终用的是OLED屏幕,但是仍然可以用这个结构。
LCD显示原理:
什么是LCD?就是多行多列的像素点:
- 对于黑白屏幕(单色屏幕),这些像素点只有2个状态:点亮、熄灭。
- 对于彩色屏幕,这些像素点有颜色:可以用RGB三原色来表示。
怎么控制LCD上每个像素的状态?
- 通过显存,就是一块内存,也被称为
FrameBuffer
。 - 每个像素在显存上都有对应的数据,会在屏幕上对应位置显示。
- 对于黑白屏(单色屏),每个像素点在显存里有对应的1位数据,只有两种状态,表示点亮和熄灭。
- 对于彩色屏,每个像素点在显存里有几个字节(可能是1字节、2字节、4字节),可以表示多种颜色。
- BPP:Bits Per Pixel,用来表示每个像素点有多少位数据。
LCD可能自带显存,也可能不带有显存(要使用LCD的话,就需要在系统内存中分配显存),有三种类型的LCD。
- LCD含有显存, CPU通过I2C协议访问显示
如上图,很多I支持I2C、SPI接口的屏幕,本身是含有显存的,要在LCD上显示文字、图片,就需要网显存里写入数据,程序通过I2C接口写显存,LCD控制器就会让LCD屏幕显示相应内容。
- LCD没有显存, LCD控制器从内存得到数据
如上图,很多TFT LCD本身是没有显存的,那么数据保存在系统内存里分配一块空间,这块RAM中的内存就可以看作是显存。设置好LCD控制器后,它就会自动从这个显存取出数据、发送给LCD,我们只需要写数据到RAM中的显存即可。
- LCD含有显存, CPU可以直接访问
如上图,有些LCD含有显存,并且CPU可以直接访问显存,不需要I2C灯协议,就像访问一般内存一样直接访问显存,我们只需要写数据到显存即。
对于软件来说,这3种LCD都有显存,第1种无法直接写显存;第2、3种可以直接写显存,能否让第1种LCD,能否也直接写显存?可以:
- 在系统内存RAM中分配另一个显存
FrameBuffer
。 - 应用程序直接写这个显存。
- 设备层等下层再通过I2C将RAM显存中的数据发送到LCD自带的显存中。
如上图,同样按照五层来实现程序。
🍚管理及设备层
在设备层要抽象出一个显示设备的结构体,根据前面的分析以及LED设备的经验,该结构体包含:
- 初始化函数,用来初始化显示设备。
- 在RAM中都有显存,通过显存的起始地址,显示设备的分辨率,以及
bpp
来描述显存。 - 对于第一种LCD,还需要一个
Flush
函数,把RAM显存中的数据刷到LCD显存中去。
如上图头文件中代码,抽象出了显示设备的结构体,用这个结构体可以描述多种类型的显示设备,包括LCD和OLED,这些显示设备可以用链表管理起来。
- void* FBBase:显示设备的显存。
如上图所示源文件,创建了一个静态的全局显示设备链表,用这个链表来管理所有显示设备,提供了向链表中注册新设备的函数,以及从链表中获取设备的函数。
- 由于
pDisplayDevice
链表头指针被static
修饰了,就只能在当前源文件访问和操作这个链表。- 使用
__
修饰的函数表明该函数会在其他位置被调用,而且要实现的功能相同。
此时设备层的宏观描述已经有了,接下来就是创建具体的显示设备了,这里创建的是OLED屏。
如上图所示,创建一个全局的DisplayDevice
变量用来实例化OLED设备,根据OLED的特性填充该结构体变量,其中RAM中的显存就是一个全局的数组,用static
修饰的初始化和刷新显存的函数初始化结构体中的方法。
对于点亮(X , Y)处像素的函数本喵单独讲解一下:
如上图所示坐标系便是显存抽象出来的坐标,其中左上角的坐标原点就是RAM显存数组的首地址,本喵使用的OLED是128*64的,所以可以分为8页,128列。
现在要点亮坐标(x, y)处的像素点,所以要计算出该像素点位于RAM显存中的哪个位置,然后在程序中向该位置写入数据即可。
共有64行像素点,每8行分为一页,所以(x, y)所在页为page = y / 8
,由于RAM中的显存是一个数组,它并不存在页的概念,所以可以计算出(x,y)对应那个字节在数组中的下标是page*128 + x
,地址就是FrameBuffer + page * 128 + x
由于一个字节有8个bit,而每一个像素点用一个bit,所以(x, y)所用那个bit在该字节中是第y % 8
个bit。
如上图代码所示,在将(x, y)坐标所对应的显存位置计算出来后,根据dwColor
颜色值来决定是点亮该像素点函数熄灭,或者是用哪种颜色点亮。
- OLED不支持显示不同颜色,所以
dwColor
的值不为0则表示点亮,为0则表示熄灭。
如上图所示代码便是OLED设备剩下的代码,在添加OLED显示设备的时候用到了static
修饰的g_DisplayDevice
全局变量,该变量同样只能在该源文件内使用。
AddDisplayDeviceOLED
函数中调用的DisplayDeviceRegister
注册函数是属于display_device.h
文件中的,所以需要包含该头文件。
在display_device
中需要有添加显示设备的函数AddDisplayDevices
,在该函数中势必会调用oled_device.h
中的AddDisplayDeviceOLED
函数,所以要包含该头文件。
- 此时就产生了互相包含的场景,
display_device
中包含oled_device.h
,oled_device
中包含display_device.h
。
为了避免互相包含,再创建一个dispaly_system.c
文件来管理这两个导致互相包含的函数。
如上图所示,在这里实现AddDisplayDevices
更加合适,而获取设备的方法也是放在这里更合适。
如上图所示便是这些文件中的内容概述和调用关系,这些所有内容构成了整个设备层。
🍚内核抽象层
内核抽象层需要实现的只有显示设备的初始化已经将数据刷新到OLED自带的显存中的Flush
函数。
如上图代码,同样为了方便或者和维护,对于不同的内核,调用不同的方式,本喵使用的是裸机,所以需要调用芯片抽象层对应的函数。
🍚芯片抽象层及硬件操作
芯片抽象层同样是分为支持HAL库和支持其他库,只是需要实现初始化函数和CAL_OLEDDeviceFlush
函数即可。
如上图所示,对于HAL库,在初始化的时候直接初始化I2C协议用到的引脚,以及调用OLED屏幕的初始化函数,这里部分内容本喵在I2C通信协议 | OLED屏一文中有详细讲解,这里本喵就直接使用了。
在CAL_OLEDDeviceFlush
函数中,对于HAL库,调用OLED_Copy
拷贝函数将数据从RAM显存中搬运到OLED自带的显存中,该拷贝函数本喵没有实现过,这里实现一下:
如上图,将RAM显存中的数据分八次写入OLED自带的显存中,每次写入一个page的数据,也就是128字节。
🍚单元测试
显示设备的五层实现以后,同样需要进单元测试:
如上图所示,在测试显示设备的时候,先添加所有显示设备(本喵这里只有一个OLED显示设备),然后从设备管理列表中获取名为OLED
的设备,如果不存在则打印错误信息。
获取成功后,先调用显示设备的初始化函数进行初始化,然后清屏,就是将RAM中的显存全部清0,再调用显示设备中的SetPixel
设置像素函数在OLED屏幕上画一个十字。
如上图所示,在OLED屏幕上显示了一个十字。
🍛风扇设备
如上图所示,在本喵的开发板上有一个电机模块,上面有一个风扇,可以控制它顺时针转,逆时针转,停止。
如上图所示是电机接口模块示意图,风扇的控制非常简单,只需要改变PC6
和PE6
也就是INB
和INA
口的电平状态就可以,真值表如下:
风扇状态 | INA | INB |
---|---|---|
顺时针旋转 | 0 | 1 |
逆时针旋转 | 1 | 0 |
停止 | 0 | 0 |
停止 | 1 | 1 |
其中0表示该接口输入低电平,1表示该接口输出高电平。风扇设备分为四层,本喵就不详细讲解了,直接上代码。
🍚设备层
如上图所示头文件代码,定义了描述风扇设备的结构体,包含风扇的速度属性,初始化函数,设置速度的函数,当前速度属性是多余的,本喵这里并不会控制速度,包括设置速度函数也只是控制风扇的启停和正反转。
如果使用PWM波来控制电风扇就可以控制其速度,所以为了以后方便扩展维护,本喵就保留了速度这个属性。
如上图所示是源文件,创建了一个全局的风扇设备变量来实例化,并进行了初始化,还提供了获取风扇设备的函数,不再多说。
🍚内核抽象层
如上图所示,对于不同的内核调用相应层的函数即可,不再讲解。
🍚芯片抽象层
如上图代码,在初始化函数中,对于HAL库,由于在使用CubeMX创建工程的已经配置好了引脚,所以这里不用再调用HAL库的初始化函数了,直接返回0即可,表示初始化成功,对于设置速度的函数则需要调用HAL库中的设置速度函数。
🍚硬件操作
如上图代码所示,根据iSpeed
的不同情况,对照风扇的真值表设置INA
和INB
引脚的电平状态即可。
🍚单元测试
如上图所示测试代码,让风扇顺时针转2秒,停止2秒,逆时针转2秒,停止2秒,如此循环。
为了实现应用层的独立,延时函数使用的是KAL_Delay
,其最在芯片抽象层仍然是封装的HAL_Delay
。
如上图代码所示,实现了延时函数,头文件自己加就行,本喵不在讲解。
如上图所示是风扇转起来的状态,符合我们的要求。
相关文章:
【智能家居项目】裸机版本——设备子系统(LED Display 风扇)
🐱作者:一只大喵咪1201 🐱专栏:《智能家居项目》 🔥格言:你只管努力,剩下的交给时间! 输入子系统中目前仅实现了按键输入,剩下的网络输入和标准输入在以后会逐步实现&am…...
[Linux]记录plasma-wayland下无法找到HDMI接口显示器的问题解决方案
内核:Linux 6.5.5-arch1-1 Plasma 版本:5.27.8 窗口系统:Wayland 1 问题 在前些时候置入了一块显示器,接口较多,有 HDMI 接口,type-C 接口。在 X11 中可以找到外接显示器,但是卡顿明显…...
【计算机网络】高级IO之select
文章目录 1. 什么是IO?什么是高效 IO? 2. IO的五种模型五种IO模型的概念理解同步IO与异步IO整体理解 3. 阻塞IO4. 非阻塞IOsetnonblock函数为什么非阻塞IO会读取错误?对错误码的进一步判断检测数据没有就绪时,返回做一些其他事情完整代码myt…...
如何设计一个高效的应用缓冲区【一个动态扩容的buffer类】
文章目录 前言一、为什么需要设计应用层缓冲区必须要有 output buffer目的问题output buffer的解决方案: 必须要有 input buffer总结 二、设计要点三、buffer设计思路基础函数关于iovec与readv readfd如何实现动态扩容 问题 前言 在上一个博客,我们介绍…...
图像处理初学者导引---OpenCV 方法演示项目
OpenCV 方法演示项目 项目地址:https://github.com/WangQvQ/opencv-tutorial 项目简介 这个开源项目是一个用于演示 OpenCV 方法的工具,旨在帮助初学者快速理解和掌握 OpenCV 图像处理技术。通过这个项目,你可以轻松地对图像进行各种处理&a…...
管道-匿名管道
一、管道介绍 管道(Pipe)是一种在UNIX和类UNIX系统中用于进程间通信的机制。它允许一个进程的输出直接成为另一个进程的输入,从而实现数据的流动。管道是一种轻量级的通信方式,用于协调不同进程的工作。 1. 创建和使用管道&#…...
【JavaEE基础学习打卡08】JSP之初次认识say hello!
目录 前言一、JSP技术初识1.动态页面2.JSP是什么3.JSP特点有哪些 二、JSP运行环境配置1.JDK安装2.Tomcat安装 三、编写JSP1.我的第一个JSP2.JSP执行过程3.在IDEA中开发JSP 总结 前言 📜 本系列教程适用于JavaWeb初学者、爱好者,小白白。我们的天赋并不高…...
使用序列到序列深度学习方法自动睡眠阶段评分
深度学习方法,用于使用单通道脑电图进行自动睡眠阶段评分。 def build_firstPart_model(input_var,keep_prob_0.5):# List to store the output of each CNNsoutput_conns []######### CNNs with small filter size at the first layer ########## Convolutionnetw…...
【算法】排序——选择排序和交换排序(快速排序)
主页点击直达:个人主页 我的小仓库:代码仓库 C语言偷着笑:C语言专栏 数据结构挨打小记:初阶数据结构专栏 Linux被操作记:Linux专栏 LeetCode刷题掉发记:LeetCode刷题 算法头疼记:算法专栏…...
Docker 容器监控 - Weave Scope
Author:rab 目录 前言一、环境二、部署三、监控3.1 容器监控 - 单 Host3.2 容器监控 - 多 Host 总结 前言 Docker 容器的监控方式有很多,如 cAdvisor、Prometheus 等。今天我们来看看其另一种监控方式 —— Weave Scope,此监控方法似乎用的人…...
Spring Boot集成redis集群拓扑动态刷新
项目场景: Spring Boot集成Redis集群,使用lettuce连接Cluster集群实例。 问题描述 redis其中一个节点挂了之后,springboot集成redis集群配置信息没有及时刷新,出现读取操作报错。 java.lang.IllegalArgumentException: Connec…...
COCI2022-2023#1 Neboderi
P9032 [COCI2022-2023#1] Neboderi 题目大意 有一个长度为 n n n的序列 h i h_i hi,你需要从中选择一个长度大于等于 k k k的子区间 [ l , r ] [l,r] [l,r],使得 g ( h l h l 1 ⋯ h r ) g\times (h_lh_{l1}\cdotsh_r) g(hlhl1⋯hr)最小&…...
由于找不到d3dx9_43.dll无法继续执行此代码怎么解决?全面解析d3dx9_43.dll
在使用计算机过程中,我们可能会遇到各种各样的问题。其中之一就是d3dx9_43.dll文件丢失的问题。这个问题通常会出现在运行某些应用程序或游戏时,导致程序无法正常启动或运行。那么,如何解决这个问题呢?小编将为您提供一些解决方案…...
Linux--网络编程-字节序
进程间的通信: 管道、消息队列、共享内存、信号、信号量。 特点:都依赖于linux内核。 缺陷:无法多机通信。 一、网络编程: 1、地址:基于网络,ip地址端口号。 端口号作用: 一台拥有ip地址的主机…...
python实现http/https拦截
python实现http拦截 前言:为什么要使用http拦截一、技术调研二、技术选择三、使用方法前言:为什么要使用http拦截 大多数爬虫玩家会直接选择API请求数据,但是有的网站需要解决扫码登录、Cookie校验、数字签名等,这种方法实现时间长,难度高。需求里面不需要高并发,有没有…...
农产品团购配送商城小程序的作用是什么
农产品覆盖稻麦油蛋等多种细分类目,各地区经营商家众多,随着人们生活品质提升,对食物的要求也在提升,绿色无污染无激素的农产品往往受到不少人喜爱,而在销售中,也有不少人选择自建商城线上经营。 通过【雨…...
使用van-dialog二次封装微信小程序模态框
由于微信小程序的wx.showModal不支持富文本内容,无法实现更灵活的展示效果,故需要进行二次封装 实现思路:使用van-dialog以及微信小程序的rich-text实现 代码如下: // index.wxml <van-dialoguse-slottitle"提示"s…...
生鲜蔬果同城配送社区团购小程序商城的作用是什么
生鲜蔬果行业作为市场主要支撑之一,从业商家众多的同时消费者也从不缺,尤其对中高城市,生鲜蔬果除了传统线下超市、市场经营外,线上更是受到大量消费者信任,而很多商家也是自建了生鲜蔬果商城多场景生意经营。 那么通…...
Unity实现设计模式——状态模式
Unity实现设计模式——状态模式 状态模式最核心的设计思路就是将对象的状态抽象出一个接口,然后根据它的不同状态封装其行为,这样就可以实现状态和行为的绑定,最终实现对象和状态的有效解耦。 在实际开发中一般用到FSM有限状态机的实现&…...
差分数组的应用技巧
前缀和技巧 针对的算法场景是不需要对原始数组进行修改的情况下,频繁查询某个区间的累加和。 差分数组 主要适用场景是频繁对原始数组的某个区间的元素进行增减。 相关题目 1094. 拼车 1109. 航班预订统计 370. 区间加法 # 1094. 拼车 class Solution:def carPool…...
斯坦福数据挖掘教程·第三版》读书笔记(英文版)Chapter 10 Mining Social-Network Graphs
来源:《斯坦福数据挖掘教程第三版》对应的公开英文书和PPT。 Chapter 10 Mining Social-Network Graphs The essential characteristics of a social network are: There is a collection of entities that participate in the network. Typically, these entiti…...
DFS:842. 排列数字
给定一个整数 nn,将数字 1∼n1∼n 排成一排,将会有很多种排列方法。 现在,请你按照字典序将所有的排列方法输出。 输入格式 共一行,包含一个整数 nn。 输出格式 按字典序输出所有排列方案,每个方案占一行。 数据…...
pytorch之nn.Conv1d详解
自然语言处理中一个句子序列,一维的,所以使用Conv1d...
H5生成二维码
H5生成二维码: 1.引入js库,可自行点击链接复制使用 <script type"text/javascript" src"http://static.runoob.com/assets/qrcode/qrcode.min.js"></script>2.加入二维码占位区HTML <div id"qrCode">…...
Three.js加载360全景图片/视频
Three.js加载360全景图片/视频 效果 原理 将全景图片/视频作为texture引入到three.js场景中将贴图与球形网格模型融合,将球模型当做成环境容器使用处理视频时需要以dom为载体,加载与控制视频动作每次渲染时更新当前texture,以达到视频播放效…...
北大硕士7年嵌入式学习经验分享
阶段 1 大一到大三这个阶段我与大多数学生相同: 学习本专业知识(EE专业),学习嵌入式软件开发需要的计算机课程(汇编原理,计算机组成原理,操作系统,C语言等),…...
华为鸿蒙手表开发之动态生成二维码
华为鸿蒙手表开发之动态生成二维码 前言: 最近入职新公司,由于之前的哥们临时离职,走得很突然,所以没有任何交接和文档,临时顶上公司手表应用的上架,更换了新的密钥和key之后重新测试功能和流程ÿ…...
2023-09-28 monetdb-databae的概念和作用-分析
摘要: 每个数据库对于db,schema以及user,role都有一套自己的设计, 不同数据库间对于相同名字的东西例如database和schema可以说南辕北辙, 例如mysql中schema其实是database的同义词. 本文分析monetdb的database的概念和作用 database的概念和作用: 和mysql的database完全不同…...
2024级199管理类联考之数学基础(上篇)
管理类考试介绍 管理综合200分,时间3小时 数学:75分/25题,是拉开差距的核心模块 问题求解题:15个,5选一条件充分性判断:10个,结合两个条件选择答案 条件一充分,条件二不充分:A条件一不充分,条件二充分:B条件一充分,条…...
RFID技术引领汽车零部件加工新时代
RFID技术的兴起引领了汽车零部件加工领域的新时代,作为一种利用无线电频率进行自动识别的技术,RFID技术能够快速、准确地识别物体并获取相关数据,在汽车零部件加工中,RFID技术具有重要的应用价值,可以提高生产效率、降…...
青岛网站设计哪家好/seoul是什么意思中文
state 1.类中方法this的指向 constructor和render里的this指向类组件的实例对象在类组件内部定义的普通函数,作为onClick的回调,不是通过实例调用的,是直接调用,并且类组件内部默认开启了局部严格模式,所以this指向u…...
网站建栏目建那些/微博热搜榜排名今日
查表法import java.util.Scanner;public class Main{/** 使用查表法*//*查表法的应用:* 有规律的,就可以使用查表法* */public static void main(String[] args){Scanner cin new Scanner(System.in);{int x cin.nextInt();/** 查询星期* */System.out…...
做会计要看什么关注什么网站/网站seo优化总结
3172: [Tjoi2013]单词 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 4293 Solved: 2083[Submit][Status][Discuss]Description 某人读论文,一篇论文是由许多单词组成。但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多…...
做高端网站的公司/线下推广有哪些渠道
由于各种各样的原因,表格中出现了一些多余的空白行/空白列/空白单元格,怎样快速删除这些空白呢? 使用正则的来进行批量替换:^\n以换行符开头的信息替换成空。间接实现空行的删除。 替换成功后的效果:...
做招生网站/长春网站快速排名提升
upx upx加壳脱壳程序 upx -d 脱壳 objdump -d 反编译整个程序 readelf -r target_elf objdump -R target_elf 查看GOT表中的内容...
奉贤网站建设公司/公司品牌宣传
一、百度上输入百度地图API 点击进入 二、下拉页面到底部 点击地图快速生成工具,进去 四、当前城市下面的框里输入你想定位的地点,再点击查找 五、下拉网页,网页中间看到生成代码按钮点击,就能看到生成的代码块 (1&…...