ZYNQ:【1】深入理解PS端的TTC定时器(Part1:原理+官方案例讲解)
碎碎念:好久不见,甚是想念!本期带来的是有关ZYNQ7020的内容,我们知道ZYNQ作为一款具有硬核的SOC,PS端很强大,可以更加便捷地实现一些算法验证。本文具体讲解一下里面的TTC定时器,之后发布的Part2将基于具体项目出发,实现PS端单核进行六路不等长占空比的PWM输出~
虽然最后对我自己毕业好像没有什么帮助QAQ,但是毕竟花费了一些时间阅读手册等内容,还是打算记录一下供大家参考。
目录
1 TTC原理分析
1.1 主要特点
1.2 结构框图
1.3 功能描述
1.3.1 操作模式
1.3.2 事件定时器/脉宽计数器(Event Timer)操作
1.4 寄存器概述
1.5 编程模型
1.5.1 计数器使能的步骤
1.5.2 计数器停止的步骤
1.5.3 计数器重启的步骤
1.5.4 事件计数器(脉宽计数器)使能的步骤
1.5.5 清除中断和确认的步骤
1.6 计数器时钟输入的选择
2 SDK分析
2.1 工程建立
2.2 案例分析
1.设置中断系统:SetupInterruptSystem()
2.设置Ticker定时器:SetupTicker()
3.设置PWM定时器:SetupPWM()
4.逐渐修改占空比:WaitForDutyCycleFull()
5.停止计数器:XTtcPs_Stop()
1 TTC原理分析
这一部分我们直接按照UG585的思路,进行分析和介绍,由于原文的内容本身是英文理解起来还是需要一些经验(尽管更推荐去阅读原文部分)。
TTC包含了三个独立的定时器,分别是上图中的Timer/Clock 0、Timer/Clock 1、Timer/Clock 2。从左下角可以看到在PS端包含两个TTC,分别是TTC0和TTC1,因此两个TTC共包含6个独立的定时器。TTC控制器可以通过修改nic301_addr_region_ctrl_registers.security_apb [ttc1_apb]这个寄存器的位,来实现对于安全模式(secure mode)和非安全模式(non-secure mode)的切换。对于这两种模式的内容可以参考下面:
传送门
Secure mode and Non-secure mode:
这两种模式来源于ARM TrustZone技术,ARM在CPU的常规模式之外引入了一种称为“安全模式”的特殊CPU模式,建立了“安全世界”和“正常世界”之间的的概念。默认情况下,安全世界访问正常世界的所有状态,反之则不然。由于ARM基本使用的都是基于存储映射的结构,我的理解是通过这两种模式的分隔,来实现对于重要寄存器的保护。
1.1 主要特点
每个TTC有如下特点:
1.三个独立16位预分频器和16位的向上/向下计数器。(向上:0,1,2,3,4... 向下:9,8,7,6...)
2.可选的时钟源输入(内部PS总线时钟:CPU_1x,内部时钟:PL,外部时钟:MIO)
3.对于TTC内部每一个counter,都各自有一个中断
4.在一定间隔内的溢出中断,或者计数匹配到设定的值时会发出中断
5.产生波形输出,可以通过MIO或者PL(EMIO)
1.2 结构框图
通过上面的结构框图,对于TTC中第一个计数器Timer/Clock 0的时钟输入、波形输出信号的多路控制是通过slcr.MIO_PIN_xx寄存器实现的,默认情况下使用EMIO接口。
1.3 功能描述
每个预分频模块(Pre-scaler)都可以独立设置为使用PS内部总线时钟或者外部时钟(来自MIO或者PL)。对于外部时钟输入,通过使用SLCR寄存器来选择具体的信号输入。预分频模块可以将输入时钟在/2和/65536之间进行分频,当如分频寄存器为0的时候,会对时钟进行二分频,之后输出给后面的计数器。
计时器可以设置为增计数、减计数,并且通过设置间隔寄存器的值,可以控制计数的范围。同时可以比较三个匹配寄存器的值和计数器(一个TTC包含3个计数器Counter和3组匹配寄存器)的值,产生中断信号。
中断模块组合了各种类型的中断:计数器间隔中断(Interval Interrupt)、计数器匹配中断(Match Interrupt)、计数器溢出中断(Overflow Interrupt)、事件计时器溢出。每种类型都可以单独启用。
1.3.1 操作模式
一个TTC中的每个计数器模块,都可以独立编程,并以以下两种模式中的任何一种运行。
间隔模式(Interval mode):
通过修改计数器控制寄存器(Counter Control register)的DEC位,可以控制计数器的计数方向是+1还是-1。通过修改间隔计数器(Interval mode)的值可以控制计数的范围是0到间隔计数器的值。当计数值经过0的时候,会产生一个计数器间隔中断(Interval Interrupt)。当计数器的值等于匹配计数器(Match register)值的时候,会产生一个匹配中断(Match Interrupt)。
溢出模式(Overflow mode):
计数器在0x0000和0xFFFF之间连续的+1或者-1变化,并通过修改计数器控制寄存器的DEC位来控制计数的方向。当计数值经过0的时候,会产生一个溢出中断(Overflow Interrupt)。当计数器的值等于匹配计数器值的时候,会产生一个匹配中断。
1.3.2 事件定时器/脉宽计数器(Event Timer)操作
从名字脉宽计数器,可以推断出其功能是对外部输入信号的脉宽进行测量,原理有一些类似电机差分编码器的M法测速。
事件定时器内部有一个对用户不可见的16位内部计数器(Internal Counter),该计数器被CPU_1x的时钟控制,其满足如下两个条件:
1.当外部脉冲的非计数阶段,被重置为0
2.在外部脉冲的计数阶段,开始增加
修改事件定时器控制内部计数器的行为,主要通过三个位来控制:
1 E_En bit 使能位,等于0时,将内部计数器复位到0,并停止计数
2 E_Lo bit 指定外部脉冲的计数相位
3 E_Ov bit 指定如何处理当内部计数器溢出时,如何处理。
当为0的时候,溢出导致E_En置为0;
当为1的时候,溢出导致内部计数器继续循环计数;
在另一个寄存器的控制下,可以决定溢出时是否产生中断(而与E_Ov bit本身的值无关)。
当外部计数脉冲的计数相位结束的时候,会使用内部计数器的非零计数值对事件寄存器(Event Register)的值进行更新。因此,这个值展示了外部脉冲的宽度。由于内部计数器被CPU_1x的时钟控制,因此脉冲宽度是由CPU_1x的时钟周期数来衡量的。
当外部计数脉冲的计数相位阶段,如果内部计数器由于溢出被重置为0,那么事件寄存器将不会被更新,并保持上次非溢出计数操作的旧值。
1.4 寄存器概述
功能 | 名称 | 概述 |
时钟控制 | 时钟控制寄存器 | 控制预分频器,选择时钟输入,选择边沿 |
计数器控制寄存器 | 使能计数器,设置操作模式,设置计数方向,使能匹配,使能波形输出 | |
状态 | 计数器数值寄存器 | 返回计数器的当前值 |
计数器控制 | 间隔寄存器 | 设置间隔值 |
匹配寄存器1 匹配寄存器2 匹配寄存器3 | 设置匹配值,一共有3组,对应了一个TTC内部的3个Counter(这种说法不准确,其实每个Counter都有自己的一组三个匹配寄存器) | |
中断 | 中断寄存器 | 显示当前中断状态 |
中断使能寄存器 | 使能中断 | |
事件 | 事件控制计时器寄存器 | 使能事件计时器,停止计时器,设置计数相位 |
事件寄存器 | 显示外部脉冲的宽度(即内部计数器的计数值) |
1.5 编程模型
1.5.1 计数器使能的步骤
- 选择时钟输入源,设置预分频值(slcr.MIO_MUX_SEL registers, TTC Clock Control register),进行这一步前需要保证TTC处于不使能状态(slcr.MIO_MUX_SEL registers, TTC Clock Control register)
- 设置间隔值(Interval register),这一步骤是可选的,仅在间隔模式进行
- 设置匹配值(Match registers),这一步是可选的,如果匹配是使能状态则需要设置
- 使能中断(Interrupt Enable register),这一步是可选的,如果需要中断则需要使能
- 设置波形输出的使能状态,设置匹配的使能状态,设置计数的方向,设置模式,使能计数器 (TTC Counter Control register),这一步开启计数器
1.5.2 计数器停止的步骤
- 读取当前计数器控制器的值
- 设置DIS位为1,保持其他位不变
- 将上面修改了DIS位的数值写回计数器控制器
1.5.3 计数器重启的步骤
- 读取计数器控制器的值
- 设置RST位为1,保持其他位不变
- 将上面修改了DIS位的数值写回计数器控制器
1.5.4 事件计数器(脉宽计数器)使能的步骤
- 选择外部脉冲源(slcr.MIO_MUX_SEL registers),所选择的外部脉冲的脉宽将会被时钟CPU_1x的周期所衡量
- 设置计数溢出时的处理,选择外部脉冲的电平,使能事件计数器(select external pulse level),这一步开始测量选择的外部脉冲的脉宽(高电平或者低电平)
- 使能中断(Interrupt Enable register),这一步是可选的,如果需要中断则需要使能
- 读取测量到的脉冲宽度(Event register),注意当计数溢出发生的时候,返回来的脉宽计数值是不准确的。具体可以看前文对事件计数器的叙述
1.5.5 清除中断和确认的步骤
- 读取中断寄存器,将会自动读取并清除中断寄存器中的所有位
1.6 计数器时钟输入的选择
下面展示了如何设置SoC选择对于TTC0中Counter/timer 0 的时钟源,使用的是一组if else 语句来实现。
if slcr.MIO_PIN_19[6:0] is 1100000, use MIO pin 19
else if slcr.MIO_PIN_31[6:0] is 1100000, use MIO pin 31
else if slcr.MIO_PIN_43[6:0] is 1100000, use MIO pin 43
else use EMIOTTC0CLKI0
TTC0 的 Counter/timer 1只能使用EMIOTTC0CLKI1
TTC0 的 Counter/timer 2只能使用EMIOTTC0CLKI2
下面展示了如何设置SoC选择对于TTC1中Counter/timer 0 的时钟源,使用的是一组if else 语句来实现。
if slcr.MIO_PIN_17[6:0] is 1100000, use MIO pin 17
else if slcr.MIO_PIN_29[6:0] is 1100000, use MIO pin 29
else if slcr.MIO_PIN_41[6:0] is 1100000, use MIO pin 41
else use EMIOTTC1CLKI0
TTC1 的 Counter/timer 1只能使用EMIOTTC1CLKI1
TTC1 的 Counter/timer 2只能使用EMIOTTC1CLKI2
IMPORTANT:当选择MIO引脚或EMIOTTCxCLKIx作为时钟源时,如果时钟停止运行,相应的计数值寄存器将保留旧值,而不管时钟已经停止的事实。在这种情况下必须谨慎。这句话理解为,时钟停止运行这件事可能是很容易被忽略的。
2 SDK分析
2.1 工程建立
在任意一个ZYNQ工程中进行如下配置:
这里对TTC0和TTC1都打上对勾,在Block Design就会多出6个Pin脚。(为下一期的6占空比PWM输出做准备~)
右键每一个Pin脚,设置Make External:
之后在xdc文件中对输出的引脚进行绑定即可。
同时可以在Clock Configuration看到时钟的频率,这里显示TTC1和TTC2的时钟源都是来自CPU_1x的内部时钟,频率是133.333333MHz
至此,Block Design部分就设置完毕了。
首先修改完Block Design之后,需要先点F6,进行Validate Design操作,验证Block Design的正确性。
之后点击Generate Output Products生成输出。
下一步点击左侧的Generate Bitstream输出比特流文件。
之后点击File-Export-Export Hardware,将硬件信息导出。
之后点击File-Lauch SDK,新建一个空的工程。(这一步的流程可以参考正点原子的领航者ZYNQ系列视频的嵌入式开发系列)
打开Vivado工程对应的SDK文件后,我们可以在左侧找到所提供的一些ttc参考文件:
我们只需要关注xttcps.h这个头文件即可,他是PS中TTC模块驱动头文件,给出了比较详细的函数定义
同时也可以找到一些示例文件:
这里主要对第一个案例进行代码的讲解。
2.2 案例分析
这里需要读者自行打开上述的案例文件~由于不需要额外硬件设置,可以直接在SDK中看到上述内容。
这里我们针对这一文件简单介绍一下ttc的设置流程。
这个文件内部给出了利用TTC产生中断的案例,共分成了几个步骤。
1.设置中断系统:SetupInterruptSystem()
Line547+552:初始化中断控制器
Line562:注册中断处理
Line569:使能中断
2.设置Ticker定时器:SetupTicker()
需要注意的是SetupTicker里面包含了信息的初始化,对单个定时器的设置,中断的设置。相当于将这几部分结合在了一起。
该函数从Line257开始,这里引用了一个数据结构TmrCntrSetup,定义在Line100
typedef struct {
u32 OutputHz; /* Output frequency */
XInterval Interval; /* Interval value */
u8 Prescaler; /* Prescaler value */
u16 Options; /* Option settings */
} TmrCntrSetup;
并且Line261调用了Line131定义的数组:
static TmrCntrSetup SettingsTable[2] = {
{100, 0, 0, 0}, /* Ticker timer counter initial setup, only output freq */
{200, 0, 0, 0}, /* PWM timer counter initial setup, only output freq */
};
可以看到这个数组分别用来设置Ticker timer和PWM timer的状态,分别包括:输出频率;间隔值;预分频系数;输出选项设置。
对于输出选项的设置,是在Line267通过或操作来实现,具体的可选参数可以看xttcps.h中的定义:
回到xttcps_intr_example中,Line267定义当前模式为间隔模式,同时设置了不输出波形。(如果这里设置输出波形,那么当计数器值等于匹配值的时候,会将输出进行翻转,实现波形输出)。
之后在Line275调用了SetupTimer函数,实现对单个定时器的具体设置。这一函数定义在Line469。注意信息的传递是通过TTC_TICK_DEVICE_ID来实现的。
主要实现的功能就是初始化设备(XTtcPs_LookupConfig、XTtcPs_CfgInitialize),将SetupTicker中的设置传递过来,分别包括(设置选项模式XTtcPs_SetOptions、计算间隔值XTtcPs_CalcIntervalFromFreq、设置间隔值XTtcPs_SetInterval、设置预分频系数XTtcPs_SetPrescaler)
设置完成后,就获得了设置好的设备TtcPsTick。
回到SetupTicker中,Line285实现对中断控制器的设置,将设备以及中断处理函数进行定义。
中断处理函数TickHandler定义在Line592,首先在Line599获取中断的类型,之后在Line600清除中断。在Line602对中断的类型进行判断,这里检测的是XTTCPS_IXR_INTERVAL_MASK,其定义以及其他类型的中断,我们可以在xttcps_hw.h找到,这里面定义了六种中断类型:
当检测到对应类型的中断,我们就利用TickCount对间隔终端出现的次数进行累加处理。
回到SetupTicker中,在Line294和Line300进行了中断的使能操作,之后在Line305设置开启定时器。
3.设置PWM定时器:SetupPWM()
这个相信也是很多人比较关注的部分。
Line328实现一些设置信息,主要是将前面的数组第二个元素存储过来。
Line334设置间隔模式、匹配模式、并使能wave的输出,这里就保证了当计数值与匹配值相同的时候,输出信号就会发生翻转。从而可以利用间隔值设置PWM的周期,利用匹配值设置PWM的占空比。
Line342同样调用SetupTimer来实现对单个定时器的具体设置,具体说明可以看上面的部分。这一函数定义在Line469。注意信息的传递是通过TTC_PWM_DEVICE_ID来实现的。
主要实现的功能就是初始化设备(XTtcPs_LookupConfig、XTtcPs_CfgInitialize),将SetupPWM中的设置传递过来,分别包括(设置选项模式XTtcPs_SetOptions、计算间隔值XTtcPs_CalcIntervalFromFreq、设置间隔值XTtcPs_SetInterval、设置预分频系数XTtcPs_SetPrescaler)
设置完成后,就获得了设置好的设备TtcPsPWM
Line352通过调用XScuGic_Connect实现对中断控制器,设备ID,中断处理函数以及匹配值指针的设置。
中断处理函数PWMHandler定义在Line637,当检测到中断信号是间隔中断(也就是表示输出了一个周期),就会在Line653调用XTtcPs_SetMatchValue进行匹配值的设置,在代码注释中提到,匹配寄存器0是特殊的,如果输出被使能,当匹配值与计数值相等时,会修改输出的极性。
但是这个地方的注释是容易被误解的,TTC定时器的三个匹配寄存器功能是不一致的,并不是都可以用于波形的输出,在ZYNQ官方实例中,register0被指定为Special,也就是当计数器与register0的匹配值相等时,会触发特殊中断事件并翻转输出电平。经试验表明,对于同一个Counter来说,register1和register2并不会影响PWM输出的翻转,但是由于每个TTC中有三个Counter,其实可以设置三个register0的值来实现三个不同占空比PWM的输出。
回到SetupPWM中,在Line361和Line367进行了中断的使能操作,之后在Line372设置开启定时器。
4.逐渐修改占空比:WaitForDutyCycleFull()
这个函数定义在Line397,主要是通过当每一次循环输出一次PWM波之后,TickHandler函数会在Line607将PWM_UpdateFlag更新为TRUE,之后会在WaitForDutyCycleFull中满足if的条件,从而修改全局变量MatchValue的值。通过中断处理函数PWMHandler中的Line643,就实现了MatchValue对MatchReg的赋值,从而在Line653可以修改MatchReg的值,进而就修改了占空比。
整体逻辑只要抓住下面三点:1.间隔模式中断:在PWM周期结束更新flag;2.修改占空比:检测flag修改全局变量,改变占空比;3.PWM输出中断处理函数(也是间隔模式中断)将匹配值设置进去。
5.停止计数器:XTtcPs_Stop()
这里直接在Line236和Line238调用了XTtcPs_Stop实现了计数器的停止。
这就是本期的全部内容啦,如果你喜欢我的文章,不要忘了点赞+收藏+关注,分享给身边的朋友哇~
相关文章:

ZYNQ:【1】深入理解PS端的TTC定时器(Part1:原理+官方案例讲解)
碎碎念:好久不见,甚是想念!本期带来的是有关ZYNQ7020的内容,我们知道ZYNQ作为一款具有硬核的SOC,PS端很强大,可以更加便捷地实现一些算法验证。本文具体讲解一下里面的TTC定时器,之后发布的Part…...

蓝牙设备如何自定义UUID
如何自定义UUID 所有 BLE 自定义服务和特性必须使用 128 位 UUID 来识别,并且要确保基本 UUID 与 BLE 定义的基本 UUID(00000000-0000-1000-8000-00805F9B34FB)不一样。基本 UUID 是一个 128 位的数值,根据该值可定义标准UUID&am…...

好看的html登录界面,
界面效果: 代码: <!DOCTYPE html> <html><head><title>Login Page</title><style>body {background-color: #f2f2f2;font-family: Arial, sans-serif;}form {background-color: #fff;border-radius: 5px;box-shado…...

Java模拟星空
目录 前言 JavaFX基础 1. GraphicsContext 2. AnimationTimer 代码实现 完整代码 前言 看了Python模拟星空很漂亮,Java也应该必须有一个! 环境:只需要JDK1.8就好!不需要外部包!!! Jav…...

YGG 代表 Web3 Gaming 参加 2023 年游戏开发者大会
Yield Guild Games(YGG)在 2023 年 3 月 20 日至 24 日在加州旧金山举行的游戏开发者大会(GDC)上大显身手,这是游戏开发者的重要交流学习活动。虽然 GDC 本身提供了多种多样的活动,包括讲座、小组讨论、圆桌…...

水库安全运行智慧管理平台解决方案筑牢防汛“安全墙”
解决方案 水库安全运行智慧管理系统解决方案,系统主要由降雨量监测站、水库水位监测站、大坝安全监测中的渗流量、渗流压力和变形监测站及视频和图像监测站等站点组成,同时建立规范、统一的监测平台,集数据传输、信息共享、数据储存于一体&a…...

Exchange升级部署方案
目录 前言 一、需求分析 二、升级前准备 1.备份当前 Exchange Server 数据...

AE开发之图层渲染20210603
AE开发之图层渲染比例符号化地图的整饰唯一值符号的符号化过程点符号设置,线符号设置标注图层,(写得不好,不推荐看) 唯一值符号化,字段进行设置,这里用到了UniqueValueRenderer接口,这里面有一…...

需要了解的过滤器
过滤器 1. 概念 过滤器: 从名字上理解就是对于事件的过滤操作,在web 中的过滤器,就是对于请求进行过滤操作,我们使用过滤器,就可以对于请求进行拦截操作,然后进行响应的处理操作,实现很多的特殊…...

VUE3的setup函数
文章目录 目录 文章目录 前言 一、setup函数是什么? 二、使用步骤 三、vue3中文文档和面向vue3的组件库 总结 前言 Vue3是一个面向数据驱动的渐进式JavaScript框架,其的设计理念包括简洁、灵活和高效。相比Vue2,Vue3的架构设计有很大的不同&…...

停车场管理系统文件录入(C++版)
❤️作者主页:微凉秋意 ✅作者简介:后端领域优质创作者🏆,CSDN内容合伙人🏆,阿里云专家博主🏆 文章目录一、案例需求描述1.1、汽车信息模块1.2、普通用户模块1.3、管理员用户模块二、案例分析三…...

线程(Thread)的三种等待唤醒机制详解
1、为什么需要线程的等待和唤醒 线程的等待唤醒机制是一种经典的“生产者和消费者”模型。例如食品加工厂,食品加工人员和原料补给人员,在有充足原料时,补给人员是在等待,等到原料不够时,食品加工人员通知补给人员&am…...

从零学习python - 13模块的导入与使用(实现单例模式)
模块基础知识 # 项目 > 包 > 模块 > 变量\方法\类 # 在python中,模块是代码组织的一种方式,把功能相近的函数或类放到一个文件中,一个文件(.py)就是一个模块,模块名就是文件名去掉py后缀. # 好处:提高代码可复用性和可维护性,一个模块编写完成后,很方便在其他项目中导…...

国产SSD、内存卷哭国外大厂,三星宣布减产涨价在路上了
PC 圈有一句话是这么说的:论价格屠夫还得看国产品牌! 可不是嘛,国产长鑫、长江算是彻底将全球存储芯片市场搅局者这一「骂名」坐实了! 不说特别早期,前几年吧,普通单条 8G DDR4 内存都能卖到六七百元&…...

数据库管理-第六十六期 SQL Domain(20230413)
数据库管理 2023-04-13第六十六期 SQL Domain1 基本介绍2 Domain的表达式和条件3 语法4 语义5 示例总结第六十六期 SQL Domain 上一期一笔带过了部分Oracle 23c的新特性,这一期重点讲一下SQL Domain新特性。 【https://docs.oracle.com/en/database/oracle/oracle-…...

《Vue3实战》 第一章 nods/npm安装、配置
1、nods.js安装(Windows) 1.1、下载并安装node https://nodejs.org/en/ , 安装到d盘nodejs目录 1.2、配置环境变量 path配置 1.3、配置全局包存放目录和缓存目录 在根目录下创建node_global(全局包存放目录)和node_cache&…...

JAVA练习104-四数相加 II
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 一、题目-四数相加 II 1.题目描述 2.思路与代码 2.1 思路 2.2 代码 总结 前言 提示:这里可以添加本文要记录的大概内容: 4月10日练…...

【C++基础】引用(引用的概念;引用的特性;常引用;使用场景:做输出型参数、大对象传参、做输出型返回值、返回大对象的引用);引用和指针的区别)
六、引用 6.1 引用的概念 引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。(语法上) 格式:类型& 引用变量名(对象名) …...

Redis只用来做缓存?来认识一下它其他强大的能力吧。
当今互联网应用中,随着业务的发展,数据量越来越大,查询效率越来越高,对于时序数据的存储、查询和分析需求也越来越强烈,这时候 Redis 就成为了首选的方案之一。 Redis 提供了多种数据结构,如字符串、哈希表…...

【ES】数据同步集群
【ES】数据同步&集群3.数据同步3.1.思路分析3.1.1.同步调用3.1.2.异步通知3.1.3.监听binlog3.1.4.选择3.2.实现数据同步3.2.1.思路3.2.2.导入demo3.2.3.声明交换机、队列1)引入依赖2)声明队列交换机名称3)声明队列交换机3.2.4.发送MQ消息…...

37岁男子不愿熬夜,回乡养鸡每天准时下班,青山绿水中养鸡,直播间里卖鸡蛋...
37岁男子不愿熬夜,回乡养鸡每天准时下班,青山绿水中养鸡,直播间里卖鸡蛋。今天和大家分享一个创业案例,他叫胡铭浩,来自安徽省旌德县,今年37岁,曾做过车床操作工,开过婚纱摄影店&…...

深度学习和人工智能之间是什么样的关系?
深度学习与人工智能概念的潜在联系,我们依然借助维恩图来说明,如图4.1所示。 1、人工智能 “人工智能”这个概念新鲜时髦但又含混模糊,同时包罗万象。尽管如此,我们仍尝试对 人工智能进行定义:用一台机器处理来自其周围环境的信息,然后将这些…...

实战打靶集锦-016-lampiao
提示:本文记录了博主打靶过程中一次曲折的提权经历 文章1. 主机发现2. 端口扫描3. 服务枚举4. 服务探查4.1 80端口探查4.2 1898端口探查4.3 EXP搜索4.3.1 exploit/unix/webapp/drupal_coder_exec4.3.2 exploit/unix/webapp/drupal_drupalgeddon25. 提权5.1 系统信息…...

《Web前端应用开发》考试试卷(模拟题)
一、产品搜索页面 打开“考试文件夹”中的input.html,完成以下步骤: 注意:本题仅能在input.html的(1)为产品名称所在的div添加样式属性,使得产品名称保持在文本框的左边; (2…...

【react全家桶学习】react简介
react是什么? react是用于构建用户界面的JS库,是一个将数据渲染为HTML视图的开源JS库 谁开发的? 由Facebook开发,且开源 为什么要学? 原生JavaScript操作DOM繁琐、效率低 ( DOM-API操作 UI)使用JavaScript直接操作…...

此战成硕,我成功上岸西南交通大学了~~~
友友们,好久不见,很长时间没有更一个正式点的文章了! 是因为我在去年年底忙着准备初试,今年年初在准备复试,直到3月底拟录取后,终于可以写下这篇上岸贴,和大家分享一下考研至上岸的一个过程 文章…...

光耦继电器工作原理及优点概述
光耦继电器是一种电子元器件,也是固态继电器的一种,其主要作用是隔离输入与输出电路,用于保护或者控制电路的正常工作。 光耦继电器工作原理是利用光电转换器将外界信号转化为光信号,通过光纤传输到另一端,再由另一端的…...

【Mysql】mysql8.0.26解压包部署方式
版本背景: 操作系统:centos7.3 mysql版本:mysql-8.0.26-linux-glibc2.12-x86_64.tar 一、前期准备 1、检测操作系统自带安装的mysql和mariadb服务,如存在,需卸载 rpm -qa | grep mysql rpm -qa | grep mariadb 卸载…...

进销存管理系统能为企业带来哪些实际效益?
随着互联网的不断发展,如今的商业世界已经越来越向数字化转型。拥有一套完整的数字化的进销存管理能够极大地提升公司货物进出库存情况的效率和准确性,避免过程中出现不必要的错误和漏洞,从而帮助企业更加稳健地自我发展。那么,一…...

图片怎么转换成pdf格式?这几个方法帮你一键转换
现今电子书籍越来越受到欢迎,其中PDF格式也成为了一种常用的电子书籍格式。无论是工作还是学习,我们都可能会遇到需要将图片转换成PDF格式的情况,例如保存一些资料证明、公文公告、学习资料等。在这篇文章中,我们将为大家介绍三种…...