Last active
December 15, 2015 08:39
-
-
Save btolfa/5232492 to your computer and use it in GitHub Desktop.
Как настроить запуск ADС от таймера, результаты сохранять через DMA
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*---------------------------------------------------------------------------- | |
Программа, которая измеряет напряжение и по DMA помещает данные в массив | |
АЦП запускается от таймера Т2 с частотой 1кГц. Размер массива -2000 слов. | |
Сначала генерируется прерывание обработчика первого полумассива, затем второго. | |
*---------------------------------------------------------------------------*/ | |
#include <stm32f10x_adc.h> | |
#include <stm32f10x_dma.h> | |
#include <stm32f10x_gpio.h> | |
#include <stm32f10x_rcc.h> | |
#include <stm32f10x_tim.h> | |
#define ADC1_DR_Address ((uint32_t)0x4001244C) | |
volatile uint16_t ADCConvertedValue[2000]; | |
uint16_t dmacounter; | |
uint16_t dmacounter2; | |
/*---------------------------------------------------------------------------- | |
Настройки ADC-DMA | |
*---------------------------------------------------------------------------*/ | |
void ADCDMA_Init() { | |
GPIO_InitTypeDef GPIO_InitStructure; | |
ADC_InitTypeDef ADC_InitStructure; | |
DMA_InitTypeDef DMA_InitStructure; | |
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; | |
NVIC_InitTypeDef NVIC_InitStructure; | |
TIM_OCInitTypeDef TIM_OCInitStructure; | |
/* Enable DMA1 clock */ | |
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); | |
/* Enable ADC1 and GPIOC clock */ | |
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC, ENABLE); | |
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); | |
/* Configure PC.04 (ADC Channel14) as analog input -------------------------*/ | |
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; | |
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; | |
GPIO_Init(GPIOC, &GPIO_InitStructure); | |
/* DMA1 channel1 configuration ----------------------------------------------*/ | |
DMA_DeInit(DMA1_Channel1); | |
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) &(ADC1->DR); | |
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADCConvertedValue; | |
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; | |
DMA_InitStructure.DMA_BufferSize = 2000; | |
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_Low; | |
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; | |
DMA_Init(DMA1_Channel1, &DMA_InitStructure); | |
// Включим прерывание от ДМА по окончанию передачи блока | |
DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE); | |
DMA_ITConfig(DMA1_Channel1, DMA_IT_HT, ENABLE); | |
NVIC_EnableIRQ(DMA1_Channel1_IRQn); | |
/* Enable DMA1 channel1 */ | |
DMA_Cmd(DMA1_Channel1, ENABLE); | |
/* TIM1 configuration ------------------------------------------------------*/ | |
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); | |
/* Time Base configuration */ | |
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); | |
TIM_TimeBaseStructure.TIM_Period = 0xBB; | |
TIM_TimeBaseStructure.TIM_Prescaler = 64; | |
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); | |
TIM_OCStructInit(&TIM_OCInitStructure); | |
// 0x5D ~ 0xBB/2 - Канал сравнения сработает где-то посередине периода TIM2 | |
TIM_OCInitStructure.TIM_Pulse = 0x5D; | |
TIM_OC2Init(TIM2, &TIM_OCInitStructure); | |
/* ADC1 configuration ------------------------------------------------------*/ | |
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; | |
ADC_InitStructure.ADC_ScanConvMode = ENABLE; | |
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); | |
/* ADC1 regular channel14 configuration */ | |
ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_7Cycles5); | |
/* Enable ADC1 DMA */ | |
ADC_DMACmd(ADC1, ENABLE); | |
/* Enable ADC1 external trigger */ | |
ADC_ExternalTrigConvCmd(ADC1, ENABLE); | |
/* Enable ADC1 */ | |
ADC_Cmd(ADC1, ENABLE); | |
/* Enable ADC1 reset calibration register */ | |
ADC_ResetCalibration(ADC1); | |
/* Check the end of ADC1 reset calibration register */ | |
while(ADC_GetResetCalibrationStatus(ADC1)); | |
/* Start ADC1 calibration */ | |
ADC_StartCalibration(ADC1); | |
/* Check the end of ADC1 calibration */ | |
while(ADC_GetCalibrationStatus(ADC1)); | |
/* TIM1 counter enable */ | |
TIM_Cmd(TIM2, ENABLE); | |
} | |
/*---------------------------------------------------------------------------- | |
Обработчик прерывания от DMA - АЦП по окончании передачи блока | |
*---------------------------------------------------------------------------*/ | |
void DMA1_Channel1_IRQHandler(void){ | |
if (DMA_GetITStatus(DMA1_IT_HT1)) { | |
dmacounter++; | |
DMA_ClearITPendingBit(DMA1_IT_HT1); | |
} | |
if (DMA_GetITStatus(DMA1_IT_TC1)) { | |
dmacounter2++; | |
DMA_ClearITPendingBit(DMA1_IT_TC1); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment