cancel
Showing results for 
Search instead for 
Did you mean: 

Can the array DAC DMA for signals be controlled?

macam1
Associate III

I generated a sinusoidal signal through the DAC using DMA. I understand that DMA performs looping since I use circular mode. In short, I want to control the numbers generated by the DMA. So, when the signal changes to DC (the array contains only 2048 or hold_samples and hold_samples2), it will immediately be detected by my program using the function:

 

 

deteksisinyal(void)

 

 

 However, I have NOT yet figured out how to control the numbers/results/shape of the generated signal in terms of code. I want to control the signal changes, namely from peak - flat - valley - flat. I will use the flat part for another function, specifically to detect changes in a device. Please, I need help from experts with examples or guidance on what I should do. I will include my code below. Please provide feedback or ask questions about my code.

 

 

// DAC SIGNAL GENERATOR	
#define VALUE_SIZE 557
uint16_t value[VALUE_SIZE] = {};
uint16_t hold_samples = 30; 
uint16_t hold_samples2 = 400;
	
uint16_t firstHalf[] = {
2100, 2249, 2450, 2646, 2834, 3018, 3188, 3351, 3503, 3636, 3755, 3860, 3944, 4012, 4095, 
4058, 4012, 3944, 3860, 3755, 3636, 3503, 3351, 3188, 3018, 2834, 2646, 2450, 2249, 2100
}; 	

uint16_t secondHalf[] = {
1997, 1847, 1702, 1562, 1427, 1297, 1172, 1052, 900, 722, 622, 527, 437, 352, 272, 197, 100, 
0, 100, 197, 272, 352, 437, 527, 622, 722, 900, 1052, 1172, 1297, 1427, 1562, 1700, 1850, 2000
}; 	

// ADC SIGNAL GENERATOR
uint16_t totalSize;
uint16_t sum_signal = 0;
uint16_t filtered_input; //ngantuk bgt ya lord
void generate_signal() {
	uint16_t index = 0;
	for (uint16_t i = 0; i < sizeof(firstHalf) / sizeof(firstHalf[0]); i++) {
			value[index++] = firstHalf[i];
	}
  for (uint16_t i = 0; i < hold_samples; i++) {
			value[index++] = 2048;
	}
	for (uint16_t i = 0; i < sizeof(secondHalf) / sizeof(secondHalf[0]); i++) {
			value[index++] = secondHalf[i];
	}
	for (uint16_t i = 0; i < hold_samples2; i++) {
			value[index++] = 2048;
	}
	totalSize = (sizeof(firstHalf) / sizeof(firstHalf[0])) + hold_samples + (sizeof(secondHalf) / sizeof(secondHalf[0]))+ hold_samples2;
	HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, (uint32_t*)value, totalSize, DAC_ALIGN_12B_R);
}

uint32_t cnt=0;
uint16_t input_start = 0; 
uint32_t input_end = 4095;  
uint16_t output_start = 25;
uint16_t output_end = 3900;
uint16_t newArray = 2048;
uint16_t input;
uint16_t hasil;
uint16_t i;
uint16_t y;
uint16_t x;
uint16_t newArray;

void signal_function(){
	
		input = adc_buffer[1];
		cnt++;
		if (cnt > 15)
		{
			filtered_input = sum_signal / 15;
			sum_signal=0;
			cnt=0;
			
			hasil = output_start + ((output_end - output_start) * (filtered_input - input_start)) / (input_end - input_start); 
			__HAL_TIM_SET_AUTORELOAD(&htim4, hasil);
			__HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_1, hasil);
			y = hasil;
			x = input;
		}
		else 
			sum_signal += input;
}

void deteksisinyal(void){
//how to detect the DC signallllll
}

 

 

and the shape of the signal is as follows: and the shape of the signal is as follows:and the shape of the signal is as follows:

Is it possible? I need your help.

@TDK @ST_Employee_AME 

3 REPLIES 3
MM..1
Chief III

Hi you with DMA require add and use complete callbacks interrupts. Then after half buff is complete you change first half ... or double buffer or more with prepare and switch on full complete...

thakn u so much for your response but i have any question:

 

Can I see when my DC signal starts to form using that method?
I know which array index it starts to become DC, but I can’t control it because I’m confused. Could you explain further?

Enable IRQ and some on your stream used... only example code

void DMA1_Stream5_IRQHandler(void)
{
/* Test on DMA Stream Half Transfer interrupt */
if (DMA_GetITStatus(DMA1_Stream5, DMA_IT_HTIF5)) {
/* Clear DMA Stream Half Transfer interrupt pending bit */
DMA_ClearITPendingBit(DMA1_Stream5, DMA_IT_HTIF5);
/* Add code to process First Half of Buffer */
}

/* Test on DMA Stream Transfer Complete interrupt */
if (DMA_GetITStatus(DMA1_Stream5, DMA_IT_TCIF5)) {
/* Clear DMA Stream Transfer Complete interrupt
* pending bit */
DMA_ClearITPendingBit(DMA1_Stream5,DMA_IT_TCIF5);
/* Add code to process Second Half of Buffer
* */
}