当前位置: 首页 > news >正文

蓝桥杯嵌入式考前模块总结

一.RTC

使用RTC直接再cubeMX中配置启动时钟和日历

如第六届省赛

想要让RTC的秒每隔一秒递增1需要在时钟树界面观察RTC的主频

由于RTC时钟主频为32KHZ将异步预分频计数器的值设为31,将同步预分频计数器的值设为999这样就可以将RTC的时钟信号分频为1HZ达到1秒自增的效果

生成代码首先定义时间,日期结构体

RTC_TimeTypeDef T={0};
RTC_DateTypeDef D={0};

然后使用两个函数得到时间和日期就可以啦

void RTC_proc(void)
{if(uwTick-rtc_tick<100)return ;rtc_tick=uwTick;HAL_RTC_GetTime(&hrtc,&T,RTC_FORMAT_BIN);HAL_RTC_GetDate(&hrtc,&D,RTC_FORMAT_BIN);
}

放在LCD显示

sprintf((char *)lcd_buf,"     T:%02d-%02d-%02d  ",T.Hours,T.Minutes,T.Seconds);LCD_DisplayStringLine(Line8,lcd_buf);

RTC很简单只要记得结构体和获取时间,日期就行要注意的是在RTC函数中要先获取时间然后再获取日期,省赛好像只考过两回没有什么大的区别这里只展示第六届省赛

二.ADC

G4板子有两个ADC一般省赛用的较多的是R37,我们这里展示R37,R38的操作和R37一模一样

在cubemx中选择PB15然后选择ADC2——IN15然后将通道15打开就可以了

u32 r37_value=0;
float r37_volt=0;

然后定义两个变量存放测量值和电压值,注意value要定义成u32不然会导致数据放不下而使得结果出现问题

然后就可以写R37函数了

HAL_ADCEx_Calibration_Start(&hadc2,ADC_SINGLE_ENDED);//开启ADC校验HAL_ADC_Start(&hadc2);//开启ADCr37_value=HAL_ADC_GetValue(&hadc2);//获得valuer37_volt=r37_value*3.3/4096.0;//计算电平

有的省赛题目会要求ADC进行滤波这里我们采用均值滤波

如:

第七届省赛

采用均值滤波法设置一个求和变量

u32 ADC_tick=0;
u32 R37_value=0;
u32 R37_sum=0;
float R37_volt=0;
u8 height=0;

第七届ADC代码展示

void ADC_proc(void)
{if(uwTick-ADC_tick<1000)return ;ADC_tick=uwTick;HAL_ADCEx_Calibration_Start(&hadc2,ADC_SINGLE_ENDED);HAL_ADC_Start(&hadc2);R37_value=HAL_ADC_GetValue(&hadc2);for(int i=0;i<10;i++){R37_sum+=R37_value;}R37_volt=(R37_sum/10.0)*3.3/4096.0;R37_sum=0;height=R37_volt*(100.0/3.3);HAL_ADC_Stop(&hadc2);
}

这里的原理就是用求和均值达到滤波的要求

三.LCD

这个不用多说,直接上内容

以第六届代码为例

首先是LCD的初始化

	LCD_Init();LCD_SetTextColor(White);
LCD_SetBackColor(Black);
LCD_Clear(Black);

这里要注意初始化的位置一定要在

/* USER CODE BEGIN 2 */

这里不然的话就会显示白屏

u8 ui=0;
u8 lcd_buf[50];
void LCD_proc(void)
{if(uwTick-lcd_tick<300)return ;lcd_tick=uwTick;if(ui==0){sprintf((char *)lcd_buf,"     V1:%4.2fV     ",r37_volt);LCD_DisplayStringLine(Line2,lcd_buf);sprintf((char *)lcd_buf,"     K:%.1f     ",K_value);LCD_DisplayStringLine(Line4,lcd_buf);if(led_mode==0)sprintf((char *)lcd_buf,"     LED:%s       ","OFF");elsesprintf((char *)lcd_buf,"     LED:%s       ","ON");LCD_DisplayStringLine(Line6,lcd_buf);sprintf((char *)lcd_buf,"     T:%02d-%02d-%02d  ",T.Hours,T.Minutes,T.Seconds);LCD_DisplayStringLine(Line8,lcd_buf);LCD_DisplayStringLine(Line9,(unsigned char *)"                  1");}else if(ui==1){sprintf((char *)lcd_buf,"       Setting      ");LCD_DisplayStringLine(Line3,lcd_buf);if(time_light==1){time_light=0;sprintf((char *)lcd_buf,"      %02d-%02d-%02d   ",T_Start.Hours,T_Start.Minutes,T_Start.Seconds); }
else
{time_light=1;if(time_line==0)sprintf((char *)lcd_buf,"        -%02d-%02d   ",T_Start.Minutes,T_Start.Seconds);else if(time_line==1)sprintf((char *)lcd_buf,"      %02d-  -%02d   ",T_Start.Hours,T_Start.Seconds);else if(time_line==2)
sprintf((char *)lcd_buf,"      %02d-%02d-  ",T_Start.Hours,T_Start.Minutes); 
}
LCD_DisplayStringLine(Line5,lcd_buf);	LCD_DisplayStringLine(Line9,(unsigned char *)"                  2");}
}

还需要注意的是题目一般都是从Line1到Line10但是官方给的例程LCD是从Line0到Line9所以题目上让显示第二行的话我们代码应该写Line1这个需要注意不然到时LCD显示会串行

LCD有时候会考到高亮显示

如:第七届省赛

 高亮显示就是将要高亮显示的内容换个背景颜色高亮显示完成后再换回原来的颜色

sprintf((char *)lcd_buff,"  Parameter Setup   ");LCD_DisplayStringLine(Line1,lcd_buff);if(threshold_line==0)LCD_SetBackColor(Yellow);sprintf((char *)lcd_buff," Threshold1:%dcm   ",Threshold[0]);LCD_DisplayStringLine(Line4,lcd_buff);LCD_SetBackColor(White);if(threshold_line==1)LCD_SetBackColor(Yellow);sprintf((char *)lcd_buff," Threshold2:%dcm   ",Threshold[1]);LCD_DisplayStringLine(Line6,lcd_buff);LCD_SetBackColor(White);if(threshold_line==2)LCD_SetBackColor(Yellow);sprintf((char *)lcd_buff," Threshold3:%dcm   ",Threshold[2]);LCD_DisplayStringLine(Line8,lcd_buff);LCD_SetBackColor(White);

以及数字闪烁

拿第六届代码做个示范(第六届没有要求这里是自己加的)

闪烁就是将原本该显示数字的位置拿空格替换掉就可以了注意只替换要闪烁的部分不然会导致一整行都开始左右移动

if(time_line==0)sprintf((char *)lcd_buf,"        -%02d-%02d   ",T_Start.Minutes,T_Start.Seconds);else if(time_line==1)sprintf((char *)lcd_buf,"      %02d-  -%02d   ",T_Start.Hours,T_Start.Seconds);else if(time_line==2)
sprintf((char *)lcd_buf,"      %02d-%02d-  ",T_St

此外

第十三届赛题的LCD密码这里也给大家展示一下

int password[3]={-1,-1,-1};//密码初始显示-1时显示字符@
void LCD_INPUT(void)//LCD输入密码界面
{sprintf((char *)lcd_buff,"       PSD          ");LCD_DisplayStringLine(Line1,lcd_buff);
if(ui==0)//处于界面一
{for(int i=0;i<3;i++)//for循环控制三位密码{if(password[i]==-1)//如果密码是初始状态显示字符@{sprintf((char *)lcd_buff,"    B%d:%c            ",i+1,'@');	}else//否则显示对应的数字{sprintf((char *)lcd_buff,"    B%d:%d            ",i+1,password[i]);}switch(i)//规定每位密码在LCD的那一行显示{case 0:LCD_DisplayStringLine(Line3,lcd_buff);break;case 1:LCD_DisplayStringLine(Line4,lcd_buff);break;case 2:LCD_DisplayStringLine(Line5,lcd_buff);break;default:break;}}
}
}
void LCD_OUTPUT(void)
{if(ui==1)//处于界面二{sprintf((char *)lcd_buff,"       STA          ");LCD_DisplayStringLine(Line1,lcd_buff);sprintf((char *)lcd_buff,"    F:%dHz            ",FRQ);LCD_DisplayStringLine(Line3,lcd_buff);sprintf((char *)lcd_buff,"    D:%d%%           ",(int)(duty*100));LCD_DisplayStringLine(Line4,lcd_buff);}
}

四.按键

在cubemx直接将对应引脚设置为GPIO_INPUT

代码里面首先定义几个变量

u8 key_down,key_up,key_value,key_old=0;

按键读取函数

void key_read(void)
{if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==GPIO_PIN_RESET)key_value=1;else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==GPIO_PIN_RESET)key_value=2;else if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)==GPIO_PIN_RESET)key_value=3;else if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==GPIO_PIN_RESET)key_value=4;elsekey_value=0;key_down=key_value&(key_value^key_old);key_up=~key_value&(key_value^key_old);key_old=key_value;
}

按键执行函数(以第六届代码为例)

void key_proc(void)
{if(uwTick-key_tick<20)return ;key_tick=uwTick;key_read();uint16_t b4_sum=0;uint16_t b4_bclk=0;if(key_down==1&&ui==0){led_mode = !led_mode;}else if(key_down==2){ui=!ui;LCD_Clear(Black);T_vaild.Hours=T_Start.Hours;T_vaild.Minutes=T_Start.Minutes;T_vaild.Seconds=T_Start.Seconds;}else if(key_down==3&&ui==1){time_line++;if(time_line>2)time_line=0;}else if(key_down==4&&ui==1){b4_bclk++;if(time_line==0){T_Start.Hours++;if(b4_bclk==2){T_Start.Hours--;if(T_Start.Hours<=0){T_Start.Hours=0;}}if(T_Start.Hours>23)T_Start.Hours=0;}else if(time_line==1){T_Start.Minutes++;if(T_Start.Minutes>60)T_Start.Minutes=0;}else if(time_line==2){T_Start.Seconds++;if(T_Start.Seconds>60)T_Start.Seconds=0;}}
}

前面都是一些按键简单功能在省赛中有时会考到按键的长短按键

如:第九届省赛

按键长短按可以拿定时器完成这里在后续的定时器部分展示,我们这里使用的是一种比较简单的方法即写一个宏定义规定长按键的时间然后利用系统的滴答定时器完成长短按键

#define long_press_time 800

按键代码

void KEY_proc(void)
{if(uwTick-key_tick<50)return ;key_tick=uwTick;key_read();if(key_down==1){s_line=0;time_line=3;number++;if(number%6==0)number=1;}else if(key_down==2)//按键按下{k2_press_start_tick=uwTick;//开始计时key_long_flag=0;//长按键标志位0表示不是长按}else if(key_value==2){if(uwTick-k2_press_start_tick>=long_press_time)//计时时间达到我们规定的长按时间{time_line=3;
//			addre=0x01;
//			for(int i=0;i<5;i++)
//			{
//				EEP_Write(addre++,time[i].hour);
//			  EEP_Write(addre++,time[i].minue);
//				EEP_Write(addre++,time[i].secend);
//			}EEP_Write(0x01,time[1].hour);//储存EEP_Write(0x02,time[1].minue);EEP_Write(0x03,time[1].secend);EEP_Write(0x04,time[2].hour);EEP_Write(0x05,time[2].minue);EEP_Write(0x06,time[2].secend);EEP_Write(0x07,time[3].hour);EEP_Write(0x08,time[3].minue);EEP_Write(0x10,time[3].secend);EEP_Write(0x11,time[4].hour);EEP_Write(0x12,time[4].minue);EEP_Write(0x13,time[4].secend);EEP_Write(0x14,time[5].hour);EEP_Write(0x15,time[5].minue);EEP_Write(0x16,time[5].secend);s_line=0;//设置状态key_long_flag=1;//标志位置1表示长按}}else if(key_up==2)//短按{if(key_long_flag){}else{if(s_line!=1)//不是设置状态{time_line=3;//谁也没选中s_line=1;//变为设置状态return ;}time_line++;if(time_line>2)//切换设置位置time_line=0;}
}else if(key_down==3){k3_press_start_tick=uwTick;key_long_flag=0;}else if(key_value==3){if(uwTick-k3_press_start_tick>=long_press_time)//长按{key_long_flag=1;if(time_line==0)//长按一直加{time[number].hour++;if(time[number].hour>23)time[number].hour=0;}if(time_line==1){time[number].minue++;if(time[number].minue>59)time[number].minue=0;}if(time_line==2){time[number].secend++;if(time[number].secend>59)time[number].secend=0;}}}else if(key_up==3){if(key_long_flag){}else{if(time_line==0)//短按加{time[number].hour++;if(time[number].hour>23)time[number].hour=0;}if(time_line==1){time[number].minue++;if(time[number].minue>59)time[number].minue=0;}if(time_line==2){time[number].secend++;if(time[number].secend>59)time[number].secend=0;}}
}else if(key_down==4){k4_press_start_tick=uwTick;key_long_flag=0;}else if(key_value==4){if(uwTick-k4_press_start_tick>=long_press_time)//长按{s_line=0;key_long_flag=1;}}else if(key_up==4){if(key_long_flag){s_line=0;printf("   s_lin=%d\r\n",s_line);}else//短按{if(s_line!=2){s_line=2;	printf("   s_lin2=%d\r\n",s_line);}else{s_line=3;printf("   s_lin3=%d\r\n",s_line);}if(time[number].hour==0&&time[number].minue==0&&time[number].secend==0){	s_line=3;}}
}}

还有按键的双击(这个目前为止没有考到过但是以防万一我们在这里简单写一下)


#define double_click_time 1000//定义双击时间

代码展示这里

void KEY_proc(void)
{if(uwTick-key_tick<50)return ;key_tick=uwTick;key_read();if(key_down==1)//按键按下{k1_press__start_tick=uwTick;//开始计时key_long_flag=0;//刚开始未达到时间要求}else if(key_value==1)//按键1按下{if(uwTick-k1_press__start_tick>=long_press_time)//超过时间判定为长按{key_long_flag=1;//长按标志位置1k1++;}}else if(key_up==1)//按键短按{k1+=1;
//		if(key_long_flag)
//		{
//			
//			
//		}
//		else 
//		{
//			k1+=1;
//			
//		}}if(key_down==2){k2_press__start_tick=uwTick;key_long_flag=0;}else if(key_value==2){if(uwTick-k2_press__start_tick>=long_press_time){key_long_flag=1;k2++;}}if(key_down==3)//按键3按下{if(uwTick-k3_press__last_tick<=double_click_time)//小于设置时间内如果再次检测到按键按下判定为双击按键{if(k1>0)k1--;}k3_press__last_tick=uwTick;//更新时间为了下一次按键双击判断}if(key_down==4){if(uwTick-k4_press__last_tick<=double_click_time){if(k2>0)k2--;}k4_press__last_tick=uwTick;}
}

五.LED

这个只需要注意别忘了PD2锁存引脚就行,可以在配置完引脚后现将LED引脚都拉高

以第六届代码为例(这里闪烁使用的是滴答定时器)

void led_disp(u8 led)
{HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOC,0XFF00,GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOC,led<<8,GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);}
void led_proc(void)
{if(uwTick-led_tick<200)return ;led_tick=uwTick;
//	if(led_num !=0)
//		led_num=0;
//	else
//		led_num=0xff;if(r37_volt>3.3f*K_value&&led_mode==1){led_num ^=0x01;}elseled_num&=~0x01;led_disp(led_num);
}

六.E2PROM

这个可以去芯片手册里找到E2PROM读写图照着图打代码就可以了

第六届的E2PROM就很典型这里我们展示第六届E2PROM代码

首先先去芯片手册中找到读写时序图

因为这个也是官方提供例程的所以我们直接添加官方例程然后再自己的.C文件中直接先读写函数就可以了

void EEP_write(uint8_t add,uint8_t date)
{I2CStart();I2CSendByte(0xA0);I2CWaitAck();I2CSendByte(add);I2CWaitAck();I2CSendByte(date);I2CWaitAck();I2CStop();HAL_Delay(5);
}

E2PROM写函数既要地址有需要数据所以要有两个参数,写函数需要9行,0XA0是写操作这个要在芯片手册里看现在直接记住就行

uint8_t EEP_read(uint8_t add)
{uint8_t data;I2CStart();I2CSendByte(0xA0);I2CWaitAck();I2CSendByte(add);I2CWaitAck();I2CStart();I2CSendByte(0xA1);
I2CWaitAck();data=I2CReceiveByte();I2CSendNotAck();I2CStop();return data;
}

E2PROM读刚开始需要定义一个变量存放读到的数据最后要放回数据值一般为13行0XA1是读操作直接记住就行

这里给大家放一下第六届E2PROM要求

这里要求将串口修改的K值存储所以存储代码和后面的串口放在一起展示

这里要只要我们还需要初始I2C

I2CInit();
if(EEP_read(123) !=123)
{EEP_write(123,123);K_value=0.1;EEP_write(0x01,K_value*10);}
else
K_value=EEP_read(0x01)/10.0;

这里if的作用是判断是否是第一次写入如果是第一次写入(也就是123!=123这里123是自己定义的也可以是其他数字)那就写入,不过不是第一次写入就读取

这里要注意EEP——witre要写入整型(也位传入写浮点型但是我不会那种)所以在写入时给k*10转换成整型然后再读出k的值后再除以10变回原来的值

七.串口

这个在cubemx中只需要配置好引脚然后再改一下波特率就可以了波特率看赛题一般为9600,要注意的是记得勾选接收中断

这里串口展示我们选择第六届串口以及第十二届串口

首先我们现将串口的重定向函数加到代码中,这个重定向函数不用记忆到时可以在keil中找到

查找步骤:

点击列出主题,选择第一个双击就可以找到啦

第六届串口模块:

定时上报电压功能:

void tx_proc(void)
{if(uwTick-tx_tick<1000)return ;tx_tick=uwTick;if(T.Hours==T_vaild.Hours&&T.Minutes==T_vaild.Minutes&&T.Seconds==T_vaild.Seconds)printf("%.2f+%.1f+%02d%02d%02d\n",r37_volt,K_value,T_vaild.Hours,T_vaild.Minutes,T_vaild.Seconds); }

记得要在重定向函数中添加串口发送函数

struct __FILE
{int handle;
};FILE __stdout;
int fputc(int ch, FILE *f) 
{
HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,50);return ch;
}

在写接收函数之前要在初始化位置打开接收中断

HAL_UART_Receive_IT(&huart1,&rx_data,1);

定义变量

u8 rx_data,rx_pointer;
u8 rx_buff[30];
u32 rx_tick=0;

设置K值

memset(rx_buff,0,sizeof(rx_buff));

这个函数作用就是将缓存区中的内容清零,这样这次接收的东西不会影响下次接收的内容

第十二届串口模块:

赛题要求如下:

这届串口功能很难,我在写这个代码时参考了一位国一大佬的源码这个在博客十二届省赛中有大佬文章链接大家感兴趣的可以去看看

重定向和上面的第六届的一样这里就不给大家写了

HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,HAL_MAX_DELAY);

超时时间不想定义为50的话可以定义为最大超时时间

由于串口功能过于复杂这里关于串口写了好几个函数

1.判断合法性

unsigned char isRxCplt()//判断串口是否合法
{if(rx_dex!=22)//如果字符不是22位return 0;//不合法返回0if(((rx_buf[0]=='C')||(rx_buf[0]=='V'))&&(rx_buf[1]=='N')&&(rx_buf[2]=='B')&&(rx_buf[3]=='R')&&(rx_buf[4]==':')&&(rx_buf[9]==':'))//判断字符是否符合题目格式{unsigned char i;for(i=10;i<22;i++){if((rx_buf[i]>'9')||(rx_buf[i]<'0'))//判断时间是否合法return 0;//不合法返回0}return 1;//合法返回1}
elsereturn 0;//不合法}

2.判断车辆是否已经停在停车场

unsigned char isexis(unsigned char *str)
{unsigned char i;for(i=0;i<8;i++)//一共八辆车从第一辆开始比对{if(strcmp((char *)str,(char *)car_data[i].id)==0)//判断传入的字符串是否与车辆id相同相同则表示车辆已经在停车场中return i;}return 0xFF;//如果不相同则没有在停车场中
}

3.判断停车场是否有空位置

unsigned char isempty()
{unsigned char i;for(i=0;i<8;i++)//一次检索八个位置{if(car_data[i].empty==0)//之前设置的标志位标志位为0表示这个位置为空return i;}return 0xFF;//没有空闲位置,停车场满了
}

4.车辆进出停车场信息储存

void srt_tran(unsigned char*d_str,unsigned char*str,unsigned char num,unsigned char lenth)//将str中的部分信息提取到d_str中存储起来,num表示源码位置,length表示要截取字符串的长度
{unsigned char i;for(i=0;i<lenth;i++)//依次存储八辆车的信息{d_str[i]=str[num+i];//存储d_str[lenth]='\0';//将字符串的最后一位设置为\0作为字符串的结束}	
}

5.总的串口功能

void UART_proc(void)
{static __IO uint32_t UART_tick;unsigned char tx[30];if(uwTick-UART_tick<100)return ;UART_tick=uwTick;
unsigned char car_id[5],car_type[5],year,month,day,hour,min,sec;//定义车辆信息用于进行提取存储
//	if(!isRxCplt())
//	{
//		sprintf((char *)tx,"Error\r\n");
//		HAL_UART_Transmit(&huart1,tx,strlen(tx),50);
//		memset(&rx_buf,0,sizeof(rx_buf));
//		rx_dex=0;
//		return ;
//	}if(isRxCplt())//数据合法{year=(rx_buf[10]-'0')*10+(rx_buf[11]-'0');//由于是字符串所以需要转化成数字month=(rx_buf[12]-'0')*10+(rx_buf[13]-'0');day=(rx_buf[14]-'0')*10+(rx_buf[15]-'0');hour=(rx_buf[16]-'0')*10+(rx_buf[17]-'0');min=(rx_buf[18]-'0')*10+(rx_buf[19]-'0');sec=(rx_buf[20]-'0')*10+(rx_buf[21]-'0');if((month>12)||(day>31)||(hour>23)||(min>59)||(sec>59))//时间不合法goto SEND_ERROR;//这是一个跳转指令,不合法就跳转到ERROR执行ERRORsrt_tran(car_id,rx_buf,5,4);//提取id信息srt_tran(car_type,rx_buf,0,4);//提取车辆类型信息if(isexis(car_id)==0xFF)//如果车辆不存在{unsigned char in_close=isempty();//判断是否有空闲位置,有空闲位置close等于空闲位置if(in_close==0xFF)//没有空闲位置goto SEND_ERROR;//跳转srt_tran(car_data[in_close].type,car_type,0,4);//提取车辆类型到空闲位置中表示车辆停进去了srt_tran(car_data[in_close].id,car_id,0,4);//提取车辆id到位置信息中car_data[in_close].year=year;//将停车时间赋值给位置信息的时间car_data[in_close].month=month;car_data[in_close].day=day;car_data[in_close].hour=hour;car_data[in_close].min=min;car_data[in_close].sec=sec;car_data[in_close].empty=1;//空闲标志位置1表示有车停入if(car_data[in_close].type[0]=='C')//如果车辆类型是C那么C的数量加一cnbr_number++;if(car_data[in_close].type[0]=='V')//同理vnbr_number++;idle_numer--;//一共八个停车位置有车停进总位置要减1}else if(isexis(car_id)!=0xFF)//如果车辆之前已经在停车场了,就表示要出停车场{unsigned char out_locate=isexis(car_id);//获取车辆的位置信息signed int time;//定义时间自然数,可正可负可为0if(strcmp((char *)car_type,(char *)car_data[out_locate].type)!=0)//比对车辆编号与车辆类型是否一致goto SEND_ERROR;//不一致出错跳转time=(year-car_data[out_locate].year)*365*24*60*60+(month-car_data[out_locate].month)*31*24*60*60+(day-car_data[out_locate].day)*24*60*60+(hour-car_data[out_locate].hour)*60*60+(min-car_data[out_locate].min)*60+(sec-car_data[out_locate].sec);//将总体的时间转化为秒用于计算费用if(time<0)//时间小于0,时间不合法goto SEND_ERROR;//跳转time=(time+3599)/3600;//不足一个小时按一个小时计算sprintf((char *)tx,"%s:%s:%d:%.2f\r\n",car_data[out_locate].type,car_data[out_locate].id,time,(car_data[out_locate].type[0]=='C'?time*cnbr:time*vnbr));HAL_UART_Transmit(&huart1,tx,strlen(tx),50);if(car_data[out_locate].type[0]=='C')//如果出停车的车辆类型是C,那么停车场内C的数量减1cnbr_number--;else if(car_data[out_locate].type[0]=='V')//同理vnbr_number--;memset(&car_data[out_locate],0,sizeof(car_data[out_locate]));//清空这个车位的车辆信息方便下一辆车记录}}
if(rx_dex>0&&!isRxCplt())//数据不合法
{printf("Error\r\n");//输出EEOR
}goto CLEAR;//跳转到清除语句SEND_ERROR://错误语句sprintf((char *)tx,"Error\r\n");//输出ERRORHAL_UART_Transmit(&huart1,tx,strlen(tx),50);//串口发送CLEAR://清除语句memset(&rx_buf,0,sizeof(rx_buf));//清除缓存区内的内容rx_dex=0;
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef*huart)
{if(rx_dex< sizeof(rx_buf)){rx_buf[rx_dex++]=rx;}else{memset(rx_buf,0,sizeof(rx_buf));rx_dex=0;}HAL_UART_Receive_IT(&huart1,&rx,1);
}

八.PWM

以第九届省赛为例

PWM函数

void RWM_proc(void)
{if(s_line==2){HAL_TIM_PWM_Start(&htim16,TIM_CHANNEL_1);}else{HAL_TIM_PWM_Stop(&htim16,TIM_CHANNEL_1);}}

这道题只要求打开PWM和关闭PWM比较单一

所以我们展示一下第十四届PWM功能(输入输出都有)

赛题

HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);//PWMHAL_TIM_IC_Start_IT(&htim17,TIM_CHANNEL_1);//输入捕获

由于频率部分和ADC部分密切相关我们这里一起展示

高低频转换计算速度以及更新最大值

void ADC_frq()
{velo=(frq1*2*3.14*R)/(100*K);//将PA7测量的频率值转化为速度duty=((double)TIM2->CCR2/(TIM2->ARR+1))*100;//直接用寄存器计算PWM的占空比ADC_frq1=getADC(&hadc2)*0.375-0.275;//根据图上的信息表示ADC的值与频率的关系if(ADC_frq1<0.1) ADC_frq1=0.1;//看图ADC值小于0.1时等于0.1if(ADC_frq1>0.85) ADC_frq1=0.85;//同理if(fre_flag == 0 || fre_flag == 2)//低频高频时更新CCR的值用于更新占空比{TIM2->CCR2 = ADC_frq1 * (TIM2->ARR + 1);}
}
void HL_MAN()
{if(fre_flag==0)//低频{if(max_L<velo) max_L=velo;//更新速度最大值}if(fre_flag==2)//高频{if(max_H<velo) max_H=velo;//更新速度最大值}
}

步进值

uint16_t fre4000=4000;
uint16_t fre8000=8000;
if(htim->Instance==TIM6){	if(fre_flag==1)//转化过程中{count++;//计时fre4000+=80;//频率每100毫秒加80TIM2->CNT=0;//定时器计数器清零TIM2->ARR = 1000000/fre4000 -1;//更新自动重装载器的值TIM2->CCR2 = ADC_frq1 * (TIM2->ARR +1);//更新CCR的值if(count>=50)//5秒时间达到{count=0;//计数清零fre_flag=2;//转化成高频fre4000=4000;//低频值重新值为4000}}if(fre_flag==3)//高频{count++;fre8000-=80;//每100毫秒减80TIM2->CNT=0;TIM2->ARR = 1000000/fre8000 -1;TIM2->CCR2 = ADC_frq1 * (TIM2->ARR +1);if(count>=50){count=0;fre_flag=0;fre8000=8000;}}}
}uint16_t ccrl_val1a=0,ccrl_val1b=0;
uint32_t frq1=0;
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{if (htim->Instance == TIM3) {ccrl_val1a=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_2)+1;//捕获频率值__HAL_TIM_SetCounter(htim, 0);//计数器清零frq1=(80000000 / 80) /ccrl_val1a;//计算频率值HAL_TIM_IC_Start(htim,TIM_CHANNEL_2);//开启PWM捕获}
}

步进值就不在这里给大家解释了大家看这两位位大佬的文章

【蓝桥杯嵌入式】蓝桥杯嵌入式第十四届省赛程序真题,真题分析与代码讲解_蓝桥杯 嵌入式-CSDN博客

第十四届蓝桥杯嵌入式省赛程序设计题解析(基于HAL库)_蓝桥杯嵌入式14届省赛-CSDN博客

九.定时器

在第九届省赛里面涉及到了一个进行一秒递减的定时器我们在这里展示一下

首先现在cubeMX里面配置一个定时器7

在使用定时器前现在初始化部分将定时器打开

HAL_TIM_Base_Start_IT(&htim7);

然后再it.C函数中找到定时器中断回调函数

添加进我们的.C文件中直接编写就行啦

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance==htim7.Instance){time_cnt++; if(time_cnt==1000){time_cnt=0;if(s_line==2){if(time[number].secend>0){time[number].secend--;}else if(time[number].minue>0){time[number].secend=59;time[number].minue--;}else if(time[number].hour>0){time[number].minue=59;time[number].secend=59;time[number].hour--;}else{s_line=0;}}}	}
}

这里为什么CNT等于1000时是1秒我们做一个解释

等cnt等于1000时刚好达到1秒

临时增加一MCP4017

大家记住就好啦

首先要在主函数中初始化部分调用I2C初始化函数

I2CInit();

然后再i2c.c中写

void wirte_resistor(uint8_t value)
{I2CStart();I2CSendByte(0x5E);I2CWaitAck();I2CSendByte(value);I2CWaitAck();I2CStop();}
uint8_t read_resistor(void)
{uint8_t value;I2CStart();I2CSendByte(0x5F);I2CWaitAck();value=I2CReceiveByte();I2CSendNotAck();I2CStop();return value;}

明天就要比赛了,祝大家旗开得胜取得自己满意的成绩,比赛加油!!

相关文章:

蓝桥杯嵌入式考前模块总结

一.RTC 使用RTC直接再cubeMX中配置启动时钟和日历 如第六届省赛 想要让RTC的秒每隔一秒递增1需要在时钟树界面观察RTC的主频 由于RTC时钟主频为32KHZ将异步预分频计数器的值设为31&#xff0c;将同步预分频计数器的值设为999这样就可以将RTC的时钟信号分频为1HZ达到1秒自增的…...

《汽车电器与电子技术》实验报告

SRS系统结构原理与故障检测诊断 车辆上为什么要配安全气囊&#xff1f;——解析汽车被动安全的关键防线 一、安全气囊的核心作用&#xff1a;应对高速碰撞的“救命缓冲垫” 车辆在高速碰撞时&#xff08;如正面碰撞、侧面碰撞&#xff09;&#xff0c;人体会因惯性以极高速度…...

小刚说C语言刷题——第22讲 二维数组

昨天我们讲了一维数组&#xff0c;今天我们来讲二维数组。 1.定义 二维数组是指在数组名后跟两个方括号的数组。 2.语法格式 数据类型 数组名[下标][下标] 例如&#xff1a;int a[5][9];//表示5行9列的数组 3.访问二维数组元素 格式&#xff1a;数组名[行坐标][列坐标]…...

04--网络属性设置与多路复用

一、TCP可靠性分析 二、 scoket 属性设置 1、socket 属性设置表 NAMEgetsockopt, setsockopt - get and set options on sockets获取 和 设置 套接字属性 SYNOPSIS#include <sys/types.h> /* See NOTES */#include <sys/socket.h>int getsockopt(int so…...

AI大模型从0到1记录学习 day17

第 2 章 数据结构与算法基础 2.1 数据结构基础 2.1.1 什么是数据结构 数据结构是为了高效访问数据而设计出的一种数据的组织和存储方式。更具体的说&#xff0c;一个数据结构包含一个数据元素的集合、数据元素之间的关系以及访问和操作数据的方法。 像前面我们接触到的list、se…...

scanf函数功能与使用详解

【DeepSeek提问】 解释一下下面这段话&#xff1a; 函数scanf()是从标准输入流 stdin (标准输入设备&#xff0c; 一般指键盘)中读内容的通用子程序&#xff0c;可以按说明的格式读入多个字符&#xff0c;并保存在对应地址的变量中。 scanf函数返回成功读入的数据项数&#xf…...

使用Python从零开始构建端到端文本到图像 Transformer大模型

简介&#xff1a;通过特征向量从文本生成图像 回顾&#xff1a;多模态 Transformer 在使用Python从零实现一个端到端多模态 Transformer大模型中&#xff0c;我们调整了字符级 Transformer 以处理图像&#xff08;通过 ResNet 特征&#xff09;和文本提示&#xff0c;用于视觉…...

NDT和ICP构建点云地图 |【点云建图、Ubuntu、ROS】

### 本博客记录学习NDT&#xff0c;ICP构建点云地图的实验过程&#xff0c;参考的以下两篇博客&#xff1a; 无人驾驶汽车系统入门&#xff08;十三&#xff09;——正态分布变换&#xff08;NDT&#xff09;配准与无人车定位_settransformationepsilon-CSDN博客 PCL中点云配…...

第 1 篇✅ 用 AI 编程之前,你得先搞清楚你和 AI 是啥关系

程序员不是被替代的,是要学会主导 AI 的人 🧠 那些把 AI 当兄弟的程序员,后来都踩了坑 最近的一次线下开发者聚会,我们聊到“AI 编程”,现场笑声不断,也点醒了不少人。 有个朋友说: “我让 AI 写一个 Web 服务,它写得飞快,我一激动就上线了,结果上线后一堆坑,日志…...

Android Jetpack Compose 高级开发核心技术

Android Compose 高级技术总结 1. 性能优化 1.1 状态管理优化 状态提升原则&#xff1a;将状态提升到共享的最近共同父组件derivedStateOf&#xff1a;当需要基于多个状态计算派生状态时使用 val scrollState rememberScrollState() val showButton by remember {derivedS…...

Go小技巧易错点100例(二十五)

本期分享&#xff1a; 1. 使用atomic包实现无锁并发控制 2. Gin框架的中间件机制 3. 搞懂nil切片和空切片 使用atomic包实现无锁并发控制 sync/atomic包提供了原子操作&#xff0c;用于在多goroutine环境下安全地操作共享变量&#xff0c;避免使用锁带来的性能开销。 代码…...

如何用海伦公式快速判断点在直线的哪一侧

一、海伦公式的定义与推导 1. 海伦公式的定义 海伦公式&#xff08;Heron’s Formula&#xff09;是用于计算三角形面积的一种方法&#xff0c;适用于已知三角形三边长度的情况。公式如下&#xff1a; S s ( s − a ) ( s − b ) ( s − c ) S \sqrt{s(s - a)(s - b)(s - c…...

【异常处理】Clion IDE中cmake时头文件找不到 头文件飘红

如图所示是我的clion项目目录 我自定义的data_structure.h和func_declaration.h在unit_test.c中无法检索到 cmakelists.txt配置文件如下所示&#xff1a; cmake_minimum_required(VERSION 3.30) project(noc C) #设置头文件的目录 include_directories(${CMAKE_SOURCE_DIR}/…...

自动驾驶技术关键技术梳理

一、硬件 1、 传感器系统设计主要注意以下几个问题&#xff1a; 1.时间同步 一般包括多传感器之间时钟同源、帧同步触发的问题。首先要解决时钟同源问题&#xff0c;然后为了帧同步触发&#xff0c;可以让所有传感器整秒触发。常用GPS&#xff08;最多分2路&#xff09;给激光雷…...

MySQL索引介绍

索引的定义 扇区&#xff1a;磁盘存储的最小单位&#xff0c;扇区一般大小为512Byte。磁盘块&#xff1a;文件系统与磁盘交互的的最小单位&#xff08;计算机系统读写磁盘的最小单位&#xff09;&#xff0c;一个磁盘块由连续几个&#xff08;2^n&#xff09;扇区组成&#xf…...

2025认证杯一阶段各题需要使用的模型或算法(冲刺阶段)

A题&#xff08;小行星轨迹预测&#xff09; 问题一&#xff1a;三角测量法、最小二乘法、空间几何算法、最优化方法 问题二&#xff1a;Gauss/Laplace轨道确定方法、差分校正法、数值积分算法&#xff08;如Runge-Kutta法&#xff09;、卡尔曼滤波器 B题&#xff08;谣言在…...

每天学一个 Linux 命令(13):touch

Linux 文件管理命令:touch touch 是 Linux 中一个简单但高频使用的命令,主要用于创建空文件或修改文件的时间戳(访问时间、修改时间)。它是文件管理和脚本操作的实用工具。 1. 命令作用 创建空文件:快速生成一个或多个空白文件。更新时间戳:修改文件的访问时间(Access …...

Flutter常用组件实践

Flutter常用组件实践 1、MaterialApp 和 Center(组件居中)2、Scaffold3、Container(容器)4、BoxDecoration(装饰器)5、Column(纵向布局)及Icon(图标)6、Column/Row(横向/横向布局)+CloseButton/BackButton/IconButton(简单按钮)7、Expanded和Flexible8、Stack和Po…...

Python 实现最小插件框架

文章目录 Python 实现最小插件框架1. 基础实现项目结构plugin_base.py - 插件基类plugins/hello.py - 示例插件1plugins/goodbye.py - 示例插件2main.py - 主程序 2. 更高级的特性扩展2.1 插件配置支持2.2 插件依赖管理2.3 插件热加载 3. 使用 setuptools 的入口点发现插件3.1 …...

AUTOSAR_SWS_MemoryDriver图解

AUTOSAR 存储驱动程序&#xff08;Memory Driver&#xff09;详解 AUTOSAR存储驱动规范 - 技术解析与架构详解 目录 1. 概述2. Memory Driver架构设计 2.1 整体架构 3. Memory Driver核心组件4. 作业管理5. Memory Driver错误处理6. 时序流程7. 配置与设置8. 总结 1. 概述 A…...

AI结合VBA提升EXCEL办公效率尝试

文章目录 前言一、开始VBA编程二、主要代码三、添加到所有EXCEL四、运行效果五、AI扩展 前言 EXCEL右击菜单添加一个选项&#xff0c;点击执行自己逻辑的功能。 然后让DeepSeek帮我把我的想法生成VBA代码 一、开始VBA编程 我的excel主菜单没有’开发工具‘ 选项&#xff0c;…...

Python中NumPy的索引和切片

在数据科学和科学计算领域&#xff0c;NumPy是一个功能强大且广泛使用的Python库。它提供了高效的多维数组对象以及丰富的数组操作函数&#xff0c;其中索引和切片是NumPy的核心功能之一。通过灵活运用索引和切片操作&#xff0c;我们可以轻松访问和操作数组中的元素&#xff0…...

普通通话CSFB方式(2g/3g)

一、CSFB的触发条件 当模块&#xff08;或手机&#xff09;驻留在 4G LTE网络 时&#xff0c;若发生以下事件&#xff0c;会触发CSFB流程&#xff1a; 主叫场景&#xff1a;用户主动拨打电话。被叫场景&#xff1a;接收到来电&#xff08;MT Call&#xff09;。紧急呼叫&…...

daily routines 日常生活

总结 🛏 起床相关(Waking Up) 动作常用表达示例句子醒来wake upI usually wake up around 6:30.起床(离床)get up / get out of bedI got out of bed at 6:45.赖床stay in bed / lay thereI stayed in bed for another 10 minutes.关闭闹钟turn off the alarm / hit snoo…...

系分论文《论面向服务开发方法在设备租赁行业的应用》

系统分析师论文系列 【摘要】 2022年5月&#xff0c;我司承接某工程机械租赁企业"智能租赁运营管理平台"建设项目&#xff0c;我作为系统分析师主导系统架构设计。该项目需整合8大类2000余台设备资产&#xff0c;覆盖全国15个区域运营中心与300家代理商&#xff0c;实…...

深度解析python生成器和关键字yield

一、生成器概述 生成器&#xff08;Generator&#xff09;是Python中用于创建迭代器的工具&#xff0c;通过yield关键字实现。与普通函数不同&#xff0c;生成器函数返回的是迭代器对象&#xff0c;具有以下核心特性&#xff1a; 内存效率&#xff1a;只在需要时生成值&#x…...

蓝桥杯大模板

init.c void System_Init() {P0 0x00; //关闭蜂鸣器和继电器P2 P2 & 0x1f | 0xa0;P2 & 0x1f;P0 0x00; //关闭LEDP2 P2 & 0x1f | 0x80;P2 & 0x1f; } led.c #include <LED.H>idata unsigned char temp_1 0x00; idata unsigned char temp_old…...

Python装饰器的基本使用详解

各类资料学习下载合集 ​​https://pan.quark.cn/s/8c91ccb5a474​​ 装饰器是Python中的一个强大且灵活的特性&#xff0c;它允许我们在不修改函数代码的情况下为其添加额外功能。装饰器广泛应用于日志记录、性能测试、权限验证等场景。本文将详细介绍装饰器的基本使用&…...

5Why分析法

1. 基本概念 5Why分析法是一种通过连续追问"为什么"来探究问题根本原因的思考工具&#xff0c;由丰田生产方式创始人丰田喜一郎提出。其核心思想是&#xff1a;通过至少5次连续的"为什么"追问&#xff0c;穿透表面现象&#xff0c;直达问题本质。 2. 实施…...

AI Agent入门指南

图片来源网络 ‌一、开箱暴击&#xff1a;你以为的"智障音箱"&#xff0c;其实是赛博世界的007‌ ‌1.1 从人工智障到智能叛逃&#xff1a;Agent进化史堪比《甄嬛传》‌ ‌青铜时代&#xff08;2006-2015&#xff09;‌ “小娜同学&#xff0c;关灯” “抱歉&…...

华为机试—最大最小路

题目 对于给定的无向无根树&#xff0c;第 i 个节点上有一个权值 wi​ 。我们定义一条简单路径是好的&#xff0c;当且仅当&#xff1a;路径上的点的点权最小值小于等于 a &#xff0c;路径上的点的点权最大值大于等于 b 。 保证给定的 a<b&#xff0c;你需要计算有多少条简…...

java之多线程

目录 创建多线程的三种创建方式 常用的成员方法 守护线程 多线程的声明周期 ​编辑 同步代码块​编辑 同步方法 死锁 等待唤醒机制&#xff08;线程协调&#xff09; 线程池 创建多线程的三种创建方式 继承 Thread 类 通过继承 Thread 类并重写 run() 方法创建线程。 …...

php伪协议

PHP 伪协议&#xff08;PHP Stream Wrapper&#xff09; PHP 的伪协议&#xff08;Protocol Wrapper&#xff09;是一种机制&#xff0c;允许开发者通过统一的文件访问函数&#xff08;如 file_get_contents、fopen、include 等&#xff09;访问不同类型的数据源&#xff0c;包…...

六、测试分类

设计测试用例 万能公式&#xff1a;功能测试性能测试界面测试兼容性测试安全性测试易用性测试 弱网测试&#xff1a;fiddler上行速率和下行速率 安装卸载测试 在工作中&#xff1a; 1.基于需求文档来设计测试用例&#xff08;粗粒度&#xff09; 输入字段长度为6~15位 功…...

【AM2634】启动和调试

目录 【AM2634】启动和调试1. 上电流程1.1 BootFlow and Bootloader1.2 Rom Code1.2.1 功能介绍1.2.2 模式选择1.2.2.1 QSPI Boot1.2.2.2 UART Boot1.2.2.3 Dev Boot 1.3 SBL1.3.1 文件构成1.3.2 文件构建1.3.3 appimage解析和core启动流程 1.4 Appimage1.4.1 RPRC文件构成1.4.…...

鲁大师绿色版,纯净无广告

鲁大师是我们常用的硬件跑分软件,可以非常准确的识别电脑硬件,对电脑性能进行评估 但他的流氓行为:广告弹窗,捆绑下载其他软件,疯狂的吃硬件性能,无法卸载等因素&#xff0c;又使我们大家既享用又不敢用 我为大家整理了一款纯净的绿色版鲁大师 主要实现了以下功能: 01屏蔽了…...

Python数组(array)学习之旅:数据结构的奇妙冒险

Python数组学习之旅:数据结构的奇妙冒险 第一天:初识数组的惊喜 阳光透过窗帘缝隙洒进李明的房间,照亮了他桌上摊开的笔记本和笔记本电脑。作为一名刚刚转行的金融分析师,李明已经坚持学习Python编程一个月了。他的眼睛因为昨晚熬夜编程而微微发红,但脸上却挂着期待的微…...

spring cloud微服务API网关详解及各种解决方案详解

微服务API网关详解 1. 核心概念 定义&#xff1a;API网关作为微服务的统一入口&#xff0c;负责请求路由、认证、限流、监控等功能&#xff0c;简化客户端与后端服务的交互。核心功能&#xff1a; 路由与转发&#xff1a;将请求分发到对应服务。协议转换&#xff1a;HTTP/HTTP…...

工程师 - 场效应管分类

What Are the Different Types of FETs? Pulse Octopart Staff Jul 31, 2021 Field effect transistors (FETs) are today’s workhorses for digital logic, but they enjoy plenty of applications outside of digital integrated circuits, everything from motor driver…...

asm汇编源代码之按键处理相关函数

提供5个子程序: 1. 发送按键 sendkey 2. 检测是否有按键 testkey 3. 读取按键 getkey 4. 判断键盘缓冲区是否为空 bufempty 5. 判断键盘缓冲区是否已满 buffull 具体功能及参数描述如下 sendkey proc  far ; axcharcode testkey proc  far ; out: ;   zf1 buff empt…...

程序化广告行业(78/89):多因素交织下的行业剖析与展望

程序化广告行业&#xff08;78/89&#xff09;&#xff1a;多因素交织下的行业剖析与展望 在程序化广告这片充满活力又不断变化的领域&#xff0c;持续学习和知识共享是我们紧跟潮流、实现突破的关键。一直以来&#xff0c;我都渴望能与大家一同探索这个行业的奥秘&#xff0c…...

如何使用MaxScript+dotNet在UI中显示图像?

在MaxScript中,你可以使用dotNetControl来显示图像。以下是一个简单的示例脚本,它创建一个UI窗口并在其中显示logo.jpg图像: rollout logoRollout "Logo Display" width:300 height:300 (dotNetControl logoPicture "System.Windows.Forms.PictureBox"…...

BitMap和RoaringBitmap:极致高效的大数据结构

目录 1、引言 2、BitMap:基础 2.1、核心原理 2.2、BitMap的优势 2.3、BitMap的局限性 3、RoaringBitmap:进化 3.1、分段策略 3.2、三种容器类型 3.2.1. ArrayContainer(数组容器) 3.2.2. BitMapContainer(位图容器) 3.2.3. RunContainer(行程容器) 3.3、行…...

Java高性能并发利器-VarHandle

1. 什么是 VarHandle&#xff1f;​​ VarHandle 是 Java 9 引入的类&#xff0c;用于对变量&#xff08;对象字段、数组元素、静态变量等&#xff09;进行低级别、高性能的原子操作&#xff08;如 CAS、原子读写&#xff09;。它是 java.util.concurrent.atomic 和 sun.misc.…...

关于读完《毛泽东选集》的一些思考迭代

看完毛选前四卷&#xff0c;从革命初期一直讲到抗战胜利&#xff0c;共75.8W字&#xff0c;花费67个小时读完。从1925年发表的“中国社会各阶级的分析”&#xff0c;跨越100年&#xff0c;通过67个小时向主席学习到&#xff1a; 实事求是 从实践中来再到实践中去 用辩证与发展…...

机器学习 第一章

&#x1f9e0; 机器学习 第一章 一、什么是机器学习 (Machine Learning) 让计算机自己从数据中学习出规律&#xff0c;无需人手写规则 输入: 特征 x输出: 标签 y学习目标: 学习出 f(x) 等价于 y 二、三大类型任务 类型英文特点示例回归Regression输出是连续值房价预测分类Cla…...

LVS+Keepalived+DNS 高可用项目

项目架构 主机规划 主机IP角色软件lb-master172.25.250.105主备负载均衡器ipvsadm&#xff0c;keepalivedlb-backup172.25.250.106同时做web和dns调度ipvsadm&#xff0c;keepaliveddns-master172.25.250.107VIP&#xff1a;172.25.250.100binddns-slave172.25.250.108LVS DNS…...

app逆向专题三:adb工具的使用

app逆向专题三&#xff1a;adb工具的使用 一、adb工具的配置二、adb工具的下载与安装 一、adb工具的配置 adb它是一个通用命令行工具&#xff0c;它可以作为Android与PC端连接的一个桥梁&#xff0c;所以adb又成为Android调试桥&#xff0c;用户可以通过adb在电脑上对Android设…...

CAD导入arcgis中保持面积不变的方法

1、加载CAD数据&#xff0c;选择面数据&#xff0c;如下&#xff1a; 2、加载进来后&#xff0c;右键导出数据&#xff0c;导出成面shp数据&#xff0c;如下&#xff1a; 3、选择存储路径&#xff0c;导出面后计算面积&#xff0c;如下&#xff1a; 4、与CAD中的闭合线面积核对…...

提示词 (Prompt)

引言 在生成式 AI 应用中&#xff0c;Prompt&#xff08;提示&#xff09;是与大型语言模型&#xff08;LLM&#xff09;交互的核心输入格式。Prompt 的设计不仅决定了模型理解任务的准确度&#xff0c;还直接影响生成结果的风格、长度、结构与可控性。随着模型能力和应用场景…...