基于STM32-Socket-Qt 遥控小车(一代)

news2024/11/26 18:37:39

文章目录

  • 一、项目分析
    • 1. 项目简介
    • 2. 知识储备
    • 3. 硬件选择
  • 二、STM32部分
  • 三、QT部分
  • 四、遥控小车演示
    • 程序源码


一、项目分析

1. 项目简介

本项目本质为客户端与服务器之间的通信,通过发送不同的指令,服务器和客户端进行不同的操作。

客户端:基于STM32制作简单行驶小车
服务器:安卓手机,基于Socket编程下 用QT进行安卓开发,将app传输到手机上。
TCP通信:ESP8266

手机端发送不同指令,小车执行不同操作

2. 知识储备

  • STM32基础 可移步 “ STM32专栏 ” 进行知识充能
  • ESP8266WiFi模块 可移步 “ ESP8266WiFi模块的基本通信 ” 学习使用
  • Socket编程基础 可移步 “ Socket编程基础 ” 学习使用
  • QT_Socket_TCP 可移步 “ QT_Socket_tcp通信 ” 学习使用
  • QT_Android环境搭建 可移步 “ QT Android环境搭建 ” 学习使用

3. 硬件选择

1. esp8266WiFi模块
在这里插入图片描述
2. 直流电机
(笔者这里用编码器电机代替,普通直流电机即可)
在这里插入图片描述

3. STM32F103C8T8
在这里插入图片描述
4. 驱动电机模块
(笔者这里用的是TB6612,L298N啥的都行)
在这里插入图片描述
5. 烧写器 ST-Link
在这里插入图片描述
6. 安卓手机
在这里插入图片描述

7. 电池、杜邦线、螺母、轮胎等等

在这里插入图片描述

二、STM32部分

1. pwm

void TIM3_PWM_Init(u16 per,u16 psc)
{
	/*使能TIM4时钟*/
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
	
	/*使能GPIO*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	
	/*使能AFIO*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
	
	/*配置GPIO*/
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	/*设置重映射*/
	//GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3,ENABLE);//部分重映射	
	
	/*初始化定时器参数*/
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//选择时钟分频为1分频
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//选择计数模式为向上计数
	TIM_TimeBaseInitStructure.TIM_Period = per;//配置周期(ARR自动重装器的值)
	TIM_TimeBaseInitStructure.TIM_Prescaler = psc;//配置PSC预分频器的值
	//TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;//重复计数器的值,高级计数器才需配置
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);
	//TIM_ClearFlag(TIM4,TIM_FLAG_Update);//先清除标志位,避免刚初始化就进入中断
	
	/*初始化PWM参数*/
	TIM_OCInitTypeDef TIM_OCInitStructure;
	TIM_OCInitStructure.TIM_Pulse = 0;
	TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;   //选择空闲状态下的非工作状态 低电平
	TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set;  //选择互补空闲状态下的非工作状态 低电平
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//选择PWM1模式
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//输出极性:高电平有效
	TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;  //输出比较使能
	TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;  //互补输出比较使能
	TIM_OC1Init(TIM3,&TIM_OCInitStructure);
	TIM_OC2Init(TIM3,&TIM_OCInitStructure);
	TIM_OC3Init(TIM3,&TIM_OCInitStructure);
	TIM_OC4Init(TIM3,&TIM_OCInitStructure);
	
	/*使能TIMX在CCRX上的预装载寄存器*/
	TIM_OC1PreloadConfig(TIM3,TIM_OCPreload_Enable);
	TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);
	TIM_OC3PreloadConfig(TIM3,TIM_OCPreload_Enable);
	TIM_OC4PreloadConfig(TIM3,TIM_OCPreload_Enable);
	
	TIM_CtrlPWMOutputs(TIM3,ENABLE);
	
	/*使能TIMX在ARR上的预装载寄存器允许位*/
	//TIM_ARRPreloadConfig(TIM4,ENABLE);
	
	/*开启定时器*/
	TIM_Cmd(TIM3,ENABLE);
}	

2. Car

void forward()
{
	GPIO_SetBits(GPIOB,GPIO_Pin_7| GPIO_Pin_11 | GPIO_Pin_13 | GPIO_Pin_15);
	GPIO_ResetBits(GPIOB,GPIO_Pin_8| GPIO_Pin_10 | GPIO_Pin_12 | GPIO_Pin_14);
}

void back()
{
	GPIO_SetBits(GPIOB,GPIO_Pin_8| GPIO_Pin_10 | GPIO_Pin_12 | GPIO_Pin_14);
	GPIO_ResetBits(GPIOB,GPIO_Pin_7| GPIO_Pin_11 | GPIO_Pin_13 | GPIO_Pin_15);
}

//  PB7,PB8:  右后	 
//	PB14,PB15:右前   
//	PB12,PB13:左前	 
//	PB10,PB11:左后   

void turn_left()
{
	GPIO_SetBits(GPIOB,GPIO_Pin_7| GPIO_Pin_10 | GPIO_Pin_13 | GPIO_Pin_15);
	GPIO_ResetBits(GPIOB,GPIO_Pin_8| GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_14);
}

void turn_left1()
{
	GPIO_SetBits(GPIOB,GPIO_Pin_8| GPIO_Pin_11 | GPIO_Pin_13 | GPIO_Pin_14);
	GPIO_ResetBits(GPIOB,GPIO_Pin_7| GPIO_Pin_10 | GPIO_Pin_12 | GPIO_Pin_15);
}

void turn_right()
{
	GPIO_SetBits(GPIOB,GPIO_Pin_8| GPIO_Pin_11 | GPIO_Pin_13 | GPIO_Pin_15);
	GPIO_ResetBits(GPIOB,GPIO_Pin_7| GPIO_Pin_10 | GPIO_Pin_12 | GPIO_Pin_14);
}

void turn_right1()
{
	GPIO_SetBits(GPIOB,GPIO_Pin_8| GPIO_Pin_10 | GPIO_Pin_12 | GPIO_Pin_15);
	GPIO_ResetBits(GPIOB,GPIO_Pin_7| GPIO_Pin_11 | GPIO_Pin_13 | GPIO_Pin_14);
}

void stop(void)
{
	GPIO_ResetBits(GPIOB,GPIO_Pin_8 | GPIO_Pin_7 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15);
}

3. esp8266

void esp8266_start_trans(void)
{
	//printf("等待初始化\r\n");
	while(esp8266_send_cmd((u8 *)"AT",(u8 *)"OK",20));
	
	//设置工作模式 1:station模式   2:AP模式  3:兼容 AP+station模式
	while(esp8266_send_cmd((u8*)"AT+CWMODE=1",(u8*)"OK",20));
	//printf("设置工作模式成功\r\n");
	
	delay_ms(1000);

	//让模块连接上自己的路由
	while(esp8266_send_cmd((u8*)"AT+CWJAP=\"226\",\"226226226\"",(u8*)"WIFI GOT IP",200));
	//printf("连接路由器成功\r\n");
	delay_ms(1000);
	
	//=0:单路连接模式     =1:多路连接模式
	while(esp8266_send_cmd((u8*)"AT+CIPMUX=0",(u8*)"OK",200)){printf("设置单路连接模式失败\r\n");}
	//printf("设置单路连接模式成功\r\n");
	delay_ms(1000);
	
while(esp8266_send_cmd((u8*)"AT+CIPSTART=\"TCP\",\"192.168.124.66\",8080",(u8*)"OK",500));
	//printf("TCP连接成功\r\n");
	delay_ms(1000);
	
	//是否开启透传模式  0:表示关闭 1:表示开启透传
	esp8266_send_cmd((u8*)"AT+CIPMODE=1",(u8*)"OK",200);
	//printf("开启透传模式\r\n");
	
	esp8266_send_cmd((u8*)"AT+CIPSEND",(u8*)"OK",50);
	//printf("开启透传成功\r\n");
}

4. usart

void USART2_init(u32 bound)
{  
	NVIC_InitTypeDef NVIC_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	// GPIOB时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE); //串口3时钟使能

 	USART_DeInit(USART2);  //复位串口3
		 //USART2_TX   PB10
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PB10
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
  GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PB10
   
    //USART2_RX	  PB11
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
  GPIO_Init(GPIOA, &GPIO_InitStructure);  //初始化PB11
	
	USART_InitStructure.USART_BaudRate = bound;//波特率一般设置为9600;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式
  
	USART_Init(USART2, &USART_InitStructure); //初始化串口	3
  

	USART_Cmd(USART2, ENABLE);                    //使能串口 
	
	//使能接收中断
  USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启中断   
	
	//设置中断优先级
	NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2 ;//抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器
		
	TIM2_Int_Init(1000-1,7200-1);		//10ms中断
	USART2_RX_STA=0;		//清零
	TIM_Cmd(TIM2,DISABLE);			//关闭定时器7

}

5. time2

void TIM2_IRQHandler(void)
{ 	
	if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)//是更新中断
	{	 			   
		USART2_RX_STA|=1<<15;	//标记接收完成
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update  );  //清除TIM2更新中断标志    
		TIM_Cmd(TIM2, DISABLE);  //关闭TIM2 
	}	    
}
 
//通用定时器7中断初始化,这里时钟选择为APB1的2倍
//arr:自动重装值 psc:时钟预分频数
//定时器溢出时间计算方法:Tout=((arr+1)*(psc+1))/Ft us.
//Ft=定时器工作频率,单位:Mhz 
//通用定时器中断初始化 
void TIM2_Int_Init(u16 arr,u16 psc)
{	
	NVIC_InitTypeDef NVIC_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//TIM2时钟使能    
	
	//定时器TIM2初始化
	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位
 
	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE ); //使能指定的TIM2中断,允许更新中断
	
	TIM_Cmd(TIM2,ENABLE);//开启定时器7
	
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;//抢占优先级0
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;		//子优先级2
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器
	
}

6. main

int main(void)
{
	unsigned char*	m=NULL;
	int k1,k2,k3,k4,flag,f1,f2,f3;
	delay_init();	    	 			//延时函数初始化	  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 			//设置NVIC中断分组2:2位抢占优先级,2位响应优先级
	uart_init(115200);	 				//串口初始化为115200
	USART2_init(115200);	 				//串口初始化为115200
	 
	esp8266_quit_trans();
	esp8266_start_trans();							//esp8266进行初始化
	 
	GPIOB_Init();
	
	TIM3_PWM_Init(100-1,72-1);
	int i,j=15;
	flag=1;
	while(1)
	{
		m=WIFI_Rece_Data();	
		if(flag == 1) 
		{
			m[0]='S';
			flag = 0;
		}

		else if(m[0]=='F')  i=0;
		
		else if(m[0]=='L')  i=1;
		
		else if(m[0]=='R')  i=3;
		
		else if(m[0]=='S')  i=5;
		
		else if(m[0]=='B')  i=7;
		
		else if(m[0]=='u'&& m[1]=='p')  i=2;
		
		else if(m[0]=='u'&& m[1]=='d')  i=4;
		
		switch(i)
		{
			case 0:
				f1=1;
				setpwm(j);
				forward();
			  break;
			
			case 1:
				f2=1;
				k1=j-15;
				k2=j+15;
				if(k1<=0) 	k1=0;
				if(k2>=100) k2=100;
				setpwm1(k1,k2);
			
				if(f1==1)  turn_left();	
				if(f1==-1) turn_left1();	
			  break;

			case 3:
				f3=1;
				k3=j+15;
				k4=j-15;
				if(k3>=100) k3=100;
				if(k4<=0) 	k4=0;
				setpwm1(k3,k4);
			
				if(f1==1)  turn_right();
				if(f1==-1) turn_right1();
			  break;

			case 5:
				stop();	
				break;
			
			case 7:
				f1=-1;
				setpwm(j);
				back();
				break;
			
			case 2:
					if(f2==1) 
					{ 
							k1+=2;k2+=10; 
							if(k1>=30) k1=30; 
							if(k2>=100) k2=100; 
							setpwm1(k1,k2);
							delay_ms(20);
							f2=0;
							break;
					} 
					else if(f3==1) 
						{ k3+=10;k4+=2; 
							if(k3>=100) k3=100; 
							if(k4>=30) k4=30; 
							setpwm1(k3,k4);
							delay_ms(20);
							f3=0;
							break;
					} 
					else {
						if(j>=100) j=100;	
						setpwm(j);
						j++;
						delay_ms(50);
						break;
					}
			
			case 4:
					if(f2==1) { k1-=2;k2-=5; if(k1<=0) k1=0; if(k2<=30) k2=30; setpwm1(k1,k2); delay_ms(20);f2=0; break;} 
					else if(f3==1) { k3-=5;k4-=2; if(k3<=30) k3=30; if(k4<=0) k4=0; setpwm1(k3,k4); delay_ms(20); f3=0;break;} 
					else{
							if(j<=0) j=0;
							setpwm(j);
							j--;
							delay_ms(50);
							break;
					}				
		}		
	}
}

三、QT部分

Server

server::server(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::server)
{
    ui->setupUi(this);
    tcpserver=nullptr;
    tcpsocket=nullptr;
    //创建监听套接字
    tcpserver=new QTcpServer(this);//指定父对象 回收空间

    //bind+listen
    tcpserver->listen(QHostAddress::Any,8080);//绑定当前网卡所有的ip 绑定端口 也就是设置服务器地址和端口号

    //服务器建立连接
    connect(tcpserver,&QTcpServer::newConnection,[=](){
        //取出连接好的套接字
        tcpsocket=tcpserver->nextPendingConnection();

        //获得通信套接字的控制信息
        QString ip=tcpsocket->peerAddress().toString();//获取连接的 ip地址
        quint16 port=tcpsocket->peerPort();//获取连接的 端口号
        QString temp=QString("[%1:%2] 客服端连接成功").arg(ip).arg(port);
       //显示连接成功
        ui->textEditRead->setText(temp);
    });
}

void server::on_forward_clicked()
{
    if(tcpsocket==nullptr)  return ;
    QString str="F";
    tcpsocket->write(str.toUtf8().data());
}


void server::on_back_clicked()
{
    if(tcpsocket==nullptr)  return ;
    QString str="B";
    tcpsocket->write(str.toUtf8().data());
}


void server::on_turn_left_clicked()
{
    if(tcpsocket==nullptr)  return ;
    QString str="L";
    tcpsocket->write(str.toUtf8().data());
}


void server::on_turn_right_clicked()
{
    if(tcpsocket==nullptr)  return ;
    QString str="R";
    tcpsocket->write(str.toUtf8().data());
}


void server::on_stop_clicked()
{
    if(tcpsocket==nullptr)  return ;
    QString str="S";
    tcpsocket->write(str.toUtf8().data());
}


void server::on_speed_up_clicked()
{
    if(tcpsocket==nullptr)  return ;
    QString str="up";
    tcpsocket->write(str.toUtf8().data());
}


void server::on_speed_down_clicked()
{
    if(tcpsocket==nullptr)  return ;
    QString str="ud";
    tcpsocket->write(str.toUtf8().data());
}

四、遥控小车演示

基于STM32-Socket-Qt 遥控小车(一代)

程序源码

若需程序源码 可评论区留言QQ邮箱 或 直接私信即可

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

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

相关文章

声学特征提取

声学特征提取流程图 语谱图 语谱图的横坐标是时间&#xff0c;纵坐标是频率&#xff0c;坐标点值为语音数据能量。由于是采用二维平面表达三维信息&#xff0c;所以能量值的大小是通过颜色来表示的&#xff0c;颜色深&#xff0c;表示该点的语音能量越强。 语谱图形成过程 …

zabbix监控Linux

1. 环境配置&#xff1a; 主机名主机地址操作系统角色zabbix192.168.188.201Rocky Linux release 8.6zabbix-servernode1192.168.188.111CentOS7zabbix-agent 2. 配置zabbix客户端&#xff1a; 1>. 下载并安装zabbix客户端&#xff1a; [rootnode1 ~]# wget https://mi…

Ubuntu 22.04安装Cuda11.7和cudnn

安装显卡驱动 打开‘软件和更新。 点击附加驱动安装显卡驱动 如果已经安装显卡驱动&#xff0c;请忽略上面的步骤。 安装gcc 新安装的Ubuntu22.04 没有安装gcc&#xff0c;需要安装gcc。在终端输入gcc -version 查看有没有gcc。 执行命令 sudo apt install gcc安装CUDA …

什么是蜂窝移动网络?

文章目录前言移动网络 vs WIFI蜂窝移动通信网蜂窝网络实现移动上网通信网架构总结前言 本博客仅做学习笔记&#xff0c;如有侵权&#xff0c;联系后即刻更改 科普&#xff1a; 移动网络 vs WIFI 计网课外实验月&#xff0c;我走在宿舍一楼正数着AP有多少个&#xff0c;突然W…

待业将近一个月,晚上11点接到面试邀约电话,我却拒绝了...

前言 一位测试朋友最近一直在找工作&#xff0c;前两天刚拒绝了一个面试。那天晚上11点多&#xff0c;他接到一个HR的面试电话&#xff0c;让他第二天早上10点去公司面试。朋友和HR聊了两句&#xff0c;了解到这位HR经常加班&#xff0c;于是果断拒绝了这个面试。我还为他可惜&…

LongAdder的源码学习与理解

&#x1f468;‍&#x1f4bb;个人主页&#xff1a; 才疏学浅的木子 &#x1f647;‍♂️ 本人也在学习阶段如若发现问题&#xff0c;请告知非常感谢 &#x1f647;‍♂️ &#x1f4d2; 本文来自专栏&#xff1a; Java基础 ❤️ 支持我&#xff1a;&#x1f44d;点赞 &#x1…

Android Studio开发之使用内容组件Content获取通讯信息讲解及实战(附源码 包括添加手机联系人和发短信)

运行有问题或需要源码请点赞关注收藏后评论区留言 一、利用ContentResolver读写联系人 在实际开发中&#xff0c;普通App很少会开放数据接口给其他应用访问。内容组件能够派上用场的情况往往是App想要访问系统应用的通讯数据&#xff0c;比如查看联系人&#xff0c;短信&#…

Linux top命令的cpu使用率和内存使用率

文章目录前言一、cpu使用率1.1 top简介1.2 cpu使用率的来源二、内存使用率2.1 总内存有关的数据2.2 进程使用内存有关的数据2.3 内存使用率的来源三、 pmap参考资料前言 NAMEtop - display Linux processes一、cpu使用率 1.1 top简介 top程序提供当前运行系统的动态实时视图…

网络协议:一文搞懂Socket套接字

本篇内容包括&#xff1a;Socket 套接字的简介、Socket 套接字的分类、Java 中的 Socket 即 java.net.ServerSocket、java.net.Socket 的使用&#xff0c;以及Java 使用套接字 Scoket 编程的Demo。 一、Socket 简介 TCP&#xff08;传输控制协议&#xff09;是一种面向连接的、…

Qt编写跨平台RTSP/RTMP/HTTP视频流播放器

一、前言 很早以前就做过这款播放器的入门版本&#xff0c;最开始用的ffmpeg去解析&#xff0c;后面陆续用vlc播放器、mpv播放器来做&#xff0c;毕竟播放器提供的接口使用也很方便&#xff0c;而且功能强大&#xff0c;后面发现播放器主要的应用场景是播放视频文件&#xff0…

安装配置Anaconda3

1.装anaconda&#xff0c;就不需要单独装python了 2、 下载Anaconda Anaconda | Anaconda Distribution 3、 安装Anaconda 其他默认 4、配置Anaconda环境变量 此电脑——属性——高级系统设置——环境变量——path——编辑——新建 C:\ProgramData\Anaconda3 C:\ProgramDa…

mybatis 自动化处理 mysql 的json类型字段 终极方案

文章目录mybatis 自动化处理 mysql 的json类型字段 终极方案mysql 建表 json 字段&#xff0c;添加1条json 数据对应的java对象 JsonEntitymybatis&#xff0c;不使用 通用mapper手动自定义1个类型处理器&#xff0c;专门处理 JsonNode 和Json 的互相转化将 自定义的类型处理器…

Java笔记(十二)

文献种类&#xff1a;专题技术总结文献 开发工具与关键技术&#xff1a; IntelliJ IDEA、Java 语言 作者&#xff1a; 方建恒 年级&#xff1a; 2020 撰写时间&#xff1a; 2022 年 11 月 8 日 Java笔记(十二) 今天我给大家继续分享一下我的Java笔记&#xff0c; 我们继续来了…

使用前缀和数组解决“区间和查询“问题

本文已收录到 GitHub AndroidFamily&#xff0c;有 Android 进阶知识体系&#xff0c;欢迎 Star。技术和职场问题&#xff0c;请关注公众号 [彭旭锐] 进 Android 面试交流群。 前言 大家好&#xff0c;我是小彭。 今天分享到一种非常有趣的数据结构 —— 前缀和数组。前缀和…

每日一题|2022-11-8|1684. 统计一致字符串的数目|哈希表|Golang

1684. 统计一致字符串的数目 思路1:丢人做法 哈希记录allowed&#xff0c;暴力遍历words所有字母&#xff0c;如果有不在哈希表里的&#xff0c;计数。最后用words的长度减去 计数 就行。 func countConsistentStrings(allowed string, words []string) int {has1 : make(map[…

如何判断一段程序是否是裸机程序?

在嵌入式MCU领域&#xff0c;一般将不移植操作系统直接烧录运行的程序称为裸机程序。 一般来说&#xff0c;非易失性存储&#xff0c;时钟&#xff0c;图形显示&#xff0c;网络通讯&#xff0c;用户I/O设备…都需要硬件依赖。 基于硬件基础&#xff0c;内存管理、文件系统、…

【API部署】fastapi与nuitka打包py项目

提示&#xff1a;分两部分&#xff1a;fastapi接口调用&#xff0c;与nuitka快速打包 功能&#xff1a;作为一名算法工程师&#xff0c;训练机器学习模型只是为客户提供解决方案的一部分。 除了生成和清理数据、选择和调整算法之外&#xff0c;还需交付和部署结果&#xff0c;…

130道基础OJ编程题之: 29 ~ 38 道

130道基础OJ编程题之: 29 ~ 38 道 文章目录130道基础OJ编程题之: 29 ~ 38 道0. 昔日OJ编程题:29. BC23 时间转换30. BC24 总成绩和平均分计算31. BC30 KiKi和酸奶32. BC31 发布信息33. BC3 输出学生信息34. BC33 计算平均成绩35. BC34 进制AB36. BC37 网购37.BC39 争夺前五名38…

【谷粒商城】

一、项目介绍 1.微服务架构图 2.微服务划分图 二、环境搭建 1.虚拟机搭建环境 这里我买了华为云&#xff0c;没用虚拟机 华为云配置 2.Linux 安装docker docker文档&#xff1a;https://docs.docker.com/engine/install/centos/ # 1. 卸载之前的dockersudo yum remove d…

[MySql]初识数据库与常见基本操作

专栏简介 :MySql数据库从入门到进阶. 题目来源:leetcode,牛客,剑指offer. 创作目标:记录学习MySql学习历程 希望在提升自己的同时,帮助他人,,与大家一起共同进步,互相成长. 学历代表过去,能力代表现在,学习能力代表未来! 文章目录 前言 1.初识数据库 1.1 数据库概述 1.2 数据库…