【GD32】 TIMER通用定时器学习+PWM输出占空比控制LED

扩展:对PWM波形的输出进行捕获

目录

  • 一、简介
  • 二、具体功能描述
    • 1、时钟源的选择:
    • 2、预分频器:
    • 3、计数模式:
      • 向上计数模式:
      • 向下计数模式:
      • 中央对齐模式:
    • 4、捕获/比较通道
      •  输入捕获模式
      •  输出比较模式:
    • 5、PWM模式
    • 6、正交译码器
  • 三、示例
    • 目标任务1:输出模式
    • 目标任务2:输入捕获
    • 目标任务3:计数

一、简介

基本定时器和系统时钟配置可以参考我的上一篇文章,
文章链接为:
【GD32系列–基本定时器Timer + 定时1ms 灯光间隔1s闪烁例程】
【GD32】_时钟架构及系统时钟频率配置
下表为各定时器的差异,以通用定时器TIME1为例。
在这里插入图片描述
由上表可知通用定时器也分为四大类,黑圈代表具有此功能,x代表无此功能,一目了然。
由系统框图可知TIMER5 TIMER1 TIMER2 TIMER13均挂在APB1总线下
而TIMER0/TIMER14/15/16均挂在APB2总线下。
由图可见APB1 和APB2的预分频系数均为2,即: RCU_APB1_CKAHB_DIV2,即 PCLK1=36M。

本例程系统时钟为72MHZ,因此定时器的时钟源: CK_TIMER=36*2=72MHZ

在这里插入图片描述
TIMER1 and TIMER2是4通道定时器,
每个通道均可配置模式:输入捕获模式,输出比较模式,可编程的PWM模式,单脉冲模式
具有自动重装载功能。
时钟源有4种:内部时钟,内部触发,外部输入,外部触发;
计数器宽度:16位(TIMER2),32位(TIMER1);

二、具体功能描述

1、时钟源的选择:

通用定时器L0可以由内部时钟源TIMER_CK或者由SMC(TIMERx_SMCFG寄存器位[2:0])控制的复用时钟源驱动。

通用定时器L0可以由内部时钟源TIMER_CK驱动,若禁能禁能从模式(SMC[2:0]==3’b000),默认用来驱动计数器预分频器的是内部时钟源CK_TIMER。当CEN置位,CK_TIMER经过预分频器产生PSC_CLK。

也可以选择外部时钟模式。

2、预分频器:

预分频器可将定时器的时钟(TIMER_CK)频率按1到65536之间的任意值分频,分频后的时钟PSC_CLK驱动计数器计数。分频系数受预分频寄存器TIMERx_PSC控制,这个控制寄存器 带有缓冲器,它能够在运行时被改变。

在这里插入图片描述

3、计数模式:

有三种:向上计数、向下计数和中央计数

向上计数模式:

a、计数器从0向上计数到自动加载值(在TIMERx_CAR寄存器定义),一旦计数达到自动加载值,会重新从0开始向上计数并产生上溢事件。(此时TIMERx_CTL0寄存器中的计数方向控制位DIR应设置为0)

b、当通过TIMERx_SWEVG寄存器的UPG位置1来设置更新事件时,计数值会被清0,并产生新事件。(如果TIMERx_CTL0寄存器的UPDIS置1,则禁止更新事件。 )

c、当发生更新事件时,所有的寄存器(自动重载寄存器,预分频寄存器)都将被更新。

示例:,当TIMERx_CAR=0x63时,即自动加载值为0x63时,计数器在不同预分频因子下的状态。
在这里插入图片描述

向下计数模式:

a、计数器从自动加载值(在TIMERx_CAR寄存器定义)向下连续计数到0,一旦计数到0,计数器会重新从自动加载值开始计数并产生下溢事件。(此时TIMERx_CTL0寄存器中的计数方向控制位DIR应设置为1)

b、当通过TIMERx_SWEVG寄存器的UPG位置1来设置更新事件时,计数值会被初始化为自动加载值,并产生新事件。(如果TIMERx_CTL0寄存器的UPDIS置1,则禁止更新事件。 )

c、当发生更新事件时,所有的寄存器(自动重载寄存器,预分频寄存器)都将被更新。

示例:,当TIMERx_CAR=0x63时,即自动加载值为0x63时,计数器在不同预分频因子下的状态。

在这里插入图片描述

中央对齐模式:

a、在此模式下,计数器交替的从0开始向上计数到自动加载值,然后在向下计数到0。
(具体为: 向上计数模式中,在计数器技术到(自动加载值-1)时产生一个上溢事件;向下计数模式中,在计数器计数到1时产生一个下溢事件。)此时TIMERx_CTL0 寄存器中的计数方向控制位DIR只读,表明了的计数方向。计数方向被硬件自动更新。

b、将TIMERx_SWEVG寄存器的UPG位置1可以初始化计数值为0,并产生一个更新事件,而无需考虑计数器在中央模式下是向上计数还是向下计数。如果 TIMERx_CTL0 寄存器的 UPDIS 置 1,则禁止更新事件。

上溢或者下溢时,TIMERx_INTF 寄存器中的 UPIF 位都会被置 1,然而 CHxIF 位置 1 与
TIMERx_CTL0 寄存器中 CAM 的值有关。

c、当发生更新事件时,所有的寄存器(自动重载寄存器,预分频寄存器)都将被更新。

在这里插入图片描述

4、捕获/比较通道

通用定时器的基本计时功能与基本定时器的工作方式相同,都是把时钟源经过预分频器输出到脉冲计数器 TIMx_CNT 累加,溢出时就产生中断或 DMA 请求。通用定时器比基本定时器多出的功能,是因为通用定时器多出了一种寄存器——捕获 / 比较寄存器 TIMx_CCR(capture/compare register),它在输入时被用于捕获(存储) 输入脉冲在电平发生翻转时脉冲计数器 TIMx_CNT 的当前计数值,从而实现脉冲的频率测量 ;在输出时被用来存储一个脉冲数值,把这个数值用于与脉冲计数器TIMx_CNT 的当前计数值进行比较,根据比较结果进行不同的电平输出。

通用定时器L0有四个独立的通道用于捕获输入或比较输出是否匹配。
每个通道都围绕一个通 道捕获比较寄存器建立,包括一个输入级通道控制器输出级

 输入捕获模式

捕获模式允许通道测量一个波形时序,频率,周期,占空比等。
输入级包括一个数字滤波器, 一个通道极性选择,边沿检测和一个通道预分频器。如果在输入引脚上出现被选择的边沿, TIMERx_CHxCV寄存器会捕获计数器当前的值,同时CHxIF位被置1,如果CHxIE = 1则产生 通道中断。

在这里插入图片描述

配置步骤:
a、滤波器配置 (TIMERx_CHxCAPFLT)
b、边沿选择(TIMERx_CHCTL2寄存器中CHxP/CHxNP)
c、捕获源选择(TIMERx_CHCTL0寄存器中CHxMS):
d、中断使能 (TIMERx_DMAINTEN寄存器中CHxIE和CHxDEN):
使能相应中断,可以获得中断和DMA请求
e、捕获使能 (TIMERx_CHCTL2寄存器中CHxEN)

结果:当期望的输入信号发生时,TIMERx_CHxCV被设置成当前计数器的值,CHxIF为置1。
如果CHxIF位已经为1,则CHxOF位置1。根据TIMERx_DMAINTEN寄存器中CHxIE和
CHxDEN的配置,相应的中断和DMA请求会被提出。

直接产生:软件设置CHxG位,会直接产生中断和DMA请求。

输入捕获模式也可用来测量TIMERx_CHx引脚上信号的脉冲波宽度。

 输出比较模式:

在输出比较模式,TIMERx可以产生时控脉冲,其位置,极性,持续时间和频率都是可编程的。 当一个输出通道的CHxVAL寄存器与计数器的值匹配时,根据CHxCOMCTL的配置,这个通道 的输出可以被置高电平,被置低电平或者反转。

当计数器的值与CHxVAL寄存器的值匹配时, CHxIF位被置1,如果CHxIE = 1则会产生中断,如果CHxDEN=1则会产生DMA请求。

配置步骤如下:
a:时钟配置: 配置定时器时钟源,预分频器等。
b:比较模式配置:

设置CHxCOMSEN位来配置输出比较影子寄存器; 
设置CHxCOMCTL位来配置输出模式(置高电平/置低电平/反转); 
设置CHxP/CHxNP位来选择有效电平的极性; 
设置CHxEN使能输出。 

c:通过CHxIE/CHxDEN位配置中断/DMA请求使能。
d:通过TIMERx_CAR寄存器和TIMERx_CHxCV寄存器配置输出比较时基: CHxVAL可以在运行时根据你所期望的波形而改变。
e:设置CEN位使能定时器。

三种比较输出模式:反转/置高电平/置低电平,当设置:CAR=0x63, CHxVAL=0x3时。

在这里插入图片描述

5、PWM模式

根据计数模式,我们可以分为两种PWM波:EAPWM(边沿对齐PWM)CAPWM(中央对齐
PWM)
在 PWM 输 出模 式 下 ( PWM 模 式 0是配置 CHxCOMCTL 为3’b110, PWM 模 式 1 是配 置CHxCOMCTL为3’b111),通道根据TIMERx_CAR寄存器和TIMERx_CHxCV寄存器的值,输出PWM波形。
在这里插入图片描述
以PWM模式0、向上计数为例:定时器输出通道开始时是高电平,当计数器的值 > 输出比较寄存器的值时,输出通道变为低电平,直到计数器达到重装载寄存器的值,产生溢出并复位。
PWM模式1的电平和PWM模式0互补,向上计数和向下计数的区别是输出比较寄存器和重装载寄存器的比较方式是相反的。

在这里插入图片描述
中央对齐PWM的工作模式:当计数器的值小于输出比较寄存器的值时,通道输出为空闲电平;当计数器的值大于输出比较寄存器的值时,通道输出的是有效电平。

6、正交译码器

正交译码器功能使用由 TIMERx_CH0 和 TIMERx_CH1 引脚生成的 CI0 和 CI1 正交信号各自相互作用产生计数值。

在每个输入源改变期间,DIR 位被硬件自动改变。输入源可以是只有 CI0,可以只有 CI1,或着可以同时有 TI1 和 TI2,通过设置 SMC=0x01, 0x02 或 0x03 来选择使用哪种
模式。正交译码器可以当作一个带有方向选择的外部时钟,这意味着计数器会在 0 和自动加载值之间连续的计数。因此,必须在计数器开始计数前配置 TIMERx_CAR 寄存器。

计数器计数方向改变的机制如表 16-5. 计数方向与编码器信号之间的关系所示。
在这里插入图片描述

三、示例

目标任务1:输出模式

使用输出比较模式,得到不同的占空比,来控制灯的亮度。

void pwm_duty_cycle_led_config(void)
{/* TIMER5 configuration: generate 1msSystemCoreClock =72MHZTIMER1CLK = SystemCoreClock / 72= 1MHz *//* enable the GPTO clock */rcu_periph_clock_enable( RCU GPIOA);//设置定时器0为pwm输出功能/*Configure PA15 (TIMER1 CHO) as alternate function*/gpio_mode_set (GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_15):gpio_output_options_set (GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, GPIO_PIN_15):gpio_af_set (GPIOA, GPIO_AF_2, GPIO_PIN_15)timer_oc_parameter_struct  timer_ocintpara; timer_parameter_struct  timer_initpara:rcu_periph_clock_enable (RCU_TIMER1):timer_deinit (TIMER1):/*初始化定时器参数*//* TIMER1 configuration */timer_initpara.prescaler         = 71;timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;timer_initpara.counterdirection  = TIMER_COUNTER_UP;timer_initpara.period            = 15999;timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;//周期1MHA /(15999+1)=62.5HZtimer_init(TIMER1, &timer_initpara);/* CH1.CH2 and CH3 configuration in PWM mode1 */ timer_ocintpara.ocpolarity =TIMER_OC_POLARITY_HIGH: timer_ocintpara.outputstate = TIMER_CCX_ENABLE:tiner_channel_output_config (TIMER1, TIMER_CH_0, &timer_ocintpara): timer_channel_output_pulse_value_config (TIMER1, TIMER CH_0, 3999):timer_channel_output_mode_config (TIMERi, TIMER_CH_O, TIMER_OC_MODE_PWMO):tiner_channel_output_shadow_config (TIMERI, TIMER_CH_O, TIMER OC_SHADOw DISABLE):/* auto-reload preload enable */ timer_auto_reload_shadow_enable (TIMER1): /* auto-reload preload enable */ timer_enable (TIMER1):timer_primary_output_config (TIMER1, ENABLE) :}//很亮 
void pwm_led_low(void) 
{timer_channel_output_pulse_value_config (TIMER1, TIMER_CH_0,8999) :
}void pwm_led_high(void)
{timer_channel_output_pulse_value_config (TIMER1,TIMER_CH_0,899):}unsigned char key (void)
{unsigned char status = 0:status = (unsigned char)((GPIO_ISTAT(GPIOB)>>3)&0x00000001):return status;
}
void main(void)
{pwm_duty_cycle_led_config();while(1){if(0==key()){pwm_led_high();}else{pwm_led_low();}}}

目标任务2:输入捕获

捕获并计算PWM波的周期和占空比。
基本配置步骤:
a、周期设置为最高值(65535):为了避免计数时计数器溢出而导致数据不正确‘;
b、配置输入捕获为定时器通道0,CH0;
c、通道极性为上升沿(即在遇到上升沿时,定时器会捕获计数器的值);
d、同时设置中断(定时器一旦捕获,我们就可以在中断服务函数中开始计算对应的周期和频率。)
e、配置从模式,设置为复位模式,这样一旦发生捕获,计数器的值就会归零,重新开始计数。

void pwm_time2_config(void)
{rcu_periph_clock_enable(RCU_GPIOA);/* PWM输入管脚为浮空输入模式 */gpio_mode_set( GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN_6 ):/*TIMER2初始化*/timer_ic_parameter_struct timer_icinitpara;timer_parameter_struct  timer_initpara:rcu_periph_clock_enable (RCU_TIMER2):timer_deinit (TIMER2):timer_icinitpara.icpolarity  = TIMER_IC_POLARITY_RISING;  // 输入极性为上升沿,即上升沿有效timer_icinitpara.icselection = TIMER_IC_SELECTION_DIRECTTI;  // 输入捕获通道连接至CIxtimer_icinitpara.icprescaler = TIMER_IC_PSC_DIV1;  // 时钟1分频timer_icinitpara.icfilter    = 0x0;timer_input_pwm_capture_config(TIMER2, TIMER_CH_0, &timer_icinitpara);timer_input_trigger_source_select(TIMER2, TIMER_SMCFG_TRGSEL_CI0FE0);  // 输入触发源为通道0timer_slave_mode_select(TIMER2, TIMER_SLAVE_MODE_RESTART);  // 从模式选择为复位模式timer_master_slave_mode_config(TIMER2, TIMER_MASTER_SLAVE_MODE_ENABLE);  // 使能从模式timer_auto_reload_shadow_enable(TIMER2);  // 使能重装载影子nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);  // 抢占优先级4位,响应优先级0位nvic_irq_enable(TIMER2_IRQn, 1, 0);  // 使能中断服务,抢占优先级为1timer_interrupt_flag_clear(TIMER2, TIMER_INT_CH0);  // 清除通道0中断标志位timer_interrupt_enable(TIMER2, TIMER_INT_CH0);  // 使能通道0中断timer_enable(TIMER2);  // 使能定时器2}uint32_t ic1value = 0, ic2value = 0;
__IO uint16_t duty = 0;
__IO uint16_t freq = 0;void TIMER2_IRQHandler(void)
{if(SET == timer_interrupt_flag_get(TIMER2, TIMER_INT_CH0)){timer_interrupt_flag_clear(TIMER2, TIMER_INT_CH0);  // 清除中断标志位ic1value = timer_channel_capture_value_register_read(TIMER2, TIMER_CH_0) + 1;if(0 != ic1value){ic2value = timer_channel_capture_value_register_read(TIMER2, TIMER_CH_1) + 1;duty = (ic2value * 100) / ic1value;  // 计算占空比freq = (float)1000000 / ic1value;  // 计算频率}else{duty = 0;freq = 0;}}
}

中断代码说明:

  • TIMER_INT_CH0:

这是被设置为触发中断的通道
当定时器通道 0(TIMER_CH_0)发生中断时(可能是定时时间到达、输入捕获事件等),中断服务函数 TIMER2_IRQHandler 被调用。在中断服务函数中,首先检查是否是定时器 2 的通道 0 产生的中断(if(SET == timer_interrupt_flag_get(TIMER2, TIMER_INT_CH0)))。
如果是,则清除该中断标志位,并读取通道 0 的捕获值(ic1value)。

  • TIMER_CH_0 和 TIMER_CH_1

这两个是定时器的捕获通道。它们被配置为在不同的外部事件(如输入信号边沿)上捕获时间戳。
ic1value 是从通道 0 读取的捕获值(表示某个时间间隔的开始)。
ic2value 是从通道 1 读取的捕获值(表示该时间间隔的结束)。
在中断服务函数中,一旦确定了是通道 0 的中断,并读取了 ic1value(时间间隔的开始),就接着读取 ic2value(时间间隔的结束)。这两个值用于计算占空比和频率。

TIMER_INT_CH0 是用于触发中断的通道。当中断发生时,需要读取 ic1value(因为中断是由该事件触发的)。
TIMER_CH_1 是用于捕获另一个时间点(通常是与 TIMER_CH_0 相关联的某个事件的结束)的通道。在中断服务函数中,读取 ic2value 来与 ic1value 一起计算占空比和频率。

TIMER_INT_CH0 用于触发中断和读取开始时间戳,
而 TIMER_CH_1 用于读取结束时间戳。
这两个通道一起工作,以便在外部事件发生时能够捕获两个时间点,并使用这两个时间点来计算占空比和频率。

目标任务3:计数

获取计数值的函数是timer_cnt=timer_counter_read(TIMERx)

void timer15_config ( void )
{/* TIMER1 configuration:TIMERICLK= 72MHz, prescaler= 36000TIMER1 counter clock systemcoreclock/36000 = 2KHz.*/timer_parameter_struct timer_initpara;/* enable TIMERI clock */ rcu_periph clock_enable( RCU_TIMER15 ): /* reset TIMER1 */ timer_deinit ( TIMER15 ):/* TIMER1 configuration */timer_initpara.prescaler         = 3999;timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;timer_initpara.counterdirection  = TIMER_COUNTER_UP;timer_initpara.period            = 65535;timer_initpara.clockdivision     = TIMER_CKDIV_DIV2;timer_init(TIMER15, &timer_initpara);/* enable TIMER1 auto-reload shadow function */ timer_auto_reload_shadow_enable ( TIMER15 ):timer interrupt flag-clearTIMER15, TIMER INT UP ): /* enable the update interrupt */timer_interrupt_enable ( TIMER15, TIMER_INT_UP ): /* TIMER15 counter enable */ timer_enable ( TIMER15):
}
void main(void)
{uart1_init();timer15_config();int speed = 1:uint32 t tine_cnt = tiner_counter_read(TIMER15):timer_counter_value_config (TIMER15,0):if (time_cnt<256 && time_cnt>0){speed = time_cnt * 2;Uart_Printf ( 1, "speed: %d,  " ,speed ):}}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端问题整理

Vue vue mvvm&#xff08;Model-View-ViewModel&#xff09;架构模式原理 Model 是数据层&#xff0c;即 vue 实例中的数据View 是视图层&#xff0c; 即 domViewModel&#xff0c;即连接Model和Vue的中间层&#xff0c;Vue实例就是ViewModelViewModel 负责将 Model 的变化反映…

TCGAbiolinks包学习

TCGAbiolinks 写在前面学习目的GDCquery GDCdownload GDC prepare中间遇到的报错下载蛋白质数据 写在前面 由于别人提醒我TCGA的数据可以利用TCGAbiolinks下载并处理&#xff0c;所以我决定阅读该包手册&#xff0c;主要是该包应该是有更新的&#xff0c;我看手册进行更新了&…

【CS.PL】Lua 编程之道: 简介与环境设置 - 进度8%

1 初级阶段 —— 简介与环境设置 文章目录 1 初级阶段 —— 简介与环境设置1.1 什么是 Lua&#xff1f;特点?1.2 Lua 的应用领域1.3 安装 Lua 解释器1.3.1 安装1.3.2 Lua解释器的结构 1.4 Lua执行方式1.4.0 程序段1.4.1 使用 Lua REPL&#xff08;Read-Eval-Print Loop&#x…

LAMP部署及应用

LAMP架构 LAMP架构是指一种常用的网站开发架构&#xff0c;它由以下几个组件组成&#xff1a; Linux操作系统&#xff1a;作为服务器的操作系统&#xff0c;LAMP架构通常使用Linux作为操作系统&#xff0c;因为Linux通常被认为是稳定和安全的。 Apache HTTP服务器&#xff1a…

iOS ReactiveCocoa MVVM

学习了在MVVM中如何使用RactiveCocoa&#xff0c;简单的写上一个demo。重点在于如何在MVVM各层之间使用RAC的信号来更方便的在各个层之间进行响应式数据交互。 demo需求&#xff1a;一个登录界面(登录界面只有账号和密码都有输入&#xff0c;登录按钮才可以点击操作)&#xff0…

AI模型部署:Triton+TensorRT部署Bert文本向量化服务实践

前言 本篇介绍以Triton作为推理服务器&#xff0c;TensorRT作为推理后端&#xff0c;部署句嵌入向量模型m3e-base的工程方案和实现&#xff0c;句嵌入模型本质上是Bert结构&#xff0c;本案例可以推广到更一般的深度学习模型部署场景。 内容摘要 推理服务器和推理后端介绍Ten…

【Numpy】numpy.r_用法

numpy.r_[字符串, 数组, 数组] numpy.r_的这三个整数默认值是0,1,-1 numpy.c_就是numpy.r_在三个整数是-1,2,0时的特例&#xff0c;因为常用&#xff0c;所以单独拎出来了。第一个参数-1指沿最后一个轴(维度)连接 有一个shape(2, 3, 4)的数组 np.random.randint(low0, high1…

文章MSM_metagenomics(一):介绍

介绍 欢迎大家关注全网生信学习者系列&#xff1a; WX公zhong号&#xff1a;生信学习者Xiao hong书&#xff1a;生信学习者知hu&#xff1a;生信学习者CDSN&#xff1a;生信学习者2 用于复现Huang et al. [huang2024establishment]研究分析的计算工作流程&#xff0c;所有复…

LDR6020显示器应用:革新连接体验,引领未来显示技术

一、引言 随着科技的飞速发展&#xff0c;显示器作为信息展示的重要载体&#xff0c;其性能和应用场景不断得到拓展。特别是在办公、娱乐以及物联网等领域&#xff0c;用户对显示器的需求越来越多样化。在这一背景下&#xff0c;LDR6020显示器的出现&#xff0c;以其卓越的性能…

STM32硬件接口I2C应用(基于HMC5883L)

目录 概述 1 STM32Cube控制配置I2C 1.1 I2C参数配置 1.2 使用STM32Cube产生工程 2 HAL库函数介绍 2.1 初始化函数 2.2 写数据函数 2.3 读数据函数 3 认识HMC5883L 3.1 HMC5883L功能介绍 3.2 HMC5883L的寄存器 4 HMC5883L驱动程序实现 4.1 驱动函数实现 4.2 完整驱…

QT调用vs2019生成的c++动态库

QT调用vs2019生成的c动态库 dll库的创建方法&#xff1a; VS2019创建c动态链接库dll与调用方法-CSDN博客 加减法示范&#xff1a; 头文件 // 下列 ifdef 块是创建使从 DLL 导出更简单的 // 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 DLL3_EXPORTS // 符号编…

解决方案︱视频孪生智慧高速解决方案

系统概述 在交通强国战略的指导下&#xff0c;我国政府高度重视以数字化为核心的智慧高速公路建设与发展。2023年9月&#xff0c;交通运输部印发了《交通运输部关于推进公路数字化转型加快智慧公路建设发展的意见》&#xff0c;强调到2035年&#xff0c;全面实现公路数字化转型…

【C++】和【预训练模型】实现【机器学习】【图像分类】的终极指南

目录 &#x1f497;1. 准备工作和环境配置&#x1f495; &#x1f496;安装OpenCV&#x1f495; &#x1f496;安装Dlib&#x1f495; 下载并编译TensorFlow C API&#x1f495; &#x1f497;2. 下载和配置预训练模型&#x1f495; &#x1f496;2.1 下载预训练的ResNet…

一文入门vim

先来波快问快答。 第一个问题&#xff0c;vim是什么&#xff1f; vim就是一文本编辑器。 第二个问题&#xff0c;我们为什么要使用vim&#xff1f; 好像在终端中可选择使用的文本编辑器也不多&#xff08;其他有&#xff0c;但是相对而言vim用的比较广泛&#xff09; 第三…

automa学习:写一个取某东图书数据的片断

周五了&#xff0c;实在没事情了。正好上午有个朋友问automa的事&#xff0c;心想再写一个练习一下&#xff0c;毕竟&#xff0c;熟能生巧。 目标某东图书&#xff1a; 分析及介绍如下。 1.新建标签页 1.悬停元素。要注意 县 停 .cate_menu_item:nth-child(14) > .cate_…

SQL进阶day10————多表查询

目录 1嵌套子查询 1.1月均完成试卷数不小于3的用户爱作答的类别 1.2月均完成试卷数不小于3的用户爱作答的类别 ​编辑1.3 作答试卷得分大于过80的人的用户等级分布 2合并查询 2.1每个题目和每份试卷被作答的人数和次数 2.2分别满足两个活动的人 3连接查询 3.1满足条件…

【docker】如何解决artalk的跨域访问问题

今天折腾halo的时候&#xff0c;发现artalk出现跨域访问报错&#xff0c;内容如下。 Access to fetch at https://artk.musnow.top/api/stat from origin https://halo.musnow.top has been blocked by CORS policy: The Access-Control-Allow-Origin header contains multipl…

【字符函数】

接下来介绍部分字符函数测试 2. 字符转换函数 1.字符分类函数 1.1iscntrl 注&#xff1a;任何控制字符 检查是否有控制字符 符合为真 int main() {int i 0;char str[] "first line \n second line \n";//判断是否遇到控制字符while (!iscntrl(str[i])){p…

AI办公自动化:kimi批量搜索提取PDF文档中特定文本内容

工作任务&#xff1a;PDF文档中有资料来源这一行&#xff0c;比如&#xff1a; 资料来源&#xff1a;moomoo tech、The Information、Bloomberg、Reuters&#xff0c;浙商证券研究所 数据来源&#xff1a;CSDN、浙商证券研究所 数据来源&#xff1a;CSDN、arXiv、浙商证券研…

效率翻倍!ComfyUI 必装的工作流+模型管理插件 Workspace Manager

一、Workspace Manager 安装方式 插件 Github 网址&#xff1a; https://github.com/11cafe/comfyui-workspace-manager 如果你没有安装 Workspace Manager 插件&#xff0c;可以通过以下 2 种方式安装&#xff1a; ① 通过 ComfyUI Manager 安装&#xff08;推荐&#xff0…