STM32 定时器

目录

TIM

定时器定时中断

定时器外部时钟

PWM驱动LED呼吸灯(OC)

PWM控制舵机

PWMA驱动直流电机

输入捕获模式测频率(IC)

输入捕获模式测占空比

编码器接口测速(编码器接口)


TIM

通用定时器

高级定时器

定时器定时中断

Timer.c

#include "stm32f10x.h"                  // Device header

//extern uint16_t Num;  //使用extern声明外部变量(如果要在文件中使用其他文件中的变量)

/**
  * @brief  定时器中断初始化
  * @param  无
  * @retval 无
  */
void Timer_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//开启RCC时钟
	//TIM2是APB1总线的外设
	
	TIM_InternalClockConfig(TIM2);//选择时基单元时钟
	//TIM2的时基单元就由内部时钟来驱动(定时器上电默认使用内部时钟)
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision =  TIM_CKD_DIV1;
	//设置时钟分频,选择一分频
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	//设置计数器模式,选择向上计数
	TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1;
	//设置周期,即ARR重装值,(0-65535)
	//72000000/10000/7200 = 1s即1Hz
	TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;
	//设置预分频器值(psc),(0-65535)
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	//配置重复计数器值(高级定时器会用到)
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);//配置时基单元
	
    //在TIM_TimeBaseInit函数中,由缓冲寄存器,只有在更新事件时,
    //才会真正起作用,为了让值立刻起作用,手动生成了一个更新事件,
    //此时更新事件以及更新中断是同时发生的,更新中断会将置位标志位,故会进入中断进行中断中的操作
    TIM_ClearFlag(TIM2,TIM_FLAG_Update);//清除中断标志位
    
	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//使能中断输出信号
	//更新中断到NVIC
	
	//配置NVIC
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//NVIC优先级分组
	//选择分组2
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;//配置中断通道
	//TIM2在NVIC的通道
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;//抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//响应优先级
	NVIC_Init(&NVIC_InitStructure);//初始化NVIC
	
	TIM_Cmd(TIM2,ENABLE);//启动定时器
}


/*TIM2中断函数模板
void TIM2_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET)//检查中断标志位
	{
        Num++;
		TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除中断待处理 位
	}
}
*/

main.c

#include "stm32f10x.h"                  // Device header
#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);
	}
	
}

/**
  * @brief  TIM2的中断函数
  * @param  无
  * @retval 无
  */
void TIM2_IRQHandler()
{
	if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET)//检查中断标志位
	{
        Num++;
		TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除中断标志位
	}
}
定时器外部时钟

Timer.c

#include "stm32f10x.h"                  // Device header

//extern uint16_t Num;  //使用extern声明外部变量(如果要在文件中使用其他文件中的变量)

/**
  * @brief  定时器外部时钟中断初始化
  * @param  无
  * @retval 无
  */
void Timer_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//开启TIM2时钟
	//TIM2是APB1总线的外设
	
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//开启GPIO时钟
    
    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);
    
	TIM_ETRClockMode2Config(TIM2,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0x05);
    //通过ETR引脚的外部时钟模式2配置(选择配置时钟,预分频器,选择上升/下降有效,滤波器工作模式)
    //在此之前还需要配置GPIO
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision =  TIM_CKD_DIV1;
	//设置时钟分频,选择一分频
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	//设置计数器模式,选择向上计数
	TIM_TimeBaseInitStructure.TIM_Period = 10 - 1;
	//设置周期,即ARR重装值,(0-65535)
	//72000000/10000/7200 = 1s即1Hz
	TIM_TimeBaseInitStructure.TIM_Prescaler = 1 - 1;
	//设置预分频器值(psc),(0-65535)
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	//配置重复计数器值(高级定时器会用到)
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);//配置时基单元
	
    //在TIM_TimeBaseInit函数中,由缓冲寄存器,只有在更新事件时,
    //才会真正起作用,为了让值立刻起作用,手动生成了一个更新事件,
    //此时更新事件以及更新中断是同时发生的,更新中断会将置位标志位,故会进入中断进行中断中的操作
    TIM_ClearFlag(TIM2,TIM_FLAG_Update);//清除中断标志位
    
	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//使能中断输出信号
	//更新中断到NVIC
	
	//配置NVIC
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//NVIC优先级分组
	//选择分组2
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;//配置中断通道
	//TIM2在NVIC的通道
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;//抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//响应优先级
	NVIC_Init(&NVIC_InitStructure);//初始化NVIC
	
	TIM_Cmd(TIM2,ENABLE);//启动定时器
}

uint16_t Timer_GetCounter(void)
{
    return TIM_GetCounter(TIM2);
}

/*TIM2中断函数模板
void TIM2_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET)//检查中断标志位
	{
        Num++;
		TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除中断待处理 位
	}
}
*/

main.c

#include "stm32f10x.h"                  // Device header
#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);
	}
	
}

/**
  * @brief  TIM2的中断函数
  * @param  无
  * @retval 无
  */
void TIM2_IRQHandler()
{
	if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET)//检查中断标志位
	{
        Num++;
		TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除中断标志位
	}
}

PWM驱动LED呼吸灯(OC)

PWM.c

#include "stm32f10x.h"                  // Device header

/**
  * @brief  初始化PWM波形
  * @param  无
  * @retval 无
  */
void PWM_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	//第一步:使用RCC开启GPIO时钟
	GPIO_InitTypeDef  GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	//GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;//重映射到PA^15引脚
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	//第二步:使用GPIO_Init()初始化GPIO
	
	//端口重映射
	//RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//开启AFIO时钟
	//GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2,ENABLE);//设置重映射
	//GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);//解除JTAG复用,保留SWD复用
	
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//开启RCC时钟
	//TIM2是APB1总线的外设
	
	TIM_InternalClockConfig(TIM2);//选择时基单元时钟
	//TIM2的时基单元就由内部时钟来驱动(定时器上电默认使用内部时钟)
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//初始化时基单元
	TIM_TimeBaseInitStructure.TIM_ClockDivision =  TIM_CKD_DIV1;
	//设置时钟分频,选择一分频
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	//设置计数器模式,选择向上计数
	TIM_TimeBaseInitStructure.TIM_Period = 100 - 1;
	//设置周期,即ARR重装值,(0-65535)
	TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1;
	//设置预分频器值(psc),(0-65535)
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	//配置重复计数器值(高级定时器会用到)
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);//配置时基单元
	TIM_OCInitTypeDef TIM_OCInitstructure;//含有高级定时器参数
	TIM_OCStructInit(&TIM_OCInitstructure);//为结构体赋初始值
	TIM_OCInitstructure.TIM_OCMode = TIM_OCMode_PWM1;//输出比较模式
	TIM_OCInitstructure.TIM_OCPolarity = TIM_OCPolarity_High;//输出比较极性
	TIM_OCInitstructure.TIM_OutputState = TIM_OutputState_Enable;//设置输出使能
	TIM_OCInitstructure.TIM_Pulse = 0;//设置CCR
	//PWM频率 = 72MHz/PSC+1/ARR+1
	//PWM占空比 = CCR/ARR+1
	//PWM分辨率 = 1/(ARR+1)
	//1Hz = 1s
	TIM_OC1Init(TIM2,&TIM_OCInitstructure);//初始化输出比较单元(PA^0对应TIM_OC1Init)
	
	TIM_Cmd(TIM2,ENABLE);//启动定时器
}

/**
  * @brief  设置通道1中CCR的值
  * @param  被设定的CCR的值 
  * @retval 无
  */
void PWM_SetCompare1(uint16_t Compare)
{
	TIM_SetCompare1(TIM2,Compare);
	
}

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "PWM.h"

uint8_t KeyNum;

int main(void)
{
	OLED_Init();
	PWM_Init();
	uint8_t tmp;
	
	while(1)
	{
		for(tmp = 0;tmp <= 100;tmp++)
		{
			PWM_SetCompare1(tmp);
			Delay_ms(10);
		}
		for(tmp = 0;tmp <= 100;tmp++)
		{
			PWM_SetCompare1(100 - tmp);
			Delay_ms(10);
		}
	}
	
}

PWM控制舵机

PWM.c

#include "stm32f10x.h"                  // Device header

/**
  * @brief  初始化PWM波形
  * @param  无
  * @retval 无
  */
void PWM_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	//第一步:使用RCC开启GPIO时钟
	GPIO_InitTypeDef  GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	//第二步:使用GPIO_Init()初始化GPIO
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//开启RCC时钟
	//TIM2是APB1总线的外设
	
	TIM_InternalClockConfig(TIM2);//选择时基单元时钟
	//TIM2的时基单元就由内部时钟来驱动(定时器上电默认使用内部时钟)
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//初始化时基单元
	TIM_TimeBaseInitStructure.TIM_ClockDivision =  TIM_CKD_DIV1;
	//设置时钟分频,选择一分频
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	//设置计数器模式,选择向上计数
	TIM_TimeBaseInitStructure.TIM_Period = 20000 - 1;
	//设置周期,即ARR重装值,(0-65535)
	TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1;//这里可以得出频率为50Hz,
    //周期为0.02s,已知需要高电平0.5ms~2.5ms,周期X占空比=0.5ms,占空比为0.025
    //那么CCR = 500 ~ 2500
	//设置预分频器值(psc),(0-65535)
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	//配置重复计数器值(高级定时器会用到)
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);//配置时基单元
	TIM_OCInitTypeDef TIM_OCInitstructure;//含有高级定时器参数
	TIM_OCStructInit(&TIM_OCInitstructure);//为结构体赋初始值
	TIM_OCInitstructure.TIM_OCMode = TIM_OCMode_PWM1;//输出比较模式
	TIM_OCInitstructure.TIM_OCPolarity = TIM_OCPolarity_High;//输出比较极性
	TIM_OCInitstructure.TIM_OutputState = TIM_OutputState_Enable;//设置输出使能
	TIM_OCInitstructure.TIM_Pulse = 0;//设置CCR
	//PWM频率 = 72MHz/PSC+1/ARR+1
	//PWM占空比 = CCR/ARR+1
	//PWM分辨率 = 1/(ARR+1)
	//1Hz = 1s
	TIM_OC2Init(TIM2,&TIM_OCInitstructure);//初始化输出比较单元(PA^1对应TIM_OC2Init,见引脚定义表)
	
	TIM_Cmd(TIM2,ENABLE);//启动定时器
}

/**
  * @brief  设置通道2中CCR的值
  * @param  被设定的CCR的值 
  * @retval 无
  */
void PWM_SetCompare2(uint16_t Compare)
{
	TIM_SetCompare2(TIM2,Compare);
	
}

Servo.c

#include "stm32f10x.h"                  // Device header
#include "PWM.h"

/**
  * @brief  初始化PWM
  * @param  无
  * @retval 无
  */
void Servo_Init(void)
{
    PWM_Init(); 
}

/**
  * @brief  设置转动角度
  * @param  Angle 转动角度
  * @retval 无
  */
void Servo_SetAngle(float Angle)
{
    PWM_SetCompare2(Angle / 180 * 2000 + 500);//0   500;180    2500
}

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Servo.h"
#include "Key.h"

uint8_t KeyNum;
float Angle;

int main(void)
{
	OLED_Init();
	Servo_Init();
    Key_Init();
    
    OLED_ShowString(1,1,"Angle:");
	
	while(1)
	{
		KeyNum = Key_GetNum();//此前在Key.c中已初始化PB^1故能读出数据
        if(KeyNum == 1)
        {
            Angle += 30;
            if(Angle > 180)
            {
                Angle = 0;
            }
        }
        Servo_SetAngle(Angle);
        OLED_ShowNum(2,1,Angle,3);
	}
	
}

PWMA驱动直流电机

PWM.c

#include "stm32f10x.h"                  // Device header

/**
  * @brief  初始化PWM波形
  * @param  无
  * @retval 无
  */
void PWM_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	//第一步:使用RCC开启GPIO时钟
	GPIO_InitTypeDef  GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;//接在PA^3上
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	//第二步:使用GPIO_Init()初始化GPIO

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//开启RCC时钟
	//TIM2是APB1总线的外设
	
	TIM_InternalClockConfig(TIM2);//选择时基单元时钟
	//TIM2的时基单元就由内部时钟来驱动(定时器上电默认使用内部时钟)
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//初始化时基单元
	TIM_TimeBaseInitStructure.TIM_ClockDivision =  TIM_CKD_DIV1;
	//设置时钟分频,选择一分频
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	//设置计数器模式,选择向上计数
	TIM_TimeBaseInitStructure.TIM_Period = 100 - 1;
	//设置周期,即ARR重装值,(0-65535)
	TIM_TimeBaseInitStructure.TIM_Prescaler = 36 - 1;
	//设置预分频器值(psc),(0-65535)
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	//配置重复计数器值(高级定时器会用到)
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);//配置时基单元
	TIM_OCInitTypeDef TIM_OCInitstructure;//含有高级定时器参数
	TIM_OCStructInit(&TIM_OCInitstructure);//为结构体赋初始值
	TIM_OCInitstructure.TIM_OCMode = TIM_OCMode_PWM1;//输出比较模式
	TIM_OCInitstructure.TIM_OCPolarity = TIM_OCPolarity_High;//输出比较极性
	TIM_OCInitstructure.TIM_OutputState = TIM_OutputState_Enable;//设置输出使能
	TIM_OCInitstructure.TIM_Pulse = 0;//设置CCR
	//PWM频率 = 72MHz/PSC+1/ARR+1
	//PWM占空比 = CCR/ARR+1
	//PWM分辨率 = 1/(ARR+1)
	//1Hz = 1s
	TIM_OC3Init(TIM2,&TIM_OCInitstructure);//初始化输出比较单元(PA^2对应TIM_3C1Init)
	
	TIM_Cmd(TIM2,ENABLE);//启动定时器
}

/**
  * @brief  设置通道1中CCR的值
  * @param  被设定的CCR的值 
  * @retval 无
  */
void PWM_SetCompare3(uint16_t Compare)
{
	TIM_SetCompare3(TIM2,Compare);
	
}

Motor.c

#include "stm32f10x.h"                  // Device header
#include "PWM.h"

/**
  * @brief  初始化电机方向控制脚以及PMW
  * @param  无
  * @retval 无
  */
void Motor_Init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	//第一步:使用RCC开启GPIO时钟
	
	GPIO_InitTypeDef  GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
    //第二步:初始化电机方向控制脚
    
    PWM_Init();
}

/**
* @brief  设置电机运行速度,为负时为反转
  * @param  Speed   电机运行速度
  * @retval 无
  */
void Motor_SetSpeed(int8_t Speed)
{
    if(Speed >= 0)//正转 
    {
        GPIO_SetBits(GPIOA,GPIO_Pin_4);
        GPIO_ResetBits(GPIOA,GPIO_Pin_5);
        PWM_SetCompare3(Speed);
    }else{//反转
        GPIO_SetBits(GPIOA,GPIO_Pin_5);
        GPIO_ResetBits(GPIOA,GPIO_Pin_4);
        PWM_SetCompare3(-Speed);
    }
}

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Motor.h"
#include "Key.h"

uint8_t KeyNum;
int8_t Speed;

int main(void)
{
	OLED_Init();
	Motor_Init();
    Key_Init();
	
    OLED_ShowString(1,1,"Speed:");
    
	while(1)
	{
		KeyNum = Key_GetNum();
        if(KeyNum == 1)
        {
            Speed += 20;
            if(Speed > 60)
            {
                Speed = -60;
            }
        }
         Motor_SetSpeed(Speed);
         OLED_ShowSignedNum(2,1,Speed,3);
	}
	
}

注意:这里尽量不要满速,跑一下,香味就出来了

输入捕获模式测频率(IC)

PWM.c

#include "stm32f10x.h"                  // Device header

/**
  * @brief  初始化PWM波形
  * @param  无
  * @retval 无
  */
void PWM_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	//第一步:使用RCC开启GPIO时钟
	GPIO_InitTypeDef  GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	//GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;//重映射到PA^15引脚
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	//第二步:使用GPIO_Init()初始化GPIO
	
	//端口重映射
	//RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//开启AFIO时钟
	//GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2,ENABLE);//设置重映射
	//GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);//解除JTAG复用,保留SWD复用
	
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//开启RCC时钟
	//TIM2是APB1总线的外设
	
	TIM_InternalClockConfig(TIM2);//选择时基单元时钟
	//TIM2的时基单元就由内部时钟来驱动(定时器上电默认使用内部时钟)
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//初始化时基单元
	TIM_TimeBaseInitStructure.TIM_ClockDivision =  TIM_CKD_DIV1;
	//设置时钟分频,选择一分频
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	//设置计数器模式,选择向上计数
	TIM_TimeBaseInitStructure.TIM_Period = 100 - 1;
	//设置周期,即ARR重装值,(0-65535)
	TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1;
	//设置预分频器值(psc),(0-65535)
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	//配置重复计数器值(高级定时器会用到)
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);//配置时基单元
    
	TIM_OCInitTypeDef TIM_OCInitstructure;//含有高级定时器参数
	TIM_OCStructInit(&TIM_OCInitstructure);//为结构体赋初始值
	TIM_OCInitstructure.TIM_OCMode = TIM_OCMode_PWM1;//输出比较模式
	TIM_OCInitstructure.TIM_OCPolarity = TIM_OCPolarity_High;//输出比较极性
	TIM_OCInitstructure.TIM_OutputState = TIM_OutputState_Enable;//设置输出使能
	TIM_OCInitstructure.TIM_Pulse = 0;//设置CCR
	//PWM频率 = 72MHz/PSC+1/ARR+1
	//PWM占空比 = CCR/ARR+1
	//PWM分辨率 = 1/(ARR+1)
	//1Hz = 1s
	TIM_OC1Init(TIM2,&TIM_OCInitstructure);//初始化输出比较单元(PA^0对应TIM_OC1Init)
	
	TIM_Cmd(TIM2,ENABLE);//启动定时器
}

/**
  * @brief  设置通道1中CCR的值(占空比)
  * @param  被设定的CCR的值 
  * @retval 无
  */
void PWM_SetCompare1(uint16_t Compare)
{
	TIM_SetCompare1(TIM2,Compare);
}

/**
  * @brief  写入PSC数值(修改频率)
  * @param  被设定的PSC数值
  * @retval 无
  */
void PWM_SetPrescaler(uint16_t Prescaler)
{
    TIM_PrescalerConfig(TIM2,Prescaler,TIM_PSCReloadMode_Immediate);
    //所使用定时器,设定数值,立刻重装载模式
}

IC.c

#include "stm32f10x.h"                  // Device header

/**
  * @brief  输入捕获初始化
  * @param  无
  * @retval 无
  */
void IC_Init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	//第一步:使用RCC开启GPIO时钟
	GPIO_InitTypeDef  GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;//使用TIM3通道1查表为PA^6
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	//第二步:使用GPIO_Init()初始化GPIO
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//开启RCC时钟
	//TIM3是APB1总线的外设(因为TIM2要放出被测的PWM)
	
	TIM_InternalClockConfig(TIM3);//选择时基单元时钟
	//TIM2的时基单元就由内部时钟来驱动(定时器上电默认使用内部时钟)
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//初始化时基单元
	TIM_TimeBaseInitStructure.TIM_ClockDivision =  TIM_CKD_DIV1;
	//设置时钟分频,选择一分频
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	//设置计数器模式,选择向上计数
	TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1;
	//设置周期,即ARR重装值,(0-65535)
	TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1;
	//设置预分频器值(psc),(0-65535)
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	//配置重复计数器值(高级定时器会用到)
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);//配置时基单元
    
    TIM_ICInitTypeDef IC_InitStructure;
    IC_InitStructure.TIM_Channel = TIM_Channel_1 ;//配置通道1
    IC_InitStructure.TIM_ICFilter = 0xF ;//配置输入捕获滤波器
    IC_InitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising ;//配置极性(上升沿触发)
    IC_InitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1 ;//配置触发信号分频器(不分频)
    IC_InitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI ;//配置数据选择器(直连)
    TIM_ICInit(TIM3,&IC_InitStructure);
    
    TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);//配置TRGI
    
    TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);//配置从模式
    
    TIM_Cmd(TIM3,ENABLE);//启动定时器
}

uint32_t IC_GetFreq(void)
{
    return 1000000 / (TIM_GetCapture1(TIM3) + 1); //1M是当前TIM3频率
    //待测PWM的频率为1000Hz,
}

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "PWM.h"
#include "IC.h"

int main(void)
{
	OLED_Init();
	PWM_Init();
    IC_Init();
    
    OLED_ShowString(1,1,"Freq:00000Hz");
    
    PWM_SetPrescaler(720 - 1);//设置PSC   Freq = 72MHz / (PSC + 1) / (ARR + 1)
    PWM_SetCompare1(50);//设置CCR  Duty(占空比) =  CCR / (ARR + 1)
    
	while(1)
	{
		OLED_ShowNum(1,6,IC_GetFreq(),5);
	}
	
}

输入捕获模式测占空比

IC.c

#include "stm32f10x.h"                  // Device header

/**
  * @brief  输入捕获初始化
  * @param  无
  * @retval 无
  */
void IC_Init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	//第一步:使用RCC开启GPIO时钟
	GPIO_InitTypeDef  GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;//使用TIM3通道1查表为PA^6
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	//第二步:使用GPIO_Init()初始化GPIO
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//开启RCC时钟
	//TIM3是APB1总线的外设(因为TIM2要放出被测的PWM)
	
	TIM_InternalClockConfig(TIM3);//选择时基单元时钟
	//TIM2的时基单元就由内部时钟来驱动(定时器上电默认使用内部时钟)
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//初始化时基单元
	TIM_TimeBaseInitStructure.TIM_ClockDivision =  TIM_CKD_DIV1;
	//设置时钟分频,选择一分频
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	//设置计数器模式,选择向上计数
	TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1;
	//设置周期,即ARR重装值,(0-65535)
	TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1;
	//设置预分频器值(psc),(0-65535)
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	//配置重复计数器值(高级定时器会用到)
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);//配置时基单元
    
    TIM_ICInitTypeDef IC_InitStructure;
    IC_InitStructure.TIM_Channel = TIM_Channel_1 ;//配置通道1
    IC_InitStructure.TIM_ICFilter = 0xF ;//配置输入捕获滤波器
    IC_InitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising ;//配置极性(上升沿触发)
    IC_InitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1 ;//配置触发信号分频器(不分频)
    IC_InitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI ;//配置数据选择器(直连)
    //TIM_ICInit(TIM3,&IC_InitStructure);
    TIM_PWMIConfig(TIM3,&IC_InitStructure);//会自动把剩下的一个通道(1或2)初始化成相反的配置
    
    TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);//配置TRGI
    
    TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);//配置从模式
    
    TIM_Cmd(TIM3,ENABLE);//启动定时器
}

/**
  * @brief  获取频率
  * @param  无
  * @retval 返回被测端口频率
  */
uint32_t IC_GetFreq(void)
{
    return 1000000 / (TIM_GetCapture1(TIM3) + 1); //1M是当前TIM3频率
    //待测PWM的频率为1000Hz,
}

/**
  * @brief  获取占空比
  * @param  无
  * @retval 返回被测端口占空比
  */
uint32_t IC_GetDuty(void)
{
    return (TIM_GetCapture2(TIM3)+1) * 100 / (TIM_GetCapture1(TIM3) + 1);
    //通道二存储有效电平计次,通道一存储整个周期计次
}

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "PWM.h"
#include "IC.h"

int main(void)
{
	OLED_Init();
	PWM_Init();
    IC_Init();
    
    OLED_ShowString(1,1,"Freq:00000Hz");
    OLED_ShowString(2,1,"Duty:000%");
    
    PWM_SetPrescaler(7200 - 1);//设置PSC   Freq = 72MHz / (PSC + 1) / (ARR + 1)
    PWM_SetCompare1(80);//设置CCR  Duty(占空比) =  CCR / (ARR + 1)
    
	while(1)
	{
		OLED_ShowNum(1,6,IC_GetFreq(),5);
        OLED_ShowNum(2,6,IC_GetDuty(),3);
	}
	
}

编码器接口测速(编码器接口)

Ecoder.c

#include "stm32f10x.h"                  // Device header

/**
  * @brief  对GPIO,时基单元,TIM捕获配置以及定时器编码器接口进行初始化
  * @param  无
  * @retval 无
  */
void Encoder_Init(void)
{
    //打开各自RCC时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
    
    //GPIO配置
    GPIO_InitTypeDef GPIO_InitStructrue;
    GPIO_InitStructrue.GPIO_Mode = GPIO_Mode_IPU ;//设置上拉输入
    //如果外部空闲模块默认输出高电平,就选择上拉输入,默认输入高电平
    //如果外部空闲模块默认输出低电平,就选择下拉输入,默认输入低电平
    //和外部模块保持状态一致,防止默认电平打架。
    //如果不确定外部模块输出的默认状态或外部信号输出功率非常小,这时候选择浮空输入
    //浮空输入:没有上拉电阻和下拉电阻去影响外部信号,但缺点是当引脚悬空时,
    //没有默认的电平了,输入就会收噪声干扰,来回不断的跳变
    GPIO_InitStructrue.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 ;
    GPIO_InitStructrue.GPIO_Speed = GPIO_Speed_50MHz ;
    GPIO_Init(GPIOA,&GPIO_InitStructrue);
    
    //时基单元配置
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1;//ARR
    TIM_TimeBaseInitStructure.TIM_Prescaler = 1 - 1 ;//PSC(不进行分频)
    TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);
    
    //输入捕获配置
    TIM_ICInitTypeDef  TIM_ICInitStructure;
    TIM_ICStructInit(&TIM_ICInitStructure);//为结构体赋初始值
    TIM_ICInitStructure.TIM_Channel = TIM_Channel_1 ;
    TIM_ICInitStructure.TIM_ICFilter = 0xf;
    //TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
    //这里的极性选择不代表上升沿有效,这里代表的是高低电平极性不翻转(也就是TI1与TI2是否反向)
    //上升沿不反向,下降沿反向
    TIM_ICInit(TIM3,&TIM_ICInitStructure);
    
    TIM_ICInitStructure.TIM_Channel = TIM_Channel_2 ;
    TIM_ICInitStructure.TIM_ICFilter = 0xf;
    //TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
    //这里的极性选择不代表上升沿有效,这里代表的是高低电平极性不翻转(也就是TI1与TI2是否反向)
    //上升沿不反向,下降沿反向(后面编码器接口会进行重复配置)
    TIM_ICInit(TIM3,&TIM_ICInitStructure);
    
    //配置编码器接口
    TIM_EncoderInterfaceConfig(TIM3,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising);
    
    TIM_Cmd(TIM3,ENABLE);//启动定时器
}

/**
  * @brief  返回TIM3在1s的时间下CNT的值
  * @param  无
  * @retval 无
  */
int16_t Encoder_Get(void)
{
    int16_t tmp;
    tmp = TIM_GetCounter(TIM3);
    TIM_SetCounter(TIM3,0);//读取cnt并将其置零,用于测频法测频率以及测速
    return tmp;
}

Timer.c

#include "stm32f10x.h"                  // Device header

//extern uint16_t Num;  //使用extern声明外部变量(如果要在文件中使用其他文件中的变量)

/**
  * @brief  定时器中断初始化
  * @param  无
  * @retval 无
  */
void Timer_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//开启RCC时钟
	//TIM2是APB1总线的外设
	
	TIM_InternalClockConfig(TIM2);//选择时基单元时钟
	//TIM2的时基单元就由内部时钟来驱动(定时器上电默认使用内部时钟)
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision =  TIM_CKD_DIV1;
	//设置时钟分频,选择一分频
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	//设置计数器模式,选择向上计数
	TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1;
	//设置周期,即ARR重装值,(0-65535)
	//72000000/10000/7200 = 1s即1Hz
	TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;
	//设置预分频器值(psc),(0-65535)
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	//配置重复计数器值(高级定时器会用到)
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);//配置时基单元
	
    //在TIM_TimeBaseInit函数中,由缓冲寄存器,只有在更新事件时,
    //才会真正起作用,为了让值立刻起作用,手动生成了一个更新事件,
    //此时更新事件以及更新中断是同时发生的,更新中断会将置位标志位,
    //故会进入中断进行中断中的操作
    TIM_ClearFlag(TIM2,TIM_FLAG_Update);//清除中断标志位
    
	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//使能中断输出信号
	//更新中断到NVIC
	
	//配置NVIC
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//NVIC优先级分组
	//选择分组2
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;//配置中断通道
	//TIM2在NVIC的通道
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;//抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//响应优先级
	NVIC_Init(&NVIC_InitStructure);//初始化NVIC
	
	TIM_Cmd(TIM2,ENABLE);//启动定时器
}


/*TIM2中断函数模板
void TIM2_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET)//检查中断标志位
	{
        Num++;
		TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除中断待处理 位
	}
}
*/

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Timer.h"
#include "Encoder.h"

int16_t Speed;

int main(void)
{
	OLED_Init();
    Timer_Init();
	Encoder_Init();
    
	OLED_ShowString(1,1,"Speed:");
	
	while(1)
	{
		OLED_ShowSignedNum(1,7,Speed,5);
        //Delay_ms(1000);//防止阻塞将其移动至定时器中断进行配置
	}
	
}

/**
  * @brief  TIM2的中断函数(1s)
  * @param  无
  * @retval 无
  */
void TIM2_IRQHandler()
{
	if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET)//检查中断标志位
	{
        Speed = Encoder_Get();
		TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除中断标志位
	}
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CentOS7集群配置免密登录

准备工作 提前开启三台虚拟机hadoop102、hadoop103,hadoop104,关于三台虚拟机的安装可以参考&#xff1a;https://mp.csdn.net/mp_blog/creation/editor/136010108 配置免密登录 一、分别修改三台机器的hosts,配置主机映射关系 vim /etc/hosts 文件中输入以下内容&#xf…

【C语言期末】商品管理系统

本文资源&#xff1a;https://download.csdn.net/download/weixin_47040861/88820155 1.题目要求 商品管理系统 商品信息包括&#xff1a;包括编号、类别、名称、价格、折扣比例、生产时间 、存货数量等要求&#xff1a;1、信息首先保存在文件中&#xff0c;然后打开文件进行…

AcWing 1240 完全二叉树的权值(双指针)

[题目概述] 给定一棵包含 N 个节点的完全二叉树&#xff0c;树上每个节点都有一个权值&#xff0c;按从上到下、从左到右的顺序依次是 A 1 , A 2 , ⋅ ⋅ ⋅ A N A_1,A_2,⋅⋅⋅A_N A1​,A2​,⋅⋅⋅AN​&#xff0c;如下图所示&#xff1a; 现在小明要把相同深度的节点的权值…

Python pandas中read_csv函数的io参数

前言 在数据分析和处理中&#xff0c;经常需要读取外部数据源&#xff0c;例如CSV文件。Python的pandas库提供了一个强大的 read_csv() 函数&#xff0c;用于读取CSV文件并将其转换成DataFrame对象&#xff0c;方便进一步分析和处理数据。在本文中&#xff0c;将深入探讨 read…

Android 移动应用开发 创建第一个Android项目

文章目录 一、创建第一个Android项目1.1 准备好Android Studio1.2 运行程序1.3 程序结构是什么app下的结构res - 子目录&#xff08;所有图片、布局、字AndroidManifest.xml 有四大组件&#xff0c;程序添加权限声明 Project下的结构 二、开发android时&#xff0c;部分库下载异…

VitePress-13- 配置-title的作用详解

作用描述 1、title 是当前站点的标题&#xff1b;2、默认值是 &#xff1a;VitePress&#xff1b;3、当使用默认主题时&#xff0c;会直接展示在 页面的【导航条】中&#xff1b;4、一个特殊的作用 &#xff1a; 会作为单个页面的默认标题后缀&#xff01;除非又指定了【title…

EMC学习笔记(二十三)降低EMI的PCB设计指南(三)

双层板电源分配 1.单点与多点分布2.星型分布3.创建网格平面4.旁路和磁珠5.将噪声保持在芯片附近 tips&#xff1a;资料主要来自网络&#xff0c;仅供学习使用。 1.单点与多点分布 在一个真正的单点配电系统中&#xff0c;每个有源元件都有自己独立的电源和地&#xff0c;这些…

ChatGPT高效提问—prompt常见用法(续篇八)

ChatGPT高效提问—prompt常见用法(续篇八) 1.1 对抗 ​ 对抗是一个重要主题,深入探讨了大型语言模型(LLM)的安全风险。它不仅反映了人们对LLM可能出现的风险和安全问题的理解,而且能够帮助我们识别这些潜在的风险,并通过切实可行的技术手段来规避。 ​ 截至目前,网络…

DVWA-old (老版本)csrf

csrf lowmedium low 打开burp抓包&#xff0c;发现是get请求&#xff0c;尝试在burp中修改密码&#xff0c;发下可以直接修改成功 根据url地址栏中的信息构造链接 &#xff0c;将此链接放在.html为后缀的文件并将此文件放在本地www目录下&#xff0c;在保持登陆状态点击此链接…

【维生素C语言】附录:strlen 函数详解

写在前面&#xff1a;本篇将专门为 strlen 函数进行讲解&#xff0c;总结了模拟实现 strlen 函数的三种方法&#xff0c;并对其进行详细的解析。手写库函数是较为常见的面试题&#xff0c;希望通过本篇博客能够加深大家对 strlen 的理解。 0x00 strlen函数介绍 【百度百科】str…

如何将 Hexo 部署到 GitHub Pages

引言 在数字时代&#xff0c;拥有个人博客是展示自己想法、分享知识和技能的绝佳方式。Hexo 是一个基于 Node.js 的静态博客生成器&#xff0c;它结合了简洁性和功能性&#xff0c;让我们可以轻松地建立并维护一个博客。而 GitHub Pages 提供了一个免费的平台来托管这些静态网站…

4核8G服务器性能怎么样?4核8G12M配置能支持多少人同时访问?

4核8G服务器性能怎么样?4核8G12M配置能支持多少人同时访问&#xff1f;腾讯云轻量4核8G12M轻量应用服务器支持多少人同时在线&#xff1f;通用型-4核8G-180G-2000G&#xff0c;2000GB月流量&#xff0c;系统盘为180GB SSD盘&#xff0c;12M公网带宽&#xff0c;下载速度峰值为…

CSP-202112-2-序列查询新解

CSP-202112-2-序列查询新解 【70分思路】 【暴力枚举】按照题目思路遍历一遍f(x)和g(x)&#xff0c;计算error(A)&#xff0c;时间复杂度为O(N)&#xff0c;时间超限。 #include <iostream> using namespace std; int main() {long long n, N, sum 0;cin >> n …

MNIST数据集介绍及基于Pytorch下载数据集

MNIST数据集介绍及基于Pytorch下载数据集 &#x1f335;文章目录&#x1f335; &#x1f333;引言&#x1f333;&#x1f333;MNIST数据集介绍&#x1f333;&#x1f333;基于Pytorch下载MNIST数据集并可视化&#x1f333;&#x1f333;使用MNIST数据集进行图像分类任务&#x…

Linux操作系统基础(六):Linux常见命令(一)

文章目录 Linux常见命令 一、命令结构 二、ls命令 三、cd命令 四、mkdir命令 五、touch命令 六、rm命令 七、cp命令 八、mv命令 九、cat命令 十、more命令 Linux常见命令 一、命令结构 command [-options] [parameter]说明: command : 命令名, 相应功能的英文单词…

零基础学python之高级编程(1)---面向对象编程及其类的创建

面向对象编程及其类的创建 文章目录 面向对象编程及其类的创建前言一、面向过程编程和面向对象编程的概念1.面向过程编程(Procedural Programming)2.面向对象编程(Object-Oriented Programming&#xff0c;OOP) 二、面向对象编程基础1.初识类(class)和对象调用方法 2.类中的两种…

如何快速搭建springboot项目(新手入门)

一、创建项目 1.1、创建项目 1.2、配置编码 1.3、取消无用提示 1.4、取消无用参数提示 二、添加POM父依赖 <!-- 两种方式添加父依赖或者import方式 --> <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-p…

Java强训day17(选择题编程题)

选择题 编程题 题目1 import java.util.Scanner;public class Main { public static void main(String[] args) {Scanner sc new Scanner(System.in);char[] c1 sc.nextLine().toCharArray();char[] c2 sc.next().toCharArray();//取c2[0]if(c2[0]>A && c2[…

在windows server2016部署域控服务器DC

1.正常配置vmware虚拟机基础环境 2.启动虚拟机&#xff0c;会先到efi network&#xff0c;等待几分钟 3.进入boot manager&#xff0c;选择启动方式&#xff0c;记得提示CD启动的时候需要按回车&#xff0c;不然又会回到这个界面 4.选择安装版本为桌面版&#xff08;开始直接…

Web后端开发:事务与AOP

事务管理 在学习数据库时&#xff0c;讲到&#xff1a;事务是一组操作的集合&#xff0c;它是一个不可分割的工作单位。事务会把所有的操作作为一个整体&#xff0c;一起向数据库提交或者是撤销操作请求&#xff0c;要么同时成功&#xff0c;要么同时失败。 事务的操作主要有三…