diff --git a/Power_Pico/BSP/GATE/gate.c b/Power_Pico/BSP/GATE/gate.c index 6a3ff63..1c41ded 100644 --- a/Power_Pico/BSP/GATE/gate.c +++ b/Power_Pico/BSP/GATE/gate.c @@ -1,6 +1,8 @@ #include "gate.h" +#include "usart.h" +#include "math.h" -static uint8_t status = HIGH_CUR; // Default status +uint8_t gate_status = HIGH_CUR; // Default status void Gate_Port_Init(void) { @@ -31,6 +33,10 @@ void Gate_Port_Init(void) void flow_route_selection(uint8_t selection) { + if(selection > HIGH_CUR) + selection = HIGH_CUR; // Invalid selection + if(selection < LOW_CUR) + selection = LOW_CUR; if(selection == HIGH_CUR) { HAL_GPIO_WritePin(EN1_PORT, EN1_PIN, GPIO_PIN_SET); @@ -46,16 +52,75 @@ void flow_route_selection(uint8_t selection) HAL_GPIO_WritePin(EN1_PORT, EN1_PIN, GPIO_PIN_RESET); HAL_GPIO_WritePin(EN2_PORT, EN2_PIN, GPIO_PIN_RESET); } - else - { - // Invalid selection - HAL_GPIO_WritePin(EN1_PORT, EN1_PIN, GPIO_PIN_SET); - HAL_GPIO_WritePin(EN2_PORT, EN2_PIN, GPIO_PIN_SET); - } - status = selection; // Update the status + gate_status = selection; // Update the status } uint8_t Gate_get_status(void) { - return status; + return gate_status; +} + +// DMA中断中执行, 不能有阻塞 +void Gate_Swich_and_UART_Send(ADC_Packet adc_packet) +{ + static uint8_t high_times = 0; + static uint8_t low_times = 0; + // low mid high + uint16_t cur_adc = 0; + switch(Gate_get_status()) { + case LOW_CUR: + cur_adc = adc_packet.data[0][1]; + break; + case MID_CUR: + cur_adc = adc_packet.data[0][2]; + break; + case HIGH_CUR: + cur_adc = adc_packet.data[0][3]; + break; + } + // 可信范围内 + if(cur_adc < ADC_TRUST_MAX) { + adc_packet.header[3] = Gate_get_status(); + HAL_UART_Transmit_DMA(&huart6, (uint8_t*)&adc_packet, sizeof(adc_packet)); + // 计算电压电流值 + global_valtage = adc_packet.data[0][0] * 3.0f / 4096.0f * 11.0f; // 11 = (100+10)/10 + if(Gate_get_status() == LOW_CUR) { + global_current = (adc_packet.data[0][1] - 2048) * (3.0f / 4096.0f / 50.0f / LOW_CUR_RES * 1000000.0f); + global_cur_unit = UNIT_UA; + } + else if(Gate_get_status() == MID_CUR) { + global_current = (adc_packet.data[0][2] - 2048) * (3.0f / 4096.0f / 50.0f / MID_CUR_RES * 1000.0f); + global_cur_unit = UNIT_MA; + } + else if(Gate_get_status() == HIGH_CUR) { + global_current = (adc_packet.data[0][3] - 2048) * (3.0f / 4096.0f / 50.0f / HIGH_CUR_RES * 1000.0f); + global_cur_unit = UNIT_MA; + } + // 超过量程 + uint16_t diff = abs((int)cur_adc - 2048); + if(diff > THRESH_HIGH) { + high_times++; + low_times = 0; + if(high_times >= THRESH_TIMES) { + high_times = 0; + flow_route_selection(Gate_get_status()+1); + } + } + else if(diff < THRESH_LOW) { + low_times++; + high_times = 0; + if(low_times >= THRESH_TIMES) { + low_times = 0; + flow_route_selection(Gate_get_status()-1); + } + } + else { + high_times = 0; + low_times = 0; + } + } + // 不可信范围内 + else { + flow_route_selection(Gate_get_status()+1); + } } diff --git a/Power_Pico/BSP/GATE/gate.h b/Power_Pico/BSP/GATE/gate.h index 0e49b85..d07c127 100644 --- a/Power_Pico/BSP/GATE/gate.h +++ b/Power_Pico/BSP/GATE/gate.h @@ -6,6 +6,7 @@ extern "C" { #endif #include "main.h" +#include "adc.h" // EN1 #define EN1_PORT GPIOB @@ -16,18 +17,19 @@ extern "C" { #define EN2_PIN GPIO_PIN_15 // Flow route selection -#define HIGH_CUR 2 -#define MID_CUR 1 -#define LOW_CUR 0 +#define HIGH_CUR 3 +#define MID_CUR 2 +#define LOW_CUR 1 // Resistance values in ohms -#define HIGH_CUR_RES 0.005 // 5 m ohm -#define MID_CUR_RES 0.5 // 500 m ohm -#define LOW_CUR_RES 50.0 // 50 ohm +#define HIGH_CUR_RES 0.005f // 5 m ohm +#define MID_CUR_RES 0.5f // 500 m ohm +#define LOW_CUR_RES 50.0f // 50 ohm void Gate_Port_Init(void); void flow_route_selection(uint8_t selection); uint8_t Gate_get_status(void); +void Gate_Swich_and_UART_Send(ADC_Packet adc_packet); #ifdef __cplusplus } diff --git a/Power_Pico/Core/Inc/adc.h b/Power_Pico/Core/Inc/adc.h index d6a5792..9b9b77c 100644 --- a/Power_Pico/Core/Inc/adc.h +++ b/Power_Pico/Core/Inc/adc.h @@ -30,19 +30,34 @@ extern "C" { /* USER CODE BEGIN Includes */ -#define ADC_TIMES 10 +#define ADC_TIMES 1 #define ADC_CHANELS 4 typedef struct { - uint8_t header[6]; //2的倍数 + uint8_t header[4]; //2的倍数 // 0x55, 0xAA header // 0x0A adc times, 0x05 adc channels (so data lenth is times * channels * 2 bytes) - // and 1byte for direct & unit, 0x0? for positive, 0x1? for negative, 0x?0 for LOW, 0x?1 for MID, 0x?2 for HIGH. + // 0x?0 for LOW, 0x?1 for MID, 0x?2 for HIGH. uint16_t data[ADC_TIMES][ADC_CHANELS]; } __attribute__((packed)) ADC_Packet; extern ADC_Packet adc_packet; +#define UNIT_UA 0 +#define UNIT_MA 1 + +// 量程阈值 +#define ADC_TRUST_MAX 4000 +#define THRESH_HIGH 1900 +#define THRESH_LOW 18 + +// 次数 +#define THRESH_TIMES 10 + +extern uint8_t global_cur_unit; +extern float global_valtage; +extern float global_current; + /* USER CODE END Includes */ extern ADC_HandleTypeDef hadc1; diff --git a/Power_Pico/Core/Src/adc.c b/Power_Pico/Core/Src/adc.c index 0761012..eb05476 100644 --- a/Power_Pico/Core/Src/adc.c +++ b/Power_Pico/Core/Src/adc.c @@ -24,6 +24,10 @@ ADC_Packet adc_packet; +uint8_t global_cur_unit = UNIT_MA; // default mA +float global_valtage = 0.0; +float global_current = 0.0; + /* USER CODE END 0 */ ADC_HandleTypeDef hadc1; @@ -66,7 +70,7 @@ void MX_ADC1_Init(void) */ sConfig.Channel = ADC_CHANNEL_5; sConfig.Rank = 1; - sConfig.SamplingTime = ADC_SAMPLETIME_15CYCLES; + sConfig.SamplingTime = ADC_SAMPLETIME_28CYCLES; if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { Error_Handler(); @@ -143,7 +147,7 @@ void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle) hdma_adc1.Init.MemInc = DMA_MINC_ENABLE; hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; - hdma_adc1.Init.Mode = DMA_NORMAL; + hdma_adc1.Init.Mode = DMA_CIRCULAR; hdma_adc1.Init.Priority = DMA_PRIORITY_LOW; hdma_adc1.Init.FIFOMode = DMA_FIFOMODE_DISABLE; if (HAL_DMA_Init(&hdma_adc1) != HAL_OK) diff --git a/Power_Pico/Core/Src/stm32f4xx_it.c b/Power_Pico/Core/Src/stm32f4xx_it.c index 82deb19..44b129a 100644 --- a/Power_Pico/Core/Src/stm32f4xx_it.c +++ b/Power_Pico/Core/Src/stm32f4xx_it.c @@ -24,6 +24,7 @@ /* USER CODE BEGIN Includes */ #include "usart.h" #include "adc.h" +#include "gate.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ @@ -204,11 +205,7 @@ void DMA2_Stream0_IRQHandler(void) /* USER CODE BEGIN DMA2_Stream0_IRQn 0 */ if(__HAL_DMA_GET_FLAG(&hdma_adc1, DMA_FLAG_TCIF0_4)) { __HAL_DMA_CLEAR_FLAG(&hdma_adc1, DMA_FLAG_TCIF0_4); - HAL_ADC_Stop_DMA(&hadc1); - // 填充模式位 - adc_packet.header[4] = 0x10; - HAL_UART_Transmit_DMA(&huart6, (uint8_t *)&adc_packet, sizeof(adc_packet)); - HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_packet.data, ADC_TIMES * ADC_CHANELS); + Gate_Swich_and_UART_Send(adc_packet); } /* USER CODE END DMA2_Stream0_IRQn 0 */ HAL_DMA_IRQHandler(&hdma_adc1); diff --git a/Power_Pico/User/Tasks/Src/user_DataTask.c b/Power_Pico/User/Tasks/Src/user_DataTask.c index 1ce67d0..f3f87ff 100644 --- a/Power_Pico/User/Tasks/Src/user_DataTask.c +++ b/Power_Pico/User/Tasks/Src/user_DataTask.c @@ -29,8 +29,20 @@ void DataTask(void *argument) if(osMessageQueueGet(Key_MessageQueue, &keystr, NULL, 0)==osOK) { // UART6_TX_Send((uint8_t *)"key pressed\r\n", 13); + } - + // __disable_irq(); + // if(adc_buf_index == 0) + // memcpy((uint16_t*)adc_packet.data, (uint16_t*)ADC_BUF[1], sizeof(adc_packet.data)); + // else + // memcpy((uint16_t*)adc_packet.data, (uint16_t*)ADC_BUF[0], sizeof(adc_packet.data)); + // __enable_irq(); + // adc_packet.header[0] = 0x55; + // adc_packet.header[1] = 0xAA; + // adc_packet.header[2] = ADC_TIMES; + // adc_packet.header[3] = ADC_CHANELS; + // adc_packet.header[4] = 0x10; + // HAL_UART_Transmit_DMA(&huart6, (uint8_t *)&adc_packet, sizeof(adc_packet)); osDelay(1); } } diff --git a/Power_Pico/User/Tasks/Src/user_HardwareInitTask.c b/Power_Pico/User/Tasks/Src/user_HardwareInitTask.c index 6d63229..80ecf33 100644 --- a/Power_Pico/User/Tasks/Src/user_HardwareInitTask.c +++ b/Power_Pico/User/Tasks/Src/user_HardwareInitTask.c @@ -54,10 +54,8 @@ void HardwareInitTask(void *argument) adc_packet.header[0] = 0x55; adc_packet.header[1] = 0xAA; - adc_packet.header[2] = ADC_TIMES; - adc_packet.header[3] = ADC_CHANELS; // 填充模式位 - adc_packet.header[4] = 0x10; + adc_packet.header[2] = 0x03; // gate, for current flow route selection, high current by default Gate_Port_Init();