2024-05-08 12:00 PM
Hello everyone,
First of all, I want to say that I have a very limited knowledge about C memory stuff, so a bit of guidance would be of help. I am trying to set up a timer-triggered multi channel ADC with DMA, which I have already succesfully achieved, but as I implement other pieces of code, the DMA buffer either fully stops or does very strange things like swapping around the positions of the channels. I have realized this because commenting out parts of the interrupt of the timer or setting up the ADC with another timer works, so I suspect I am doing something very wrong with pointers usage or variable declaration. I would like to ask for a bit of help figuring out what am I doing wrong. I'll attach the whole project for if anyone wants to take a closer look.
Thank you in advance! :) Here are the code snippets
Here's the code ran just before the while(1) loop (invLeft is declared as extern and it's just a big struct holding everything).
inverterStruct invLeft = {0};
void inv_init(inverterStruct *inv, LED *led, GPIO_TypeDef *enable_port, uint16_t enable_pin, TIM_HandleTypeDef *htim, ADC_HandleTypeDef *hadc) {
// Initialize inverter structure
inv->state = INV_STATE_STARTUP;
inv->led = led;
inv->enable_pin = enable_pin;
inv->enable_port = enable_port;
inv->htim = htim;
inv->hadc = hadc;
inv->duties.Da = 0.5;
inv->duties.Db = 0.5;
inv->duties.Dc = 0.5;
HAL_TIM_Base_Start_IT(inv->htim); // Initializes Inverter timer with interrupt
HAL_ADC_Start_DMA(hadc, (uint32_t *) inv->ADC_raw,4); // Starts ADC DMA
enable_PWM(inv->htim);
}
Here's the interrupt code:
void TIM1_UP_TIM10_IRQHandler(void)
{
/* USER CODE BEGIN TIM1_UP_TIM10_IRQn 0 */
/* USER CODE END TIM1_UP_TIM10_IRQn 0 */
HAL_TIM_IRQHandler(&htim1);
/* USER CODE BEGIN TIM1_UP_TIM10_IRQn 1 */
getADCelec(invLeft.ADC_raw, &invLeft.measurements);
calc_duties(&invLeft.duties); // this function should have more inputs using numbers makes the ADC work, calculating stuff does not
set_PWM(invLeft.htim, invLeft.duties);
/* USER CODE END TIM1_UP_TIM10_IRQn 1 */
}
The functions called:
uint8_t getADCelec(volatile uint32_t* ADC_raw, volatile Measurements* measurements) {
// Calculate currents and voltage
float ia = getLinear(ADC_raw[0], CURRENT_SLOPE, CURRENT_OFFSET);
float ib = getLinear(ADC_raw[1], CURRENT_SLOPE, CURRENT_OFFSET);
float ic = getLinear(ADC_raw[2], CURRENT_SLOPE, CURRENT_OFFSET);
float VDC = getLinear(ADC_raw[3], VOLTAGE_SLOPE, VOLTAGE_OFFSET);
// Store the measurements
measurements->ia = ia;
measurements->ib = ib;
measurements->ic = ic;
measurements->VDC = VDC;
return 1; // Success
}
void calc_duties(Duties *duties) {
// irot_struct irot;
// irot.d = vd/vDC;
// irot.q = vq/vDC;
// irot.sinFi = sin(thetae);
// irot.cosFi = cos(thetae);
// irot_calc(&irot);
// svpwm_struct svpwm;
// Assign values to SVPWM structure
// svpwm.alpha = irot.alpha;
// svpwm.beta = irot.beta;
// svpwm_calc(&svpwm);
// Just use the constant numbers instead
duties->Da = 0.5F;
duties->Db = 0.5F;
duties->Dc = 0.5F;
}
void set_PWM(TIM_HandleTypeDef *htim, Duties duties) {
Compare3F_struct Compare = {0};
Compare.alphaA = 1.0F - duties.Da;
Compare.alphaB = 1.0F - duties.Db;
Compare.alphaC = 1.0F - duties.Dc;
Compare3F_calc(htim, &Compare);
htim->Instance->CCR1 = Compare.compA;
htim->Instance->CCR2 = Compare.compB;
htim->Instance->CCR3 = Compare.compC;
}