cancel
Showing results for 
Search instead for 
Did you mean: 

Frustrated with UART&ADC dual mode

ardavantycoon
Associate II
Posted on February 24, 2016 at 13:56

I am really got tired after so many attempt to use this hal drivers for ADC sampling in dual mode and send data over uart. For god sake plz help me. I did whatever user manuals said but still no output.

This is the code:

/**
/* Includes ------------------------------------------------------------------*/
include ''stm32f4xx_hal.h''
/* USER CODE BEGIN Includes */
include <
stdio.h
>
/* USER CODE END Includes */
/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc1;
ADC_HandleTypeDef hadc2;
DMA_HandleTypeDef hdma_adc1;
DMA_HandleTypeDef hdma_adc2;
UART_HandleTypeDef huart3;
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
//__IO uint16_t ADC_val[2]={0};
char senddata1[20];
char senddata2[20];
__IO uint32_t ADC_val=0;
__IO uint16_t ADC1_val=0;
__IO uint16_t ADC2_val=0;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_ADC1_Init(void);
static void MX_ADC2_Init(void);
static void MX_USART3_UART_Init(void);
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE END PFP */
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration----------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_ADC1_Init();
MX_ADC2_Init();
MX_USART3_UART_Init();
/* USER CODE BEGIN 2 */
HAL_ADCEx_MultiModeStart_DMA(&hadc1, (uint32_t*)&ADC_val, 2);
//HAL_ADC_Start(&hadc1);
//HAL_ADC_Start(&hadc2);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/** System Clock Configuration
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
__PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = 16;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 168;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
/* ADC1 init function */
void MX_ADC1_Init(void)
{
ADC_MultiModeTypeDef multimode;
ADC_ChannelConfTypeDef sConfig;
/**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) 
*/
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV8;
hadc1.Init.Resolution = ADC_RESOLUTION12b;
hadc1.Init.ScanConvMode = DISABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
hadc1.Init.DMAContinuousRequests = ENABLE;
hadc1.Init.EOCSelection = EOC_SINGLE_CONV;
HAL_ADC_Init(&hadc1);
/**Configure the ADC multi-mode 
*/
multimode.Mode = ADC_DUALMODE_REGSIMULT;
multimode.DMAAccessMode = ADC_DMAACCESSMODE_2;
multimode.TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_5CYCLES;
HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode);
/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. 
*/
sConfig.Channel = ADC_CHANNEL_2;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
}
/* ADC2 init function */
void MX_ADC2_Init(void)
{
ADC_MultiModeTypeDef multimode;
ADC_ChannelConfTypeDef sConfig;
/**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) 
*/
hadc2.Instance = ADC2;
hadc2.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV8;
hadc2.Init.Resolution = ADC_RESOLUTION12b;
hadc2.Init.ScanConvMode = DISABLE;
hadc2.Init.ContinuousConvMode = ENABLE;
hadc2.Init.DiscontinuousConvMode = DISABLE;
hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc2.Init.NbrOfConversion = 1;
hadc2.Init.DMAContinuousRequests = ENABLE;
hadc2.Init.EOCSelection = EOC_SINGLE_CONV;
HAL_ADC_Init(&hadc2);
/**Configure the ADC multi-mode 
*/
multimode.Mode = ADC_DUALMODE_REGSIMULT;
multimode.DMAAccessMode = ADC_DMAACCESSMODE_2;
multimode.TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_5CYCLES;
HAL_ADCEx_MultiModeConfigChannel(&hadc2, &multimode)

;

/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. 
*/
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
HAL_ADC_ConfigChannel(&hadc2, &sConfig);
}
/* USART3 init function */
void MX_USART3_UART_Init(void)
{
huart3.Instance = USART3;
huart3.Init.BaudRate = 256000;
huart3.Init.WordLength = UART_WORDLENGTH_8B;
huart3.Init.StopBits = UART_STOPBITS_1;
huart3.Init.Parity = UART_PARITY_NONE;
huart3.Init.Mode = UART_MODE_TX_RX;
huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart3.Init.OverSampling = UART_OVERSAMPLING_16;
HAL_UART_Init(&huart3);
}
/** 
* Enable DMA controller clock
*/
void MX_DMA_Init(void) 
{
/* DMA controller clock enable */
__DMA2_CLK_ENABLE();
/* DMA interrupt init */
HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
}
/** Pinout Configuration
*/
void MX_GPIO_Init(void)
{
/* GPIO Ports Clock Enable */
__GPIOA_CLK_ENABLE();
__GPIOB_CLK_ENABLE();
}
/* USER CODE BEGIN 4 */
//void ADC_MultiModeDMAConvCplt(DMA_HandleTypeDef *hdma) {
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc){
ADC_val=HAL_ADCEx_MultiModeGetValue(&hadc1);
ADC1_val=(ADC_val)&0xFFFF; //extract lower 16 bit
ADC2_val=(ADC_val>>16)&0xFFFF; //extract higher 16 bit
sprintf(senddata1,''data1:%d'', ADC1_val); 
sprintf(senddata2,''data2:%d'', ADC2_val); 
HAL_UART_Transmit(&huart3, (uint8_t*)&senddata1,20,10000);
HAL_UART_Transmit(&huart3, (uint8_t*)&senddata2,20,10000);
}
/* USER CODE END 4 */
ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf(''Wrong parameters value: file %s on line %d\r\n'', file, line) */
/* USER CODE END 6 */
}
endif
/**
* @}
*/ 
/**
* @}
*/ 
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

uart-flag no-hablo-hal usart-adc-multi-mode waste-of-time at-last-i-see-light usart-dma-adc wonder-question
14 REPLIES 14
Posted on February 24, 2016 at 17:42

For god sake plz help me. 

The pool of available support is pretty shallow here.

Reviewing what I can see, ADC clocks not enabled, USART clocks not enabled, Analogue pins not enabled/configured, USART pins not enabled/configured.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
ardavantycoon
Associate II
Posted on February 24, 2016 at 22:13 They have been enable through:

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_ADC1_Init(void);
static void MX_USART3_UART_Init(void);

I test it for single channel continues conversion mode and it works. But for dual mode, it is mystery. This is very sad that STM release new Library without enough supports or examples! I am going to migrate back to old standard library. I just waste my whole time. Now I have to begin from start point with old Std library.
ardavantycoon
Associate II
Posted on February 25, 2016 at 17:16

Standard peripheral is far better than this new hal library. Anyway, I modify the example file included in projects. The example file is for sampling 2x2 channels in scan mode.

0690X00000602lKQAQ.png It works perfectly but I have to modify to only sample one channel for each ADC1 and ADC2. First solution I change 2nd channel in each ADC identical to 1st channel. So ADC1 sample channel 11 twice and ADC2 sample channel 12 twice. It works without any problem but it is stupid way.

/* ADC1 regular channels 10, 11 configuration */
//ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_3Cycles);
//ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 2, ADC_SampleTime_3Cycles);
ADC_RegularChannelConfig(ADC1, 

ADC_Channel_11

, 1, ADC_SampleTime_480Cycles);

ADC_RegularChannelConfig(ADC1, 

ADC_Channel_11

, 2, ADC_SampleTime_480Cycles);
/* ADC2 regular channels 11, 12 configuration */
//ADC_RegularChannelConfig(ADC2, ADC_Channel_11, 1, ADC_SampleTime_3Cycles);
//ADC_RegularChannelConfig(ADC2, ADC_Channel_12, 2, ADC_SampleTime_3Cycles);
ADC_RegularChannelConfig(ADC2, ADC_Channel_12, 1, ADC_SampleTime_480Cycles);
ADC_RegularChannelConfig(ADC2, ADC_Channel_12, 2, ADC_SampleTime_480Cycles);
For better modification I did this changes. But It doesn't work properly. The problem is that only channel 12 data shown correctly and channel 11 data is missed!! There is something with DMA I assume. >Change DMA buffer size from 4 to 2 >Change variable aADCDualConvertedValue[4] toaADCDualConvertedValue[2] >Turn off scan mode >ChangeADC_InitStructure.ADC_NbrOfConversion = 2 to 1 >Remove second channels in each ADC config

/* Includes ------------------------------------------------------------------*/
#include ''stm32f4xx.h'' 
#include ''stm32f4_discovery.h''
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define ADC_CCR_ADDRESS ((uint32_t)0x40012308)
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
__IO uint16_t aADCDualConvertedValue[2];
/* Private function prototypes -----------------------------------------------*/
static void DMA_Config(void);
static void GPIO_Config(void);
static void ADC1_CH11_Config(void);
static void ADC2_CH12_Config(void);
/* Private functions ---------------------------------------------------------*/
int main(void)
{
ADC_CommonInitTypeDef ADC_CommonInitStructure;
/* Enable peripheral clocks *************************************************/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE);
/* DMA2 Stream0 channel0 configuration **************************************/
DMA_Config();
/* ADCs configuration ------------------------------------------------------*/
/* Configure ADC 11, 12 pin as analog input */
GPIO_Config();
/* ADC Common Init */
ADC_CommonInitStructure.ADC_Mode = ADC_DualMode_RegSimult;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div8;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);
/* ADC1 regular channels 11 configuration */
ADC1_CH11_Config();
/* ADC2 regular channels 12 configuration */
ADC2_CH12_Config();
/* Enable DMA request after last transfer (Multi-ADC mode) */
ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
/* Enable ADC2 */
ADC_Cmd(ADC2, ENABLE);
/* Start ADC1 Software Conversion */
ADC_SoftwareStartConv(ADC1);
while (1)
{
}
}
/**
* @brief ADC1 regular channels 11 configuration
* @param None
* @retval None
*/
static void ADC1_CH11_Config(void)
{
ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channels 11 configuration */ 
ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_480Cycles);
}
/**
* @brief ADC2 regular channels 12 configuration
* @param None
* @retval None
*/
static void ADC2_CH12_Config(void)
{
ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC2, &ADC_InitStructure);
/* ADC2 regular channels 12 configuration */ 
ADC_RegularChannelConfig(ADC2, ADC_Channel_12, 1, ADC_SampleTime_480Cycles);
}
/**
* @brief DMA Configuration
* @param None
* @retval None
*/
static void DMA_Config(void)
{
DMA_InitTypeDef DMA_InitStructure;
DMA_InitStructure.DMA_Channel = DMA_Channel_0; 
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&aADCDualConvertedValue;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC_CCR_ADDRESS;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = 2;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable; 
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream0, &DMA_InitStructure);
/* DMA2_Stream0 enable */
DMA_Cmd(DMA2_Stream0, ENABLE);
}
/**
* @brief Configure ADC Channels 11, 12 pins as analog inputs
* @param None
* @retval None
*/
static void GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* ADC Channel 11 -> PC1
ADC Channel 12 -> PC2
*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{ 
/* User can add his own implementation to report the file name and line number,
ex: printf(''Wrong parameters value: file %s on line %d

'', file, line) */
/* Infinite loop */
while (1)
{
}
}
#endif
/**
* @}
*/ 
/**
* @}
*/ 
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

ardavantycoon
Associate II
Posted on February 26, 2016 at 08:30

well. I found the problem. I have to modifyDMA_PeripheralDataSize andDMA_MemoryDataSize accordingly.

Now, I need to send these data to MATLAB through USART. any suggestion? I read somewhere EOC flag is slow. Consider that my DMA is in mode1 and I have two ADC1 and ADC2 in regular dual mode. I find these candidates in library:

DMA_GetFlagStatus(DMA2_Stream0, DMA_FLAG_TCIFx)
ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)

I may write the code like this:

while (1) {
while(!DMA_GetFlagStatus(DMA2_Stream0, DMA_FLAG_TCIF0)) {
USART_SendData(USART3, aADCDualConvertedValue[0]);
USART_SendData(USART3, aADCDualConvertedValue[1]);

} }

AvaTar
Lead
Posted on February 26, 2016 at 08:55

>I read somewhere EOC flag is slow. Consider that my DMA mode is 1. I find these candidates in library:

I use the ''transmission complete'' interrupt of the DMA for this purpose:

DMA_ITConfig (<YOUR_DMA_STREAM>, DMA_IT_TC, ENABLE);

>I may write the code like this:

while (1) {
while(!DMA_GetFlagStatus(DMA2_Stream0, DMA_FLAG_TCIF0)) {
USART_SendData(USART3, aADCDualConvertedValue[0]);
USART_SendData(USART3, aADCDualConvertedValue[1]);

} }

IMHO potentially problematic. Make sure your UART transmissions can keep up with the sampling/DMA rate - else you miss data. And don't forget to clear the flag.
ardavantycoon
Associate II
Posted on February 26, 2016 at 10:06

Can you write it for that flag u mention? According dma driver, we have two methods.

To control DMA events you can use one of the following two methods:
a- Check on DMA Stream flags using the function DMA_GetFlagStatus().
b- Use DMA interrupts through the function DMA_ITConfig() at initialization phase and DMA_GetITStatus() function into interrupt routines in communication phase.
After checking on a flag you should clear it using DMA_ClearFlag() function. And after checking on an interrupt event you should clear it using DMA_ClearITPendingBit() function.

andwhat do u mean IMHO? Assume my baud rate is921600, so sending two bytes (ADC1 sample and ADC2 sample) with no parity bit takes 7 us.I have two options to slow down ADC sampling in order to syn with baud rate. 1. slow down ADC clock as far as I can: sample cycle=480, ADC_div=8, APB2 prescaler=4 As result the throughput is about 11KHz or 90us which is enough to send in 7us by usart before next sample begin. 2. Use Timer for triggering ADC in specific time. It is more accurate but I consider it for next step for improvement.
AvaTar
Lead
Posted on February 26, 2016 at 10:35

> andwhat do u mean IMHO?

http://onlineslangdictionary.com/meaning-definition-of/imho

>Can you write it for that flag u mention? According dma driver, we have two methods. I use a ''transmission complete'' interrupt of the DMA channel. This way, output is ''synchronous'' with the ADC data.

void DMA2_Stream0_IRQHandler (void)
{
/* ADC data have arrived;
* do something with them here */
if (DMA_GetITStatus (DMA2_Stream0, DMA_IT_TCIF0) != RESET)
{
DMA_ClearITPendingBit (DMA2_Stream0, DMA_IT_TCIF0);
... // do something
}
}

> Assume my baud rate is921600, Seems o.k. at first glance - just wanted to mention that your output rate must at least match your input data rate. There are posts from other guys here (and elsewhere) calling 9600 baud UART output (sometimes indirectly via printf()) from a multi - kHz interrupt. I generally avoid blocking calls (i.e. functions depending on other interrupts) inside interrupts.
ardavantycoon
Associate II
Posted on February 26, 2016 at 13:09

IMHO :)) I thought it was register.

Thanks for your help. It works but imperfectly! It sends samples irregularly. something like: 126 255 126 126 126 125 126126 126 126 126 12. I have to comment one of the

USART_SendData(USART3, aADCDualConvertedValue[0]) or

USART_SendData(USART3, aADCDualConvertedValue[1])

I need both ADC1 and ADC2 data to be sent. According to user manual:

– DMA mode 1: On each DMA request (one data item is available), a half-word representing an ADC-converted data item is transferred. In Dual ADC mode, ADC1 data are transferred on the first request, ADC2 data are transferred on the second request and so on.
Example:
Regular simultaneous triple mode: 3 consecutive DMA requests are generated
(one for each converted data item)
1st request: ADC_CDR[31:0] = ADC1_DR[15:0]
2nd request: ADC_CDR[31:0] = ADC2_DR[15:0]
3rd request: ADC_CDR[31:0] = ADC3_DR[15:0]
4th request: ADC_CDR[31:0] = ADC1_DR[15:0]

It may something with DMA in MODE1. This is my all related code for DMA. Configuration is correct, but why the interrupt function doesn't send both data?

/*******Enable clock for DMA*********/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
/***Configures the DMA mode for multi ADC mode **/
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1;
/*******8 Enable DMA request after last transfer (Multi-ADC mode)*******/
ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);
while (1)
{
if (DMA_GetITStatus (DMA2_Stream0, DMA_IT_TCIF0) != RESET){
DMA_ClearITPendingBit (DMA2_Stream0, DMA_IT_TCIF0);
USART_SendData(USART3, aADCDualConvertedValue[0]);
USART_SendData(USART3, aADCDualConvertedValue[1]);
}
}
/****************** DMA2 Stream0 channel0 configuration **************************************/
static void DMA_Config(void)
{
DMA_InitTypeDef DMA_InitStructure;
DMA_InitStructure.DMA_Channel = DMA_Channel_0; 
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&aADCDualConvertedValue;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC_CCR_ADDRESS;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = 2;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize =DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable; 
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream0, &DMA_InitStructure);
/* DMA2_Stream0 enable */
DMA_Cmd(DMA2_Stream0, ENABLE);
/* DMA2_Stream0 transfer complete intterupt enable */
DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE);
}

ardavantycoon
Associate II
Posted on February 26, 2016 at 13:32

I did sth very ridiculously in order to make it work and it does. But I dont know it sends corresponding data or not. I mean I have one sample for each of ADC1 and ADC2. does interrupt happen for each dma transfer or it happen after both data transfer. In order words. The order of sent data is this:

data1: ADC1(t1) data2:ADC2(t1) data3: ADC1(t2) data4:ADC2(t2) ... OR data1: ADC1(t1) data2:ADC2(t2) data3: ADC1(t3) data4:ADC2(t4) ....

while (1)
{
if (DMA_GetITStatus (DMA2_Stream0, DMA_IT_TCIF0) != RESET){
DMA_ClearITPendingBit (DMA2_Stream0, DMA_IT_TCIF0);
USART_SendData(USART3, aADCDualConvertedValue[i]);
i=i+1;
if (i>1) {
i=0;
}
}
}