We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hi,
I want to program STM32F103 in which define an array that is completed with ADC value. I need to trigger the ADC with timer and also use DMA. It means that when the array complete, the DMA_IRQ Handler send this array by USART channel. I wrote this code but it doesn't work.
I would be appreciate if you help me to correct this program.
#include "stm32f10x.h" #define ADC1_DR_Address ((uint32_t)0x4001244C) uint16_t array [32]; DMA_InitTypeDef DMA_InitStructure; int main(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_AFIO, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC , ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOA, &GPIO_InitStructure); NVIC_InitTypeDef sara3; sara3.NVIC_IRQChannel = DMA1_Channel1_IRQn; sara3.NVIC_IRQChannelPreemptionPriority = 0; sara3.NVIC_IRQChannelSubPriority = 0; sara3.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&sara3); TIM_TimeBaseInitTypeDef Tim_TimeBaseStructure; TIM_TimeBaseStructInit(&Tim_TimeBaseStructure); Tim_TimeBaseStructure.TIM_Period = 9000; Tim_TimeBaseStructure.TIM_Prescaler = 0x0; Tim_TimeBaseStructure.TIM_ClockDivision = 0x0; Tim_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &Tim_TimeBaseStructure); TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update); TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); /* TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0x7F; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OC1Init(TIM2, &TIM_OCInitStructure); */ ADC_InitTypeDef ADC_InitStructure; ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = DISABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_CC2; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 1; ADC_Init(ADC1, &ADC_InitStructure); ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_55Cycles5); //ADC_SoftwareStartConvCmd(ADC1,ENABLE); DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)array; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = 32; 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_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel1, &DMA_InitStructure); USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate = 115200; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART1, &USART_InitStructure); USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); USART_ITConfig(USART1, USART_IT_TXE, ENABLE); USART_ClearFlag(USART1,USART_FLAG_TC); DMA_ITConfig (DMA1_Channel1, DMA_IT_TC,ENABLE); DMA_Cmd(DMA1_Channel1, ENABLE); ADC_Cmd(ADC1, ENABLE); ADC_DMACmd(ADC1, ENABLE); USART_Cmd(USART1, ENABLE); TIM_Cmd(TIM2, ENABLE); ADC_ResetCalibration(ADC1); while(ADC_GetResetCalibrationStatus(ADC1)); ADC_StartCalibration(ADC1); while(ADC_GetCalibrationStatus(ADC1)); while (1); } void DMA1_Channel1_IRQHandler(void) { uint8_t i = 0; if( DMA_GetITStatus(DMA1_FLAG_TC1) ) { for(i = 0;i < 32 ; i++){ USART_SendData(USART1, (uint8_t) array[i]); while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) {} USART_SendData(USART1, (uint8_t) array[i]>> 8); while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) {} } DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)array; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = 32; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel1, &DMA_InitStructure); ADC_DMACmd(ADC1, ENABLE); DMA_Cmd(DMA1_Channel1, ENABLE); DMA_ClearITPendingBit(DMA1_IT_TC1); DMA_ClearITPendingBit(DMA1_IT_GL1); } }
I guess that nobody want to do the work for you, so you must solve them instead.
Where is the DMA channel declaration?
like: DMA_InitStructure.DMA_Channel = DMA_Channel_0;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)array; <--- this don't works. DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&array;<-- This works - see my example
DMA_InitStructure.DMA_BufferSize = 32; 32 half-word are used as Buffer? ADC_InitStructure.ADC_NbrOfChannel = 1; and just one CHannel should be aquire????
ADC_InitStructure.ADC_NbrOfChannel = 1; one channel needs just DMA_InitStructure.DMA_BufferSize = 1; one memory sized of a half-word buffer
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; <-- not required to fill - you do P2M
// This should used to trigger the conversation by the timer. // ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; // ADC_InitStructure.ADC_ExternalTrigConv = 0;
I don't had looked your code longer because the structure is mystic.