diff --git a/checher_slave.uvoptx b/checher_slave.uvoptx index 16fae3c..30bd841 100644 --- a/checher_slave.uvoptx +++ b/checher_slave.uvoptx @@ -103,7 +103,7 @@ 1 0 0 - 4 + 6 @@ -114,7 +114,7 @@ - Segger\JL2CM3.dll + STLink\ST-LINKIII-KEIL_SWO.dll @@ -381,18 +381,34 @@ 0 0 - 185 + 291 1 -
134234652
+
134275382
0 0 0 0 0 1 - .\source\rt_thread\libcpu\arm\cortex-m3\context_rvds.S + D:\work\SVN\鍐夊窛\mcu_program\checker_slave\source\interface\if_can.c - \\checker_slave_app\source/rt_thread/libcpu/arm/cortex-m3/context_rvds.S\185 + \\checker_slave_app\source/interface/if_can.c\291 +
+ + 1 + 0 + 22 + 1 +
134303466
+ 0 + 0 + 0 + 0 + 0 + 1 + D:\work\SVN\鍐夊窛\mcu_program\checker_slave\source\rt_thread\core_delay.c + + \\checker_slave_app\source/rt_thread/core_delay.c\22
@@ -406,7 +422,7 @@ 1 1 - 0x20002CE0 + 0x20002a00 0 @@ -476,16 +492,6 @@ - - - System Viewer\TIM4 - 35905 - - - System Viewer\TIM5 - 35904 - - 1 1 @@ -840,7 +846,7 @@ stm32lib - 1 + 0 0 0 0 @@ -1204,7 +1210,7 @@ dev - 1 + 0 0 0 0 @@ -2008,6 +2014,18 @@ 0 0 + + 9 + 99 + 1 + 0 + 0 + 0 + .\source\soft\filter.c + filter.c + 0 + 0 + @@ -2018,7 +2036,7 @@ 0 10 - 99 + 100 1 0 0 @@ -2030,7 +2048,7 @@ 10 - 100 + 101 1 0 0 @@ -2042,7 +2060,7 @@ 10 - 101 + 102 1 0 0 @@ -2054,7 +2072,7 @@ 10 - 102 + 103 1 0 0 @@ -2066,7 +2084,7 @@ 10 - 103 + 104 1 0 0 @@ -2078,7 +2096,7 @@ 10 - 104 + 105 1 0 0 @@ -2090,7 +2108,7 @@ 10 - 105 + 106 1 0 0 @@ -2110,7 +2128,7 @@ 0 11 - 106 + 107 1 0 0 @@ -2130,7 +2148,7 @@ 0 12 - 107 + 108 1 0 0 @@ -2142,7 +2160,7 @@ 12 - 108 + 109 1 0 0 @@ -2154,7 +2172,7 @@ 12 - 109 + 110 1 0 0 @@ -2166,7 +2184,7 @@ 12 - 110 + 111 1 0 0 @@ -2178,7 +2196,7 @@ 12 - 111 + 112 1 0 0 @@ -2190,7 +2208,7 @@ 12 - 112 + 113 1 0 0 @@ -2210,7 +2228,7 @@ 0 13 - 113 + 114 5 0 0 @@ -2230,7 +2248,7 @@ 0 14 - 114 + 115 5 0 0 @@ -2242,7 +2260,7 @@ 14 - 115 + 116 5 0 0 diff --git a/checher_slave.uvprojx b/checher_slave.uvprojx index 15db327..b363148 100644 --- a/checher_slave.uvprojx +++ b/checher_slave.uvprojx @@ -2344,6 +2344,113 @@ huffman.c 1 .\source\soft\huffman.c + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + filter.c + 1 + .\source\soft\filter.c + + + 2 + 0 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + @@ -3980,6 +4087,11 @@ 1 .\source\soft\huffman.c + + filter.c + 1 + .\source\soft\filter.c + @@ -5255,6 +5367,11 @@ 1 .\source\soft\huffman.c + + filter.c + 1 + .\source\soft\filter.c + diff --git a/python/prottcp.py b/python/prottcp.py index 8eb04c4..c5a8fdd 100644 --- a/python/prottcp.py +++ b/python/prottcp.py @@ -416,7 +416,7 @@ class protu(QObject): data_str.clear() except Exception as e: print(str(e)) - # print(recv_str) + print(recv_str) # else: # print("len(data)={d1},num_ro_recv={d2}".format(d1=len(data),d2=self.num_to_recv)) def send(self,cmd:int,data:bytearray): diff --git a/python/slave_test.py b/python/slave_test.py new file mode 100644 index 0000000..f54b532 --- /dev/null +++ b/python/slave_test.py @@ -0,0 +1,44 @@ +import prottcp +import time +import numpy as np + + + +#测试小板功能 + + + + +def random(): + return int(np.random.random_sample()*10000%10000) + + + +def numlist_to_str(numlist:list): + s="" + for i in numlist: + s+=str(i)+',' + return s[:-1] + + +def randomlist(num:int): + l=[] + for i in range(num): + l.append(random()) + return l + + +if __name__ == '__main__': + u=prottcp.protu() + u.init("com11:38400") + u.start_recv() + for i in range(10): + s='test '+numlist_to_str(randomlist(20)) + print("send:",s) + u.send_str(s) + time.sleep(1) + u.close() + + + + diff --git a/source/ReadMe.txt b/source/ReadMe.txt index f959a0b..b5c843d 100644 --- a/source/ReadMe.txt +++ b/source/ReadMe.txt @@ -335,3 +335,6 @@ 在槽任务失败且异常代码不为0时才会导致 CheckerExt_Slot 任务失败 2024.1.12 添加发送失败信息记录 +2021.2.3 + 充能统计添加中间值滤波 + 修改晶振起振超时时间和flash相关以适应gd32 diff --git a/source/core/stm32f10x.h b/source/core/stm32f10x.h index 8bf7624..aced8c7 100644 --- a/source/core/stm32f10x.h +++ b/source/core/stm32f10x.h @@ -125,7 +125,7 @@ * @brief In the following line adjust the External High Speed oscillator (HSE) Startup Timeout value */ -#define HSE_STARTUP_TIMEOUT ((uint16_t)0x0500) /*!< Time out for HSE start up */ +#define HSE_STARTUP_TIMEOUT ((uint16_t)0xFFFF) /*!< Time out for HSE start up */ #define HSI_VALUE ((uint32_t)8000000) /*!< Value of the Internal oscillator in Hz*/ diff --git a/source/elec_det/driver/JQDriver.c b/source/elec_det/driver/JQDriver.c index 4b615b1..deba957 100644 --- a/source/elec_det/driver/JQDriver.c +++ b/source/elec_det/driver/JQDriver.c @@ -5,6 +5,10 @@ #include "hardware/power.h" #include "hardware/timer_cfg.h" #include "hardware/power.h" +#include "filter.h" + + + volatile static uint16_t jq_idle_current; #define JQ_IDLE_NOISE 100 @@ -71,6 +75,40 @@ static void JQ_Sample(uint16_t sample_count) } } + + + +/* +@brief 采样总线反馈数据,使用滤波算法 +@param sample_count 采样次数 +*/ + + + +static void JQ_Sample_Filtering(uint16_t sample_count) +{ + uint16_t us_adv = 0; + uint16_t ul_count = 0; + filter_def f={0}; + us_adv = GetADC_Fast(ADC_CURR_DE); + jq_ad_last_sample=us_adv; + filter_init(&f,us_adv); + for(ul_count = 0;ul_count < sample_count; ul_count++) + { + // 保证在adc转换的期间完成滤波算法 + adc_start(ADC_CURR_DE); + filter_insert(&f,us_adv); + us_adv=filter_get_mid(&f); + JQ_Read_AD_V[ul_count] = us_adv; + jq_ad_last_sample = us_adv; + us_adv = adc_get_value(ADC_CURR_DE); + + } +} + + + + /* @brief 通信反码信息初始化 */ diff --git a/source/elec_det/hardware/adc_cfg.c b/source/elec_det/hardware/adc_cfg.c index e2557f1..a65cfcd 100644 --- a/source/elec_det/hardware/adc_cfg.c +++ b/source/elec_det/hardware/adc_cfg.c @@ -4,6 +4,9 @@ #include "timer_cfg.h" #include "base/utility.h" #include "power.h" +#include "filter.h" +#include "core_delay.h" + volatile uint16_t ad0_adc_sample[AD_SCAN_SAMPLE*AD_SCAN_COUNT]; #define ADC1_SAMPLE_BUF_LEN 200 #define ADC1_SAMPLE_BUF_LEN2 20 @@ -445,6 +448,71 @@ uint16_t AD_CurMonitor_(uint32_t ul_times) +/*rc{ + 使用过滤算法的充能统计 + 这个函数给出的都是adc原始值 + sample_timeout 单位是0.1ms +}*/ +uint16_t AD_GetChgEnergy(uint16_t sample_timeout, uint16_t end_adv,uint16_t* max_cul,uint16_t *shake_adv) +{ + uint16_t adc_max = 0; + uint16_t adc_temp,adc_shake=0; + uint16_t adc_value,filter_value; + uint16_t time; + filter_def f={0}; + filter_def sort={0}; + uint32_t tick; + + // 等待开始 + adc_value = GetADC_Fast(ADC_CURR_DE); + filter_init(&f,adc_value); + tick=delay_get_us(); + do{ + adc_value=adc_get_value(ADC_CURR_DE); + adc_start(ADC_CURR_DE); +// adc_value = GetADC_Fast(ADC_CURR_DE); + filter_insert(&f,adc_value); + filter_value=filter_get_head(&f); + if(delay_check(tick,1000000)){ + // 1s超时,未进入充能阶段 + goto end; + } + }while(filter_valueend_adv); + time=(delay_get_us()-tick)/100; + end: + if(max_cul) *max_cul=adc_max; + if(shake_adv) *shake_adv=adc_shake; + return time; +} + + + /* @brief 电流降到指定电流下的时间 @@ -456,7 +524,7 @@ uint16_t AD_CurMonitor_(uint32_t ul_times) */ -uint16_t AD_GetChgEnergy(uint16_t sample_timeout, uint16_t end_adv,uint16_t* max_cul,uint16_t *shake_adv) +uint16_t AD_GetChgEnergy_(uint16_t sample_timeout, uint16_t end_adv,uint16_t* max_cul,uint16_t *shake_adv) { uint16_t aus_adc_v[5]; uint16_t aus_adv_shake[20]; @@ -466,8 +534,8 @@ uint16_t AD_GetChgEnergy(uint16_t sample_timeout, uint16_t end_adv,uint16_t* max uint16_t us_shake_minadc,us_shake_maxadc; uint8_t start_flag = 0,shake_flag = 0; Get100usCount(); - ADC_ClearFlag(ADC_CURR_DE,ADC_FLAG_EOC);//清除转换结束标志 - ADC_SoftwareStartConvCmd(ADC_CURR_DE, ENABLE); //启动转换 +// ADC_ClearFlag(ADC_CURR_DE,ADC_FLAG_EOC);//清除转换结束标志 +// ADC_SoftwareStartConvCmd(ADC_CURR_DE, ENABLE); //启动转换 aus_adc_v[4] = 0xFFFF; *max_cul = 0; *shake_adv = 0; @@ -478,23 +546,27 @@ uint16_t AD_GetChgEnergy(uint16_t sample_timeout, uint16_t end_adv,uint16_t* max } while(GetCountTimerCnt() < sample_timeout) { - time_out = 2000; - while((time_out > 0) && ( ADC_GetFlagStatus(ADC_CURR_DE,ADC_FLAG_EOC) == RESET)) - { - time_out--; - } - aus_adc_v[us_count] = ADC_GetConversionValue(ADC_CURR_DE) & 0x0FFF; +// time_out = 2000; +// while((time_out > 0) && ( ADC_GetFlagStatus(ADC_CURR_DE,ADC_FLAG_EOC) == RESET)) +// { +// time_out--; +// } +// aus_adc_v[us_count] = ADC_GetConversionValue(ADC_CURR_DE) & 0x0FFF; + aus_adc_v[us_count] = GetADC_Fast(ADC_CURR_DE); aus_adv_shake[us_shake_count] = aus_adc_v[us_count]; - ADC_ClearFlag(ADC_CURR_DE,ADC_FLAG_EOC);//清除转换结束标志 - ADC_SoftwareStartConvCmd(ADC_CURR_DE, ENABLE); //启动转换 +// ADC_ClearFlag(ADC_CURR_DE,ADC_FLAG_EOC);//清除转换结束标志 +// ADC_SoftwareStartConvCmd(ADC_CURR_DE, ENABLE); //启动转换 us_count++; us_shake_count++; us_count %= 5; us_shake_count %= 20; + + // 开始充能之后并且采集到20个值 if((us_shake_count == 0) && (start_flag > 0)) { shake_flag ++; } + // 由于刚开始时采集的20个值有可能还没有开始,这里使用第二个采集值 if(shake_flag == 2) { LED1_Out = 1; @@ -514,6 +586,7 @@ uint16_t AD_GetChgEnergy(uint16_t sample_timeout, uint16_t end_adv,uint16_t* max } time_out++; } + // 获取波动值,如果波动值太大则处于上升期,忽略波动值 us_shake_minadc = us_shake_maxadc - us_shake_minadc; if(us_shake_minadc > 900) { @@ -525,6 +598,7 @@ uint16_t AD_GetChgEnergy(uint16_t sample_timeout, uint16_t end_adv,uint16_t* max } } + // 采集到5个数据之后 if(us_count == 0) { Bubble_Sort_u16(aus_adc_v,5); @@ -747,3 +821,34 @@ uint16_t AD_GetBusCurUp(uint16_t ad_line ,uint16_t time_out) } return 0; } + + + + + + +/*rc{ + 开始转换 + +}*/ +void adc_start(ADC_TypeDef *adc){ + ADC_ClearFlag(adc,ADC_FLAG_EOC);//清除转换结束标志 + ADC_SoftwareStartConvCmd(adc,ENABLE);//启动转换 +} +/*rc{ + 获取adc值,请先开始转换 +}*/ +uint16_t adc_get_value(ADC_TypeDef *adc){ + uint16_t time_out = 10000; + uint16_t temp = 0; + while((time_out > 0) && ( ADC_GetFlagStatus(adc,ADC_FLAG_EOC) == RESET)) + { + time_out--; + } + temp = ADC_GetConversionValue(adc) & 0x0FFF; + return temp; +} + + + + diff --git a/source/elec_det/hardware/adc_cfg.h b/source/elec_det/hardware/adc_cfg.h index 98ef43a..dbe763e 100644 --- a/source/elec_det/hardware/adc_cfg.h +++ b/source/elec_det/hardware/adc_cfg.h @@ -101,4 +101,11 @@ uint16_t AD_SampleCap(uint16_t delay); @rtv 等待时间 */ uint16_t AD_GetBusCurUp(uint16_t ad_line ,uint16_t time_out); + + + +void adc_start(ADC_TypeDef *adc); +uint16_t adc_get_value(ADC_TypeDef *adc); + + #endif diff --git a/source/main/compiler_info.h b/source/main/compiler_info.h index 66b7c2c..f00a18b 100644 --- a/source/main/compiler_info.h +++ b/source/main/compiler_info.h @@ -6,7 +6,7 @@ -#define BUILD_DATE "2024-01-18 15:29:08" +#define BUILD_DATE "2024-02-03 10:04:08" #define SOFT_VERSION "2.14" diff --git a/source/main/main.c b/source/main/main.c index 7b4369e..be447e3 100644 --- a/source/main/main.c +++ b/source/main/main.c @@ -20,6 +20,8 @@ #include "dev_backup.h" #include "compiler_info.h" #include "elec_det.h" +#include "filter.h" +#include "core_delay.h" static const uint8_t ALIGN(4) g_bootcode[]={ #include "bootcode.txt" @@ -85,18 +87,32 @@ app_init_export(init_wdog) - static int test(list_def *argv) { if(list_length(argv)<2){ cmd_print("param num too less."); return -1; } - float num=str_atof(list_get_str(argv,1)); - cmd_print("test num=%f",num); + uint32_t start; + uint32_t end; + int num; + uint16_t value; + list_def *table=str_atod_list(list_get_str(argv,1),','); + filter_def f={0}; + filter_init(&f,list_get_int(table,0)); + num=list_length(table); + for(int i=0;iitems[i].data.value = value; + f->items[i].data.index = i; + } + f->index=FILTER_ITEM_NUM; +} + + +// 从指定位置开始排序 +static void filter_sort(filter_def *f,int index,uint16_t value){ + int i=index; + for(;;){ + if((if->items[i+1].data.value)){ + f->items[i].item=f->items[i+1].item; + i++; + // printf("i=%d,to tail\n",i); + }else if((i>0)&&(valueitems[i-1].data.value)){ + f->items[i].item=f->items[i-1].item; + i--; + // printf("i=%d,to head\n",i); + }else{ + break; + } + } + f->items[i].data.value = value; + f->items[i].data.index = f->index; + f->index++; +} + + +// 插入数据,小在前,大在后 +void filter_insert(filter_def *f,uint16_t value) +{ + for(int i=0;iitems[i].data.index==(uint16_t)(f->index-FILTER_ITEM_NUM)) + { + filter_sort(f,i,value); + return; + } + } + if(f->index>0){ + while(1); + } +} + + + + diff --git a/source/soft/filter.h b/source/soft/filter.h new file mode 100644 index 0000000..af863f0 --- /dev/null +++ b/source/soft/filter.h @@ -0,0 +1,55 @@ +#ifndef filter_h__ +#define filter_h__ + + +#include "stdint.h" +#include "stdio.h" +#include "stdlib.h" + + + + +// 过滤器 + +#define FILTER_ITEM_NUM 5 + + +typedef union { + struct + { + uint16_t value; + uint16_t index; + }data; + uint32_t item; +} filter_item; + + +struct _filter_def{ + uint16_t index; + filter_item items[FILTER_ITEM_NUM]; +}; +typedef struct _filter_def filter_def; + +void filter_init(filter_def *f,uint16_t value); + +void filter_insert(filter_def *f,uint16_t value); + +// 返回中间值 +#define filter_get_mid(f)\ + (f)->items[FILTER_ITEM_NUM>>1].data.value + +// 返回头 +#define filter_get_head(f)\ + (f)->items[0].data.value + +// 返回尾 +#define filter_get_tail(f)\ + (f)->items[FILTER_ITEM_NUM-1].data.value + + + + + + +#endif + diff --git a/source/stm32lib/src/stm32f10x_flash.c b/source/stm32lib/src/stm32f10x_flash.c index cdff9e9..dcb5987 100644 --- a/source/stm32lib/src/stm32f10x_flash.c +++ b/source/stm32lib/src/stm32f10x_flash.c @@ -82,8 +82,8 @@ #define FLASH_BANK1_END_ADDRESS ((uint32_t)0x807FFFF) /* Delay definition */ -#define EraseTimeout ((uint32_t)0x000B0000) -#define ProgramTimeout ((uint32_t)0x00002000) +#define EraseTimeout ((uint32_t)0x000FFFFF) +#define ProgramTimeout ((uint32_t)0x0000FFFF) /** * @} */ @@ -632,6 +632,8 @@ FLASH_Status FLASH_EraseOptionBytes(void) /* Authorize the small information block programming */ FLASH->OPTKEYR = FLASH_KEY1; FLASH->OPTKEYR = FLASH_KEY2; + __NOP(); + __NOP(); /* if the previous operation is completed, proceed to erase the option bytes */ FLASH->CR |= CR_OPTER_Set; @@ -938,6 +940,8 @@ FLASH_Status FLASH_ProgramOptionByteData(uint32_t Address, uint8_t Data) /* Authorize the small information block programming */ FLASH->OPTKEYR = FLASH_KEY1; FLASH->OPTKEYR = FLASH_KEY2; + __NOP(); + __NOP(); /* Enables the Option Bytes Programming operation */ FLASH->CR |= CR_OPTPG_Set; *(__IO uint16_t*)Address = Data; @@ -995,6 +999,8 @@ FLASH_Status FLASH_EnableWriteProtection(uint32_t FLASH_Pages) /* Authorizes the small information block programming */ FLASH->OPTKEYR = FLASH_KEY1; FLASH->OPTKEYR = FLASH_KEY2; + __NOP(); + __NOP(); FLASH->CR |= CR_OPTPG_Set; if(WRP0_Data != 0xFF) { @@ -1057,6 +1063,8 @@ FLASH_Status FLASH_ReadOutProtection(FunctionalState NewState) /* Authorizes the small information block programming */ FLASH->OPTKEYR = FLASH_KEY1; FLASH->OPTKEYR = FLASH_KEY2; + __NOP(); + __NOP(); FLASH->CR |= CR_OPTER_Set; FLASH->CR |= CR_STRT_Set; /* Wait for last operation to be completed */