电赛 | 电源题软件如何准备?
關注、星標公眾號,直達精彩內容
摘要:PWM和SPWM在電源的備戰中是很有必要的。基礎的恒流源、恒壓源需要使用PWM的占空比及頻率來達到數控的作用,往后的逆變則需要用到SPWM。當然還有ADC、DAC、IIC、SPI、算法。
一、PWM/SPWM
脈沖寬度調制(PWM),是英文“Pulse Width Modulation”的縮寫,簡稱脈寬調試。是利用微處理器的數字輸出來對模擬電路進行控制的一種非常有效的技術。廣泛應用在從測量、通信到功率控制與變換的許多領域中。
SPWM(Sinusoidal PWM) 法是一種比較成熟的、使用較廣泛的PWM法。沖量相等而形狀不同的窄脈沖加在具有慣性的環節上時,其效果基本相同。SPWM法就是以該結論為理論基礎,用脈沖寬度按正弦規律變化而和正弦波等效的PWM波形即SPWM波形控制逆變電路中開關器件的通斷,使其輸出的脈沖電壓的面積與所希望輸出的正弦波在相應區間內的面積相等,通過改變調制波的頻率和幅值則可調節逆變電路輸出電壓的頻率和幅值。
1、CubeMX相關配置-PWM
使能PWM通道
在這里我將TIM2的Channel1設置為PWM輸出通道(PWM Generation CHx 正向、PWM Generation CHxN 反向、PWM Generation CHx CHxN一對互補pwm輸出)
使能PWM通道配置頻率及占空比
頻率 = 定時器時鐘 / (Prescaler 預分頻 + 1)/ (Counter Period 計數值 + 1)Hz
占空比 = Pulse ( 對比值) / (C ounter Period 計數值)%
配置頻率及占空比2、編寫業務代碼-PWM
//?使能timx的通道y HAL_TIM_PWM_Start(&htimx,TIM_CHANNEL_y); //?修改timx的通道y的pwm比較值為z,即修改占空比 __HAL_TIM_SET_COMPARE(&htimx,?TIM_CHANNEL_y,?z);pwm 的輸出是很簡單的,但是因為定時器的頻率是有上限的通常需要在頻率和pwm的精細度兩者之間做取舍。所以你想做電源,那么你可以了解一下STM32F334這款處理器,它擁有一個高分辨率定時器 (HRTIM),能將定時器的頻率倍頻至4.096G。那你在頻率和pwm的精細度兩者都可以兼得。
SPWM 其實就是在 PWM 的基礎上,讓 PWM 的占空比做正弦變化。
3、CubeMX相關配置-SPWM
之前的 PWM 生成的操作不變,只需要開啟一個新的定時器,配置完后需要開啟定時器中斷
開啟一個新的定時器4、使用軟件生成正弦向量表-SPWM
SPWM 中值 = Pulse ( 對比值) /2SPWM 幅值 = Pulse ( 對比值) /2
周內點數影響頻率與正弦波精細度。周內點數越大,頻率越小、正弦波精細度越高。
使用軟件生成正弦向量表5、編寫業務代碼-SPWM
uint16_t?sin[]?=? {1800,1913,2025,2137,2247,2356,2462,2566,2667,2764,2858,2947,3032,3112,3186,3256,3319,3377,3428,3473,3511,3543,3568,3585,3596,3600,3596,3585,3568,3543,3511,3473,3428,3377,3319,3256,3186,3112,3032,2947,2858,2764,2667,2566,2462,2356,2247,2137,2025,1913,1800,1686,1574,1462,1352,1243,1137,1033,932,835,741,652,567,487,413,343,280,222,171,126,88,56,31,14,3,0,3,14,31,56,88,126,171,222,280,343,413,487,567,652,741,835,932,1033,1137,1243,1352,1462,1574,1686 } int?main() {HAL_TIM_PWM_Start(&htimx,TIM_CHANNEL_y);?//?開啟pwm輸出HAL_TIM_Base_Start_IT(&htimz);?//使能剛剛配置的定時器zwhile(1){} } /** *?@brief?定時器中斷的回調函數 *?@param?htim?觸發中斷的定時器 *?@retval?None */ void?HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef?*htim) {static?int?i?=?0;if(++i?==?size)i?=?0;if?(htim->Instance?==?htim3.Instance){__HAL_TIM_SET_COMPARE(&htimx,?TIM_CHANNEL_y,?sin[i]);?//由向量表修改占空比} }二、ADC/SDADC/ADS
先介紹最簡單的片上 ADC,通常是 12 位,精度則為 3.3/4096 v。讀取 ADC 的方式有很多:
1、輪詢
2、中斷
3、DMA
因為在實際開發中僅有輪詢和 DMA 存在使用場景,所以在這里我僅介紹輪詢和DMA 的方式。
1、CubeMX相關配置-輪詢方式
使能ADC引腳2、編寫業務代碼-輪詢方式
while(1) {HAL_ADC_Start(&hadc1);//啟動ADC裝換HAL_ADC_PollForConversion(&hadc1,?50);//等待轉換完成,第二個參數表示超時時間,單位ms.if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1),?HAL_ADC_STATE_REG_EOC)){AD_Value?=?HAL_ADC_GetValue(&hadc1);//讀取ADC轉換數據,數據為12位printf("[\tmain]info:v=%.1fmv\r\n",AD_Value*3300.0/4096);//打印日志} }前面介紹了通過 ADC 輪詢的方式采集單通道的數據。現在介紹一下通過 DMA 方式采集多通道的數據。
3、CubeMX相關配置-DMA方式
3.1初始化兩個ADC通道
3.2、配置相關屬性
使能掃描轉換模式 (Scan Conversion Mode), 使能連續轉換模式 (Continuous Conversion Mode)。
ADC 規則組選擇轉換通道數為 2(Number Of Conversion)。
配置 Rank 的輸入通道。
3.3、添加 DMA
添加DMA設置,設置為連續傳輸模式,數據長度為字。
添加DMA4、編寫業務代碼-DMA 方式
1、在main 函數前面添加變量。其中 ADC_Value 作為轉換數據緩存數組,ad1,ad2 存儲PA0(轉換通道 0),PA1(轉換通道1) 的電壓值。
/*?USER?CODE?BEGIN?PV?*/ /*?Private?variables?*/ uint32_t?ADC_Value[100]; uint8_t?i; uint32_t?ad1,ad2; /*?USER?CODE?END?PV?*/2、在 while(1) 前面以 DMA 方式開啟 ADC 裝換。HAL_ADC_Start_DMA() 函數第二個參數為數據存儲起始地址,第三個參數為 DMA 傳輸數據的長度。
/*?USER?CODE?BEGIN?2?*/ HAL_ADC_Start_DMA(&hadc1,?(uint32_t*)&ADC_Value,?100); /*?USER?CODE?END?2?*/由于DMA采用了連續傳輸的模式,ADC采集到的數據會不斷傳到到存儲器中(此處即為數組 ADC_Value)。ADC采集的數據從 ADC_Value[0] 一直存儲到 ADC_Value[99],然后采集到的數據又重新存儲到ADC_Value[0],一直到ADC_Value[99]。所以ADC_Value數組里面的數據會不斷被刷新。
這個過程中是通過DMA控制的,不需要CPU參與。我們只需讀取ADC_Value里面的數據即可得到 ADC 采集到的數據。其中ADC_Value[0]為通道 0(PA0) 采集的數據,ADC_Value[1]為通道 1(PA1) 采集的數據,ADC_Value[2]為通道 0 采集的數據,如此類推。數組偶數下標的數據為通道 0 采集數據,數組奇數下標的數據為通道1采集數據。
在while(1) 循環中添加應用程序,將采集的數據裝換為電壓值并輸出。
/*?USER?CODE?BEGIN?WHILE?*/ while?(1) {/*?USER?CODE?END?WHILE?*//*?USER?CODE?BEGIN?3?*/HAL_Delay(500);for(i?=?0,ad1?=0,ad2=0;?i?<?100;){ad1?+=?ADC_Value[i++];ad2?+=?ADC_Value[i++];}ad1?/=?50;ad2?/=?50;printf("\r\n********ADC-DMA-Example********\r\n");printf("[\tmain]info:AD1_value=%1.3fV\r\n",?ad1*3.3f/4096);printf("[\tmain]info:AD2_value=%1.3fV\r\n",?ad2*3.3f/4096); } /*?USER?CODE?END?3?*/程序中將數組偶數下標數據加起來求平均值,實現均值濾波的功能,再將數據裝換為電壓值,即為PA0管腳的電壓值。同理對數組奇數下標數據處理得到PA1管腳的電壓值。
同時ADC采樣也可以采用我之前描述的采用定時器對其平滑濾波!
通常片上的ADC的精度往往達不到我們的要求,因為它的精度實在是太低了。有兩個替代方案:
1、SDADC, 這個是STM32F373上特有的功能,16位高速ADC,支持差分輸入。掌握難度較大,我也沒有很好的掌握,所以就不在此展示了。
2、ADS, 就是外置 ADC。在我們比賽前,我們一直調教的是 ADS1256 這款芯片,能做到 0.01mV 的精度!這類芯片只需要進行 SPI 通信操作,便可以獲取 ADC 數據。
三、DAC數模轉化
說實話,這兩年的開發中,我還沒有使用過 DAC 的功能。但是這個功能也十分簡單,配置好引腳后,編寫業務代碼即可。
1、CubeMX相關配置
勾選DAC中的OUT Configuration, 其余配置為默認配置不需修改。
CubeMX相關配置2、編寫業務代碼
//開啟DAC轉換 HAL_DAC_Start(&hdac,?DAC_CHANNEL_2); //?設置DAC的大小 HAL_DAC_SetValue(&hdac,?DAC_CHANNEL_2,?DAC_ALIGN_12B_R,?2048);編譯程序并下載到開發板。如果沒有出錯用萬用表測管腳的電壓為1.65V。
四、I2C/SPI
在開發中,使用到 I2C/SPI 的時候通常是與其他模塊間的通信,例如:使用I2C與OLED通信,使用 SPI 與ADS1256通信。所以在此情況下,我們只需要在模塊現有庫函數的基礎之上,做少量代碼的移植即可。
1、CubeMX相關配置-I2C
直接使能 I2C 即可。
CubeMX相關配置2、編寫業務代碼-I2C
//主機的發送 HAL_StatusTypeDef?HAL_I2C_Master_Transmit(I2C_HandleTypeDef?*hi2c,?uint16_t?DevAddress,?uint8_t?*pData,?uint16_t?Size,?uint32_t?Timeout); //主機的接收 HAL_StatusTypeDef?HAL_I2C_Master_Receive(I2C_HandleTypeDef?*hi2c,?uint16_t?DevAddress,?uint8_t?*pData,?uint16_t?Size,?uint32_t?Timeout); //從機的發送 HAL_StatusTypeDef?HAL_I2C_Slave_Transmit(I2C_HandleTypeDef?*hi2c,?uint8_t?*?pData,?uint16_t?Size,?uint32_t?Timeout); //從機的接收 HAL_StatusTypeDef?HAL_I2C_Slave_Receive(I2C_HandleTypeDef?*hi2c,?uint8_t?*pData,?uint16_t?Size,?uint32_t?Timeout);3、OLED 的移植-I2C
3.1、原有庫函數的代碼
... void?I2C_Configuration(void) {I2C_InitTypeDef?I2C_InitStructure;GPIO_InitTypeDef?GPIO_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);GPIO_InitStructure.GPIO_Pin?=?GPIO_Pin_6?|?GPIO_Pin_7;GPIO_InitStructure.GPIO_Speed?=?GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode?=?GPIO_Mode_AF_OD;GPIO_Init(GPIOB,?&GPIO_InitStructure);I2C_DeInit(I2C1);I2C_InitStructure.I2C_Mode?=?I2C_Mode_I2C;I2C_InitStructure.I2C_DutyCycle?=?I2C_DutyCycle_2;I2C_InitStructure.I2C_OwnAddress1?=?0x30;I2C_InitStructure.I2C_Ack?=?I2C_Ack_Enable;I2C_InitStructure.I2C_AcknowledgedAddress?=?I2C_AcknowledgedAddress_7bit;I2C_InitStructure.I2C_ClockSpeed?=?400000;I2C_Cmd(I2C1,?ENABLE);I2C_Init(I2C1,?&I2C_InitStructure); } void?I2C_WriteByte(uint8_t?addr,uint8_t?data) {while(I2C_GetFlagStatus(I2C1,?I2C_FLAG_BUSY));I2C_GenerateSTART(I2C1,?ENABLE);while(!I2C_CheckEvent(I2C1,?I2C_EVENT_MASTER_MODE_SELECT));I2C_Send7bitAddress(I2C1,?OLED_ADDRESS,?I2C_Direction_Transmitter);while(!I2C_CheckEvent(I2C1,?I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));I2C_SendData(I2C1,?addr);while?(!I2C_CheckEvent(I2C1,?I2C_EVENT_MASTER_BYTE_TRANSMITTED));I2C_SendData(I2C1,?data);while?(!I2C_CheckEvent(I2C1,?I2C_EVENT_MASTER_BYTE_TRANSMITTED));I2C_GenerateSTOP(I2C1,?ENABLE); } void?WriteCmd(unsigned?char?I2C_Command) {I2C_WriteByte(0x00,?I2C_Command); } void?WriteDat(unsigned?char?I2C_Data) {I2C_WriteByte(0x40,?I2C_Data); } void?OLED_Init(void) {DelayMs(100); ...3.2、移植代碼分析
I2C_Configuration其實就是I2C的初始化函數,CubeMX會幫我們生成,所以直接刪除
I2C_WriteByte被接下來的兩個函數依賴,但是HAL中有相應的函數,所以直接刪除
WriteCmd和WriteDat 改寫成HAL庫的方式
DelayMs改為 HAL 庫中的函數
3.3、移植后的代碼
... #include?"i2c.h" void?WriteCmd(unsigned?char?I2C_Command) {HAL_I2C_Mem_Write(&hi2c1,OLED_ADDRESS,0x00,I2C_MEMADD_SIZE_8BIT,&I2C_Command,1,100); } void?WriteDat(unsigned?char?I2C_Data) {HAL_I2C_Mem_Write(&hi2c1,OLED_ADDRESS,0x40,I2C_MEMADD_SIZE_8BIT,&I2C_Data,1,100); } void?OLED_Init(void) {HAL_Delay(100); ...4、CubeMX相關配置-SPI
使能SPI后,但是需要根據設備的不同做分頻處理。
CubeMX相關配置5、編寫業務代碼-SPI
//SPI的發送 HAL_StatusTypeDef?HAL_SPI_Transmit(SPI_HandleTypeDef?*hspi,?uint8_t?*pData,uint16_t?Size,?uint32_t?Timeout); //SPI的接收 HAL_StatusTypeDef?HAL_SPI_Receive(SPI_HandleTypeDef?*hspi,?uint8_t?*pData,uint16_t?Size,?uint32_t?Timeout); //SPI的發送和接收 HAL_StatusTypeDef?HAL_SPI_TransmitReceive(SPI_HandleTypeDef?*hspi,?uint8_t?*pTxData,?uint8_t?*pRxData,?uint16_t?Size, uint32_t?Timeout);6、ADS1256 的移植-SPI
SPI的移植比I2C的移植要難并且復雜很多,基本上所有的函數都需要做大大小小的改動,建議大家盡量不要自己移植,最好是在網上找到相關的資源。
五、FLASH
FLASH 的操作,不需要使用Cube MX做任何的配置,只需要做編程操作即可。
1、相關定義
#define?BaseAddress?((uint32_t)0x080E0000)?//?操作FLAH基地址 //需根據自己單片機的型號進行修改 uint32_t?paper_table[100]?=?{0}?;//需要寫入FLAH中的第一張表 uint32_t?pwm_table[100]?=?{0};//需要寫入FLAH中的第二張表 uint32_t?length_table?=?0;2、FLAH 的寫入
注意:我接下來提供的例程是來自STM32F407,不同板子間的FLASH_EraseInitTypeDef可能不同。
HAL_FLASH_Unlock(); FLASH_EraseInitTypeDef?f; f.TypeErase?=?FLASH_TYPEERASE_SECTORS; //F103中為FLASH_TYPEERASE_PAGES,即頁擦除 f.Sector?=?FLASH_SECTOR_11; //F103中為?f.PageAddress?=?BaseAddress?即開始操作的地址為BaseAddress f.NbSectors?=?1; //F103中為?f.NbPages?=?x,即擦除x頁 //設置PageError uint32_t?PageError?=?0; //調用擦除函數 HAL_FLASHEx_Erase(&f,?&PageError); //對FLASH燒寫 for(int?i?=?0;?i?<?100;?i++)? {HAL_FLASH_Program(TYPEPROGRAM_WORD,?(BaseAddress?+?4?*?i),?paper_table[i]); } for(int?i?=?0;?i?<?100;?i++)? {HAL_FLASH_Program(TYPEPROGRAM_WORD,?(BaseAddress?+?400?+?4?*?i),?pwm_table[i]); } //鎖住FLASH HAL_FLASH_Lock();3、FLAH 的讀取
FLAH的讀取十分簡單,只需要讀取相應地址上的值即可。
for(int?i?=?0;?i?<?100;?i++) {paper_table[i]?=?*(__IO?uint32_t*)?(BaseAddress?+?4?*?i); } for(int?i?=?0;?i?<?100;?i++)? {pwm_table[i]?=?*(__IO?uint32_t*)?(BaseAddress?+?400?+?4?*?i); } while(paper_table[length_table]?!=?0)? {length_table++; }六、算法-排序
這兩個模板,是我用了很久的,通過長時間的測試,我向你保證它是絕對的可靠!
1、快速排序
void?quick_sort(int?q[],?int?l,?int?r) {if?(l?>=?r)?return;int?i?=?l?-?1,?j?=?r?+?1,?x?=?q[l];while?(i?<?j){do?i?++?;?while?(q[i]?<?x);do?j?--?;?while?(q[j]?>?x);if?(i?<?j)?{q[i]?=?q[i]^q[j];q[j]?=?q[i]^q[j];q[i]?=?q[i]^q[j]; } else?break; }quick_sort(q,?l,?j),?quick_sort(q,?j?+?1,?r); }2、歸并排序
void?merge_sort(int?q[],?int?l,?int?r) {if?(l?>=?r)?return;int?mid?=?l?+?r?>>?1;merge_sort(q,?l,?mid);merge_sort(q,?mid?+?1,?r);int?k?=?0,?i?=?l,?j?=?mid?+?1;while?(i?<=?mid?&&?j?<=?r)if?(q[i]?<?q[j])?tmp[k?++?]?=?q[i?++?];else?tmp[k?++?]?=?q[j?++?];while?(i?<=?mid)?tmp[k?++?]?=?q[i?++?];while?(j?<=?r)?tmp[k?++?]?=?q[j?++?];for?(i?=?l,?j?=?0;?i?<=?r;?i?++,?j?++?)?q[i]?=?tmp[j]; }3、算法-MPPT
在做最大功率點追蹤,這個算法是十分重要的。我在這里分享一下我是怎么對其優化的,首先我寫了一個能實現功能的最基礎的版本。
4、基礎版本
#include?"mppt.h" #include?"main.h" #include?"usart.h" //上一次的功率 double?l_power?=?0.0?; //功率上升或下降 int?updown?=?0; //步長 int?MPPT_STEP?=?160; /*?擾動法計算 * */ int?mppt_po(double?u,?double?i,?int?pwm)? {double?power?=?(u?*?i)?<?0???0?:?u?*?i?;printf("[Info]mppt_po:當前電流:%f,當前電壓:%f,當前功率:%f\r\n",?i,?u,?power);if(power?<?l_power?||?power?==?0)?{updown?^=?1;printf("[Info]mppt_po:當前功率:%f,小于此前功率:%f\r\n",?power,?l_power);}if(updown)?{printf("[Info]mppt_po:PWM:%d調節為:%d\r\n",?pwm,?pwm?+?MPPT_STEP);pwm?+=?MPPT_STEP;}else?{printf("[Info]mppt_po:PWM:%d調節為:%d\r\n",?pwm,?pwm?-?MPPT_STEP);pwm?-=?MPPT_STEP;}printf("[Info]mppt_po:該次調節結束\r\n");pwm?=?pwm?<?0???0?:?(pwm?>=?1599???1599?:?pwm);l_power?=?power;return?pwm; }5、算法的不足與解決方案
1、這個算法一直在調節,這很有可能造成能量的損耗。解決方案:采用標志位,判斷是否穩定。
2、這個算法步長不變,從頭到尾固定步長。如果步長太長不精細,如果步長太短整體調節較慢。解決方案:采用可變步長。
3、使用三目運算符取代大量的if-else
4、Log信息采用條件編譯的方法(很早之前寫的,沒能采用串口的終極解決方案,有點遺憾)
5、抽離變量,寫出結構體,配以初始化函數。
6、最終版本
/** *?@file :mppt.c * *?@brief:?MPPT?最大功率點追蹤 * *?@auther?:?Reyunn * */ #include?"mppt.h" #include?"main.h" #include?"usart.h" extern?void?quick_sort(int?q[],?int?l,?int?r); typedef?struct? {double?l_power;//上一次的功率uint8_t?updown;//功率上升或下降int?max_step;//步長int?min_step;//步長int?pwm_max?;?//pwm最大值int?pwm_min?;?//pwm最小值uint8_t?count;?//計算微調次數uint8_t?state;?//狀態uint8_t?time;?//改變方向次數int?l_pwm[10]; }?MPPT;MPPT?mppt; /** *?@brief?mppt?初始化 *?@param?l_power?:?上次測量功率 *?@param?updown?:?上升或下降 *?@param min_step :最小步長 *?@param max_step :最大步長 *?@param?pwm_max?:?pwm最大值 *?@param?pwm_min?:?pwm最小值 *?@retval?None */ void?mppt_init(double?l_power,?uint8_t?updown,?int?min_step,?int?max_step,?int pwm_max,?int?pwm_min) {mppt.l_power?=?l_power;mppt.updown?=?updown;mppt.max_step?=?max_step;mppt.min_step?=?min_step;mppt.pwm_max?=?pwm_max;mppt.pwm_min?=?pwm_min;mppt.count?=?0;mppt.state?=?1;mppt.time?=?0; } /** *?@brief?擾動法計算 *?@param?u?:?當前電壓值 *?@param i :當前電流值 *?@param?pwm?:?當前pwm值 *?*?@retval?計算后的pwm值 */ int?mppt_po(double?u,?double?i,?int?pwm) {double?power?=?(u?*?i)?<?0???0?:?u?*?i?;if(mppt.state)?{#if?Logprintf("[info]mppt_po:當前電流:%f,當前電壓:%f,當前功率%f\r\n",?i,?u,?power);#endifif(power?<?mppt.l_power?||?pwm?==?mppt.pwm_max?||?pwm?==?mppt.pwm_min)?{mppt.updown?^=?1;mppt.time?++;if(mppt.time?>?5?&&?power?<?mppt.l_power?)?mppt.l_pwm[mppt.count++]?=?pwm;#if?Logprintf("[info]mppt_po:當前功率:%f,小于此前功率%f\r\n",?power,?mppt.l_power);#endif}pwm?=?(mppt.updown?==?1)???((mppt.count?>?0)???pwm?+?mppt.min_step?:?pwm?+mppt.max_step)?:?(?(mppt.count?>?0?)???pwm?-?mppt.min_step?:?pwm?-?mppt.max_step);pwm?=?(pwm?<?mppt.pwm_min?)???mppt.pwm_min?:?(?(pwm?>=?mppt.pwm_max)???mppt.pwm_max?:?pwm);mppt.l_power?=?power;if(mppt.count?==?10)?{mppt.state?=?0;quick_sort(mppt.l_pwm,?0,?9);return?(?mppt.l_pwm[5]?+?mppt.l_pwm[4]?+?mppt.l_pwm[3]?+?mppt.l_pwm[6]?)?/4;}return?pwm;}?else?{if(?power?-?mppt.l_power?>?1000?||?power?-?mppt.l_power?<?-1000?){mppt.count?=?0;mppt.state?=?1;mppt.time?=?0;#if?Logprintf("[info]mppt.c:進入調整模式\r\n");#endif}return?pwm;} }-END-
?電賽專欄?
關于2021年電賽的一些想法,看到就是賺到!?
「2020年電賽」電源題詳細技術方案,立即收藏!?
2020年電賽題目,命題專家權威解析!?
如何準備電賽?19年電賽經驗總結!?
電賽 | 19年全國一等獎,北航學子回憶錄(上)
電賽 | 19年全國一等獎,北航學子回憶錄(下)
「電賽分享」電源題,省一等獎!?
2019年電賽綜合測評怎么搞?國一師兄帶你終極大測評!
-END-
最后,整理了一份電賽資源,近五年電賽真題的資源(代碼、報告等),不過是付費的,如果有需要可以聯系下方微信:
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的电赛 | 电源题软件如何准备?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 刺激战场房间权限申请
- 下一篇: 腾讯棋牌游戏有哪些(腾讯视频VIP会员)