ADC to DAC using DMA in STM32f4
Hi everyone,
ı was trying to make adc to dac using DMA. Shortly the adc value is writed into DAC data register. So that the potentiometer is turned then the digital value is writed ADC register. The brightness of led is changed. However, ı get ADC value via DMA then ı writed into DAC register and nothing happened. I did the project without DMA and it worked as what ı want. How can ı do that using DMA. In my solutions are multi DMA, triger event. Also, the ADC channel to pin A0 and DAC pin to A4. Do you have any idea ?
#include "stm32f4xx.h"
#include "stm32f4_discovery.h"
uint32_t adc;
uint32_t adc1[8];
uint32_t dac;
uint32_t dac1[8];
uint32_t buffer[8];
uint32_t *ptr;
void RCC_Config()
{
RCC->CR |= 0x00030000; // HSEON and HSEONRDY enable
while(!(RCC->CR & 0x00020000)); // HSEON Ready Flag wait
RCC->CR |= 0x00080000; // CSS Enable
RCC->CR |= 0x01000000; // PLL ON
RCC->PLLCFGR |= 0x00400000; // PLL e HSE seçtik
RCC->PLLCFGR |= 0x00000004; // PLL M = 4
RCC->PLLCFGR |= 0x00005A00; // Pll N = 168
RCC->PLLCFGR |= 0x00000000; // PLL p = 2
RCC->CFGR |= 0x00000000; // AHB Prescaler = 1
RCC->CFGR |= 0x00080000; // APB2 Prescaler = 2
RCC->CFGR |= 0x00001400; // APB1 Prescaler = 4
RCC->CIR |= 0x00800000; // CSS Flag clear
}
void GPIO_Config()
{
RCC->AHB1ENR |= (1 << 0); // GPIOA Clock Enable
GPIOA->MODER |= (3 << 0); // AP0 analog (for ADC -> connect the potentiometer)
GPIOA->MODER |= (1 << 8); // AP4 output (for DAC -> connect the led)
GPIOA->OSPEEDR |= (3 << 0); // AP0 very high speed
}
void ADC_Config()
{
RCC->APB2ENR |= 0x00000100; // ADC1 Clock enable
ADC->CCR |= 1 << 16; // ADC Clock Divided By 4
//ADC1->SMPR2 |= 6 << 0; // 144 Cycles for Channel 0
ADC1->CR1 |= 0 << 24; // ADC Resolution 12 bit
ADC1->CR1 |= 1 << 8; // Scan conversion mode enable
ADC1->CR2 |= 1 << 0; // ADC enable
ADC1->CR2 |= 1 << 1; // Continuous conversion mode enable
ADC1->CR2 |= 1 << 8; // DMA Enable
ADC1->CR2 |= 1 << 9; // DDS
ADC1->CR2 |= 1 << 10; // EOCS
//ADC1->CR2 |= 1 << 30; //
ADC1->SQR1 |= 0 << 20; // L = 1 conversion number
//ADC1->CR2 |= (15 << 24);
//ADC->CCR |= 1 << 0; // dual mode
ADC1->SQR3 |= 0 << 0; // put channel number CH0
}
void DMA_ADC_Config()
{
RCC->AHB1ENR |= 0x00400000; // RCC->AHB1ENR |= (1<<22); // DMA2 clk Enable
while((DMA2_Stream4->CR & 0x00000001) == 1); // wait for stream4 to be 0(stop)
DMA2_Stream4->PAR|= (uint32_t) &ADC1->DR;
DMA2_Stream4->M0AR |= (uint32_t) &adc1;
DMA2_Stream4->NDTR = 1;
DMA2_Stream4->CR |= 0 << 6; // Peripheral to Memory
DMA2_Stream4->CR |= 1 << 8; // Circular mode
DMA2_Stream4->CR |= 1 << 10; // memory incremented
DMA2_Stream4->CR |= 2 << 11; // peripheral data size 32 bit (word)
DMA2_Stream4->CR |= 2 << 13; // memory data size 32 bit (word)
DMA2_Stream4->CR |= 2 << 16; // priority level high
DMA2_Stream4->CR |= 0 << 25; // channel 0 selected
DMA2_Stream4->FCR |= 0 << 2; // direct mode enable
DMA2_Stream4->CR |= 1 << 0; // start stream 4
//ADC1->CR2 |= ADC_CR2_SWSTART;
}
void DMA_DAC_Config() // stream5-ch7
{
RCC->AHB1ENR |= (1 << 21); // RCC->AHB1ENR |= (1<<21); // DMA1 clk Enable
while((DMA2_Stream5->CR & 0x00000001) == 1); // wait for stream5 to be 0(stop)
DMA2_Stream5->PAR|= (uint32_t) &DAC->DHR12R1;
DMA2_Stream5->M0AR |= (uint32_t) &dac1;
DMA2_Stream5->NDTR = 1;
DMA2_Stream5->CR |= 1 << 6; // Peripheral to Memory ?
DMA2_Stream5->CR |= 1 << 8; // Circular mode
DMA2_Stream5->CR |= 1 << 10; // memory incremented
DMA2_Stream5->CR |= 2 << 11; // peripheral data size 32 bit (word) 2
DMA2_Stream5->CR |= 2 << 13; // memory data size 32 bit (word) 2
DMA2_Stream5->CR |= 2 << 16; // priority level medium
DMA2_Stream5->CR |= 7 << 25; // channel 7 selected
DMA2_Stream5->FCR |= 1 << 2; // direct mode enable ?
DMA2_Stream5->CR |= 1 << 0; // start stream 7
}
void DAC_Conifg()
{
//RCC->APB1ENR |= (1 << 29); // DAC Clock Enable
RCC->APB1ENR |= 0x20000000;
DAC->CR |= 0x00000001; // DAC Channel 1 enable
//DAC->SWTRIGR |= 0x00000000; // DAC Channel 1 software trigger disable
DAC->CR |= (0 << 6); // Wave generation disabled
DAC->CR |= (0 << 1); // output buffer enabled
DAC->DHR12R1 |= 0x00000000; // DAC Channel 1 12-bit right-aligned data
DAC->CR |= (7 << 3); // software trigger
DAC->CR |= (1 << 12); // DAC Ch1 DMA Enable
}
int main(void)
{
RCC_Config();
GPIO_Config();
ADC_Config();
DMA_ADC_Config();
DMA_DAC_Config();
ADC1->CR2 |= ADC_CR2_SWSTART; //start conversion
while (1)
{
adc = adc1[0];
dac = adc;
DAC->DHR12R1 = adc;
}
}
void EVAL_AUDIO_TransferComplete_CallBack(uint32_t pBuffer, uint32_t Size)
{
/* TODO, implement your code here */
return;
}
uint16_t EVAL_AUDIO_GetSampleCallBack(void)
{
/* TODO, implement your code here */
return -1;
}
