/*********焊管机切割控制程序************/
/***L667 CODE3565 2026 8 29 IAP15W413AS*/
/*********位置 启动 自动 手动***********/
/*********电机 气缸 手动 自动***********/
#include <REG52.H> // cutting 切割
#include <intrins.h> //
#include <string.h> //
#include "stdio.h" //
#define uint unsigned int //
#define uchar unsigned char //
sfr INT_CLKO=0x8F; //外部中断2 P3.6 扩展寄存器
#define CMD_IDLE 0 //空闲模式
#define CMD_READ 1 //IAP字节读命令
#define CMD_PROGRAM 2 //IAP字节编程命令
#define CMD_ERASE 3 //IAP扇区擦除命令
#define ENABLE_IAP 0x83 // SYSCLK < 12MHz
#define IAP_ADDRESS 0x1200 // 选择一段不会与用户程序重叠的 Flash 地址
typedef unsigned char BYTE; //Catch_Up接上Catch_Dwon接下
typedef unsigned int WORD;
bit Signauto=0; /*退出循环检测*/
bit Rst_Bit=0; /**/
bit MODE_FLAG; /*工作模式*/
bit AutoCut_FLAG; //自动切割
bit ManualCut_FLAG; //手动切割
bit TableBack_FLAG; //台板退到位
sbit Motor=P2^6; //电机
sbit Cutting_dwon=P2^7; //切割机下降
sbit Manual=P1^0; //手动指示
sbit Automatic=P1^1; //自动指示
sbit OUT2=P1^2; //台板
sbit OUTA=P1^3; //备用
sbit OUTB=P1^5; //时间,模式 位置模式 指示
sbit OUT0=P1^6; //手动循环信号指示
sbit OUT1=P1^7; //定时中断 指示
// sbit INTPUT0=P3^5; //气缸退
// sbit INTPUT1=P3^3; //自动P3^3
// sbit INTPUT2=P3^2; //手动P3^2
// sbit INTPUT3=P3^4; //临时切割3^4
// sbit INTPUT4=P3^5; //定长切割3^5
sbit INTPUT0=P3^2; //定长红外信号
sbit INTPUT1=P3^3; //临时切割
sbit INTPUT2=P3^4; //手动
sbit INTPUT3=P3^5; //自动
sbit INTPUT4=P3^6; //气缸退到位
uint Ad_data;
uint Run_TIME; //
uint DELAY_A,DELAY_B,DELAY_C; //切割延时
uint MODEMARK;
uint aa=0; /****RUN FLAG****/
uint a[10]; //定义数组a
uchar i; //串口接收计数器
uchar k; //信号输入高电平计数器
uint counter; //产量计数器
bit Receive_Flag; //串口接收标志
bit Run_Flag; //自动运行标志
uint FLAG_S; //触摸屏显示标志
uchar kcounter,kstatus; //按键计数标志 按键状态标志
/*----关闭IAP----------------------------*/
void IapIdle()
{
IAP_CONTR = 0; //关闭IAP功能
IAP_CMD = 0; //清除命令寄存器
IAP_TRIG = 0; //清除触发寄存器
IAP_ADDRH = 0x80; //将地址设置到非IAP区域
IAP_ADDRL = 0;
}
/*-从ISP/IAP/EEPROM区域读取一字节-*/
BYTE IapReadByte(WORD addr)
{
BYTE dat; //数据缓冲区
IAP_CONTR = ENABLE_IAP; //使能IAP
IAP_CMD = CMD_READ; //设置IAP命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_(); //等待ISP/IAP/EEPROM操作完成
dat = IAP_DATA; //读ISP/IAP/EEPROM数据
IapIdle(); //关闭IAP功能
return dat; //返回
}
/*-写一字节数据到ISP/IAP/EEPROM区域-*/
void IapProgramByte(WORD addr, BYTE dat)
{
IAP_CONTR = ENABLE_IAP; //使能IAP
IAP_CMD = CMD_PROGRAM; //设置IAP命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_DATA = dat; //写ISP/IAP/EEPROM数据
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_(); //等待ISP/IAP/EEPROM操作完成
IapIdle();
}
/*---扇区擦除---------------*/
void IapEraseSector(WORD addr)
{
IAP_CONTR = ENABLE_IAP; //使能IAP val=IapReadByte(IAP_ADDRESS+1);
IAP_CMD = CMD_ERASE; //设置IAP命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_(); //等待ISP/IAP/EEPROM操作完成
IapIdle();
}
/*------------------------------------------*/
void delay(uint t)
{
uint i,j;
for(i=0;i<t;i++)
for(j=0;j<1000;j++);
}
/*-----------(1)延时子程序12MHz 加千百十个显示--------*/
void Delay100ms(uint x) //
{
uint i,j;
for(i=0;i<x;i++)
for(j=0;j<11000;j++);
}
/********************************************/
void resrt_io()
{
FLAG_S=1; //1待 机2切 割
printf("va0.val=%d\xff\xff\xff",FLAG_S); //
Motor=1; //电机关
Cutting_dwon=1; //切割机下降
OUTA=1; //
OUTB=1; //
Manual=0; //手动指示
Automatic=1; //自动指示
}
/****************按键计数器状态寄存器归零*************/
void RstKey()
{
kcounter=0; //按键计数器归零
kstatus=0; //状态寄存器归零
}
/*****************按键低电平检测函数*****************/
void LowVoltKey(void) //按键计数器状态标志加一
{
kcounter++;
kstatus++;
}
/*****************按键高电平检测函数*****************/
void HighVoltKey(void) //按键计数器加一 状态标志归零
{
kcounter++; //按键计数器加一
kstatus=0; //按键状态标志归零
}
/******************************************/
void red_eeprom(void)
{
uint m,n;
m=IapReadByte(IAP_ADDRESS); //时间前八位
n=IapReadByte(IAP_ADDRESS+1); //时间后八位
DELAY_A=m*256+n; //排气一段延时时间
m=IapReadByte(IAP_ADDRESS+2); //时间前八位
n=IapReadByte(IAP_ADDRESS+3); //时间后八位
DELAY_B=m*256+n; //排气一段延时时间
MODEMARK=IapReadByte(IAP_ADDRESS+4);//工作模式
DELAY_C=IapReadByte(IAP_ADDRESS+5);//电机启动后延时切割
}
/******************************************/
void Write_EepromTime()
{
IapEraseSector(IAP_ADDRESS); //扇区擦除
IapProgramByte(IAP_ADDRESS,DELAY_A/256); // 高位
IapProgramByte(IAP_ADDRESS+1,DELAY_A%256); // 低位
IapProgramByte(IAP_ADDRESS+2,DELAY_B/256); // 高位
IapProgramByte(IAP_ADDRESS+3,DELAY_B%256); // 低位
IapProgramByte(IAP_ADDRESS+4,MODEMARK); // 工作模式
IapProgramByte(IAP_ADDRESS+5,DELAY_C%256); // 电机启动后延时切割
}
/*****************************************/
/***产量 工作模式 自动手动 启动Run_TIME***/
void start()
{
Manual=1; //手动指示
Automatic=0; //自动指示
Run_TIME=0; //初始化
if(MODE_FLAG==1) //
{
/*一:启动无输入为1,永久循环*/
FLAG_S=2; // 位置模式
printf("va2.val=%d\xff\xff\xff",FLAG_S); //定时器刷新标志
do
{ //INTPUT3 启动信号
if(ManualCut_FLAG==1) //手动临时切割标志
{
ManualCut_FLAG=0;
FLAG_S=2; //1待 机2切 割
printf("va0.val=%d\xff\xff\xff",FLAG_S); //定时器刷新标志
Motor=0; //电机开
Delay100ms(DELAY_C); //电机启动后延时切割
Cutting_dwon=0; //切割机下降
Delay100ms(DELAY_B);
Motor=1; //电机关
Delay100ms(10); //延时1秒
OUT2=0; //台板返回
TableBack_FLAG=1; //台板退标志
Cutting_dwon=1; //切割机上升
FLAG_S=1; //1待 机2切 割
printf("va0.val=%d\xff\xff\xff",FLAG_S); //定时器刷新标志
Delay100ms(100); //延时 启动按键释放
}
//INTPUT3 临时切割
if(AutoCut_FLAG==1) //按键低电平
{
AutoCut_FLAG=0;
FLAG_S=2; //1待 机2切 割
printf("va0.val=%d\xff\xff\xff",FLAG_S); //定时器刷新标志
Motor=0; //电机开
Delay100ms(DELAY_C); //电机启动后延时切割
Cutting_dwon=0; //切割机下降
Delay100ms(DELAY_B);
Motor=1; //电机关
Delay100ms(10); //延时1秒
OUT2=0; //台板返回
TableBack_FLAG=1; //台板退标志
//
Cutting_dwon=1; //切割机上升
FLAG_S=1; //1待 机2切 割
printf("va0.val=%d\xff\xff\xff",FLAG_S); //定时器刷新标志
counter++; //产量加1
printf("n0.val=%d\xff\xff\xff",counter); //产量计数
Delay100ms(100); //延时 启动按键释放
}
//INTPUT4 定长切割
RstKey(); //
for(;kcounter<5;) //按键循环5次
{
if(!INTPUT2) //手动按键低电平 INTPUT2=P3^4
{
LowVoltKey(); //按键低电平 计数器加一状态标志加一
}
else if(~!INTPUT2) //手动按键高电平
{
HighVoltKey(); //按键计数器加一 状态标志归零
}
}
if(kstatus>=3) /*按键状态标志大于等于3为有效值*/
{
FLAG_S=1; //1待 机2切割
printf("va0.val=%d\xff\xff\xff",FLAG_S); //
FLAG_S=1; //1手 动2自 动
printf("va1.val=%d\xff\xff\xff",FLAG_S); //va1触摸屏变量 发送第一次
resrt_io();
Signauto=0; /*行程输入信号连续检测到3次Signauto=0退出循环*/
Run_Flag=0;
break;
}
//手动退出位置循环
}
while(Run_Flag);
}
//位置模式
else
{
FLAG_S=1; //时间模式
printf("va2.val=%d\xff\xff\xff",FLAG_S); //定时器刷新标志
do
{
Delay100ms(10);
Run_TIME++;
printf("n3.val=%d\xff\xff\xff",Run_TIME); //计时器显示
RstKey();
for(;kcounter<5;) //按键循环5次
{
if(!INTPUT3) //按键低电平
{
LowVoltKey(); //按键低电平 计数器加一状态标志加一
}
else if(~!INTPUT3) //按键高电平
{
HighVoltKey(); //按键计数器加一 状态标志归零
}
}
if(kstatus>=3) /*按键状态标志大于等于3为有效值*/
{
FLAG_S=2; //1待 机2切 割
printf("va0.val=%d\xff\xff\xff",FLAG_S); //定时器刷新标志
Motor=0; //电机开
Delay100ms(DELAY_C); //电机启动后延时切割
Cutting_dwon=0; //切割机下降
Delay100ms(DELAY_B);
Motor=1; //电机关
Cutting_dwon=1; //切割机上升
FLAG_S=1; //1待 机2切 割
printf("va0.val=%d\xff\xff\xff",FLAG_S); //定时器刷新标志
Run_TIME=0; //临时切割 计时器归零
}
if(Run_TIME>=DELAY_A)
{
FLAG_S=2; //1待 机2切 割
printf("va0.val=%d\xff\xff\xff",FLAG_S); //定时器刷新标志
Motor=0; //电机开
Delay100ms(DELAY_C); //电机启动后延时切割
Cutting_dwon=0; //切割机下降
Delay100ms(DELAY_B);
Motor=1; //电机关
Cutting_dwon=1; //切割机上升
FLAG_S=1; //1待 机2切 割
printf("va0.val=%d\xff\xff\xff",FLAG_S); //定时器刷新标志
Run_TIME=0; //计时器归零
counter++; //产量加1
printf("n0.val=%d\xff\xff\xff",counter);//产量计数
}
RstKey(); //
for(;kcounter<5;) //按键循环5次
{
if(!INTPUT2) //手动按键低电平
{
LowVoltKey(); //按键低电平 计数器加一状态标志加一
}
else if(~!INTPUT2) //手动按键高电平
{
HighVoltKey(); //按键计数器加一 状态标志归零
}
}
if(kstatus>=3) /*按键状态标志大于等于3为有效值*/
{
FLAG_S=1; //1待 机2切割
printf("va0.val=%d\xff\xff\xff",FLAG_S); //
Delay100ms(2);
FLAG_S=1; //1手 动2自 动
printf("va1.val=%d\xff\xff\xff",FLAG_S); //va1触摸屏变量 发送第一次
Run_TIME=0; //计时器归零
printf("n4.val=%d\xff\xff\xff",Run_TIME);//计时器归零
resrt_io();
Signauto=0; /*行程输入信号连续检测到3次Signauto=0退出循环*/
Run_Flag=0;
break;
}
}
while(Run_Flag);
}
//时间模式
}
/*------------初始化串口---------------------*/
void InitUart()
{
SCON=0X50; //8位数据,可变波特率
AUXR|=0x01; //串口1选择定时器2为波特率发生器
AUXR|=0X04; //定时器2时钟为Fosc,即1T
T2L=0XE0; //设置定时器处置 110592》9600
T2H=0XFE; //设置定时器处置 110592》9600
AUXR|=0X10; //启动定时器2
TI=1;
ES=1; //
EA=1;
}
/*×--------UART 中断服务程序-------------------**/
/**×**把接收到的数据存进数组a[i]**i开机初始化****/
/***×*接收到触摸屏结束码Receive_Flag标志位置1****/
void Uart() interrupt 4 using 1
{
if(RI)
{
if(SBUF==0XFA) //触摸屏结束码
{
Receive_Flag=1; //接收数据标志置一
RI=0; //
i=0; //数组计数器归零
}
else
{
a[i]=SBUF; //数组下标位置的数据等于SBUF
RI=0; //
i++;
}
}
}
/**************定时中断*************************/
void timer0() interrupt 1
{
TH0=0X53;
TL0=0X32;
aa++;
if(aa>=300)
{
OUT1=~OUT1;
aa=0;
}
}
//---------外部中断0服务程序 红外检测位置到-----------
void Exint0_Routine(void) interrupt 0 // INT0中断入口(中断号0)
{
uchar j,q;
for(;j<8;) //按键循环5次
{
if(!INTPUT0) //按键低电平
{
j++;
q++;
}
else if(~!INTPUT0) //按键高电平
{
j++;
q=0;
}
if(q>6) //按键低电平
AutoCut_FLAG=1;
else
AutoCut_FLAG=0;
}
}
//----------外部中断1服务程序 手动临时切割-------------------
void Exint1_Routine(void) interrupt 2 // INT1中断入口(中断号2)
{
uchar j,q;
for(;j<8;) //按键循环5次
{
if(!INTPUT1) //按键低电平
{
j++;
q++;
}
else if(~!INTPUT1) //按键高电平
{
j++;
q=0;
}
if(q>6) //按键低电平
ManualCut_FLAG=1;
else
ManualCut_FLAG=0;
}
}
//----------外部中断2服务程序 气缸退到位-------------------
void Exint2_Routine(void) interrupt 10 // INT2中断入口(中断号10)
{
uchar j,q;
if(TableBack_FLAG==1) //台板退
{
for(;j<8;) //按键循环8次
{
if(!INTPUT4) //按键低电平 P3^6;
{
j++;
q++;
}
else if(~!INTPUT4) //按键高电平
{
j++;
q=0;
}
if(q>6) //检测有效值
{
OUT2=1; //台板
TableBack_FLAG=0; //台板退到位
}
}
}
}
/*************************************************/
//E0 00 循环时间
//E0 01 切割时间
//B0 00 显示参数
//printh F0 00 00 00 00 00 FA 电机开启
//printh F0 01 00 00 00 00 FA 电机关闭
//printh F0 02 00 00 00 00 FA 切割开启
//printh F0 03 00 00 00 00 FA 切割关闭
void main( ) /*主程序开始*/
{
INTPUT0=1; //定长红外信号 P3.2
INTPUT1=1; //临时切割 P3.3
INTPUT4=1; //气缸退到位 P3.6
AutoCut_FLAG=0; //自动切割
ManualCut_FLAG=0; //手动切割
TableBack_FLAG=0; //台板退到位
AUXR=0X80; //STC系列的1T 设置
TMOD=0X01;
TH0=0X53;
TL0=0X32;
ET0=1;
TR0=1;
P_SW1=0x00; //RXD/P3.0, TXD/P3.1
/* 4. 开启中断 */
EX0=1; /* 允许INT0中断 */
EX1=1; /* 允许INT1中断 */
IT0 = 1; //设置INT0的中断类型 (1:仅下降沿 0:上升沿和下降沿)
EX0 = 1; //使能INT0中断
IT1 = 1; //设置INT1的中断类型 (1:仅下降沿 0:上升沿和下降沿)
EX1 = 1; //使能INT1中断
INT_CLKO |= 0x10; //(EX2 = 1)使能INT2中断
Receive_Flag=0;
delay(20);
InitUart(); //初始化串口
resrt_io();
Delay100ms(20);
red_eeprom(); //
printf("XFF,XFF,XFF"); //
if(MODEMARK==0X55) //工作模式
{
MODE_FLAG=0; // 时间模式
FLAG_S=1; // 时间模式
printf("va2.val=%d\xff\xff\xff",FLAG_S); //定时器刷新标志
}
else //
{
MODE_FLAG=1; // 位置模式
FLAG_S=2; // 位置模式
printf("va2.val=%d\xff\xff\xff",FLAG_S); //定时器刷新标志
} //
i=0; //数据接收计数器等于0
Run_Flag=0; //自动标志等于0
counter=0; //产量归零
printf("n0.val=%d\xff\xff\xff",counter); // 产量计数
printf("n0.val=%d\xff\xff\xff",counter); // 产量计数
printf("n1.val=%d\xff\xff\xff",DELAY_A); // 延时切割时间
printf("n2.val=%d\xff\xff\xff",DELAY_B); // 切割时间
printf("n4.val=%d\xff\xff\xff",DELAY_C);//切割时间 校对
printf("n5.val=%d\xff\xff\xff",MODEMARK);//切割时间 校对
while(1)
{
OUT0=~OUT0; //手动循环信号指示
Delay100ms(20);
////////////////////////////////
RstKey(); //按键复位
for(;kcounter<5;) //按键循环5次
{
if(!INTPUT3) //自动 INTPUT3 P3^5;按键低电平
{
LowVoltKey();
}
else if(~!INTPUT3) //按键高电平
{
HighVoltKey();
}
}
if(kstatus>=4) /*按键状态标志大于等于3为有效值*/
{ /*循环检测 */
Run_Flag=1; //自动运行标志
}
//自动
if(Receive_Flag==1) //串口数据更新标志
{
Receive_Flag=0;
if(a[0]==0XE0) //EEPROM参数存储
{
OUT0=0; //写EEPROM指示
if(a[1]==0X00)
{
DELAY_A=a[3]*256+a[2]; //延时切割时间
}
else if(a[1]==0X01)
{
DELAY_B=a[3]*256+a[2]; //延时切割时间
}
else if(a[1]==0X02)
{
DELAY_C=a[3]*256+a[2]; //延时切割时间
}
Write_EepromTime();
red_eeprom();
printf("n1.val=%d\xff\xff\xff",DELAY_A);//切割循环时间 校对
printf("n1.val=%d\xff\xff\xff",DELAY_A);//切割循环时间 校对
printf("n2.val=%d\xff\xff\xff",DELAY_B);//切割时间 校对
printf("n4.val=%d\xff\xff\xff",DELAY_C);//切割时间 校对
printf("n5.val=%d\xff\xff\xff",MODEMARK);//切割时间 校对
}
//
else if(a[0]==0XB0) //B0 00发送主画面 内容
{
if(a[1]==0X00) //
{
red_eeprom();
printf("n1.val=%d\xff\xff\xff",DELAY_A);//切割循环时间 校对
printf("n1.val=%d\xff\xff\xff",DELAY_A);//切割循环时间 校对
printf("n2.val=%d\xff\xff\xff",DELAY_B);//切割时间 校对
printf("n4.val=%d\xff\xff\xff",DELAY_C);//切割时间 校对
printf("n5.val=%d\xff\xff\xff",MODEMARK);//切割时间 校对
if(MODEMARK==0X55) //工作模式
{
MODE_FLAG=0; // 时间模式
FLAG_S=1; // 时间模式
printf("va2.val=%d\xff\xff\xff",FLAG_S); //定时器刷新标志
}
else //
{
MODE_FLAG=1; // 位置模式
FLAG_S=2; // 位置模式
printf("va2.val=%d\xff\xff\xff",FLAG_S); //定时器刷新标志
} //
}
if(a[1]==0X01) //
{
if(MODE_FLAG==0) // 时间模式
{
FLAG_S=1;
printf("r0.val=%d\xff\xff\xff",FLAG_S);//
printf("bt0.val=%d\xff\xff\xff",FLAG_S);//
FLAG_S=0; // 时间模式
printf("r1.val=%d\xff\xff\xff",FLAG_S);//
FLAG_S=1;
printf("n3.val=%d\xff\xff\xff",1);// 时间模式
}
else if(MODE_FLAG==1) // 位置模式
{
FLAG_S=0;
printf("r0.val=%d\xff\xff\xff",FLAG_S);//
printf("bt0.val=%d\xff\xff\xff",FLAG_S);//
FLAG_S=1;
printf("r1.val=%d\xff\xff\xff",FLAG_S);//
FLAG_S=2;
printf("n3.val=%d\xff\xff\xff",2);// 位置模式
}
}
}
//发送参数到触摸屏
else if(a[0]==0XC0) //控制模式
{
if(a[1]==0X00) //
{
OUTB=0;
MODE_FLAG=0; /*时间模式*/
MODEMARK=0X55;
Write_EepromTime();
FLAG_S=1; // 时间模式
printf("va2.val=%d\xff\xff\xff",FLAG_S); //定时器刷新标志
}
else if(a[1]==0X01) //
{
OUTB=1;
MODE_FLAG=1; /*位置模式*/
MODEMARK=0XAA;
Write_EepromTime();
FLAG_S=2; // 时间模式
printf("va2.val=%d\xff\xff\xff",FLAG_S); //定时器刷新标志
}
}
//工作模式
else if(a[0]==0XF0) //B0 00发送主画面 内容
{
if(a[1]==0X00) //电机开启
{
Motor=0;
}
else if(a[1]==0X01) //电机关闭
{
Motor=1;
}
else if(a[1]==0X02) //电机开启
{
Cutting_dwon=0; //切割机下降
}
else if(a[1]==0X03) //电机关闭
{
Cutting_dwon=1; //切割机下降
}
}
}
//
if(Run_Flag==1) //自动运行标志
{
printf("page 0\XFF\XFF\XFF"); //自动界面显示
Manual=1; //手动指示
Automatic=0; //自动指示
FLAG_S=2; //1手 动2自 动
printf("va1.val=%d\xff\xff\xff",FLAG_S); //va1触摸屏变量 发送第一次
Delay100ms(5);
start(); //自动运行循环子程序
}
}
} //L667 CODE3565 2026 8 29
IAP15W413AS焊管机切割控制程序
张小明
前端开发工程师
用 Scrapling 写 Python 爬虫:反爬与多页数据采集实战指南
用 Scrapling 写 Python 爬虫:反爬与多页数据采集实战指南 【免费下载链接】Scrapling 🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl! 项目地址: https://gitcode.com/GitHub_Trend…
Python网页抓取怎么抓各种页面:Scrapling从单个请求到全站爬取的实战教程
Python网页抓取怎么抓各种页面:Scrapling从单个请求到全站爬取的实战教程 【免费下载链接】Scrapling 🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl! 项目地址: https://gitcode.co…
MySQL八股文核心考点:索引、事务与锁的底层原理与面试串讲
说句实话,后端面试刷八股文这件事,本身挺枯燥的。尤其是 MySQL,内容又多又杂,今天问索引,明天问事务,后天问锁,看起来每个知识点都懂一点,但真要你用口头表达讲清楚,很容…
9 个开箱即用的 Godot 扩展模块:一次编译,物理、烘焙与补全当天生效
9 个开箱即用的 Godot 扩展模块:一次编译,物理、烘焙与补全当天生效 【免费下载链接】godot Godot Engine – Multi-platform 2D and 3D game engine 项目地址: https://gitcode.com/GitHub_Trending/go/godot 2D 碰撞抖动,换套物理引…
Hoppscotch API测试工具零基础快速上手:完整安装与配置教程
Hoppscotch API测试工具零基础快速上手:完整安装与配置教程 【免费下载链接】hoppscotch Open-Source API Development Ecosystem • https://hoppscotch.io • Offline, On-Prem & Cloud • Web, Desktop & CLI • Open-Source Alternative to Postman, In…
拼多多面试全流程复盘:算法、项目深挖与场景设计要点
最近刚面完拼多多,趁着记忆还热乎,我把这一整轮PDD面经按流程、按轮次拆开复盘了一遍。整体感受是:节奏比想象中快,算法占比比预期高,问项目时特别看重量化指标,而且每一轮都会留出反问时间。如果你正在准备…