cancel
Showing results for 
Search instead for 
Did you mean: 

How to develop code for getting Sine Wave as Analog input and apply it as AO with STM32F407G.

umairgist
Visitor

Hello Everyone,

Problem: I am working with a instrument where we frequently get the problem of frequency drop out, i.e. suddenly frequency signal goes missing i.e. goes to zero, this cause the loss in data as shown in the below image. Yellow is received frequency signal from Photodetector and Purple is the demodulated data (our desire output). When frequency goes zero the purple line is constant so data is lost.

Solution: 

In order to solve this problem, I have solution in my mind, i.e. I should develop an algorithm which could work as follow,

In this case I will have two Analog Inputs F_A, F_B and one analog output A_out.

// F_A is our sensor data 

// Based on F_A, F_B is our final result obtained by demodulation of F_A.

I want to developed following logic 

 

When data is not missing (i.e. F_A is not zero then output (A_out) of microprocessor should be zero, while F_B should store in the buffer zone.

If F_A =0 is detected then the output (A_out) should be the (F_B stored in buffer zone) i.e. I want to utilize the previous value of F_B when F_A was not zero. 

As a visualization: Look at picture 

umairgist_0-1720578075998.png

 

 

Yellow (F_A) will be continuously monitored, Purple (F_B) should be store in buffer zone. As can be seen rectangular point yellow goes zero and purple become constant, so this constant purple gap should be filled by buffer zone.

P.S I am Mechanical Engineering Student and I never had programming experience with MCU, I just used arduino once in my life. So, I developed a code with ChatGPT but it's giving me error, The code is of 250+ lines but my logic part is just of 10-20 lines starting from line 115 to 137

Sincerely.

Umair

//After providing a lot of errors and my code in main.c file this code is directly copied from chat-gpt
//Instead of using main.c I can use this main2.c file for further developments
// All the errors are resolved with ChatGPT and internet search. So, use main2c file for further developement of your work.


#include "stm32f4xx.h"
#include "stm32f4xx_hal.h"
#include "stm32f4xx_hal_conf.h"
#include "stm32f4xx_hal_rcc.h"
#include "stm32f4xx_hal_adc.h"
#include "stm32f4xx_hal_dma.h"
#include "stm32f4xx_hal_gpio.h"
#include "stm32f4xx_hal_dac.h"
#include "stm32f4xx_hal_tim.h"
#include "stm32f4xx_hal_rcc_ex.h"
#include "stm32f4xx_hal_adc_ex.h"
#include "stm32f4xx_hal_dma_ex.h"
#include "stm32f4xx_hal_gpio_ex.h"
#include "stm32f4xx_hal_dac_ex.h"
#include "stm32f4xx_hal_tim_ex.h"

#define BUFFER_SIZE 1000  // Adjust buffer size as needed

uint16_t F_B_Buffer[BUFFER_SIZE]; // This will store pulses when frequency is greater than zero
uint16_t Verification_Buffer[BUFFER_SIZE]; // This will store pulses when frequency is zero
volatile int F_B_Index = 0; // This will initialize it to 0. Volatile means value may change
volatile int Ver_Index = 0; // This will initialize it to 0. Ver means it will track the verification buffer 
volatile int F_A_Val = 0; // This will initialize it to 0. This will hold the frequency values

ADC_HandleTypeDef hadc1;
DAC_HandleTypeDef hdac;
TIM_HandleTypeDef htim2;


void Error_Handler(void)
{
    // User can add their own implementation to report the HAL error return state
    while(1)
    {
    }
}
void ADC_Config(void)
{
    ADC_ChannelConfTypeDef sConfig = {0};

    // Common config
    hadc1.Instance = ADC1;
    hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
    hadc1.Init.Resolution = ADC_RESOLUTION_12B;
    hadc1.Init.ScanConvMode = DISABLE;
    hadc1.Init.ContinuousConvMode = ENABLE;
    hadc1.Init.DiscontinuousConvMode = DISABLE;
    hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
    hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
    hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
    hadc1.Init.NbrOfConversion = 1;
    hadc1.Init.DMAContinuousRequests = ENABLE;
    hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
    if (HAL_ADC_Init(&hadc1) != HAL_OK)
    {
        // Initialization Error
        Error_Handler();
    }

    // Configure for the selected ADC regular channel
    sConfig.Channel = ADC_CHANNEL_0;
    sConfig.Rank = 1;
    sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
    if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
    {
        // Channel Configuration Error
        Error_Handler();
    }
}

void DAC_Config(void)
{
    DAC_ChannelConfTypeDef sConfig = {0};

    hdac.Instance = DAC;
    if (HAL_DAC_Init(&hdac) != HAL_OK)
    {
        // Initialization Error
        Error_Handler();
    }

    sConfig.DAC_Trigger = DAC_TRIGGER_NONE;
    sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
    if (HAL_DAC_ConfigChannel(&hdac, &sConfig, DAC_CHANNEL_1) != HAL_OK)
    {
        // Channel configuration Error
        Error_Handler();
    }
}

void SystemClock_Config(void);
void ADC_Config(void);
void DMA_Config(void);
void GPIO_Config(void);
void TIM_Config(void);
void DAC_Config(void);



int main(void)
{
    HAL_Init(); // This function initialize the Hardware Abstraction Layer
    SystemClock_Config(); // This function configures the system clock.
    ADC_Config(); // This function configures the ADC (Analog-to-Digital Converter)
    DMA_Config(); // This function configures the DMA (Direct Memory Access)
    GPIO_Config(); // This function configures the GPIO (General-Purpose Input/Output) pins 
    TIM_Config(); // This function configures the timers.
    DAC_Config(); // This function configures the DAC (Digital-to-Analog Converter)

    while (1)
    {
        if (F_A_Val > 0)
        {
            // Step 1: F_A > 0, store F_B in buffer
            HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&F_B_Buffer[F_B_Index], 1);
            F_B_Index = (F_B_Index + 1) % BUFFER_SIZE;
            // Analog output A_out = 0
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);
        }
        else
        {
            // Step 2: F_A == 0, output F_B from buffer
            for (int i = 0; i < BUFFER_SIZE; i++)
            {
                HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, F_B_Buffer[i]);
                HAL_Delay(1); // Adjust delay for correct timing
            }
            // Store current F_B for verification
            HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&Verification_Buffer[Ver_Index], 1);
            Ver_Index = (Ver_Index + 1) % BUFFER_SIZE;
        }
    }
	}

void DMA_Config(void)
{
    // DMA Initialization
    __HAL_RCC_DMA2_CLK_ENABLE();
    DMA_HandleTypeDef hdma_adc1;
    hdma_adc1.Instance = DMA2_Stream0;
    hdma_adc1.Init.Channel = DMA_CHANNEL_0;
    hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
    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_CIRCULAR;
    hdma_adc1.Init.Priority = DMA_PRIORITY_HIGH;
    hdma_adc1.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
    HAL_DMA_Init(&hdma_adc1);
    __HAL_LINKDMA(&hadc1, DMA_Handle, hdma_adc1);
}

void GPIO_Config(void)
{
    // GPIO Initialization
    __HAL_RCC_GPIOA_CLK_ENABLE();
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    GPIO_InitStruct.Pin = GPIO_PIN_0;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

void TIM_Config(void)
{
    // Timer Initialization
    TIM_HandleTypeDef htim2;
    __HAL_RCC_TIM2_CLK_ENABLE();

    htim2.Instance = TIM2;
    htim2.Init.Prescaler = 84 - 1;  // 1 MHz frequency
    htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim2.Init.Period = 1000 - 1;   // 1 kHz update rate
    htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
    {
        // Initialization Error
        Error_Handler();
    }

    if (HAL_TIM_Base_Start_IT(&htim2) != HAL_OK)
    {
        // Starting Error
        Error_Handler();
    }
    HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(TIM2_IRQn);
}

void TIM2_IRQHandler(void)
{
    // Timer interrupt handler
    if (__HAL_TIM_GET_FLAG(&htim2, TIM_FLAG_UPDATE) != RESET)
    {
        if (__HAL_TIM_GET_IT_SOURCE(&htim2, TIM_IT_UPDATE) != RESET)
        {
            __HAL_TIM_CLEAR_IT(&htim2, TIM_IT_UPDATE);
            HAL_ADC_Start(&hadc1);
            HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
            F_A_Val = HAL_ADC_GetValue(&hadc1);
        }
    }
}

 

0 REPLIES 0