電機應用開發-直流有刷電機電流環控制實現

目錄

直流有刷電機電流環控制實現

硬件設計

直流電機電流環控制-位置式PID實現

編程要點

配置ADC可讀取電流值

配置基本定時器6產生定時中斷讀取當前電路中驅動電機的電流值并執行PID運算

配置定時器1輸出PWM控制電機

ADC數據處理

編寫位置式PID算法

直流電機電流環控制-增量式PID實現

編程要點

配置ADC可讀取電流值

配置基本定時器6產生定時中斷讀取當前電路中驅動電機的電流值并執行PID運算

配置定時器1輸出PWM控制電機

ADC數據處理

編寫增量式PID算法


直流有刷電機電流環控制實現

利用直流有刷驅動板來完成對電流的采集,最終實現電流環的閉環控制。

在一些場景中想讓電機吊起超出電機能力的重物(即超載),但電機的能力有限,電機長期超載工作會嚴重損壞電機。如果想合理利用電機的性能,就需要控制電流的輸出,所以需要電流環的控制。

硬件設計

可選:L298N電機驅動板、野火MOS搭建的驅動板。

直流電機電流環控制-位置式PID實現

編程要點

配置ADC可讀取電流值

配置基本定時器產生定時中斷讀取當前電路中驅動電機的電流值并執行PID運算

配置定時器輸出PWM控制電機

編寫位置式PID算法

編寫電流控制函數

增加上位機曲線觀察相關代碼

編寫按鍵控制代碼

配置ADC可讀取電流值
#define VBUS_MAX      		14    // 電壓最大值
#define VBUS_MIN      		10    // 電壓最小值#define VBUS_HEX_MAX  		((VBUS_MAX/37.0+1.24)/VREF*65536)    // 電壓最大值(測量電壓是電源電壓的1/37)
#define VBUS_HEX_MIN  		((VBUS_MIN/37.0+1.24)/VREF*65536)    // 電壓最小值(測量電壓是電源電壓的1/37)__IO uint16_t ADC_ConvertedValue;
DMA_HandleTypeDef DMA_Init_Handle;
ADC_HandleTypeDef ADC_Handle;static uint16_t adc_buff[1024];
static uint16_t vbus_adc_mean = 0;  	// 電源電壓 ADC 采樣結果平均值
static uint32_t adc_mean_sum = 0;   	// 平均值累加
static uint32_t adc_mean_count = 0; 	// 累加計數/*** @brief  電流采集初始化* @param  無* @retval 無*/
void ADC_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;__GPIOB_CLK_ENABLE();__DMA2_CLK_ENABLE();__ADC1_CLK_ENABLE();// PB1--電流GPIO_InitStructure.Pin = GPIO_PIN_1;GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;GPIO_InitStructure.Pull = GPIO_NOPULL;HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);// PB0--電壓GPIO_InitStructure.Pin = GPIO_PIN_0;HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);// ADC1使用DMA2,數據流0,通道0,這個是手冊固定死的DMA_Init_Handle.Instance 					= DMA2_Stream0;DMA_Init_Handle.Init.Direction 				= DMA_PERIPH_TO_MEMORY;DMA_Init_Handle.Init.PeriphInc 				= DMA_PINC_DISABLE;DMA_Init_Handle.Init.MemInc 				= DMA_MINC_ENABLE;DMA_Init_Handle.Init.PeriphDataAlignment 	= DMA_PDATAALIGN_HALFWORD;DMA_Init_Handle.Init.MemDataAlignment 		= DMA_MDATAALIGN_HALFWORD;DMA_Init_Handle.Init.Mode 					= DMA_CIRCULAR;DMA_Init_Handle.Init.Priority 				= DMA_PRIORITY_HIGH;DMA_Init_Handle.Init.FIFOMode 				= DMA_FIFOMODE_DISABLE;DMA_Init_Handle.Init.FIFOThreshold 			= DMA_FIFO_THRESHOLD_HALFFULL;DMA_Init_Handle.Init.MemBurst 				= DMA_MBURST_SINGLE;DMA_Init_Handle.Init.PeriphBurst 			= DMA_PBURST_SINGLE;// 選擇 DMA 通道,通道存在于流中DMA_Init_Handle.Init.Channel 				= DMA_CHANNEL_0;//初始化DMA流,流相當于一個大的管道,管道里面有很多通道HAL_DMA_Init(&DMA_Init_Handle);__HAL_LINKDMA(&ADC_Handle, DMA_Handle, DMA_Init_Handle);ADC_Handle.Instance 					= ADC1;ADC_Handle.Init.ClockPrescaler 			= ADC_CLOCKPRESCALER_PCLK_DIV4;ADC_Handle.Init.Resolution 				= ADC_RESOLUTION_12B;ADC_Handle.Init.ScanConvMode 			= ENABLE;ADC_Handle.Init.ContinuousConvMode 		= ENABLE;ADC_Handle.Init.DiscontinuousConvMode 	= DISABLE;ADC_Handle.Init.NbrOfDiscConversion   	= 0;ADC_Handle.Init.ExternalTrigConvEdge 	= ADC_EXTERNALTRIGCONVEDGE_NONE;ADC_Handle.Init.ExternalTrigConv 		= ADC_SOFTWARE_START;ADC_Handle.Init.DataAlign 				= ADC_DATAALIGN_LEFT;ADC_Handle.Init.NbrOfConversion 		= 2;ADC_Handle.Init.DMAContinuousRequests 	= ENABLE;ADC_Handle.Init.EOCSelection          	= ADC_EOC_SINGLE_CONV;HAL_ADC_Init(&ADC_Handle);ADC_ChannelConfTypeDef ADC_Config;ADC_Config.Channel      = ADC_CHANNEL_9;ADC_Config.Rank         = 1;ADC_Config.SamplingTime = ADC_SAMPLETIME_3CYCLES;ADC_Config.Offset       = 0;HAL_ADC_ConfigChannel(&ADC_Handle, &ADC_Config);/** Configure the analog watchdog*/ADC_AnalogWDGConfTypeDef AnalogWDGConfig = {0};AnalogWDGConfig.WatchdogMode 	= ADC_ANALOGWATCHDOG_SINGLE_REG;AnalogWDGConfig.HighThreshold 	= VBUS_HEX_MAX;AnalogWDGConfig.LowThreshold 	= VBUS_HEX_MIN;AnalogWDGConfig.Channel 		= ADC_CHANNEL_8;AnalogWDGConfig.ITMode 			= ENABLE;if (HAL_ADC_AnalogWDGConfig(&ADC_Handle, &AnalogWDGConfig) != HAL_OK){while (1);}/** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.*/ADC_Config.Channel 		= ADC_CHANNEL_8;ADC_Config.Rank 		= 2;ADC_Config.SamplingTime = ADC_SAMPLETIME_3CYCLES;ADC_Config.Offset       = 0;if (HAL_ADC_ConfigChannel(&ADC_Handle, &ADC_Config) != HAL_OK){while (1);}// 外設中斷優先級配置和使能中斷配置HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 4, 0);HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);HAL_NVIC_SetPriority(ADC_IRQn, 3, 0);HAL_NVIC_EnableIRQ(ADC_IRQn);HAL_ADC_Start_DMA(&ADC_Handle, (uint32_t *)&adc_buff, 1024);
}

配置基本定時器6產生定時中斷讀取當前電路中驅動電機的電流值并執行PID運算
TIM_HandleTypeDef TIM_TimeBaseStructure;/*** @brief  初始化基本定時器定時,默認50ms產生一次中斷* @param  無* @retval 無*/
void TIMx_Configuration(void)
{HAL_NVIC_SetPriority(TIM6_DAC_IRQn, 1, 3);HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn);__TIM6_CLK_ENABLE();TIM_TimeBaseStructure.Instance = TIM6;TIM_TimeBaseStructure.Init.Period = 50 * 50 - 1;TIM_TimeBaseStructure.Init.Prescaler = 1680 - 1;TIM_TimeBaseStructure.Init.CounterMode = TIM_COUNTERMODE_UP;TIM_TimeBaseStructure.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;HAL_TIM_Base_Init(&TIM_TimeBaseStructure);// 開啟定時器更新中斷HAL_TIM_Base_Start_IT(&TIM_TimeBaseStructure);uint32_t temp = (__HAL_TIM_GET_AUTORELOAD(&TIM_TimeBaseStructure) + 1) / 50.0;  // 計算周期,單位msset_computer_value(SEND_PERIOD_CMD, CURVES_CH1, &temp, 1);  					// 給通道 1 發送目標值
}/*** @brief  定時器更新事件回調函數* @param  無* @retval 無*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if (htim == (&TIM_TimeBaseStructure)){motor_pid_control();	// 每50ms執行一次PID運算}
}

配置定時器1輸出PWM控制電機
TIM_HandleTypeDef  DCM_TimeBaseStructure;/*** @brief  初始化控制通用定時器* @param  無* @retval 無*/
void Motor_TIMx_Configuration(void)
{GPIO_InitTypeDef GPIO_InitStruct;TIM_OC_InitTypeDef  TIM_OCInitStructure;__HAL_RCC_GPIOA_CLK_ENABLE();__TIM1_CLK_ENABLE();// PA8--PWM_TIM_CH1GPIO_InitStruct.Pin 		= GPIO_PIN_8;GPIO_InitStruct.Mode 		= GPIO_MODE_AF_PP;GPIO_InitStruct.Speed 		= GPIO_SPEED_FREQ_HIGH;GPIO_InitStruct.Alternate 	= PWM_TIM_GPIO_AF;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);// PA9--PWM_TIM_CH2GPIO_InitStruct.Pin 		= GPIO_PIN_9;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);// TIM1 66.7us一次周期DCM_TimeBaseStructure.Instance = TIM1;DCM_TimeBaseStructure.Init.Period = 5600 - 1;DCM_TimeBaseStructure.Init.Prescaler = 1 - 1;DCM_TimeBaseStructure.Init.CounterMode = TIM_COUNTERMODE_UP;DCM_TimeBaseStructure.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;HAL_TIM_PWM_Init(&DCM_TimeBaseStructure);/*PWM模式配置*/TIM_OCInitStructure.OCMode = TIM_OCMODE_PWM1;TIM_OCInitStructure.Pulse = 0;TIM_OCInitStructure.OCPolarity = TIM_OCPOLARITY_HIGH;TIM_OCInitStructure.OCNPolarity = TIM_OCNPOLARITY_HIGH;TIM_OCInitStructure.OCIdleState = TIM_OCIDLESTATE_SET;TIM_OCInitStructure.OCNIdleState = TIM_OCNIDLESTATE_RESET;/*配置PWM通道*/HAL_TIM_PWM_ConfigChannel(&DCM_TimeBaseStructure, &TIM_OCInitStructure, TIM_CHANNEL_1);/*開始輸出PWM*/HAL_TIM_PWM_Start(&DCM_TimeBaseStructure, TIM_CHANNEL_1);/*配置PWM通道*/HAL_TIM_PWM_ConfigChannel(&DCM_TimeBaseStructure, &TIM_OCInitStructure, TIM_CHANNEL_2);/*開始輸出PWM*/HAL_TIM_PWM_Start(&DCM_TimeBaseStructure, TIM_CHANNEL_2);
}/*** @brief  設置TIM通道的占空比* @param  channel		通道	(1,2,3,4)* @param  compare		占空比*	@note 	無* @retval 無*/
void TIM1_SetPWM_pulse(uint32_t channel, int compare)
{switch (channel){case TIM_CHANNEL_1:__HAL_TIM_SET_COMPARE(&DCM_TimeBaseStructure, TIM_CHANNEL_1, compare);break;case TIM_CHANNEL_2:__HAL_TIM_SET_COMPARE(&DCM_TimeBaseStructure, TIM_CHANNEL_2, compare);break;case TIM_CHANNEL_3:__HAL_TIM_SET_COMPARE(&DCM_TimeBaseStructure, TIM_CHANNEL_3, compare);break;case TIM_CHANNEL_4:__HAL_TIM_SET_COMPARE(&DCM_TimeBaseStructure, TIM_CHANNEL_4, compare);break;}
}

ADC數據處理
static uint16_t flag_num = 0;
/*** @brief  常規轉換在非阻塞模式下完成回調* @param  hadc: ADC  句柄.* @retval 無*/
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{uint32_t adc_mean = 0;HAL_ADC_Stop_DMA(hadc);       // 停止 ADC 采樣,處理完一次數據在繼續采樣/* 計算電流通道采樣的平均值 */for (uint32_t count = 0; count < 1024; count += 2){adc_mean += (uint32_t)adc_buff[count];}adc_mean_sum += adc_mean / (1024 / 2);    // 保存平均值adc_mean_count++;adc_mean = 0;/* 計算電壓通道采樣的平均值 */for (uint32_t count = 1; count < 1024; count += 2){adc_mean += (uint32_t)adc_buff[count];}vbus_adc_mean = adc_mean / (1024 / 2);    // 保存平均值HAL_ADC_Start_DMA(&ADC_Handle, (uint32_t *)&adc_buff, 1024); // 開始 ADC 采樣
}/*** @brief  在非阻塞模式模擬看門狗回調* @param  hadc: ADC  句柄.* @retval 無*/
void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef *hadc)
{float temp_adc;flag_num++;     	// 電源電壓超過閾值電壓temp_adc = get_vbus_val();if (temp_adc > VBUS_MIN && temp_adc < VBUS_MAX){flag_num = 0;}if (flag_num > 10) 	// 電源電壓超過閾值電壓10次{set_motor_disable();flag_num = 0;printf("電源電壓超過限制!請檢查原因,復位開發板在試!\r\n");while (1);}
}/*** @brief  獲取電流值(應定時調用)* @param  無* @retval 轉換得到的電流值*/
int32_t get_curr_val(void)
{static uint8_t flag = 0;static uint32_t adc_offset = 0;    				// 偏置電壓int16_t curr_adc_mean = 0;         				// 電流 ACD 采樣結果平均值curr_adc_mean = adc_mean_sum / adc_mean_count;  // 保存平均值adc_mean_count = 0;adc_mean_sum = 0;if (flag < 17 && is_motor_en == 0)				//	僅在電機未啟動時記錄{adc_offset = curr_adc_mean;    				// 多次記錄偏置電壓,待系統穩定偏置電壓才為有效值flag += 1;}if (curr_adc_mean >= adc_offset){curr_adc_mean -= adc_offset;                // 減去偏置電壓}else{curr_adc_mean = 0;}float vdc = (float)curr_adc_mean/(float)65536 * 3.3f;	// 獲取電壓值return (float)vdc / 8.0f / 0.02f * 1000.0f;
}/*** @brief  獲取電源電壓值* @param  無* @retval 轉換得到的電流值*/
float get_vbus_val(void)
{float vdc = (float)vbus_adc_mean/(float)65536 * 3.3f;	// 獲取電壓值return ((float)vdc - (float)1.24) * (float)37.0;		// 電源電壓值(測量電壓是電源電壓的1/37)
}

編寫位置式PID算法
typedef struct
{float target_val;	// 目標值float actual_val;	// 實際值float err;       	// 定義偏差值float err_last;  	// 定義上一個偏差值float Kp,Ki,Kd;  	// 定義比例、積分、微分系數float integral;  	// 定義積分值
}_pid;
_pid pid;/*** @brief  PID參數初始化*	@note 	無* @retval 無*/
void PID_param_init()
{/* 初始化參數 */pid.target_val 	= 40.0;pid.actual_val 	= 0.0;pid.err 		= 0.0;pid.err_last 	= 0.0;pid.integral 	= 0.0;pid.Kp 			= 0;pid.Ki 			= 3.5;pid.Kd 			= 0;float pid_temp[3] = {pid.Kp, pid.Ki, pid.Kd};set_computer_value(SEND_P_I_D_CMD, CURVES_CH1, pid_temp, 3);     // 給通道 1 發送 P I D 值
}/*** @brief  設置目標值* @param  val		目標值*	@note 	無* @retval 無*/
void set_pid_target(float temp_val)
{pid.target_val = temp_val;    // 設置當前的目標值
}/*** @brief  獲取目標值* @param  無*	@note 	無* @retval 目標值*/
float get_pid_target(void)
{return pid.target_val;    // 設置當前的目標值
}/*** @brief  設置比例、積分、微分系數* @param  p:比例系數 P* @param  i:積分系數 i* @param  d:微分系數 d*	@note 	無* @retval 無*/
void set_p_i_d(float p, float i, float d)
{pid.Kp = p;    // 設置比例系數 Ppid.Ki = i;    // 設置積分系數 Ipid.Kd = d;    // 設置微分系數 D
}/*** @brief  PID算法實現* @param  actual_val:實際值*	@note 	無* @retval 通過PID計算后的輸出*/
float PID_realize(float actual_val)
{/* 限制電流幅值,野火電機空載時最大電流在100ma左右,如果過大容易積分飽和 */if (pid.target_val >= 120){pid.target_val = 120.0;}else if (pid.target_val <= 5){pid.target_val = 0.0;}/*計算目標值與實際值的誤差*/pid.err = pid.target_val - actual_val;/*誤差累積*/pid.integral += pid.err;/*PID算法實現*/pid.actual_val = pid.Kp * pid.err + pid.Ki * pid.integral + pid.Kd * (pid.err - pid.err_last);/*誤差傳遞*/pid.err_last = pid.err;/*返回當前實際值*/return pid.actual_val;
}/*** @brief  定時器每50ms產生一次中斷回調函數* @param  htim:定時器句柄* @retval 無*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if (htim == (&TIM_TimeBaseStructure)){motor_pid_control();}
}/*** @brief  電機位置式 PID 控制實現(定時調用)* @param  無* @retval 無*/
void motor_pid_control(void)
{int32_t actual_current = get_curr_val();    // 讀取當前電流值if (is_motor_en == 1)     					// 電機在使能狀態下才進行控制處理{float cont_val = 0;                     // 當前控制值cont_val = PID_realize(actual_current); // 進行 PID 計算if (cont_val < 0){cont_val = 0;    // 下限處理}else if (cont_val > 5500){cont_val = 5600;    // 速度上限處理}set_motor_speed(cont_val);              // 設置 PWM 占空比set_computer_value(SEND_FACT_CMD, CURVES_CH1, &actual_current, 1);  // 給通道 1 發送實際值}
}

直流電機電流環控制-增量式PID實現

編程要點

配置ADC可讀取電流值

配置基本定時器產生定時中斷讀取當前電路中驅動電機的電流值并執行PID運算

配置定時器輸出PWM控制電機

編寫增量式PID算法

編寫電流控制函數

增加上位機曲線觀察相關代碼

編寫按鍵控制代碼

配置ADC可讀取電流值

同上。

配置基本定時器6產生定時中斷讀取當前電路中驅動電機的電流值并執行PID運算

同上。

配置定時器1輸出PWM控制電機

同上。

ADC數據處理

同上。

編寫增量式PID算法
typedef struct
{float target_val; 	//目標值float actual_val; 	//實際值float err;        	//定義當前偏差值float err_next;   	//定義下一個偏差值float err_last;   	//定義最后一個偏差值float Kp, Ki, Kd; 	//定義比例、積分、微分系數
}_pid;
_pid pid;/*** @brief  PID參數初始化*	@note 	無* @retval 無*/
void PID_param_init()
{/* 初始化參數 */pid.target_val 	= 80;pid.actual_val 	= 0.0;pid.err 		= 0.0;pid.err_last	= 0.0;pid.err_next	= 0.0;pid.Kp 			= 0;pid.Ki 			= 2.8;pid.Kd 			= 0;float pid_temp[3] = {pid.Kp, pid.Ki, pid.Kd};set_computer_value(SEND_P_I_D_CMD, CURVES_CH1, pid_temp, 3);     // 給通道 1 發送 P I D 值
}/*** @brief  設置目標值* @param  val		目標值*	@note 	無* @retval 無*/
void set_pid_target(float temp_val)
{pid.target_val = temp_val;    // 設置當前的目標值
}/*** @brief  獲取目標值* @param  無*	@note 	無* @retval 目標值*/
float get_pid_target(void)
{return pid.target_val;    // 設置當前的目標值
}/*** @brief  設置比例、積分、微分系數* @param  p:比例系數 P* @param  i:積分系數 i* @param  d:微分系數 d*	@note 	無* @retval 無*/
void set_p_i_d(float p, float i, float d)
{pid.Kp = p;    // 設置比例系數 Ppid.Ki = i;    // 設置積分系數 Ipid.Kd = d;    // 設置微分系數 D
}/*** @brief  PID算法實現* @param  actual_val:實際值*	@note 	無* @retval 通過PID計算后的輸出*/
float PID_realize(float actual_val)
{/*計算目標值與實際值的誤差*/pid.err = pid.target_val - actual_val;/*PID算法實現*/pid.actual_val += pid.Kp * (pid.err - pid.err_next) + pid.Ki * pid.err + pid.Kd * (pid.err - 2 * pid.err_next + pid.err_last);/* 限幅輸出,防止深度飽和 */if (pid.actual_val > 5600){pid.actual_val = 5600;}else if (pid.actual_val <= 0){pid.actual_val = 0;}/*傳遞誤差*/pid.err_last = pid.err_next;pid.err_next = pid.err;/*返回當前實際值*/return pid.actual_val;
}/*** @brief  定時器每50ms產生一次中斷回調函數* @param  htim:定時器句柄* @retval 無*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if (htim == (&TIM_TimeBaseStructure)){motor_pid_control();}
}/*** @brief  電機增量式 PID 控制實現(定時調用)* @param  無* @retval 無*/
void motor_pid_control(void)
{int32_t actual_current = get_curr_val();    // 讀取當前電流值if (is_motor_en == 1)     					// 電機在使能狀態下才進行控制處理{float cont_val = 0;                    	// 當前控制值static __IO int32_t Capture_Count = 0; 	// 當前時刻總計數值static __IO int32_t Last_Count = 0;    	// 上一時刻總計數值cont_val = PID_realize(actual_current); // 進行 PID 計算if (cont_val > 0)    // 判斷電機方向{//set_motor_direction(MOTOR_FWD);}else{cont_val = 0;//      cont_val = -cont_val;//set_motor_direction(MOTOR_REV);}cont_val = (cont_val > PWM_MAX_PERIOD_COUNT) ? PWM_MAX_PERIOD_COUNT : cont_val;    	// 速度上限處理set_motor_speed(cont_val);                                                 			// 設置 PWM 占空比set_computer_value(SEND_FACT_CMD, CURVES_CH1, &actual_current, 1);                	// 給通道 1 發送實際值}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/163698.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/163698.shtml
英文地址,請注明出處:http://en.pswp.cn/news/163698.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

3、領導跟你談話,講到你的團隊里面的好友,公司會進行觀察裁員,你會去傳話么?

作為一個團隊成員&#xff0c;我會認真聽取領導的意見&#xff0c;并尊重公司的決定。然而&#xff0c;作為一個好友&#xff0c;我也會考慮他們的利益&#xff0c;我會與他們溝通&#xff0c;提醒他們注意自己的表現和工作&#xff0c;努力提高業績和工作質量&#xff0c;以確…

5個免費在線工具推薦

NSDT 三維場景建模工具GLTF/GLB在線編輯器Three.js AI自動紋理化開發包YOLO 虛幻合成數據生成器3D模型在線轉換 1、NSDT 三維場景建模 訪問地址&#xff1a;NSDT 編輯器 2、GLTF/GLB在線編輯器 訪問地址&#xff1a;GLTF 編輯器 3、Three.js AI自動紋理化開發包 圖一為原始模…

Linux下安裝兩個版本python

1 python下載&#xff1a; 官網地址&#xff1a;Download Python | Python.org 第一&#xff1a;點擊下載如下圖&#xff1a; 第二&#xff1a;找到對應的python版本源碼包&#xff1a; 點擊右鍵復制下載地址&#xff0c;如下圖 例如我的是&#xff1a;https://www.python.org/…

【鴻蒙應用ArkTS開發系列】- 云開發入門實戰二 實現省市地區聯動地址選擇器組件(上)

目錄 概述 云數據庫開發 一、創建云數據庫的對象類型。 二、預置數據&#xff08;為對象類型添加數據條目&#xff09;。 三、部署云數據庫 云函數實現業務邏輯 一、創建云函數 二、云函數目錄講解 三、創建resources目錄 四、獲取云端憑據 五、導出之前創建的元數據…

企業如何通過軟文推廣提高競爭力

數字時代我們每天接收到的信息遠遠超過可接受的量&#xff0c;且技術進步帶來的“信息繭房”使用戶很難獲取真正有效的信息&#xff0c;但越是雜亂的信息環境&#xff0c;有價值信息的穿透力就越強&#xff0c;軟文推廣正是憑借價值感信息助力企業提高競爭力&#xff0c;接下來…

RabbitMQ快速學習之WorkQueues模型、三種交換機、消息轉換器(SpringBoot整合)

文章目錄 前言一、WorkQueues模型消息發送消息接收能者多勞 二、交換機類型1.Fanout交換機消息發送消息接收 2.Direct交換機消息接收消息發送 3.Topic交換機消息發送消息接收 三、編程式聲明隊列和交換機fanout示例direct示例基于注解 四、消息轉換器總結 前言 WorkQueues模型…

C plus plus

環境配置 vscodewindows vscode c 環境配置(終極版)_vscode配置c/c環境_BangBang的博客-CSDN博客VsCode安裝和配置C環境詳細全流程_vscode安裝c-CSDN博客MinGW、MinGW-w64 與TDM-GCC 應該如何選擇&#xff1f; - 知乎、VsCode安裝和配置C環境詳細全流程_vscode安裝c-CSDN博客 …

?LeetCode解法匯總5-正則表達式匹配?

目錄鏈接&#xff1a; 力扣編程題-解法匯總_分享記錄-CSDN博客 GitHub同步刷題項目&#xff1a; https://github.com/September26/java-algorithms 原題鏈接&#xff1a;力扣&#xff08;LeetCode&#xff09;官網 - 全球極客摯愛的技術成長平臺 描述&#xff1a; 「HTML 實…

Educoder中Hive綜合應用案例——用戶學歷查詢

第1關:查詢每一個用戶從出生到現在的總天數 ---------- 禁止修改 ----------drop database if exists mydb cascade; ---------- 禁止修改 -------------------- begin ---------- ---創建mydb數據庫 create database mydb;---使用mydb數據庫 use mydb;---創建表user create …

電腦找不到xinput1_3.dll怎么修復,快速處理dll問題的5個方法分享

在使用電腦的過程中&#xff0c;我們常常會遇到一些常見的問題&#xff0c;其中之一就是“電腦缺少xinput1_3.dll”。這個問題可能會影響到我們對電腦的使用體驗&#xff0c;甚至導致某些軟件無法正常運行。在我遇到這個問題并解決之后&#xff0c;我深刻地體會到了解決問題的重…

迅鐳激光板材切割自動化生產線中標高端機械裝備龍頭豪邁集團!

近年來&#xff0c;中國制造業逐步由低端制造業向高端制造業邁進、由勞動密集型向技術密集型轉變&#xff0c;智能制造帶動了制造業生產環節的自動化、信息化、數字化、智能化的迭代升級。 位于山東省的高端機械裝備龍頭——豪邁集團&#xff0c;緊跟國家發展戰略&#xff0c;加…

【Spring集成MyBatis】MyBatis的Dao層實現(基于配置,非注解開發)

文章目錄 1. MyBatis的dao層實現(傳統方式)——需要寫接口及其實現類2. MyBatis的代理開發方式——僅需寫接口 1. MyBatis的dao層實現(傳統方式)——需要寫接口及其實現類 傳統方式就是在項目下邊建立dao包&#xff0c;里面包含接口及其實現類&#xff0c;文件結構如下&#x…

交直流一體化電源系統測試步驟詳解

交直流一體化電源擁有高度適應性&#xff0c;可以用于不同的電力需求領域。但是為了確保其質量和性能&#xff0c;需要對交直流一體化電源進行各項測試以保證正常工作。本文納米軟件將介紹交直流一體化電源的測試方法&#xff0c;以及如何用交直流一體化電源測試系統進行測試。…

Java,數據結構與集合源碼,關于Map接口的實現類(HashMap、LinkedHashMap)

HashMap中的元素的特點&#xff1a; HashMap中的所有key之間是不可重復的、無序的。所有的key構成一個Set集合。 HashMap中的所有的value彼此之間是可重復的、無序的。所有的value構成一個Collection集合。 HashMap中的一對key-value&#xff0c;就構成了一個entry。Map中的ent…

python常用第三方模塊---openyxl

openyxl模塊&#xff1a;用于處理excel文件的木塊&#xff0c;可以Excel中的數據進行寫入和讀取 函數或類的名稱功能描述load_workbook(filename)打開已經存在的工作簿&#xff0c;結果為工作簿對象 workbook.sheetnames 工作簿對象的sheetnames屬性&#xff0c;用戶獲取所有工…

深入理解 pytest Fixture 方法及其應用!

當涉及到編寫自動化測試時&#xff0c;測試框架和工具的選擇對于測試用例的設計和執行非常重要。在Python 中&#xff0c;pytest是一種廣泛使用的測試框架&#xff0c;它提供了豐富的功能和靈活的擴展性。其中一個很有用的功 能是fixture方法&#xff0c;它允許我們初始化測試環…

《實現領域驅動設計》筆記——上下文映射圖

一個項目的上下文映射圖可以用方式來表示。比較容易的一種是畫一個簡單的框圖表示兩個或多個限界上下文之間的映射關系。該框圖表示了不同的限界上下文在解決方案空間中是如何通過集成相互關聯的。另一種更詳細的方式是通過限界上下文集成的源代碼實現來表示。 上下文映射圖為什…

微軟WHQL認證

windows驅動開發要擺脫在測試模式下的開發&#xff0c;需要通過WHQL認證。 1&#xff1a;申請EV代碼簽名證書。EV代碼簽名證書在后續注冊Windows硬件開發中心帳戶&#xff0c;以及提交WHQL認證前為驅動程序進行數字簽名等流程中都需要用到&#xff0c;所以申請EV代碼簽名證書是…

唯一索引和普通索引的使用上要注意什么

考慮下面一種情況&#xff1a; select name from CUser where id_card xxxxxxxyyyyyyzzzzz;你可能會將id_card作為主鍵了&#xff0c;但最好別這么做。你想想這么長一串的字符串做主鍵&#xff0c;查詢時候效率其實是比較低的&#xff0c;其實是建議選擇其他的作為主鍵。 那么…

BUUCTF [SWPU2019]我有一只馬里奧 1

BUUCTF:https://buuoj.cn/challenges 題目描述&#xff1a; 得到的 flag 請包上 flag{} 提交。 密文&#xff1a; 下載附件&#xff0c;得到一個.exe文件。 解題思路&#xff1a; 1、雙擊.exe文件運行&#xff0c;得到一個1.txt文本。打開&#xff0c;如下圖。 2、提示我們…