【STM32单片机】#5 定时中断

news2025/4/6 13:46:34

主要参考学习资料:

B站@江协科技

STM32入门教程-2023版 细致讲解 中文字幕

开发资料下载链接:https://pan.baidu.com/s/1h_UjuQKDX9IpP-U1Effbsw?pwd=dspb

单片机套装:STM32F103C8T6开发板单片机C6T6核心板 实验板最小系统板套件科协

实验:

  • 定时器定时中断
  • 定时器外部时钟

新函数:

  • 定时器库函数(部分)

目录

  • TIM简介
    • 定时器类型
    • 定时器结构
      • 基本定时器
      • 通用定时器
      • 高级定时器
  • 定时中断
    • 定时中断基本结构
    • 时基单元时序图
      • 预分频器时序
      • 计数器时序
      • RCC时钟树
  • 函数详解
    • 定时中断初始化
      • TIM_DeInit函数
      • TIM_TimeBaseInit函数
        • TIM_TimeBaseInitTypeDef结构体
      • TIM_TimeBaseStructInit函数
      • TIM_Cmd函数
      • TIM_ITConfig函数
    • 时钟选择
      • TIM_InternalClockConfig函数
      • TIM_ITRxExternalClockConfig函数
      • TIM_TIxExternalClockConfig函数
      • TIM_ETRClockMode1Config函数
      • TIM_ETRClockMode2Config函数
      • TIM_ETRConfig函数
    • 定时器配置
      • TIM_PrescalerConfig函数
      • TIM_CounterModeConfig函数
      • TIM_ARRPreloadConfig函数
    • 定时器读写
      • TIM_SetCounter函数
      • TIM_SetAutoreload函数
      • TIM_GetCounter函数
    • TIM_GetPrescaler函数
    • 中断标志位
  • 实验8 定时器定时中断
    • 接线图
    • 定时器驱动
    • 主程序
  • 实验9 定时器外部时钟
    • 接线图
    • 定时器驱动
    • 主程序

TIM简介

  • TIM(Timer)定时器
  • 定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断。
  • STM32的定时器拥有16位计数器、预分频器、自动重装寄存器的时基单元,在72MHz计数时钟下可以实现最大59.65s的定时。
  • 定时器不仅具备基本的定时中断功能,而且还包含内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等多种功能。
  • 根据复杂度和应用场景,定时器分为高级定时器、通用定时器、基本定时器三种类型。

定时器类型

STM32F103C8T6定时器资源:TIM1、TIM2、TIM3、TIM4

定时器结构

基本定时器

基本定时器只能以内部时钟为时钟源,其信号来源于RCC的TIMxCLK,频率值一般为系统主频72MHz。

预分频器对72MHz的计数时钟进行预分频。预分频器写入n则分频系数为n+1,此时输出频率=输入频率/(n+1)。该预分频器为16位,最大可进行65536分频。

计数器对预分频后的计数时钟进行计数,每到达一个上升沿,计数器的值加一。该计数器为16位,其目标值最大为65535,目标值由自动重装载寄存器存储。计数器到达目标值继续计数将重新从零开始,并产生通往NVIC的更新中断,同时还可以产生更新事件,触发内部其他电路的工作。

除了上述向上计数方式,定时器还有向下计数(从目标值倒数到零后产生中断,重新从目标值倒数)和中央计数(向上计数和向下计数交替),一般使用向上计数方式。

通用定时器

请添加图片描述

通用定时器的时钟源除了内部时钟还可以选择外部时钟。

TIMx_ETR来自相应的引脚,可接入外部方波时钟,并通过配置极性选择、边沿检测、预分频和输入滤波对外部时钟进行整形。整形后的时钟信号一路由ETRF通往时基单元,为“外部时钟模式2”;另一路由TRGI用于触发定时器从模式,后续补充,若将其作为外部时钟使用,则为“外部时钟模式1”。两种模式对时钟输入等价,只是模式1会占用触发输入通道。

ITR来自其他定时器的TRGO输出,连接方式参考数据手册。通过将其他定时器的更新事件映射到TRGO上,可以实现定时器级联,从而对更长的时间计数。

TI1F_ED来自输入捕获单元的TIMx_CH1引脚,ED(edge)意为边沿,即通过这一路输入的时钟上升沿和下降沿均有效。TI1FP1和TI2FP2来自输入捕获单元的TIMx_CH1和TIMx_CH2引脚。以上为外部时钟模式1的内容,一般情况使用TIMx_ETR即可,其余情况为扩大时钟输入范围和其余特殊应用场景设计,后续补充。

下方右侧为四通道输出比较电路,可用于输出PWM波形驱动电机。左侧为四通道输入捕获电路,可用于测量输入方波的频率。输出比较和输入捕获不会同时使用,它们共用中间的捕获/比较寄存器。

高级定时器

高级定时器在通用定时器基础上有如下改动:

申请中断处增加重复次数计数器,可以实现每隔几个计数周期发生一次更新中断和更新事件。

输出比较模块升级,暂时不必深入了解。三个通道的输出引脚由一个变成两个,可以输出一对互补的PWM波,用于驱动三相无刷电机。三相无刷电机有三个桥臂,每个桥臂由两个大功率开关管控制。DTG死区生成电路用于在开关切换瞬间产生一定时长的死区使桥臂上下管全都关断,防止直通现象。

增加刹车输入功能,为电机驱动提供安全保障。如果外部引脚TIMx_BKIN产生刹车信号或内部时钟失效,控制电路将自动切断电机输出防止意外发生。

定时中断

定时中断基本结构

以上为定时中断用到的结构,其中中断输出控制位中断输出的允许位。

时基单元时序图

预分频器时序

CK_PSC为输入时钟。CNT_EN为计数器使能,高电平计数器正常运行,低电平计数器停止。CK_CNT是预分频器的时钟输出和计数器的时钟输入。一开始计数器未使能,计数器时钟不运行。使能后,前半段预分频器系数为1,计数器时钟等于输入时钟。后半段预分频器系数为2,计数器时钟变为输入时钟的一半。计数器寄存器跟随时钟上升沿自增,在达到图中情况的自动重装值FC后重新从零开始计数,并产生一个更新事件。

后三行时序为预分频寄存器的缓存机制。预分频控制寄存器供我们读写,预分频缓冲器决定预分频器的分频系数。在写入新的分频系数后,缓冲器会等待当前计数周期完成再接收控制寄存器的值,以保证一个计数周期内频率的统一性。预分频计数器在分频系数为0时始终为0,预分频器直接输出原频率;分频系数不为0时,预分频计数器以分频系数为目标值计数,并在回到0时,CK_CNT输出一个脉冲。

计数器计数频率:CK_CNT=CK_PSC/(PSC+1)

CK_PSC:输入时钟频率;PSC:预分频控制寄存器写入值。

计数器时序

当计数器寄存器到达自动重装值时,下一次计数清零,产生计数器溢出和更新事件,并将更新中断标志位置一以申请中断,中断响应后需要再中断程序中手动清零。

计数器溢出频率:CK_CNT_OV=CK_CNT/(ARR+1)

ARR:自动重装值。

自动重装寄存器也有与预分频器类似的缓存机制,并且可以设置是否使用(预装入)。无预装时,向自动重装寄存器写入新值即改变当前计数周期的自动重装值:

但如果计数器计数已经超过更新的自动重装值,计数器只能计数到其本身的最大值再重新从零开始计数到自动重装值。有预装时,自动重装值会在当前计数周期结束后再更新到计数器中:

RCC时钟树

RCC时钟树是STM32中用来产生和配置时钟,并且把配置好的时钟发送到各个外设的系统。时钟是所有外设运行的基础,因此也是最先需要配置的东西。程序在主函数之前会隐式执行ST公司提供的SystemInit函数以配置时钟树。RCC时钟树以AHB预分频器为界,左侧为时钟产生电路,右侧为时钟分配电路,SYSCLK即72MHz系统时钟。

时钟产生电路有8MHz HSI RC(内部)、4-16MHz HSE OSC(外部)、32.768kHz LSE OSC(提供给RTC)和40kHz LSI RC(提供给看门狗)四个晶振。前两个高速晶振用于提供AHB、APB2、APB1的系统时钟,外部石英振荡器比内部RC振荡器更稳定,故一般使用外部晶振。若系统简单、不需要精确的时钟,可使用内部晶振以省下外部晶振电路。SystemInit函数会先选择启动内部时钟为系统时钟,再启动外部时钟,经PLL锁相环倍频9倍后得到72MHz,待锁相环输出稳定后选择锁相环输出为系统输出。CSS时钟安全系统检测外部时钟状态,一旦外部时钟失效则自动把外部时钟切换回内部时钟,保证系统时钟运行,防止程序卡死造成事故。

时钟分配电路中,系统时钟进入AHB总线,在AHB预分频器中根据SystemInit函数配置的分频系数一分频。时钟进入APB1总线再由APB1预分频器二分频至ABP1外设,而定时器仍将时钟还原为72MHz作为内部基准时钟(前提是不随意更改SystemInit函数配置)。APB2预分频器分频系数为1,因此时钟也为72MHz。每个时钟输出还会与外设时钟使能经过一个与门,外设时钟使能即为程序中RCC_APB2/1PeriphClockCmd作用的地方,只有使能后时钟才能通过与门输出给外设。

函数详解

本次介绍将要使用的部分定时器库函数。

定时中断初始化

TIM_DeInit函数

简介:恢复定时器初始配置。

参数:定时器名称

TIM1, ..., TIM17

TIM_TimeBaseInit函数

简介:时基单元初始化。

参数一:定时器名称

参数二:指向初始化信息TIM_TimeBaseInitTypeDef结构体的指针

TIM_TimeBaseInitTypeDef结构体

成员TIM_ClockDivision:内部时钟分频,提供滤波器采样频率。

TIM_CKD_DIV1, TIM_CKD_DIV2, TIM_CKD_DIV4

成员TIM_CounterMode:计数器模式。

TIM_CounterMode_Up(向上计数),
TIM_CounterMode_Down(向下计数),
TIM_CounterMode_CenterAligned1(先上后下中央计数),
TIM_CounterMode_CenterAligned2(先下后上中央计数),
TIM_CounterMode_CenterAligned3(交替使用两种中央计数)

成员TIM_Period:自动重装值。

成员TIM_Prescaler:预分频寄存器值。

成员TIM_RepetitionCounter:重复计数器值。

TIM_TimeBaseStructInit函数

简介:为TIM_TimeBaseInitTypeDef结构体变量赋默认值。

参数:指向初始化信息TIM_TimeBaseInitTypeDef结构体的指针

TIM_Cmd函数

简介:使能计数器。

参数一:定时器名称

参数二:使能/失能

TIM_ITConfig函数

简介:使能中断输出信号。

参数一:定时器名称

参数二:选择中断输出

TIM_IT_Update(更新中断)
TIM_IT_CC1, ..., TIM_IT_CC4(捕获/比较通道中断)
TIM_IT_COM(电机换相中断)(高级定时器)
TIM_IT_Trigger(触发中断)
TIM_IT_Break(刹车中断)(高级定时器)

参数三:使能/失能

时钟选择

TIM_InternalClockConfig函数

简介:选择内部时钟。

参数:定时器名称

TIM_ITRxExternalClockConfig函数

简介:选择ITRx其他定时器的时钟。

参数一:定时器名称

参数二:选择的ITR通道

TIM_TS_ITR0, ..., TIM_TS_ITR3

TIM_TIxExternalClockConfig函数

简介:选择TIx捕获通道的时钟。

参数一:定时器名称

参数二:选择的TI引脚

TIM_TIxExternalCLK1Source_TI1ED, TIM_TIxExternalCLK1Source_TI1
TIM_TIxExternalCLK1Source_TI2

参数三:极性(边沿触发方式)

TIM_ICPolarity_Rising, TIM_ICPolarity_Falling

参数四:滤波器(每个值对应一个采样频率和确认电平信号有效的连续采样次数,详见数据手册)

0x00~0x0F

TIM_ETRClockMode1Config函数

简介:选择ETR通过外部时钟模式1输入的时钟。

参数一:定时器名称

参数二:外部触发预分频器(以下分别为一/二/四/八分频)

TIM_ExtTRGPSC_OFF
TIM_ExtTRGPSC_DIV2, TIM_ExtTRGPSC_DIV4, TIM_ExtTRGPSC_DIV8

参数三:极性

TIM_ExtTRGPolarity_Inverted(上升沿), TIM_ExtTRGPolarity_NonInverted(下降沿)

参数四:滤波器

TIM_ETRClockMode2Config函数

简介:选择ETR通过外部时钟模式2输入的时钟。

参数一:定时器名称

参数二:外部触发预分频器

参数三:极性(同TIM_ETRClockMode1Config函数)

参数四:滤波器

TIM_ETRConfig函数

简介:单独配置ETR引脚的预分频器、极性和滤波器。

参数一:定时器名称

参数二:外部触发预分频器

参数三:极性(同TIM_ETRClockMode1Config函数)

参数四:滤波器

定时器配置

TIM_PrescalerConfig函数

简介:配置定时器的预分频器。

参数一:定时器名称

参数二:预分频控制寄存器写入值

参数三:是否预装

TIM_PSCReloadMode_Update(预装), TIM_PSCReloadMode_Immediate(无预装)

TIM_CounterModeConfig函数

简介:配置计数器的计数模式。

参数一:定时器名称

参数二:计数器模式

TIM_ARRPreloadConfig函数

简介:配置自动重装器预装功能。

参数一:定时器名称

参数二:使能/失能

定时器读写

TIM_SetCounter函数

简介:给计数器写入一个值。

参数一:定时器名称

参数二:写入值

TIM_SetAutoreload函数

简介:给自动重装器写入一个值。

参数一:定时器名称

参数二:自动重装值

TIM_GetCounter函数

简介:获取当前计数器的值。

参数:定时器名称

TIM_GetPrescaler函数

简介:获取当前预分频器的值。

参数:定时器名称

中断标志位

主程序读取、清除中断标志位:

TIM_GetFlagStatus

TIM_ClearFlag

中断程序读取、清除中断标志位:

TIM_GetITStatus

TIM_ClearITPendingBit

参数一:定时器名称

参数二:中断线路

实验8 定时器定时中断

实现功能:OLED显示数字从零开始每秒加一。

接线图

定时器驱动

由于定时器是内部硬件,因此驱动文件放在System中。

Timer.h

#ifndef __TIMER_H
#define __TIMER_H

void Timer_Init(void);

#endif

Timer.c

#include "stm32f10x.h"

void Timer_Init(void)
{
	//启用TIM2时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	//选择内部时钟(定时器上电默认使用内部时钟,可不写)
	TIM_InternalClockConfig(TIM2);
	
	//配置时基单元
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	//用不到ETR滤波器,随意配置
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	//向上计数
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	//定时1s,即计数器溢出频率1Hz,根据公式分配数值
	//取值不唯一,勿超出65535
	TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1;
	TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;
	//通用定时器无重复计数功能
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
	
	//为了立刻更新定时器配置,TIM_TimeBaseInit会主动触发更新事件
	//更新事件会将中断标志位置一,每次中断计数变量Num加一
	//清除中断标志位,否则该程序功能将从1开始计数
	TIM_ClearFlag(TIM2, TIM_FLAG_Update);
	
	//使能更新中断
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
	
	//配置NVIC
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStructure);
	
	//启动定时器
	TIM_Cmd(TIM2, ENABLE);
}

主程序

#include "stm32f10x.h" 
#include "Delay.h"
#include "OLED.h"
#include "Timer.h"

uint16_t Num;

int main(void)
{
	OLED_Init();
	Timer_Init();
	OLED_ShowString(1, 1, "Num:");
	while(1)
	{
		OLED_ShowNum(1, 5, Num, 5);
	}
}

//中断函数
void TIM2_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
	{
		Num ++;
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
	}
}

实验9 定时器外部时钟

实现功能:每遮挡一次对射式红外传感器计数器加一,每遮挡十次OLED显示Num加一。

接线图

定时器驱动

该实验驱动在实验8基础上更改,时钟选择外部时钟并配置相应GPIO,添加读取计数器计数值函数。更改部分用注释标明。

Timer.h

#ifndef __TIMER_H
#define __TIMER_H

void Timer_Init(void);
uint16_t Timer_GetCounter(void);

#endif

Timer.c

#include "stm32f10x.h"

void Timer_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	
	//配置GPIO
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	//选择外部时钟
	//不使用预分频器,下降沿触发,滤波器采样频率来自32分频,连续采样8次
	TIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x0F);
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	
	//从0计到9
	TIM_TimeBaseInitStructure.TIM_Period = 10 - 1;
	//遮挡手速慢,无需分频
	TIM_TimeBaseInitStructure.TIM_Prescaler = 1 - 1;
	
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
	
	TIM_ClearFlag(TIM2, TIM_FLAG_Update);
	
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStructure);
	
	TIM_Cmd(TIM2, ENABLE);
}

//返回计数器计数值
uint16_t Timer_GetCounter(void)
{
	return TIM_GetCounter(TIM2);
}

主程序

#include "stm32f10x.h" 
#include "Delay.h"
#include "OLED.h"
#include "Timer.h"

uint16_t Num;

int main(void)
{
	OLED_Init();
	Timer_Init();
	OLED_ShowString(1, 1, "Num:");
	OLED_ShowString(2, 1, "CNT:");
	while(1)
	{
		OLED_ShowNum(1, 5, Num, 5);
		//显示计数器计数值
		OLED_ShowNum(2, 5, Timer_GetCounter(), 5);
	}
}

//中断函数
void TIM2_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
	{
		Num ++;
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
	}
}

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

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

相关文章

OrbStack 作为 Mac 用户的 Docker 替代方案

推荐使用 OrbStack 作为 Mac 用户的 Docker 替代方案 在现代开发环境中,容器化技术已经成为了软件开发的重要组成部分。对于 Mac 用户来说,Docker Desktop 是一个广泛使用的工具,但它并不是唯一的选择。本文将推荐 OrbStack 作为 Docker Desktop 的替代方案,并探讨其优势。…

运行小程序报错

[ app.json 文件内容错误] app.json: ["tabBar"]["list"] 不能超过 5 项(env: Windows,mp,1.06.2206090; lib: 3.7.12) 他的意思大概是,微信小程序 app.json 文件中的 tabBar.list 配置项超过了 5 项。这是微信小程序的限制,tabBar…

深入剖析丝杆升降机工作原理,解锁工业传动奥秘

丝杆升降机,在工业设备的大舞台上扮演着不可或缺的角色,被广泛应用于机械制造、自动化生产线、建筑施工等众多领域。它能够精准实现重物的升降、定位等操作,为各类工业生产提供了稳定可靠的支持。想要深入了解丝杆升降机,就必须探…

【51单片机】2-3【I/O口】震动传感器控制LED灯

1.硬件 51最小系统LED灯模块震动传感器模块 2.软件 #include "reg52.h"sbit led1 P3^7;//根据原理图(电路图),设备变量led1指向P3组IO口的第7口 sbit vibrate P3^3;//震动传感器DO接P3.3口void Delay2000ms() //11.0592MHz {…

医疗思维图与数智云融合:从私有云到思维图的AI架构迭代(代码版)

医疗思维图作为AI架构演进的重要方向,其发展路径从传统云计算向融合时空智能、大模型及生态开放的“思维图”架构迭代,体现了技术与场景深度融合的趋势。 以下是其架构迭代的核心路径与关键特征分析: 一、从“智慧云”到“思维图”的架构演进逻辑 以下是针对医疗信息化领域…

【JS】接雨水题解

题目 思路 首先我们要明确如何计算每条柱子的接水量: 每条柱子对应接到的雨水量该柱子左边最大值和右边最大值中的较小值-该柱子本身的高度。举例:第二条柱子自身高度为0,左边最大值为1,右边最大值为3,取较小值1-自身…

线代[12]|《高等几何》陈绍菱(1984.9)(文末有对三大空间的分析及一个合格数学系毕业生的要求)

文章目录 一、概述二、平面仿射几何的基本概念三、平面射影几何的基本概念四、变换群和几何学五、二次曲线的射影理论、仿射理论和度量理论六、射影几何公理基础七、非欧几里得几何概要八、自我测试题九、欧氏解析几何、仿射解析几何、射影解析几何与其他(博主借助A…

第3课:状态管理与事件处理

第3课:状态管理与事件处理 学习目标 掌握useState Hook的使用理解组件事件处理机制实现表单输入与状态绑定完成任务添加功能原型 一、useState基础 1. 创建第一个状态 新建src/Counter.js: import { useState } from react;function Counter() {co…

【速写】Transformer-encoder-decoder深度解析

文章目录 一、理论分析1. Transformers概述2. Transformer的输入部分具体是如何构成?2.1 单词 Embedding2.2 位置 Embedding 3 自注意力原理3.1 自注意力结构3.2 QKV的计算3.3 自注意力的输出3.4 多头注意力 4 Encoder结构4.1 AddNorm4.2 前馈4.3 组成Encoder 二、代…

MyBatis八股文-执行流程、延迟加载、一级与二级缓存

(一)执行流程 mybatis-config.xml核心配置文件的作用: 在MyBatis框架的核心配置文件中需要去指定当前的环境配置、指定需要操作的是哪个数据库,并且输入当前的用户名与密码,只有配置了他才能真正操作数据库。同时还去加载了SQL映射文件&#…

基于Spark的哔哩哔哩舆情数据分析系统

【Spark】基于Spark的哔哩哔哩舆情数据分析系统 (完整系统源码开发笔记详细部署教程)✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 本项目基于Python和Django框架进行开发,为了便于广大用户针对舆情进行个性化分析处…

【Linux】日志模块实现详解

📢博客主页:https://blog.csdn.net/2301_779549673 📢博客仓库:https://gitee.com/JohnKingW/linux_test/tree/master/lesson 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正! &…

Java基础:面向对象高级(四)

内部类(类中五大成分之一) 四种形式 成员内部类【了解】 静态内部类【了解】 局部内部类【了解】 匿名内部类【重点】 枚举 泛型 什么是泛型 泛型类-模拟ArrayList 泛型接口-操作学生,老师增删改查 泛型方法 泛型擦除和注意事项

easy-poi 一对多导出

1. 需求: 某一列上下两行单元格A,B值一样且这两个单元格, 前面所有列对应单元格值一样的话, 就对A,B 两个单元格进行纵向合并单元格 1. 核心思路: 先对数据集的国家,省份,城市...... id 身份证进行排序…

python通过调用海康SDK打开工业相机(全流程)

首先打开海康机器人-机器视觉-下载中心 下载最新版的 MVS 安装后打开目录找到 ...\MVS\Development\Samples\Python 将MvImport内所有文件拷贝至工作目录 然后到 C:\Program Files (x86)\Common Files\MVS\Runtime 找到适合自己系统的版本,将整个文件夹拷贝至工…

manim,制作专业的数学公式动画

manim是一个Python第三方库,全称是mathematical animation engine(数学动画引擎)。manim用于解说线性代数、微积分、神经网络、黎曼猜想、傅里叶变换以及四元数等数学概念。 manim使你能够以编程的方式创建精确的数学图形、动画和场景。与传统的几何画板等绘图软件不同,man…

小刚说C语言刷题——第15讲 多分支结构

1.多分支结构 所谓多分支结构是指在选择的时候有多种选择。根据条件满足哪个分支,就走对应分支的语句。 2.语法格式 if(条件1) 语句1; else if(条件2) 语句2; else if(条件3) 语句3; ....... else 语句n; 3.示例代码 从键盘输入三条边的长度,…

[ctfshow web入门] web6

前置知识 入口点(目录)爆破 还记得之前说过网站的入口的吗,我们输入url/xxx,其中如果url/xxx存在,那么访问成功,证明存在这样一个入口点;如果访问失败则证明不存在此入口点。所以我们可以通过遍历url/xxx,…

简单程序语言理论与编译技术·22 实现一个从AST到RISCV的编译器

本文是记录专业课“程序语言理论与编译技术”的部分笔记。 LECTURE 22(实现一个从AST到RISCV的编译器) 一、问题分析 1、完整的编译器(如LLVM)需先完成AST到IR的转换,并进行代码优化,再到汇编&#xff0…

lua和C的交互

1.C调用lua例子 #include <iostream> #include <lua.hpp>int main() {//用于创建一个新的lua虚拟机lua_State* L luaL_newstate();luaL_openlibs(L);//打开标准库/*if (luaL_dofile(L, "test.lua") ! LUA_OK) {std::cerr << "Lua error: &…