蓝牙小车的具体实现

news2024/12/26 11:57:54

title: 蓝牙小车开发时的一些细节
cover: >-
https://tse1-mm.cn.bing.net/th/id/OIP-C.BrSgB91U1MPHGyaaZEqcbwHaEo?w=273&h=180&c=7&r=0&o=5&dpr=1.3&pid=1.7
abbrlink: 842d5faf
date:
tags:

#小车基本运动之最重要的—PWM
##1.PWM(Pulse Width Modulation)脉冲宽度调制是什么?
为何这个PWM(脉冲宽度)如此重要呢?因为在具有惯性的系统中,我们可以通过对一系列脉冲的宽度进行调制,来等效地获得我们所需要的模拟量,经常用于电机控速等领域(属于是常客了)
举一个例子:比如说我的占空比为50%,那么在这个一个PWM的周期内,电机处于高电平的时间是只有周期的一半,低电平默认为0,那么我们计算等效电压—( T(on) * 5v + T(off) * 0v ) / Ts = 等效电压V 所以50%占空比可以等效为2.5v电压
通过这个等效电压的例子,也为我们如何控制电机的速度以及呼吸灯等等一系列工业生产提供了新的思路—通过PWM(即控制占空比)来控制等效电压—从而GPIO配置为复用推挽输出,定时器的四个通道(STM32外设)来控制引脚输出

##2.如何实现PWM?
实现PWM,我们需要用到定时器和OC(输出比较),通过定时器不断计数然后和RCC(参考比较值)不断比较,当计数小于RCC时,输出的电平为高电平,而当计数大于RCC时,输出的电平为低电平—这个过程叫输出比较—然后统计高电平在总的计数期间的比值—占空比。
PWM基本结构
请看此图
我们三步走战略,1.初始化时基单元,2.GPIO串口复用AFIO初始化 3.定时器初始化。 以及知道参数计算的公式:1. PWMFreq = CK_PSC / (PSC+1) / (ARR+1)
2.PWM占空比Duty = CCR / (ARR + 1)
3.PWM分辨率Reso = 1 / (ARR + 1)
##3.PWM代码实现
放在***\Hardware中**那么请看具体代码
这是PWM.h的具体代码

#ifndef __PWM_H__
#define __PWM_H__

void PWM_Init(void);

#endif

这是PWM.c的具体代码

#include "stm32f10x.h"                  // Device header

//1.时基单元
//2.oc输出比较
//3.GPIO初始化

void PWM_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);   //开启TIM4的外部时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//PB6-PB9 开启GPIOB的外部时钟
	
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;  //配置为复用推挽输出,定时器的四个通道来控制引脚输出
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
	GPIO_InitStruct.GPIO_Speed =  GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStruct);
	
//定义时基单元
	TIM_TimeBaseInitTypeDef	TIM_TimeBaseInitStruct;
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; //从0开始向上计数
	TIM_TimeBaseInitStruct.TIM_Period = 100 - 1; //ARR重装值
	TIM_TimeBaseInitStruct.TIM_Prescaler = 36 - 1; //PSC
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0; //高级定时器才有的,我们用不到这里
	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;  //预分频 DIV1是0预分频
	
	TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStruct);
	
	// OC 输出比较  初始化OC比较的属性
	TIM_OCInitTypeDef TIM_OCInitStruct;
	
	//OC1 输出比较通道口1
	TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; //以高电平为有效电平
	TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStruct.TIM_Pulse = 0; //CCR 预期值 CNT 与 CCR进行比较
	TIM_OC1Init(TIM4,&TIM_OCInitStruct);
	
	//oc2
	TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; //以高电平为有效电平
	TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStruct.TIM_Pulse = 0; //CCR 预期值 CNT 与 CCR进行比较
	TIM_OC2Init(TIM4,&TIM_OCInitStruct);
	
	//oc3
	TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; //以高电平为有效电平
	TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStruct.TIM_Pulse = 0; //CCR 预期值 CNT 与 CCR进行比较
	TIM_OC3Init(TIM4,&TIM_OCInitStruct);
	
	//oc4
	TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; //以高电平为有效电平
	TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStruct.TIM_Pulse = 0; //CCR 预期值 CNT 与 CCR进行比较
	TIM_OC4Init(TIM4,&TIM_OCInitStruct);
	
	//在需要不断切换定时器的周期时,而且周期都比较短,  T = 1 / F
//程序员需要通过预加载寄存器配合自动重装载寄存器,来操作定时器 缓存
	TIM_OC1PreloadConfig(TIM4,TIM_OCPreload_Enable);
	TIM_OC2PreloadConfig(TIM4,TIM_OCPreload_Enable);
	TIM_OC3PreloadConfig(TIM4,TIM_OCPreload_Enable);
	TIM_OC4PreloadConfig(TIM4,TIM_OCPreload_Enable);
	TIM_ARRPreloadConfig(TIM4, ENABLE);
	
	TIM_Cmd(TIM4,ENABLE);
}

我们来设置小车的移动和速度。
我们分别将它们命名为Motor.c,Motor.h并放到\Hardware文件中
此为Motor.h

#ifndef __MOTOR_H__
#define __MOTOR_H__

void Motor_Init(void);
void Motor_SetSpeed(uint8_t left_1,uint8_t left_2,uint8_t right_1,uint8_t right_2);
void Motor_Run(uint8_t Speed,uint16_t time);
void Motor_Back(uint8_t Speed,uint16_t time);
void Motor_TurnLeft(uint8_t Speed,uint16_t time);
void Motor_Spin_Left(uint8_t Speed,uint16_t time);
void Motor_TurnRight(uint8_t Speed,uint16_t time);
void Motor_Spin_Right(uint8_t Speed,uint16_t time);
void Motor_Brake(uint16_t time);

#endif

此为Motor.c

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

//机器人初始化
void Motor_Init(void)
{
	PWM_Init();
}


//控制小车轮子的速度,分别设置四个通道的RCC,每两个通道,控制一个轮子
void Motor_SetSpeed(uint8_t left_1,uint8_t left_2,uint8_t right_1,uint8_t right_2)
{
	TIM_SetCompare1(TIM4,left_1);   //TIM_SetCompare是为了改变我们设置在时基单元里的RCC的大小
	TIM_SetCompare2(TIM4,left_2);
	TIM_SetCompare3(TIM4,right_1);
	TIM_SetCompare4(TIM4,right_2);
}

//车子向前开动
void Motor_Run(uint8_t Speed,uint16_t time)
{
	if (Speed > 100)
	{
		Speed = 100;
	}
	else if (Speed < 0)
	{
		Speed = 0;
	}
	Motor_SetSpeed(Speed,0,Speed,0); //可以从输出比较的图看出来
	Delay_ms(time);
	Motor_SetSpeed(0,0,0,0); //最后车子停止运动
}

//车子后退
void Motor_Back(uint8_t Speed,uint16_t time)
{
	if (Speed > 100)
	{
		Speed = 100;
	}
	else if (Speed < 0)
	{
		Speed = 0;
	}
	Motor_SetSpeed(0,Speed,0,Speed); //可以从输出比较的图看出来
	Delay_ms(time);
	Motor_SetSpeed(0,0,0,0); //最后车子停止运动
	
}

//车子左转
void Motor_TurnLeft(uint8_t Speed,uint16_t time)
{
	if (Speed > 100)
	{
		Speed = 100;
	}
	else if (Speed < 0)
	{
		Speed = 0;
	}
	Motor_SetSpeed(0,0,Speed,0); //可以从输出比较的图看出来
	Delay_ms(time);
	Motor_SetSpeed(0,0,0,0); //最后车子停止运动
	
}

//小车左旋转
void Motor_Spin_Left(uint8_t Speed,uint16_t time)
{
		if (Speed > 100)
	{
		Speed = 100;
	}
	else if (Speed < 0)
	{
		Speed = 0;
	}
	Motor_SetSpeed(0,Speed,Speed,0); //可以从输出比较的图看出来
	Delay_ms(time);
	Motor_SetSpeed(0,0,0,0); //最后车子停止运动
}

//车子右转
void Motor_TurnRight(uint8_t Speed,uint16_t time)
{
	if (Speed > 100)
	{
		Speed = 100;
	}
	else if (Speed < 0)
	{
		Speed = 0;
	}
	Motor_SetSpeed(Speed,0,0,0); //可以从输出比较的图看出来
	Delay_ms(time);
	Motor_SetSpeed(0,0,0,0); //最后车子停止运动
	
}
//小车右旋转
void Motor_Spin_Right(uint8_t Speed,uint16_t time)
{
		if (Speed > 100)
	{
		Speed = 100;
	}
	else if (Speed < 0)
	{
		Speed = 0;
	}
	Motor_SetSpeed(Speed,0,0,Speed); //可以从输出比较的图看出来
	Delay_ms(time);
	Motor_SetSpeed(0,0,0,0); //最后车子停止运动
}

//小车刹车
void Motor_Brake(uint16_t time)
{
	Motor_SetSpeed(0,0,0,0);
	Delay_ms(time);
}

#小车的蓝牙模块—Serial(串口)
1.通信的目的:将一个设备的数据传送到另一个设备,扩展硬件系统
2.通信协议:制定通信的规则,通信双方按照协议规则进行数据收发
##串口的性质
USART:
1.引脚—TX和RX 2.双工—全双工(发送双方可以同时收发数据) 3.时钟:异步 4.电平:单端 5.设备:点对点—就是说只能双方进行通信

串口接线是交叉的,蓝牙串口不是独立供电的,所以我们是要将蓝牙模块与stm32连接,以stm32供电给蓝牙。
##USART(串口)性质
1.USART,(Universal Synchronous/Asynchronous Receiver/Transmitte)通用同步/异步收发器
2.USART是STM32内部集成的硬件外设,可根据数据寄存器的一个字节数据自动生成数据帧时序,从TX引脚发送出去,也可以自动接收RX引脚的数据帧时序,拼接为一个字节数据,存放在数据寄存器里
3.自带波特率发生器,最高达4.5Mbits/s
4.可配置数据为长度(8/9),停止位长度(0.5/1/1.5/2)
5.可选校验位(无校验/奇校验/偶校验)
6.支持同步模式,硬件流控制,DMA,智能卡,IrDA,LIN
7.STM32F103C8T6 USART资源:USART1,USART2,USART3 在这里,商家给我指定了串口资源—USART3,所以后面的代码篇用到的都为USART3
##Serial代码篇(\Hardware)
1.Serial.h

#ifndef __SERIAL_H__
#define __SERIAL_H__

//接收数据的结构体
typedef struct
{
	uint8_t Data[100];   //这个是用来接收文本数据的
	uint8_t flag;    //这个是后面main里面判断要用到的
	uint8_t Length;   //接收到的文本数据的大小
	
}MyUsart;

extern MyUsart MYUSART3;
void Serial_Init(void);
#endif

2.Serial.c

#include "stm32f10x.h"                  // Device header
#include "Serial.h"    //在.h文件里面定义的结构体,你需要在这个文件里面引用
MyUsart MYUSART3;

// 1.GPIO的配置
//2.USART的配置
//3.NVIC的配置  接收文本

void Serial_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);   //USART3
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
//GPIO配置
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;   //复用推挽输出 
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStruct.GPIO_Speed =  GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11;
	GPIO_InitStruct.GPIO_Speed =  GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStruct);
	
//NIVC中断配置
	NVIC_InitTypeDef NVIC_InitStruct;   //谁来触发中断
	NVIC_InitStruct.NVIC_IRQChannel = USART3_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2;
	NVIC_Init(&NVIC_InitStruct);
	
	USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);    //配置USART中断如何触发 接收中断
	USART_ITConfig(USART3,USART_IT_IDLE,ENABLE);     //空闲中断
	
	USART_InitTypeDef USART_InitStruct;
	USART_InitStruct.USART_BaudRate = 9600; 
	USART_InitStruct.USART_HardwareFlowControl = DISABLE;
	USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;  //接收和发送
	USART_InitStruct.USART_Parity = USART_Parity_No;  //不校验
	USART_InitStruct.USART_StopBits = 8;
	USART_InitStruct.USART_WordLength = USART_WordLength_8b;
	USART_Init(USART3,&USART_InitStruct);
	
	USART_Cmd(USART3,ENABLE);
}

//中断函数
void USART3_IRQHandler(void)
{
	//接收判断
	if (USART_GetITStatus(USART3,USART_IT_RXNE) == SET)
	{
		USART_ClearITPendingBit(USART3,USART_IT_RXNE);  //清除后为了下一次接收数据做准备
		MYUSART3.Data[MYUSART3.Length++] = USART_ReceiveData(USART3);   //我接收好一次数据后,指针指向新的位置
	}
	if (USART_GetITStatus(USART3,USART_IT_IDLE) == SET)
	{
		MYUSART3.Data[MYUSART3.Length] = '\0';  //字符串的最后一位是'\0'
		MYUSART3.flag = 1;
		MYUSART3.Length = 0;
		USART_ReceiveData(USART3);
	}
	//空闲判断
}

//发送函数

这样,我们便完成了Serial的定义,我们继续再main.c里面完成编码
#蓝牙小车的最终引用

#include "stm32f10x.h"                  // Device header
#include "Serial.h"
#include "Motor.h"
#include <string.h>
#include <stdio.h>
#include "Myu3.h"


int main(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //中断优先级分组分2组
//	Serial_Init();
	USART3_init(9600);
	Motor_Init();
	while(1)
	{
		if (MyUsart3.flag)
		{
			MyUsart3.flag = 0;
			if (strcmp((const char*)MyUsart3.buff,"ONA") == 0)
			{
				Motor_Run(80,100);
			}
			if (strcmp((const char*)MyUsart3.buff,"ONB") == 0)
			{
				Motor_Back(80,100);
			}
			if (strcmp((const char*)MyUsart3.buff,"ONC") == 0)
			{
				Motor_Spin_Left(80,100);
			}
			if (strcmp((const char*)MyUsart3.buff,"OND") == 0)
			{
				Motor_Spin_Right(80,100);
			}
			if (strcmp((const char*)MyUsart3.buff,"ONF") == 0)
			{
				Motor_Brake(100);
			}
			if (strcmp((const char*)MyUsart3.buff,"ONE") == 0)
			{
				Motor_Brake(100);
			}
		}
	}
	
}

#致谢
最后,感谢你阅读完整个Blog,希望我的文章对你有所启发,有所帮助。感谢!

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

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

相关文章

关于Acrel-1000DP光伏监控系统的案例分析-安科瑞 蒋静

摘要&#xff1a;随着全球对可再生能源的需求不断增长&#xff0c;太阳能作为一种清洁、可持续的能源技术&#xff0c;得到了越来越广泛的应用。本项目通过在屋顶安装光伏组件&#xff0c;将太阳能转化为电能&#xff0c;然后通过逆变器将直流电转换为交流电&#xff0c;将电能…

振弦式表面应变计怎么安装

振弦式表面应变计是一种用于测量结构表面应变的高精度传感器&#xff0c;广泛应用于工程和科研领域。正确安装振弦式表面应变计对于确保测量结果的准确性至关重要。以下是安装振弦式表面应变计的步骤和注意事项&#xff1a; 1. 准备工作 在开始安装前&#xff0c;需要准备以下工…

【Linux】磁盘文件

思维导图 学习目标 了解磁盘的物理结构和存储结构&#xff0c;并将其存储结构进行抽象&#xff01;&#xff01; 一、了解一下磁盘及其物理结构 1.1 计算机只认识二进制 什么是二进制&#xff1f;&#xff1f;0&#xff0c;1是被规定出来的&#xff0c;在计算机里面我们用高低…

巩固学习6

正则表达式 又称规则表达式&#xff0c;Regular Expression&#xff0c;在代码中常简写为regex、regexp或RE&#xff09;&#xff0c;是一种文本模式&#xff0c;包括普通字符&#xff08;例如&#xff0c;a到z之间的字母&#xff09;和特殊字符&#xff08;称为“元字符”&…

革新机器人任务规划:TREE-PLANNER引领高效、准确的机器人动作生成新趋势

DeepVisionary 每日深度学习前沿科技推送&顶会论文分享&#xff0c;与你一起了解前沿深度学习信息&#xff01; 引言 任务规划在机器人技术中扮演着至关重要的角色。它涉及到为机器人设计一系列中级动作&#xff08;技能&#xff09;&#xff0c;使其能够完成复杂的高级任…

Scratch四级:第08讲 排序算法

第08讲 排序算法 教练&#xff1a;老马的程序人生 微信&#xff1a;ProgrammingAssistant 博客&#xff1a;https://lsgogroup.blog.csdn.net/ 讲课目录 常考的排序算法项目制作&#xff1a;“三个数排序”项目制作&#xff1a;“成绩查询”项目制作&#xff1a;“排序”项目制…

微信小程序发送订阅消息sendMessage

微信小程序发送订阅消息sendMessage 请注意订阅消息一次性订阅只只能授权一次接受一条消息多次授权会累加接受次数&#xff0c;wx.requestSubscribeMessage调用授权 目前长期性订阅消息仅向政务民生、医疗、交通、金融、教育等线下公共服务开放 //授权弹框&#xff0c;只弹出…

【Redis7】10大数据类型之Stream类型

文章目录 1. Stream简介2. 生产消息命令(XADD)3. 查询相关命令3.1 获取指定范围内的消息(XRANGE)3.2 逆序获取指定范围内的消息(XREVRANGE)3.3 返回消息的数量(XLEN) 4. 删除消息命令(XDEL)5. 截取消息命令(XTRIM)6. 消费消息命令(XREAD)7. 消费者组管理命令7.1 创建消费者组(X…

给centos机器打个样格式化挂载磁盘(新机器)

文章目录 一、先安装lvm2二、观察磁盘三、磁盘分区四、建PV五、建VG六、创建LV七、在LV上创建文件系统八、挂载到/home&#xff08;1&#xff09;临时挂载&#xff08;2&#xff09;永久挂载 九、最后reboot一下 一、先安装lvm2 yum install lvm2二、观察磁盘 三、磁盘分区 四…

Springboot + xxlJob注意事项

1. 部署 就是这个地址: https://gitee.com/xuxueli0323/xxl-job 由于xxl-job的思想是 调度中心负责调度任务,然后有执行器负责接受调度的信息,然后根据调度,执行任务中的具体逻辑 将 xl-job-admin 启动起来,操作xl-job-admin这个文件夹下的配置文件即可: 创建数据库 执行sql…

如何防止公司内部人员有意或无意的把内部核心文件资料泄露,拷贝,打印,上传,社交工具等途径外泄?

防止公司内部人员有意或无意泄露核心文件资料&#xff0c;需要采取一系列综合性的管理和技术措施。 以下是一些有效的策略&#xff1a; 加强员工意识教育&#xff1a;定期举办信息安全培训&#xff0c;提高员工对数据保护的意识&#xff0c;让员工了解数据泄露的风险和后果&…

冯喜运:5.13黄金原油震荡整理是涨还是跌?今日走势分析

【黄金消息面分析】;自5月初以来&#xff0c;黄金和白银一直在享受需求的回归&#xff0c;买家在过去几天加大了力度&#xff0c;一度推动金价重返2370美元上方&#xff0c;白银重返28.5美元上方。不过&#xff0c;经过几天的盘整后&#xff0c;黄金白银价格双双下跌。然而&…

leetcode经典例题之环形队列

P. S.&#xff1a;以下代码均在VS2019环境下测试&#xff0c;不代表所有编译器均可通过。 P. S.&#xff1a;测试代码均未展示头文件stdio.h的声明&#xff0c;使用时请自行添加。 目录 1、题目展示2、问题分析3、完整代码展示4、结语 1、题目展示 在拿到题目时&#xff0c;通…

SSH常用功能介绍-高级功能

一、介绍 SSH&#xff08;Secure Shell&#xff09;是一种用于远程登录和执行命令的网络协议&#xff0c;它提供了加密的连接&#xff0c;保证了数据的安全性。除了基本的远程登录功能外&#xff0c;SSH还提供了许多高级功能&#xff0c;以下是一些常用的高级功能介绍&#xf…

26版SPSS操作教程(高级教程第二十章)

目录 前言 粉丝及官方意见说明 第二十章一些学习笔记 第二十章一些操作方法 神经网络与支持向量机 人工神经网络&#xff08;artificial neural network&#xff0c;ANN&#xff09; 假设数据 具体操作 结果解释 对案例的进一步分析 结果解释 ​编辑 尝试将模型复…

mmdetection在训练自己数据集时候 报错‘ValueError: need at least one array to concatenate’

问题&#xff1a; mmdetection在训练自己数据集时候 报错‘ValueError: need at least one array to concatenate’ 解决方法&#xff1a; 需要修改数据集加载的代码文件&#xff0c;数据集文件在路径configs/base/datasets/coco_detection.py里面&#xff0c;需要增加meta…

水经微图万能版、专业版与企业版的区别?

水经微图&#xff08;以下简称“微图”&#xff09;的版本&#xff0c;主要分为万能版、专业版和企业版三个版本。 什么是万能版&#xff1f; 万能版是指“水经注万能地图下载器”软件功能的授权&#xff0c;虽然该软件已经停止更新&#xff0c;但购买过该软件的用户&#xf…

简单的DbUtils工具类【精细】

目录 单条通用增删改方法 1.创建maven项目&#xff0c;并加载依赖 2.创建数据库连接工具类(Dbutils类) 3.创建一个执行器(SqlExecutor类) 4.通用(增&#xff0c;删&#xff0c;改)方法 1.创建方法 2.创建userInfo实体类 3.创建测试类&#xff0c;测试增&#xff0c;删&#xf…

leetcode-最长公共子序列(二)-103

题目要求 思路 step 1&#xff1a;优先检查特殊情况。 step 2&#xff1a;获取最长公共子序列的长度可以使用动态规划&#xff0c;我们以dp[i][j]dp[i][j]dp[i][j]表示在s1中以iii结尾&#xff0c;s2中以jjj结尾的字符串的最长公共子序列长度。 step 3&#xff1a;遍历两个字…

C++——缺省参数与重载函数

目录 ​前言 一.缺省参数 1.1缺省参数概念 1.2缺省参数分类 注意事项&#xff1a; 二.函数重载 2.1函数重载概念 2.2c支持函数重载原理——命名修饰 前言 本篇文章主要讲述c中有关于缺少参数与函数重载的相关概念与实例&#xff0c;以下是本人拙见&#xff0c;如有错误…