static void ADC_Configuration(void) { ADC_InitTypeDef ADC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2 , ENABLE); // ADC1 configuration ADC_DeInit(ADC1); ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_CC2; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 3; ADC_Init(ADC1, &ADC_InitStructure); // ADC1 channel sequence ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_28Cycles5); ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_28Cycles5); ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 3, ADC_SampleTime_28Cycles5); // ADC2 configuration ADC_DeInit(ADC2); ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 3; ADC_Init(ADC2, &ADC_InitStructure); // ADC2 channel sequence ADC_RegularChannelConfig(ADC2, ADC_Channel_2, 1, ADC_SampleTime_28Cycles5); ADC_RegularChannelConfig(ADC2, ADC_Channel_3, 2, ADC_SampleTime_28Cycles5); ADC_RegularChannelConfig(ADC2, ADC_Channel_17, 3, ADC_SampleTime_28Cycles5); // Enable ADC1 ADC_Cmd(ADC1, ENABLE); // Calibrate ADC1 ADC_ResetCalibration(ADC1); while(ADC_GetResetCalibrationStatus(ADC1)); ADC_StartCalibration(ADC1); while(ADC_GetCalibrationStatus(ADC1)); // Enable ADC1 external trigger ADC_ExternalTrigConvCmd(ADC1, ENABLE); ADC_TempSensorVrefintCmd(ENABLE); // Enable ADC2 ADC_Cmd(ADC2, ENABLE); // Calibrate ADC2 ADC_ResetCalibration(ADC2); while(ADC_GetResetCalibrationStatus(ADC2)); ADC_StartCalibration(ADC2); while(ADC_GetCalibrationStatus(ADC2)); // Enable ADC2 external trigger ADC_ExternalTrigConvCmd(ADC2, ENABLE); }
static void AD_Reset() { ADC_InitTypeDef ADC_InitStructure; ADC_DeInit(ADC1); /* ADC configuration ------------------------------------------------------*/ ADC_InitStructure.ADC_Mode = ADC_Mode_RegInjecSimult; //ADC_Mode_RegSimult; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T3_TRGO; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 1; ADC_Init(ADC1, &ADC_InitStructure); ADC_ExternalTrigConvCmd(ADC1, ENABLE); ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5); ADC_ClearITPendingBit(ADC1, ADC_IT_EOC); ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE); /* enable and calibrate ADCs */ ADC_Enable(ADC1); }
/******************************************************************************* * Function Name : TIM1_CC_IRQHandler * Description : This function handles TIM1 capture compare interrupt request. * Input : None * Output : None * Return : None *******************************************************************************/ void TIM1_CC_IRQHandler(void) { if (TIM_GetITStatus(TIM1, TIM_IT_CC1) != RESET) { //CC1 - osiagniecie wartosci TIM_ClearITPendingBit(TIM1, TIM_IT_CC1); ADC_ExternalTrigConvCmd(ADC1, ENABLE); //wlaczenie triggera dla nastepnego pomiaru } }
/** * @brief Configures the ADC. * @param None * @retval None */ void ADC_Configuration(void) { ADC_InitTypeDef ADC_InitStructure; // Structure to initialize the ADC // Configure ADC1 on channel 1 ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = DISABLE; // One channel only ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; // Conversion on PWM rising edge only ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1; // Timer 1 CC1 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 1; // Initialise and enable ADC1 ADC_DeInit( ADC1 ); //Set ADC registers to default values ADC_Init( ADC1, &ADC_InitStructure ); ADC_RegularChannelConfig( ADC1, ADC_Channel_10, 1, ADC_SampleTime_71Cycles5); // Start transferts ADC_ExternalTrigConvCmd( ADC1, ENABLE ); // Enable ADC1 external trigger ADC_DMACmd( ADC1, ENABLE ); //Enable ADC1 DMA ADC_Cmd( ADC1, ENABLE ); //Enable ADC1 // Enable JEOC interrupt //ADC_ITConfig(ADC1, ADC_IT_JEOC, ENABLE); // Calibrate ADC1 ADC_ResetCalibration( ADC1 ); while ( ADC_GetResetCalibrationStatus(ADC1) ) {} //Check the end of ADC1 reset calibration register ADC_StartCalibration( ADC1 ); while ( ADC_GetCalibrationStatus(ADC1) ) {} //Check the end of ADC1 calibration }
int main(void) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_InitStructure; ADC_InitTypeDef ADC_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); GPIO_StructInit(&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); GPIO_StructInit(&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOA, &GPIO_InitStructure); TIM_TimeBaseStructInit(&TIM_InitStructure); TIM_InitStructure.TIM_Prescaler = 10000; TIM_InitStructure.TIM_Period = 100; TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_InitStructure); TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Update); ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = DISABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T3_TRGO; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 1; ADC_Init(ADC1, &ADC_InitStructure); ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 1, ADC_SampleTime_55Cycles5); ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE); ADC_ExternalTrigConvCmd(ADC1, ENABLE); NVIC_InitStructure.NVIC_IRQChannel = ADC1_IRQn; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); ADC_Cmd(ADC1, ENABLE); while(ADC_GetResetCalibrationStatus(ADC1)); ADC_StartCalibration(ADC1); while(ADC_GetCalibrationStatus(ADC1)); TIM_Cmd(TIM3, ENABLE); if (SysTick_Config(SystemCoreClock / 1000)) while (1); while(1); }
static void ADC1_Mode_Config(void) { DMA_InitTypeDef DMA_InitStructure; ADC_InitTypeDef ADC_InitStructure; /* DMA channel1 configuration */ DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; //DMA外设基地址 DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_ConvertedValue; //DMA内存基地址 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //数据传输方向,从外设发送到内存 DMA_InitStructure.DMA_BufferSize = 1; 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_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel1, &DMA_InitStructure); /* Enable DMA channel1 */ DMA_Cmd(DMA1_Channel1, ENABLE); /* ADC1 configuration */ ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //独立模式 每个ADC独立工作 ADC_InitStructure.ADC_ScanConvMode = ENABLE; //使用扫描模式 scan位设置 ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; // cont位设置 连续转换模式 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ;//EXTSEL 选择启动规则通道组转换的外部事件 设置成有软件控制 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //数据对齐 由软件置位和清楚 这里设置成右对齐 ADC_InitStructure.ADC_NbrOfChannel = 1; //规则通道序列长度 这些位由软件定义在规则通道转换序列中的通道数目 1个转换 指定由多少个通道被转换 ADC_Init(ADC1, &ADC_InitStructure); /* ADC1 regular channel11 configuration */ ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 1, ADC_SampleTime_55Cycles5); //转换时间是55.5个周期 /* Enable ADC1 external trigger */ ADC_ExternalTrigConvCmd(ADC1, DISABLE); /* Enable ADC1 DMA */ ADC_DMACmd(ADC1, ENABLE); /* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE); /* Enable ADC1 reset calibaration register */ ADC_ResetCalibration(ADC1); /* Check the end of ADC1 reset calibration register */ while(ADC_GetResetCalibrationStatus(ADC1)); /* Start ADC1 calibaration */ ADC_StartCalibration(ADC1); /* Check the end of ADC1 calibration */ while(ADC_GetCalibrationStatus(ADC1)); /* Start ADC1 Software Conversion */ ADC_SoftwareStartConvCmd(ADC1, ENABLE); }
/** @brief Stops conversion engine. */ void Analog::stop() { // Disable external triggering ADC_ExternalTrigConvCmd(_base, DISABLE); //Disable the interrupt ADC_ITConfig(_base , ADC_IT_EOC , DISABLE); //Disable the ADC ADC_Cmd(_base, DISABLE); }
/** * @brief Configures the ADC. * @param None * @retval None */ void ADC_Configuration(void) { ADC_InitTypeDef ADC_InitStructure; // Structure to initialize the ADC // Common config ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; // Conversion on PWM rising edge only ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1; // Timer 1 CC1 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 8; ADC_DeInit( ADC1 ); //Set ADC registers to default values ADC_Init( ADC1, &ADC_InitStructure ); // Channels config // Refer to SignalsRouting.png for the ranks ADC_RegularChannelConfig( ADC1, ADC_Channel_8, 2, ADC_SampleTime_1Cycles5); ADC_RegularChannelConfig( ADC1, ADC_Channel_9, 1, ADC_SampleTime_1Cycles5); ADC_RegularChannelConfig( ADC1, ADC_Channel_10, 8, ADC_SampleTime_1Cycles5); ADC_RegularChannelConfig( ADC1, ADC_Channel_11, 7, ADC_SampleTime_1Cycles5); ADC_RegularChannelConfig( ADC1, ADC_Channel_12, 3, ADC_SampleTime_1Cycles5); ADC_RegularChannelConfig( ADC1, ADC_Channel_13, 4, ADC_SampleTime_1Cycles5); ADC_RegularChannelConfig( ADC1, ADC_Channel_14, 6, ADC_SampleTime_1Cycles5); ADC_RegularChannelConfig( ADC1, ADC_Channel_15, 5, ADC_SampleTime_1Cycles5); // Enable End Of Conversion interrupt ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE); // Start transferts ADC_ExternalTrigConvCmd( ADC1, ENABLE ); // Enable ADC1 external trigger ADC_DMACmd( ADC1, ENABLE ); //Enable ADC1 DMA ADC_Cmd( ADC1, ENABLE ); //Enable ADC1 // Calibrate ADC1 ADC_ResetCalibration( ADC1 ); while ( ADC_GetResetCalibrationStatus(ADC1) ) {} //Check the end of ADC1 reset calibration register ADC_StartCalibration( ADC1 ); while ( ADC_GetCalibrationStatus(ADC1) ) {} //Check the end of ADC1 calibration }
void InitialADC(void) { ADC_InitTypeDef ADC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; DMA_InitTypeDef DMA_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); /* Configure PC.0(ADC Channel1, Channel2, ) as analog input -----------------------------------------------------------*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOA, &GPIO_InitStructure); RCC_ADCCLKConfig(RCC_PCLK2_Div6); /// 12MHz for ADC clock /* Here we config the ADC1 and ADC2 in regular simultaneous mode They are trigerred by TIM3 TRGO signal The result will stored in ADC1's DR, */ ADC_DeInit(ADC1); ADC_DeInit(ADC2); ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //ADC_ExternalTrigConv_T3_TRGO; //ADC_ExternalTrigConv_T2_CC2; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 2; ADC_Init(ADC1, &ADC_InitStructure); ADC_Init(ADC2, &ADC_InitStructure); ADC_RegularChannelConfig(ADC1, AD_CH_REF, 1, ADC_SampleTime_13Cycles5); ADC_RegularChannelConfig(ADC2, AD_CH_X, 1, ADC_SampleTime_13Cycles5); ADC_RegularChannelConfig(ADC1, AD_CH_Y, 2, ADC_SampleTime_13Cycles5); ADC_RegularChannelConfig(ADC2, AD_CH_Z, 2, ADC_SampleTime_13Cycles5); /* Initialize the ADC DMA channel */ ADC_DMACmd(ADC1,ENABLE); DMA_DeInit(DMA_ADC); DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&ADC1->DR); DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADCResult; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; 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_Word; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;//DMA_Priority_Low DMA_Priority_VeryHigh; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA_ADC, &DMA_InitStructure); // NVIC_InitTypeDef NVIC_InitStructure; // NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQChannel; // NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; // NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // NVIC_Init(&NVIC_InitStructure); // DMA_ITConfig(DMA_ADC, DMA_IT_TC, ENABLE); DMA_Cmd(DMA_ADC, ENABLE); ADC_TempSensorVrefintCmd(ENABLE); //ADC_ExternalTrigConvCmd(ADC1, ENABLE); ADC_ExternalTrigConvCmd(ADC2, ENABLE); ADC_Cmd(ADC1, ENABLE); ADC_Cmd(ADC2, ENABLE); ADC_ResetCalibration(ADC1); /* Check the end of ADC1 reset calibration register */ while(ADC_GetResetCalibrationStatus(ADC1)); /* Start ADC1 calibaration */ ADC_StartCalibration(ADC1); /* Check the end of ADC1 calibration */ while(ADC_GetCalibrationStatus(ADC1)); ADC_ResetCalibration(ADC2); /* Check the end of ADC1 reset calibration register */ while(ADC_GetResetCalibrationStatus(ADC2)); /* Start ADC1 calibaration */ ADC_StartCalibration(ADC2); /* Check the end of ADC1 calibration */ while(ADC_GetCalibrationStatus(ADC2)); }
static inline void main_init_adc(void) { /* Enable DMA1 clock */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); /* Enable ADC1 and GPIOC clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2 | RCC_APB2Periph_GPIOC, ENABLE); /* Configure PC.01 (ADC Channel11) and PC.04 (ADC Channel14) as analog input-*/ GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOC, &GPIO_InitStructure); /* DMA1 channel1 configuration ----------------------------------------------*/ DMA_InitTypeDef DMA_InitStructure; DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&coder_values; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = 1; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel1, &DMA_InitStructure); /* Enable DMA1 channel1 */ DMA_Cmd(DMA1_Channel1, ENABLE); /* ADC1 configuration ------------------------------------------------------*/ ADC_InitTypeDef ADC_InitStructure; ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; 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_239Cycles5); //Paul: Changing to use chan 10 instead ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_239Cycles5); /* Enable ADC1 DMA */ ADC_DMACmd(ADC1, ENABLE); /* ADC2 configuration ------------------------------------------------------*/ ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 1; ADC_Init(ADC2, &ADC_InitStructure); /* ADC2 regular channels configuration */ ADC_RegularChannelConfig(ADC2, ADC_Channel_11, 1, ADC_SampleTime_239Cycles5); /* Enable ADC2 external trigger conversion */ ADC_ExternalTrigConvCmd(ADC2, ENABLE); /* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE); /* Enable ADC1 reset calibaration register */ ADC_ResetCalibration(ADC1); /* Check the end of ADC1 reset calibration register */ while(ADC_GetResetCalibrationStatus(ADC1)); /* Start ADC1 calibaration */ ADC_StartCalibration(ADC1); /* Check the end of ADC1 calibration */ while(ADC_GetCalibrationStatus(ADC1)); /* Enable ADC2 */ ADC_Cmd(ADC2, ENABLE); /* Enable ADC2 reset calibaration register */ ADC_ResetCalibration(ADC2); /* Check the end of ADC2 reset calibration register */ while(ADC_GetResetCalibrationStatus(ADC2)); /* Start ADC2 calibaration */ ADC_StartCalibration(ADC2); /* Check the end of ADC2 calibration */ while(ADC_GetCalibrationStatus(ADC2)); /* Start ADC1 Software Conversion */ ADC_SoftwareStartConvCmd(ADC1, ENABLE); }
/** @brief Starts conversion engine. Can use external trigger events or software event */ void Analog::start(const Timer * const tim) { /* Possible trigger events for F1 ADC_ExternalTrigConv_None ADC_ExternalTrigConv_T1_CC1 ADC_ExternalTrigConv_T1_CC2 ADC_ExternalTrigConv_T1_CC3 ADC_ExternalTrigConv_T2_CC2 ADC_ExternalTrigConv_T3_TRGO ADC_ExternalTrigConv_T4_CC4 ADC_ExternalTrigConv_Ext_IT11_TIM8_TRGO Possible trigger events for L1 ADC_ExternalTrigConv_T2_CC3 ADC_ExternalTrigConv_T2_CC2 ADC_ExternalTrigConv_T2_TRGO ADC_ExternalTrigConv_T3_CC1 ADC_ExternalTrigConv_T3_CC3 ADC_ExternalTrigConv_T3_TRGO ADC_ExternalTrigConv_T4_CC4 ADC_ExternalTrigConv_T4_TRGO ADC_ExternalTrigConv_T6_TRGO ADC_ExternalTrigConv_T9_CC2 ADC_ExternalTrigConv_T9_TRGO ADC_ExternalTrigConv_Ext_IT11 ADC_ExternalTrigConvEdge_None ADC_ExternalTrigConvEdge_Rising ADC_ExternalTrigConvEdge_Falling ADC_ExternalTrigConvEdge_RisingFalling */ adc_trigger_t trigger;// = ADC_ExternalTrigConv_None; //L1: ADC_ExternalTrigConvEdge_None if(tim!= nullptr) trigger = tim; adc_init_t config(trigger,channel_count); // Base initialization procedure ADC_Init(_base, &config.init); // Enable conversion through external trigger if(trigger){ ADC_ExternalTrigConvCmd(_base, ENABLE); } // ADC_IT_EOC - end of conversion IRQ // ADC_IT_AWD - analog watchdog IRQ // ADC_IT_JEOC - end of injected conversion IRQ ADC_ITConfig(_base , ADC_IT_EOC , ENABLE); // Enable ADC //TODO: enabling really before calibration? Then IRQ enabling probably shoud go after calibration ADC_Cmd(_base, ENABLE); //Enable ADC1 reset calibration register ADC_ResetCalibration(_base); //Check the end of ADC1 reset calibration register while(ADC_GetResetCalibrationStatus(_base)); //Start ADC1 calibration ADC_StartCalibration(_base); //Check the end of ADC1 calibration while(ADC_GetCalibrationStatus(_base)); //Iterate through regular channel group starting with the first ch = channel_list.begin(); }
void AGC_Init(void) { NVIC_InitTypeDef NVIC_InitStructure; ADC_InitTypeDef ADC_InitStructure; DMA_InitTypeDef DMA_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = DMA2_Channel4_5_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = ADC_CHANNEL10_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(ADC_PORT, &GPIO_InitStructure); RCC_ADCCLKConfig(RCC_PCLK2_Div6); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE); ADC_DeInit(ADC3); ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = DISABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T8_TRGO; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 1; ADC_Init(ADC3, &ADC_InitStructure); ADC_RegularChannelConfig(ADC3, ADC_Channel_10, 1, ADC_SampleTime_71Cycles5); ADC_DMACmd(ADC3, ENABLE); ADC_Cmd(ADC3, ENABLE); ADC_ResetCalibration(ADC3); while (ADC_GetResetCalibrationStatus(ADC3)) ; ADC_StartCalibration(ADC3); while (ADC_GetCalibrationStatus(ADC3)) ; ADC_ExternalTrigConvCmd(ADC3, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE); DMA_DeInit(DMA2_Channel5); DMA_InitStructure.DMA_PeripheralBaseAddr = ADC3_DR_ADDRESS; DMA_InitStructure.DMA_MemoryBaseAddr = (u32) (&AgcSampleBuf); DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = AGC_BUF_NUM; 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_Medium; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA2_Channel5, &DMA_InitStructure); DMA_ClearFlag(DMA2_IT_TC5 | DMA2_IT_HT5); DMA_ITConfig(DMA2_Channel5, DMA_IT_TC | DMA_IT_HT, ENABLE); DMA_Cmd(DMA2_Channel5, ENABLE); #ifdef FILTER ch1_iir_reset(); #endif PGA113_Init(); }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f10x_xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f10x.c file */ /* System clocks configuration ---------------------------------------------*/ RCC_Configuration(); /* NVIC configuration ------------------------------------------------------*/ NVIC_Configuration(); /* GPIO configuration ------------------------------------------------------*/ GPIO_Configuration(); /* EXTI configuration ------------------------------------------------------*/ EXTI_Configuration(); /* DMA1 channel1 configuration ----------------------------------------------*/ DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_RegularConvertedValueTab; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = 64; 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_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel1, &DMA_InitStructure); /* Enable DMA1 channel1 */ DMA_Cmd(DMA1_Channel1, ENABLE); /* ADC1 configuration ------------------------------------------------------*/ ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_Ext_IT11_TIM8_TRGO; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 2; ADC_Init(ADC1, &ADC_InitStructure); /* ADC1 regular channels configuration */ ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 1, ADC_SampleTime_28Cycles5); ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 2, ADC_SampleTime_28Cycles5); /* Regular discontinuous mode channel number configuration */ ADC_DiscModeChannelCountConfig(ADC1, 1); /* Enable regular discontinuous mode */ ADC_DiscModeCmd(ADC1, ENABLE); /* Enable ADC1 external trigger conversion */ ADC_ExternalTrigConvCmd(ADC1, ENABLE); /* Set injected sequencer length */ ADC_InjectedSequencerLengthConfig(ADC1, 2); /* ADC1 injected channel configuration */ ADC_InjectedChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_28Cycles5); ADC_InjectedChannelConfig(ADC1, ADC_Channel_12, 2, ADC_SampleTime_28Cycles5); /* ADC1 injected external trigger configuration */ ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_Ext_IT15_TIM8_CC4); /* Enable ADC1 injected external trigger conversion */ ADC_ExternalTrigInjectedConvCmd(ADC1, ENABLE); /* Enable JEOC interrupt */ ADC_ITConfig(ADC1, ADC_IT_JEOC, ENABLE); /* Enable ADC1 DMA */ ADC_DMACmd(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)); while (1) { } }
/** * @brief Initialise the ADC Peripheral * @param[in] adc_oversample * @return * @arg 1 for success * @arg 0 for failure * Currently ignores rates and uses hardcoded values. Need a little logic to * map from sampling rates and such to ADC constants. */ uint8_t AHRS_ADC_Config(int32_t adc_oversample) { int32_t i; ADC_DeInit(ADC1); ADC_DeInit(ADC2); /* Setup analog pins */ GPIO_InitTypeDef GPIO_InitStructure; GPIO_StructInit(&GPIO_InitStructure); GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; /* Enable each ADC pin in the array */ for (i = 0; i < PIOS_ADC_NUM_PINS; i++) { GPIO_InitStructure.GPIO_Pin = ADC_GPIO_PIN[i]; GPIO_Init(ADC_GPIO_PORT[i], &GPIO_InitStructure); } /* Enable ADC clocks */ PIOS_ADC_CLOCK_FUNCTION; /* Map channels to conversion slots depending on the channel selection mask */ for (i = 0; i < PIOS_ADC_NUM_PINS; i++) { ADC_RegularChannelConfig(ADC_MAPPING[i], ADC_CHANNEL[i], ADC_CHANNEL_MAPPING[i], PIOS_ADC_SAMPLE_TIME); } #if (PIOS_ADC_USE_TEMP_SENSOR) ADC_TempSensorVrefintCmd(ENABLE); ADC_RegularChannelConfig(PIOS_ADC_TEMP_SENSOR_ADC, ADC_Channel_14, PIOS_ADC_TEMP_SENSOR_ADC_CHANNEL, PIOS_ADC_SAMPLE_TIME); #endif // TODO: update ADC to continuous sampling, configure the sampling rate /* Configure ADCs */ ADC_InitTypeDef ADC_InitStructure; ADC_StructInit(&ADC_InitStructure); ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = ((PIOS_ADC_NUM_CHANNELS + 1) >> 1); ADC_Init(ADC1, &ADC_InitStructure); #if (PIOS_ADC_USE_ADC2) ADC_Init(ADC2, &ADC_InitStructure); /* Enable ADC2 external trigger conversion (to synch with ADC1) */ ADC_ExternalTrigConvCmd(ADC2, ENABLE); #endif RCC_ADCCLKConfig(PIOS_ADC_ADCCLK); RCC_PCLK2Config(RCC_HCLK_Div16); /* Enable ADC1->DMA request */ ADC_DMACmd(ADC1, ENABLE); /* ADC1 calibration */ ADC_Cmd(ADC1, ENABLE); ADC_ResetCalibration(ADC1); while (ADC_GetResetCalibrationStatus(ADC1)) ; ADC_StartCalibration(ADC1); while (ADC_GetCalibrationStatus(ADC1)) ; #if (PIOS_ADC_USE_ADC2) /* ADC2 calibration */ ADC_Cmd(ADC2, ENABLE); ADC_ResetCalibration(ADC2); while (ADC_GetResetCalibrationStatus(ADC2)) ; ADC_StartCalibration(ADC2); while (ADC_GetCalibrationStatus(ADC2)) ; #endif /* Enable DMA1 clock */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); /* Configure DMA1 channel 1 to fetch data from ADC result register */ DMA_InitTypeDef DMA_InitStructure; DMA_StructInit(&DMA_InitStructure); DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) & ADC1->DR; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) & raw_data_buffer[0]; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; /* We are double buffering half words from the ADC. Make buffer appropriately sized */ DMA_InitStructure.DMA_BufferSize = (PIOS_ADC_NUM_CHANNELS * adc_oversample * 2) >> 1; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; /* Note: We read ADC1 and ADC2 in parallel making a word read, also hence the half buffer size */ DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel1, &DMA_InitStructure); DMA_Cmd(DMA1_Channel1, ENABLE); /* Trigger interrupt when for half conversions too to indicate double buffer */ DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE); DMA_ITConfig(DMA1_Channel1, DMA_IT_HT, ENABLE); /* Configure and enable DMA interrupt */ NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PIOS_ADC_IRQ_PRIO; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* Finally start initial conversion */ ADC_SoftwareStartConvCmd(ADC1, ENABLE); return 1; }
int main( void ) { //konfiguracija taktova RCC_ADCCLKConfig(RCC_PCLK2_Div2);//konfigurisanje takta za ADC RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//dovodjenje takta za DMA kontroler RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_TIM1 | RCC_APB2Periph_ADC1, ENABLE);//dovodjenje takta portu A, B, C, tajmeru TIM1 i ADC-u //konfiguracija portova - analogni ulazi GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOC, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOC, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOA, &GPIO_InitStructure); //konfiguracija portova - bargraph tj. DIGIO konektor GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_5 | GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_13; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); /* DMA1 channel1 configuration ----------------------------------------------*/ DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;//adresa izvorista za dma prenos - DATA REGISTER ADC-a DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_RegularConvertedValueTab; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = 4; 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_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel1, &DMA_InitStructure); /* Enable DMA1 channel1 */ DMA_Cmd(DMA1_Channel1, ENABLE); /* ADC1 configuration ------------------------------------------------------*/ ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 4; ADC_Init(ADC1, &ADC_InitStructure); ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 1, ADC_SampleTime_1Cycles5); ADC_RegularChannelConfig(ADC1, ADC_Channel_13, 2, ADC_SampleTime_1Cycles5); ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 3, ADC_SampleTime_1Cycles5); ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 4, ADC_SampleTime_1Cycles5); ADC_ExternalTrigConvCmd(ADC1, ENABLE);//omogucavanje externog triger moda ADC_DMACmd(ADC1, ENABLE);//omogucavanje DMA prenosa za ADC ADC_Cmd(ADC1, ENABLE); ADC_ResetCalibration(ADC1);//adc kalibracija while(ADC_GetResetCalibrationStatus(ADC1)); ADC_StartCalibration(ADC1); while(ADC_GetCalibrationStatus(ADC1)); //konfiguracija tajmera TIM1 koji radi u PWM modu, i svoj izlaz koristi za trigerovanje ADC-a TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct); TIM_TimeBaseInitStruct.TIM_Period = 150 - 1; TIM_TimeBaseInitStruct.TIM_Prescaler = 0; TIM_TimeBaseInitStruct.TIM_ClockDivision = 0x0; TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseInitStruct); TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStruct.TIM_Pulse = 150 / 2; TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OC1Init(TIM1, &TIM_OCInitStruct); TIM_Cmd(TIM1, ENABLE);//dozovla rada tajmera tek kada se konfigurisu i DMA i ADC TIM_CtrlPWMOutputs(TIM1, ENABLE);//generisanje PWM izlaza za tajmer 1 baterija_Acc_const=0.004032; servo_5V_const=0.004032; /* Inicijalizacija. */ InitGPIO_Pin(GPIOB, GPIO_Pin_11, GPIO_Mode_IPU, GPIO_Speed_50MHz); UsartInit(); /* Inicijalizacija glavnog tajmera. */ initTimerServo();//zbog ovoga se baterija meri i dok je prekidac uvucen /* Glavna masina stanja. */ while(1) { switch (state_robot) { /* Pocetno stanje u kome se inicijalizaciju sistemi, podesava preskaler, ukljucuje UV. */ case 0: // pocetno stanje, sve inicijalizujemo i krenemo napred if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11)) // ako je ocitano Vcc, tj. krene se sa izvrsavanjem, u suprotnom ostajemo u // istom stanju { /* Inicijalizacija glavnog tajmera. */ initTimer90(); /* Inicijalizacija tajmera za proveru pozicije robota. */ SysTick_Config( SysTick_Config( SystemCoreClock / 1000 ) ); /* Provera koja je stategije. */ checkStrategy(); /* Zadavanje komandi. */ issueCommand( START_RUNNING, MOTION_DEVICE_ADDRESS, 30 ); waitAck( START_RUNNING, MOTION_DEVICE_ADDRESS, 30 ); issueCommand( PRESCALER, MOTION_DEVICE_ADDRESS, 1000 ); waitAck( PRESCALER, MOTION_DEVICE_ADDRESS, 1000 ); issueCommand( ULTRASOUND_ON, MOTION_DEVICE_ADDRESS, 1 ); waitAck( ULTRASOUND_ON, MOTION_DEVICE_ADDRESS, 1 ); issueCommand( MOVE_FORWARD, MOTION_DEVICE_ADDRESS, 30 ); waitAck( MOVE_FORWARD, MOTION_DEVICE_ADDRESS, 30 ); while( TRUE ) { issueCommand( CHECK_ARRIVE, MOTION_DEVICE_ADDRESS, 1 ); sleep( 25 ); if ( FLAG_arriveOnDest ) break; sleep( 100 ); } state_robot++; sleep(100); } break; /* Blago okretanje da bi se izbegla ivica na sredini terena. */ case 1: if( FLAG_strategyLeft ) { issueCommand( ROTATE_LEFT, MOTION_DEVICE_ADDRESS, 20 ); waitAck( ROTATE_LEFT, MOTION_DEVICE_ADDRESS, 20 ); while( TRUE ) { issueCommand( CHECK_ARRIVE, MOTION_DEVICE_ADDRESS, 1 ); sleep( 25 ); if ( FLAG_arriveOnDest ) break; sleep( 100 ); } } else { issueCommand( ROTATE_RIGHT, MOTION_DEVICE_ADDRESS, 20 ); waitAck( ROTATE_RIGHT, MOTION_DEVICE_ADDRESS, 20 ); while( TRUE ) { issueCommand( CHECK_ARRIVE, MOTION_DEVICE_ADDRESS, 1 ); sleep( 25 ); if ( FLAG_arriveOnDest ) break; sleep( 100 ); } } state_robot++; sleep(100); break; /* Blago pomeranje napred, ka sredini terena. */ case 2: { issueCommand( MOVE_FORWARD, MOTION_DEVICE_ADDRESS, 50 ); waitAck( MOVE_FORWARD, MOTION_DEVICE_ADDRESS, 50 ); while( TRUE ) { issueCommand( CHECK_ARRIVE, MOTION_DEVICE_ADDRESS, 1 ); sleep( 100 ); if ( FLAG_arriveOnDest ) break; } state_robot++; sleep(100); break; } /* Blaga rotacija da bi se poravnali opet. */ case 3: if( FLAG_strategyLeft ) { issueCommand( ROTATE_RIGHT, MOTION_DEVICE_ADDRESS, 25 ); waitAck( ROTATE_RIGHT, MOTION_DEVICE_ADDRESS, 25 ); while( TRUE ) { issueCommand( CHECK_ARRIVE, MOTION_DEVICE_ADDRESS, 1 ); sleep( 100 ); if ( FLAG_arriveOnDest ) break; } } else { issueCommand( ROTATE_LEFT, MOTION_DEVICE_ADDRESS, 25 ); waitAck( ROTATE_LEFT, MOTION_DEVICE_ADDRESS, 25 ); while( TRUE ) { issueCommand( CHECK_ARRIVE, MOTION_DEVICE_ADDRESS, 1 ); sleep( 100 ); if ( FLAG_arriveOnDest ) break; } } state_robot++; sleep(100); break; /* Blago pomeranje napred da bi pomerili kocke u sredinu terena. */ case 4: issueCommand( MOVE_FORWARD, MOTION_DEVICE_ADDRESS, 10 ); waitAck( MOVE_FORWARD, MOTION_DEVICE_ADDRESS, 10 ); while( TRUE ) { issueCommand( CHECK_ARRIVE, MOTION_DEVICE_ADDRESS, 1 ); sleep( 100 ); if ( FLAG_arriveOnDest ) break; } state_robot++; sleep(100); break; /* Vracanje unazad. */ case 5: issueCommand( PRESCALER, MOTION_DEVICE_ADDRESS, 500 ); waitAck( PRESCALER, MOTION_DEVICE_ADDRESS, 500 ); issueCommand( MOVE_BACKWARD, MOTION_DEVICE_ADDRESS, 50 ); waitAck( MOVE_BACKWARD, MOTION_DEVICE_ADDRESS, 50 ); while( TRUE ) { issueCommand( CHECK_ARRIVE, MOTION_DEVICE_ADDRESS, 1 ); sleep( 100 ); if ( FLAG_arriveOnDest ) break; } state_robot++; sleep(100); break; /* Okretanje ka prvoj kucici, onoj daljoj od ivice terana i gasenje senzora. */ case 6: if( FLAG_strategyLeft ) { issueCommand( ROTATE_RIGHT, MOTION_DEVICE_ADDRESS, 175 ); waitAck( ROTATE_RIGHT, MOTION_DEVICE_ADDRESS, 175 ); while( TRUE ) { issueCommand( CHECK_ARRIVE, MOTION_DEVICE_ADDRESS, 1 ); sleep( 100 ); if ( FLAG_arriveOnDest ) break; } } else { issueCommand( ROTATE_LEFT, MOTION_DEVICE_ADDRESS, 175 ); waitAck( ROTATE_LEFT, MOTION_DEVICE_ADDRESS, 175 ); while( TRUE ) { issueCommand( CHECK_ARRIVE, MOTION_DEVICE_ADDRESS, 1 ); sleep( 100 ); if ( FLAG_arriveOnDest ) break; } } issueCommand( ULTRASOUND_OFF, MOTION_DEVICE_ADDRESS, 1 ); waitAck( ULTRASOUND_OFF, MOTION_DEVICE_ADDRESS, 1 ); state_robot++; sleep(100); break; /* Zatvaranje prvih vrata. */ case 7: issueCommand( PRESCALER, MOTION_DEVICE_ADDRESS, 700 ); waitAck( PRESCALER, MOTION_DEVICE_ADDRESS, 700 ); issueCommand( MOVE_FORWARD, MOTION_DEVICE_ADDRESS, 100 ); waitAck( MOVE_FORWARD, MOTION_DEVICE_ADDRESS, 100 ); while( TRUE ) { issueCommand( CHECK_ARRIVE, MOTION_DEVICE_ADDRESS, 1 ); sleep( 100 ); if ( FLAG_arriveOnDest ) break; } state_robot++; sleep(100); break; /* Vracanje unazad. */ case 8: issueCommand( ULTRASOUND_ON, MOTION_DEVICE_ADDRESS, 1 ); waitAck( ULTRASOUND_ON, MOTION_DEVICE_ADDRESS, 1 ); issueCommand( PRESCALER, MOTION_DEVICE_ADDRESS, 500 ); waitAck( PRESCALER, MOTION_DEVICE_ADDRESS, 500 ); issueCommand( MOVE_BACKWARD, MOTION_DEVICE_ADDRESS, 60 ); waitAck( MOVE_BACKWARD, MOTION_DEVICE_ADDRESS, 60 ); while( TRUE ) { issueCommand( CHECK_ARRIVE, MOTION_DEVICE_ADDRESS, 1 ); sleep( 100 ); if ( FLAG_arriveOnDest ) break; } state_robot++; sleep(100); break; /* Okretanje za 180 stepeni ka pocetnoj poziciji. */ case 9: //issueCommand( ULTRASOUND_ON, MOTION_DEVICE_ADDRESS, 1 ); //waitAck( ULTRASOUND_ON, MOTION_DEVICE_ADDRESS, 1 ); if( FLAG_strategyLeft ) { issueCommand( ROTATE_RIGHT, MOTION_DEVICE_ADDRESS, 180 ); waitAck( ROTATE_RIGHT, MOTION_DEVICE_ADDRESS, 180 ); while( TRUE ) { issueCommand( CHECK_ARRIVE, MOTION_DEVICE_ADDRESS, 1 ); sleep( 100 ); if ( FLAG_arriveOnDest ) break; } } else { issueCommand( ROTATE_LEFT, MOTION_DEVICE_ADDRESS, 180 ); waitAck( ROTATE_LEFT, MOTION_DEVICE_ADDRESS, 180 ); while( TRUE ) { issueCommand( CHECK_ARRIVE, MOTION_DEVICE_ADDRESS, 1 ); sleep( 100 ); if ( FLAG_arriveOnDest ) break; } } state_robot++; sleep(100); break; /* Odlazak naspram druge kucice. */ case 10: issueCommand( MOVE_FORWARD, MOTION_DEVICE_ADDRESS, 15 ); waitAck( MOVE_FORWARD, MOTION_DEVICE_ADDRESS, 15 ); while( TRUE ) { issueCommand( CHECK_ARRIVE, MOTION_DEVICE_ADDRESS, 1 ); sleep( 100 ); if ( FLAG_arriveOnDest ) break; } state_robot++; sleep(100); break; /* Okretanje ka kucici. */ case 11: if( FLAG_strategyLeft ) { issueCommand( ROTATE_LEFT, MOTION_DEVICE_ADDRESS, 175 ); waitAck( ROTATE_LEFT, MOTION_DEVICE_ADDRESS, 175 ); while( TRUE ) { issueCommand( CHECK_ARRIVE, MOTION_DEVICE_ADDRESS, 1 ); sleep( 100 ); if ( FLAG_arriveOnDest ) break; } } else { issueCommand( ROTATE_RIGHT, MOTION_DEVICE_ADDRESS, 175 ); waitAck( ROTATE_RIGHT, MOTION_DEVICE_ADDRESS, 175 ); while( TRUE ) { issueCommand( CHECK_ARRIVE, MOTION_DEVICE_ADDRESS, 1 ); sleep( 100 ); if ( FLAG_arriveOnDest ) break; } } issueCommand( ULTRASOUND_OFF, MOTION_DEVICE_ADDRESS, 1 ); waitAck( ULTRASOUND_OFF, MOTION_DEVICE_ADDRESS, 1 ); state_robot++; sleep(100); break; /* Zatvaranje druge kucice. */ case 12: issueCommand( ULTRASOUND_OFF, MOTION_DEVICE_ADDRESS, 1 ); waitAck( ULTRASOUND_OFF, MOTION_DEVICE_ADDRESS, 1 ); issueCommand( PRESCALER, MOTION_DEVICE_ADDRESS, 700 ); waitAck( PRESCALER, MOTION_DEVICE_ADDRESS, 700 ); issueCommand( MOVE_FORWARD, MOTION_DEVICE_ADDRESS, 60 ); waitAck( MOVE_FORWARD, MOTION_DEVICE_ADDRESS, 60 ); while( TRUE ) { issueCommand( CHECK_ARRIVE, MOTION_DEVICE_ADDRESS, 1 ); sleep( 100 ); if ( FLAG_arriveOnDest ) break; } state_robot++; sleep(100); break; /* Vracanje unazad. */ case 13: issueCommand( ULTRASOUND_ON, MOTION_DEVICE_ADDRESS, 1 ); waitAck( ULTRASOUND_ON, MOTION_DEVICE_ADDRESS, 1 ); issueCommand( PRESCALER, MOTION_DEVICE_ADDRESS, 500 ); waitAck( PRESCALER, MOTION_DEVICE_ADDRESS, 500 ); issueCommand( MOVE_BACKWARD, MOTION_DEVICE_ADDRESS, 60 ); waitAck( MOVE_BACKWARD, MOTION_DEVICE_ADDRESS, 60 ); while( TRUE ) { issueCommand( CHECK_ARRIVE, MOTION_DEVICE_ADDRESS, 1 ); sleep( 100 ); if ( FLAG_arriveOnDest ) break; } state_robot++; sleep(100); break; /* Okretanje ka centru naseg dela terena. */ case 14: if( FLAG_strategyLeft ) { issueCommand( ROTATE_LEFT, MOTION_DEVICE_ADDRESS, 270 ); waitAck( ROTATE_LEFT, MOTION_DEVICE_ADDRESS, 270 ); while( TRUE ) { issueCommand( CHECK_ARRIVE, MOTION_DEVICE_ADDRESS, 1 ); sleep( 100 ); if ( FLAG_arriveOnDest ) break; } } else { issueCommand( ROTATE_RIGHT, MOTION_DEVICE_ADDRESS, 270 ); waitAck( ROTATE_RIGHT, MOTION_DEVICE_ADDRESS, 270 ); while( TRUE ) { issueCommand( CHECK_ARRIVE, MOTION_DEVICE_ADDRESS, 1 ); sleep( 100 ); if ( FLAG_arriveOnDest ) break; } } state_robot++; sleep(100); break; case 15: issueCommand( MOVE_FORWARD, MOTION_DEVICE_ADDRESS, 40 ); waitAck( MOVE_FORWARD, MOTION_DEVICE_ADDRESS, 40 ); while( TRUE ) { issueCommand( CHECK_ARRIVE, MOTION_DEVICE_ADDRESS, 1 ); sleep( 100 ); if ( FLAG_arriveOnDest ) break; } state_robot++; sleep(100); break; /* Podrazumevano stanje u kome se ne radi nista. */ default: break; } } }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f10x_xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f10x.c file */ /* System clocks configuration ---------------------------------------------*/ RCC_Configuration(); /* NVIC configuration ------------------------------------------------------*/ NVIC_Configuration(); /* GPIO configuration ------------------------------------------------------*/ GPIO_Configuration(); /* TIM1 configuration ------------------------------------------------------*/ /* Time Base configuration */ TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = 0xFF; TIM_TimeBaseStructure.TIM_Prescaler = 0x4; TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /* TIM1 channel1 configuration in PWM mode */ 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(TIM1, &TIM_OCInitStructure); /* DMA1 Channel1 Configuration ----------------------------------------------*/ DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_RegularConvertedValueTab; 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); /* Enable DMA1 channel1 */ DMA_Cmd(DMA1_Channel1, ENABLE); /* ADC1 configuration ------------------------------------------------------*/ ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = DISABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1; 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_13Cycles5); /* Set injected sequencer length */ ADC_InjectedSequencerLengthConfig(ADC1, 1); /* ADC1 injected channel Configuration */ ADC_InjectedChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_71Cycles5); /* ADC1 injected external trigger configuration */ ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_None); /* Enable automatic injected conversion start after regular one */ ADC_AutoInjectedConvCmd(ADC1, ENABLE); /* Enable ADC1 DMA */ ADC_DMACmd(ADC1, ENABLE); /* Enable ADC1 external trigger */ ADC_ExternalTrigConvCmd(ADC1, ENABLE); /* Enable JEOC interrupt */ ADC_ITConfig(ADC1, ADC_IT_JEOC, 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(TIM1, ENABLE); /* TIM1 main Output Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); /* Test on channel1 transfer complete flag */ while(!DMA_GetFlagStatus(DMA1_FLAG_TC1)); /* Clear channel1 transfer complete flag */ DMA_ClearFlag(DMA1_FLAG_TC1); /* TIM1 counter disable */ TIM_Cmd(TIM1, DISABLE); while (1) { } }
/** * @brief Initialise the stick scanning. * @note Starts the ADC continuous sampling. * @param None * @retval None */ void sticks_init(void) { ADC_InitTypeDef adcInit; DMA_InitTypeDef dmaInit; GPIO_InitTypeDef gpioInit; NVIC_InitTypeDef nvicInit; TIM_TimeBaseInitTypeDef timInit; TIM_OCInitTypeDef timOC; int i; // Enable the ADC and DMA clocks RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE); gpioInit.GPIO_Speed = GPIO_Speed_50MHz; gpioInit.GPIO_Pin = 0x7F; gpioInit.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOA, &gpioInit); ADC_DeInit(ADC1); // Setup the ADC init structure ADC_StructInit(&adcInit); adcInit.ADC_ContinuousConvMode = DISABLE; adcInit.ADC_ScanConvMode = ENABLE; adcInit.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T4_CC4; adcInit.ADC_NbrOfChannel = STICK_ADC_CHANNELS; ADC_Init(ADC1, &adcInit); // Setup the regular channel cycle for (i = 0; i < STICK_ADC_CHANNELS; ++i) { ADC_RegularChannelConfig(ADC1, ADC_Channel_0 + i, i + 1, ADC_SampleTime_239Cycles5); } // Enable ADC1 + DMA ADC_Cmd(ADC1, ENABLE); ADC_DMACmd(ADC1, ENABLE); // Calibrate ADC1 ADC_ResetCalibration(ADC1); while (ADC_GetResetCalibrationStatus(ADC1)) ; ADC_StartCalibration(ADC1); while (ADC_GetCalibrationStatus(ADC1)) ; nvicInit.NVIC_IRQChannel = DMA1_Channel1_IRQn; nvicInit.NVIC_IRQChannelSubPriority = 1; nvicInit.NVIC_IRQChannelPreemptionPriority = 1; nvicInit.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&nvicInit); // DMA Configuration DMA_DeInit(DMA1_Channel1); DMA_StructInit(&dmaInit); dmaInit.DMA_PeripheralBaseAddr = (uint32_t) &ADC1->DR; dmaInit.DMA_MemoryBaseAddr = (uint32_t) &adc_data[0]; dmaInit.DMA_DIR = DMA_DIR_PeripheralSRC; dmaInit.DMA_BufferSize = STICK_ADC_CHANNELS; dmaInit.DMA_PeripheralInc = DMA_PeripheralInc_Disable; dmaInit.DMA_MemoryInc = DMA_MemoryInc_Enable; dmaInit.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; dmaInit.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; dmaInit.DMA_Mode = DMA_Mode_Circular; dmaInit.DMA_Priority = DMA_Priority_VeryHigh; dmaInit.DMA_M2M = DMA_M2M_Disable; // Configure and enable the DMA DMA_Init(DMA1_Channel1, &dmaInit); DMA_Cmd(DMA1_Channel1, ENABLE); DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE); // TIM4 OC4 is ADC conversion trigger RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); TIM_DeInit(TIM4); /* TIM4 init */ TIM_TimeBaseStructInit(&timInit); timInit.TIM_Period = 20-1; /* 20 ms */ timInit.TIM_Prescaler = SystemCoreClock/1000 - 1; /* 1ms */ timInit.TIM_ClockDivision = 0x0; timInit.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM4, &timInit); /* TIM4 OC4 configuration in PWM mode to generate ADC_ExternalTrigConv_T4_CC4 */ TIM_OCStructInit(&timOC); timOC.TIM_OCMode = TIM_OCMode_PWM1; timOC.TIM_OutputState = TIM_OutputState_Enable; timOC.TIM_Pulse = 1; timOC.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OC4Init(TIM4, &timOC); /* TIM2 enable counter */ TIM_Cmd(TIM4, ENABLE); /* enable ADC triggering */ ADC_ExternalTrigConvCmd(ADC1, ENABLE); task_register(TASK_PROCESS_STICKS, sticks_process); task_schedule(TASK_PROCESS_STICKS, 0, 20); }
static void Init_DSO(T_DSO *g_DsoA) { /* 配置GPIO. */ GPIO_InitTypeDef GPIO_InitStructure; DMA_InitTypeDef DMA_InitStructure; ADC_InitTypeDef ADC_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; /* 打开GPIO_C 和 AFIO 的时钟 */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE); /* 配置PC0为模拟输入模式 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOC, &GPIO_InitStructure); /* 使能 DMA1 时钟 */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); DMA_DeInit(DMA1_Channel1); /* 复位DMA1寄存器到缺省状态 */ DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; /* 选择ADC1的数据寄存器作为源 */ DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&g_DsoA->DMA_ADCBuf; /* 目标地址 */ DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; /* 设置DMA传输方向,外设(ADC)作为源 */ DMA_InitStructure.DMA_BufferSize = DMA_ADCBUFSIZE; /* 设置缓冲区大小 */ DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; /* 外设地址不自增 */ DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; /* 存储器地址需要自增 */ DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; /* 选择外设传输单位:16bit */ DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; /* 选择内存传输单位:16bit */ DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; /* 无需循环模式 */ DMA_InitStructure.DMA_Priority = DMA_Priority_High; /* 选择DMA优先级 */ DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; /* DMA传输类型,不是内存到内存 */ DMA_Init(DMA1_Channel1, &DMA_InitStructure); DMA_ITConfig(DMA1_Channel1,DMA_IT_TC,ENABLE); DMA_ITConfig(DMA1_Channel1,DMA_IT_TE,ENABLE); /* 使能 DMA1 通道1 */ DMA_Cmd(DMA1_Channel1, ENABLE); /*Enable DMA Channel5 Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* 配置ADC1 */ RCC_ADCCLKConfig(RCC_PCLK2_Div6); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); ADC_DeInit(ADC1); ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = DISABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; /* 连续转换静止 */ ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_CC2; /* 选择TIM1的CC3做触发 */ ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; /* 数据右对齐,高位为0 */ ADC_InitStructure.ADC_NbrOfChannel = 1; /* 1个通道 */ ADC_Init(ADC1, &ADC_InitStructure); /* ADC1 规则通道配置 */ ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_1Cycles5); /* 使能 ADC1 外部触发转换 */ ADC_ExternalTrigConvCmd(ADC1, ENABLE); /* 使能 ADC1 DMA */ ADC_DMACmd(ADC1, ENABLE); /* 使能 ADC1 */ ADC_Cmd(ADC1, ENABLE); /* 使能 ADC1 复位校准寄存器 */ ADC_ResetCalibration(ADC1); /* 检测复位校准寄存器 */ while(ADC_GetResetCalibrationStatus(ADC1)); /* 开始 ADC1 校准 */ ADC_StartCalibration(ADC1); /* 等待校准结束 */ while(ADC_GetCalibrationStatus(ADC1)); Set_SampRate(g_DsoA); }
void adcInit(void) { ADC_InitTypeDef ADC_InitStructure; DMA_InitTypeDef DMA_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; int i; adcSetConstants(); histSize = ADC_HIST_SIZE; // Use STM32's Dual Regular Simultaneous Mode capable of ~ 1.7M samples per second // NOTE: assume that RCC code has already placed all pins into Analog In mode during startup // DMA1 channel1 configuration (ADC1) DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1 + 0x4c; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&adcRawData[0]; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = sizeof(adcRawData)/4; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel1, &DMA_InitStructure); DMA_ITConfig(DMA1_Channel1, DMA_IT_TC | DMA_IT_HT, ENABLE); DMA_ClearITPendingBit(DMA1_IT_GL1 | DMA1_IT_TC1 | DMA1_IT_HT1); DMA_Cmd(DMA1_Channel1, ENABLE); // Enable the DMA1_Channel1 global Interrupt NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); // ADC1 configuration // ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult; ADC_InitStructure.ADC_Mode = ADC_Mode_RegInjecSimult; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = sizeof(adcRawData)/4; ADC_Init(ADC1, &ADC_InitStructure); #ifdef ADC_FAST_SAMPLE ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SAMPLE_TIME); // SENSE_CURRENT ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 2, ADC_SAMPLE_TIME); // SENSE_CURRENT ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SAMPLE_TIME); // SENSE_B ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 4, ADC_SAMPLE_TIME); // SENSE_B ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 5, ADC_SAMPLE_TIME); // SENSE_VIN ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 6, ADC_SAMPLE_TIME); // SENSE_VIN ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 7, ADC_SAMPLE_TIME); // SENSE_B ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 8, ADC_SAMPLE_TIME); // SENSE_B #else ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SAMPLE_TIME); // SENSE_CURRENT ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 2, ADC_SAMPLE_TIME); // SENSE_B ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 3, ADC_SAMPLE_TIME); // SENSE_VIN ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 4, ADC_SAMPLE_TIME); // SENSE_B #endif ADC_DMACmd(ADC1, ENABLE); // ADC2 configuration // ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult; ADC_InitStructure.ADC_Mode = ADC_Mode_RegInjecSimult; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = sizeof(adcRawData)/4; ADC_Init(ADC2, &ADC_InitStructure); #ifdef ADC_FAST_SAMPLE ADC_RegularChannelConfig(ADC2, ADC_Channel_1, 1, ADC_SAMPLE_TIME); // SENSE_A ADC_RegularChannelConfig(ADC2, ADC_Channel_1, 2, ADC_SAMPLE_TIME); // SENSE_A ADC_RegularChannelConfig(ADC2, ADC_Channel_3, 3, ADC_SAMPLE_TIME); // SENSE_C ADC_RegularChannelConfig(ADC2, ADC_Channel_3, 4, ADC_SAMPLE_TIME); // SENSE_C ADC_RegularChannelConfig(ADC2, ADC_Channel_1, 5, ADC_SAMPLE_TIME); // SENSE_A ADC_RegularChannelConfig(ADC2, ADC_Channel_1, 6, ADC_SAMPLE_TIME); // SENSE_A ADC_RegularChannelConfig(ADC2, ADC_Channel_3, 7, ADC_SAMPLE_TIME); // SENSE_C ADC_RegularChannelConfig(ADC2, ADC_Channel_3, 8, ADC_SAMPLE_TIME); // SENSE_C #else ADC_RegularChannelConfig(ADC2, ADC_Channel_1, 1, ADC_SAMPLE_TIME); // SENSE_A ADC_RegularChannelConfig(ADC2, ADC_Channel_3, 2, ADC_SAMPLE_TIME); // SENSE_C ADC_RegularChannelConfig(ADC2, ADC_Channel_1, 3, ADC_SAMPLE_TIME); // SENSE_A ADC_RegularChannelConfig(ADC2, ADC_Channel_3, 4, ADC_SAMPLE_TIME); // SENSE_C #endif ADC_ExternalTrigConvCmd(ADC2, ENABLE); // enable and calibrate ADC_Cmd(ADC1, ENABLE); adcCalibrateADC(ADC1); ADC_Cmd(ADC2, ENABLE); adcCalibrateADC(ADC2); nextCrossingDetect = adcMaxPeriod; // setup injection sequence ADC_InjectedSequencerLengthConfig(ADC1, 1); ADC_InjectedSequencerLengthConfig(ADC2, 1); ADC_InjectedChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SAMPLE_TIME); ADC_InjectedChannelConfig(ADC2, ADC_Channel_4, 1, ADC_SAMPLE_TIME); ADC_ExternalTrigInjectedConvCmd(ADC1, ENABLE); ADC_ExternalTrigInjectedConvCmd(ADC2, ENABLE); ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_None); ADC_ExternalTrigInjectedConvConfig(ADC2, ADC_ExternalTrigInjecConv_None); // Start ADC1 / ADC2 Conversions ADC_SoftwareStartConvCmd(ADC1, ENABLE); }
void adc_init(void){ NVIC_InitTypeDef nvic; GPIO_InitTypeDef gpio; ADC_InitTypeDef adc; /* enable ADC1 clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); /* Configure and enable ADC interrupt */ nvic.NVIC_IRQChannel = ADC1_2_IRQn; nvic.NVIC_IRQChannelPreemptionPriority = 0; nvic.NVIC_IRQChannelSubPriority = 0; nvic.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&nvic); /* GPIOA: ADC Channel 0, 1, 2 as analog input * Ch 0 -> BEMF/I_Sense of PHASE A * Ch 1 -> BEMF/I_Sense of PHASE B * Ch 2 -> BEMF/I_Sense of PHASE C */ gpio.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2; gpio.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOA, &gpio); adc_comm = 0; adc_filtered = 0; /* Configure ADC1 */ adc.ADC_Mode = ADC_Mode_Independent; adc.ADC_ScanConvMode = DISABLE; adc.ADC_ContinuousConvMode = DISABLE; adc.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; adc.ADC_DataAlign = ADC_DataAlign_Right; adc.ADC_NbrOfChannel = 0; ADC_Init(ADC1, &adc); ADC_InjectedSequencerLengthConfig(ADC1, 1); ADC_InjectedChannelConfig(ADC1, ADC_Channel_2, 1, ADC_SampleTime_28Cycles5); ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_T1_CC4); ADC_ExternalTrigInjectedConvCmd(ADC1, ENABLE); /* Enable ADC1 JEOC interrupt */ ADC_ITConfig(ADC1, ADC_IT_JEOC, ENABLE); /* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE); /* Enable ADC1 reset calibaration register */ ADC_ResetCalibration(ADC1); /* Check the end of ADC1 reset calibration */ while(ADC_GetResetCalibrationStatus(ADC1)); /* Start ADC1 calibaration */ ADC_StartCalibration(ADC1); /* Check the end of ADC1 calibration */ while(ADC_GetCalibrationStatus(ADC1)); /* Enable ADC1 External Trigger */ ADC_ExternalTrigConvCmd(ADC1, ENABLE); //ADC_ExternalTrigConvCmd(ADC1, DISABLE); }
void adcInit(void) { if(isInit) return; ADC_InitTypeDef ADC_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; NVIC_InitTypeDef NVIC_InitStructure; // Enable TIM2, GPIOA and ADC1 clock RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); //Timer configuration TIM_TimeBaseStructure.TIM_Period = ADC_TRIG_PERIOD; TIM_TimeBaseStructure.TIM_Prescaler = ADC_TRIG_PRESCALE; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); // TIM2 channel2 configuration in PWM mode TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 1; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OC2Init(TIM2, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable); // Halt timer 2 during debug halt. DBGMCU_Config(DBGMCU_TIM2_STOP, ENABLE); adcDmaInit(); // ADC1 configuration ADC_DeInit(ADC1); ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_CC2; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = NBR_OF_ADC_CHANNELS; ADC_Init(ADC1, &ADC_InitStructure); // ADC1 channel sequence ADC_RegularChannelConfig(ADC1, CH_VREF, 1, ADC_SampleTime_28Cycles5); // ADC2 configuration ADC_DeInit(ADC2); ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = NBR_OF_ADC_CHANNELS; ADC_Init(ADC2, &ADC_InitStructure); // ADC2 channel sequence ADC_RegularChannelConfig(ADC2, CH_VBAT, 1, ADC_SampleTime_28Cycles5); // Enable ADC1 ADC_Cmd(ADC1, ENABLE); // Calibrate ADC1 ADC_ResetCalibration(ADC1); while(ADC_GetResetCalibrationStatus(ADC1)); ADC_StartCalibration(ADC1); while(ADC_GetCalibrationStatus(ADC1)); // Enable ADC1 external trigger ADC_ExternalTrigConvCmd(ADC1, ENABLE); ADC_TempSensorVrefintCmd(ENABLE); // Enable ADC2 ADC_Cmd(ADC2, ENABLE); // Calibrate ADC2 ADC_ResetCalibration(ADC2); while(ADC_GetResetCalibrationStatus(ADC2)); ADC_StartCalibration(ADC2); while(ADC_GetCalibrationStatus(ADC2)); // Enable ADC2 external trigger ADC_ExternalTrigConvCmd(ADC2, ENABLE); // Enable the DMA1 channel1 Interrupt NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_ADC_PRI; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); adcQueue = xQueueCreate(1, sizeof(AdcGroup*)); xTaskCreate(adcTask, (const signed char *)"ADC", configMINIMAL_STACK_SIZE, NULL, /*priority*/3, NULL); isInit = true; }
void Analog_Config(void) { Analog_RCC_Config(); Analog_GPIO_Config(); Analog_NVIC_Config(); /* ADC1 configuration ------------------------------------------------------*/ ADC_InitStructure.ADC_Mode = ADC_Mode_SlowInterl; ADC_InitStructure.ADC_ScanConvMode = DISABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 1; ADC_Init(ADC1, &ADC_InitStructure); /* ADC1 regular channels configuration */ ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_13Cycles5); /* ADC2 configuration ------------------------------------------------------*/ ADC_InitStructure.ADC_Mode = ADC_Mode_SlowInterl; ADC_InitStructure.ADC_ScanConvMode = DISABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 1; ADC_Init(ADC2, &ADC_InitStructure); /* ADC2 regular channels configuration */ ADC_RegularChannelConfig(ADC2, ADC_Channel_10, 1, ADC_SampleTime_13Cycles5); /* Enable ADC2 external trigger conversion */ ADC_ExternalTrigConvCmd(ADC2, ENABLE); /* Enable ADC1 DMA: it should be enabled in dual mode even if the DMA is not used */ ADC_DMACmd(ADC1, ENABLE); /* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE); Delay(2); /* Enable ADC1 reset calibaration register */ ADC_ResetCalibration(ADC1); /* Check the end of ADC1 reset calibration register */ while (ADC_GetResetCalibrationStatus(ADC1)) ; /* Start ADC1 calibaration */ ADC_StartCalibration(ADC1); /* Check the end of ADC1 calibration */ while (ADC_GetCalibrationStatus(ADC1)) ; /* Enable ADC2 */ ADC_Cmd(ADC2, ENABLE); Delay(2); /* Enable ADC2 reset calibaration register */ ADC_ResetCalibration(ADC2); /* Check the end of ADC2 reset calibration register */ while (ADC_GetResetCalibrationStatus(ADC2)) ; /* Start ADC2 calibaration */ ADC_StartCalibration(ADC2); /* Check the end of ADC2 calibration */ while (ADC_GetCalibrationStatus(ADC2)) ; }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f10x_xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f10x.c file */ /* System clocks configuration ---------------------------------------------*/ RCC_Configuration(); /* GPIO configuration ------------------------------------------------------*/ GPIO_Configuration(); /* DMA1 channel1 configuration ----------------------------------------------*/ DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_DualConvertedValueTab; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = 16; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; 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); /* Enable DMA1 Channel1 */ DMA_Cmd(DMA1_Channel1, ENABLE); /* ADC1 configuration ------------------------------------------------------*/ ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 2; ADC_Init(ADC1, &ADC_InitStructure); /* ADC1 regular channels configuration */ ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_239Cycles5); ADC_RegularChannelConfig(ADC1, ADC_Channel_17, 2, ADC_SampleTime_239Cycles5); /* Enable ADC1 DMA */ ADC_DMACmd(ADC1, ENABLE); /* ADC2 configuration ------------------------------------------------------*/ ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 2; ADC_Init(ADC2, &ADC_InitStructure); /* ADC2 regular channels configuration */ ADC_RegularChannelConfig(ADC2, ADC_Channel_11, 1, ADC_SampleTime_239Cycles5); ADC_RegularChannelConfig(ADC2, ADC_Channel_12, 2, ADC_SampleTime_239Cycles5); /* Enable ADC2 external trigger conversion */ ADC_ExternalTrigConvCmd(ADC2, ENABLE); /* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE); /* Enable Vrefint channel17 */ ADC_TempSensorVrefintCmd(ENABLE); /* Enable ADC1 reset calibaration register */ ADC_ResetCalibration(ADC1); /* Check the end of ADC1 reset calibration register */ while(ADC_GetResetCalibrationStatus(ADC1)); /* Start ADC1 calibaration */ ADC_StartCalibration(ADC1); /* Check the end of ADC1 calibration */ while(ADC_GetCalibrationStatus(ADC1)); /* Enable ADC2 */ ADC_Cmd(ADC2, ENABLE); /* Enable ADC2 reset calibaration register */ ADC_ResetCalibration(ADC2); /* Check the end of ADC2 reset calibration register */ while(ADC_GetResetCalibrationStatus(ADC2)); /* Start ADC2 calibaration */ ADC_StartCalibration(ADC2); /* Check the end of ADC2 calibration */ while(ADC_GetCalibrationStatus(ADC2)); /* Start ADC1 Software Conversion */ ADC_SoftwareStartConvCmd(ADC1, ENABLE); /* Test on DMA1 channel1 transfer complete flag */ while(!DMA_GetFlagStatus(DMA1_FLAG_TC1)); /* Clear DMA1 channel1 transfer complete flag */ DMA_ClearFlag(DMA1_FLAG_TC1); while (1) { } }
/* ********************************************************************************************************* * 函 数 名: InitDSO * 功能说明: 对示波器通道1进行初始化配置。主要完成GPIO的配置、ADC的配置、DMA配置。 * 形 参:无 * 返 回 值: 无 ********************************************************************************************************* */ void InitDSO(void) { { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE); //配置IO口 RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); //使能定时器1时钟 RCC_ADCCLKConfig(RCC_PCLK2_Div2); //ADCCLK = PCLK2/4 = 18MHz GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); } #if 1 { DMA_InitTypeDef DMA_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); DMA_DeInit(DMA1_Channel1); /* 复位DMA1寄存器到缺省状态 */ DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; /* 选择ADC1的数据寄存器作为源 */ DMA_InitStructure.DMA_MemoryBaseAddr =(uint32_t)&g_DSO.buffer; /* 目标地址 */ DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; /* 设置DMA传输方向,外设(ADC)作为源 */ DMA_InitStructure.DMA_BufferSize = SAMPLE_COUNT; /* 设置缓冲区大小 */ DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; /* 外设地址不自增 */ DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; /* 存储器地址需要自增 */ // DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; /* 选择外设传输单位:16bit */ // DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; /* 选择内存传输单位:16bit */ DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; /* 选择外设传输单位:16bit */ DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; /* 选择内存传输单位:16bit */ DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; /* 无需循环模式 */ DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; /* 选择DMA优先级 */ DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; /* DMA传输类型,不是内存到内存 */ DMA_Init(DMA1_Channel1, &DMA_InitStructure); DMA_Cmd(DMA1_Channel1, ENABLE); } #endif #if 1 { ADC_InitTypeDef ADC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1|RCC_APB2Periph_ADC2, ENABLE); ADC_DeInit(ADC1); ADC_DeInit(ADC2); /* ADC1 configuration ------------------------------------------------------*/ ADC_InitStructure.ADC_Mode = ADC_Mode_FastInterl; ADC_InitStructure.ADC_ScanConvMode = DISABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC3; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 1; ADC_Init(ADC1, &ADC_InitStructure); ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_1Cycles5);//18M/(1.5+12.5)=1.2857M最大采样频率 ADC_ExternalTrigConvCmd(ADC1, ENABLE); /* ADC1 configuration ------------------------------------------------------*/ ADC_InitStructure.ADC_Mode = ADC_Mode_FastInterl; ADC_InitStructure.ADC_ScanConvMode = DISABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 1; ADC_Init(ADC2, &ADC_InitStructure); ADC_RegularChannelConfig(ADC2, ADC_Channel_10, 1, ADC_SampleTime_1Cycles5); //18M/(1.5+12.5)=1.2857M最大采样频率 ADC_ExternalTrigConvCmd(ADC2, ENABLE); /* Enable ADC1 */ ADC_DMACmd(ADC1, ENABLE); ADC_Cmd(ADC1, ENABLE); ADC_ResetCalibration(ADC1); while(ADC_GetResetCalibrationStatus(ADC1)); ADC_StartCalibration(ADC1); while(ADC_GetCalibrationStatus(ADC1)); /* Enable ADC2 */ ADC_Cmd(ADC2, ENABLE); ADC_ResetCalibration(ADC2); while(ADC_GetResetCalibrationStatus(ADC2)); ADC_StartCalibration(ADC2); while(ADC_GetCalibrationStatus(ADC2)); } #endif #if 0 { ADC_InitTypeDef ADC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE); ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = DISABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; /* 连续转换静止 */ //ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1; /* 选择TIM1的CC1做触发 */ ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC3; /* 选择TIM2的CC3做触发 */ ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; /* 数据右对齐,高位为0 */ ADC_InitStructure.ADC_NbrOfChannel = 1; /* 1个通道 */ ADC_Init(ADC3, &ADC_InitStructure); ADC_RegularChannelConfig(ADC3, ADC_Channel_11, 1, ADC_SampleTime_1Cycles5); /* ADC1 regular channels configuration */ ADC_ExternalTrigConvCmd(ADC3, ENABLE); ADC_Cmd(ADC3, ENABLE); ADC_DMACmd(ADC3, ENABLE); ADC_ResetCalibration(ADC3); while(ADC_GetResetCalibrationStatus(ADC3)); ADC_StartCalibration(ADC3); while(ADC_GetCalibrationStatus(ADC3)); } #endif //SetSampRate(g_DSO.SampleFreq); /* 配置采样触发定时器,使用TIM1 CC3修改采样频率(启动时100K) */ #if 1 { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; TIM_Cmd(TIM1, DISABLE); TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); //初始化定时器1的寄存器为复位值 TIM_TimeBaseStructure.TIM_Period = 72000000 / g_DSO.SampleFreq; //ARR自动重装载寄存器周期的值(定时时间)到设置频率后产生个更新或者中断(也是说定时时间到) TIM_TimeBaseStructure.TIM_Prescaler = 0; //PSC时钟预分频数 例如:时钟频率=TIM1CLK/(时钟预分频+1) TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; //CR1->CKD时间分割值 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //CR1->CMS[1:0]和DIR定时器模式 向上计数 TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //CCMR2在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为有效电平,否则为无效电平 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //CCER 输出使能 TIM_OCInitStructure.TIM_Pulse = TIM_TimeBaseStructure.TIM_Period / 2;//CCR3同计数器TIMx_CNT的比较,并在OC4端口上产生输出信号 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //CCER输出极性设置 高电平有效 TIM_OC3Init(TIM1, &TIM_OCInitStructure); //TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable); //CMR2 设置预装载使能 更新事件产生时写入有效 //TIM_ARRPreloadConfig(TIM1, ENABLE); //CR1 设置ARR自动重装 更新事件产生时写入有效 TIM_Cmd(TIM1, ENABLE); TIM_CtrlPWMOutputs(TIM1, ENABLE); //使能PWM 输出 } #endif }
void SampleChannel_Init() { NVIC_InitTypeDef NVIC_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; ADC_InitTypeDef ADC_InitStructure; DMA_InitTypeDef DMA_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA| RCC_APB2Periph_AFIO, ENABLE); GPIO_InitStructure.GPIO_Pin = ADC_CHANNEL10_PIN | ADC_CHANNEL11_PIN | ADC_CHANNEL12_PIN | ADC_CHANNEL14_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //端口模式为模拟输入方式 GPIO_Init(ADC_PORT, &GPIO_InitStructure); RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE); TIM_DeInit(TIM8); TIM_TimeBaseStructure.TIM_Period = 1000000 / 1000 - 1; TIM_TimeBaseStructure.TIM_Prescaler = 71; TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure); TIM_SelectOutputTrigger(TIM8, TIM_TRGOSource_Update); RCC_ADCCLKConfig(RCC_PCLK2_Div6); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); GPIO_PinRemapConfig(GPIO_Remap_ADC1_ETRGREG, ENABLE); ADC_DeInit(ADC1); ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_Ext_IT11_TIM8_TRGO; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 4; ADC_Init(ADC1, &ADC_InitStructure); ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_71Cycles5); ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 2, ADC_SampleTime_71Cycles5); ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 3, ADC_SampleTime_71Cycles5); ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 4, ADC_SampleTime_71Cycles5); ADC_DiscModeChannelCountConfig(ADC1, 1); ADC_DiscModeCmd(ADC1, ENABLE); ADC_DMACmd(ADC1, ENABLE); ADC_Cmd(ADC1, ENABLE); ADC_ResetCalibration(ADC1); while (ADC_GetResetCalibrationStatus(ADC1)) ; ADC_StartCalibration(ADC1); while (ADC_GetCalibrationStatus(ADC1)) ; ADC_ExternalTrigConvCmd(ADC1, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_ADDRESS; DMA_InitStructure.DMA_MemoryBaseAddr = (u32) (&ADCBuff); DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = ADCNUM; 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_Medium; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel1, &DMA_InitStructure); DMA_ClearFlag(DMA1_IT_TC1 | DMA1_IT_HT1); DMA_ITConfig(DMA1_Channel1, DMA_IT_TC | DMA_IT_HT, ENABLE); DMA_Cmd(DMA1_Channel1, ENABLE); }
/** * @brief Configure the ADC to run at a fixed oversampling * @param[in] oversampling the amount of oversampling to run at * @param[in] internal_adc_id handle to the device */ static void PIOS_INTERNAL_ADC_Config(uint32_t internal_adc_id, uint32_t oversampling) { struct pios_internal_adc_dev * adc_dev = (struct pios_internal_adc_dev *)internal_adc_id; if(!PIOS_INTERNAL_ADC_validate(adc_dev)) { return; } adc_dev->adc_oversample = (oversampling > PIOS_ADC_MAX_OVERSAMPLING) ? PIOS_ADC_MAX_OVERSAMPLING : oversampling; ADC_DeInit(ADC1); ADC_DeInit(ADC2); /* Disable interrupts */ DMA_ITConfig(adc_dev->cfg->dma.rx.channel, adc_dev->cfg->dma.irq.flags, DISABLE); /* Enable ADC clocks */ PIOS_ADC_CLOCK_FUNCTION; /* Map channels to conversion slots depending on the channel selection mask */ for (int32_t i = 0; i < PIOS_ADC_NUM_PINS; i++) { ADC_RegularChannelConfig(ADC_MAPPING[i], ADC_CHANNEL[i], ADC_CHANNEL_MAPPING[i], PIOS_ADC_SAMPLE_TIME); } #if (PIOS_ADC_USE_TEMP_SENSOR) ADC_TempSensorVrefintCmd(ENABLE); ADC_RegularChannelConfig(PIOS_ADC_TEMP_SENSOR_ADC, ADC_Channel_16, PIOS_ADC_TEMP_SENSOR_ADC_CHANNEL, PIOS_ADC_SAMPLE_TIME); #endif // return /* Configure ADCs */ ADC_InitTypeDef ADC_InitStructure; ADC_StructInit(&ADC_InitStructure); ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = ((PIOS_ADC_NUM_CHANNELS + 1) >> 1); ADC_Init(ADC1, &ADC_InitStructure); #if (PIOS_ADC_USE_ADC2) ADC_Init(ADC2, &ADC_InitStructure); /* Enable ADC2 external trigger conversion (to synch with ADC1) */ ADC_ExternalTrigConvCmd(ADC2, ENABLE); #endif RCC_ADCCLKConfig(PIOS_ADC_ADCCLK); /* Enable ADC1->DMA request */ ADC_DMACmd(ADC1, ENABLE); /* ADC1 calibration */ ADC_Cmd(ADC1, ENABLE); ADC_ResetCalibration(ADC1); while (ADC_GetResetCalibrationStatus(ADC1)) ; ADC_StartCalibration(ADC1); while (ADC_GetCalibrationStatus(ADC1)) ; #if (PIOS_ADC_USE_ADC2) /* ADC2 calibration */ ADC_Cmd(ADC2, ENABLE); ADC_ResetCalibration(ADC2); while (ADC_GetResetCalibrationStatus(ADC2)) ; ADC_StartCalibration(ADC2); while (ADC_GetCalibrationStatus(ADC2)) ; #endif /* This makes sure we have an even number of transfers if using ADC2 */ adc_dev->dma_block_size = ((PIOS_ADC_NUM_CHANNELS + PIOS_ADC_USE_ADC2) >> PIOS_ADC_USE_ADC2) << PIOS_ADC_USE_ADC2; adc_dev->dma_half_buffer_size = adc_dev->dma_block_size * adc_dev->adc_oversample; /* Configure DMA channel */ DMA_InitTypeDef dma_init = adc_dev->cfg->dma.rx.init; dma_init.DMA_MemoryBaseAddr = (uint32_t) &adc_dev->raw_data_buffer[0]; dma_init.DMA_MemoryInc = DMA_MemoryInc_Enable; dma_init.DMA_BufferSize = adc_dev->dma_half_buffer_size; /* x2 for double buffer /2 for 32-bit xfr */ DMA_Init(adc_dev->cfg->dma.rx.channel, &dma_init); DMA_Cmd(adc_dev->cfg->dma.rx.channel, ENABLE); /* Trigger interrupt when for half conversions too to indicate double buffer */ DMA_ITConfig(adc_dev->cfg->dma.rx.channel, DMA_IT_TC, ENABLE); DMA_ITConfig(adc_dev->cfg->dma.rx.channel, DMA_IT_HT, ENABLE); /* Configure DMA interrupt */ NVIC_Init((NVIC_InitTypeDef*)&adc_dev->cfg->dma.irq.init); /* Finally start initial conversion */ ADC_SoftwareStartConvCmd(ADC1, ENABLE); /* Use simple averaging filter for now */ for (int32_t i = 0; i < adc_dev->adc_oversample; i++) adc_dev->fir_coeffs[i] = 1; adc_dev->fir_coeffs[adc_dev->adc_oversample] = adc_dev->adc_oversample; /* Enable DMA1 clock */ RCC_AHBPeriphClockCmd(adc_dev->cfg->dma.ahb_clk, ENABLE); }
/* * @brief Read the analog value of a pin. * Should return a 16-bit value, 0-65536 (0 = LOW, 65536 = HIGH) * Note: ADC is 12-bit. Currently it returns 0-4096 */ int32_t analogRead(uint16_t pin) { // Allow people to use 0-7 to define analog pins by checking to see if the values are too low. if (pin < FIRST_ANALOG_PIN) { pin = pin + FIRST_ANALOG_PIN; } // SPI safety check if (SPI.isEnabled() == true && (pin == SCK || pin == MOSI || pin == MISO)) { return LOW; } // I2C safety check if (Wire.isEnabled() == true && (pin == SCL || pin == SDA)) { return LOW; } // Serial1 safety check if (Serial1.isEnabled() == true && (pin == RX || pin == TX)) { return LOW; } if (pin >= TOTAL_PINS || PIN_MAP[pin].adc_channel == NONE ) { return LOW; } int i = 0; if (adcChannelConfigured != PIN_MAP[pin].adc_channel) { digitalPinModeSaved = PIN_MAP[pin].pin_mode; pinMode(pin, AN_INPUT); } if (adcInitFirstTime == true) { ADC_DMA_Init(); adcInitFirstTime = false; } if (adcChannelConfigured != PIN_MAP[pin].adc_channel) { // ADC1 regular channel configuration ADC_RegularChannelConfig(ADC1, PIN_MAP[pin].adc_channel, 1, ADC_Sample_Time); // ADC2 regular channel configuration ADC_RegularChannelConfig(ADC2, PIN_MAP[pin].adc_channel, 1, ADC_Sample_Time); // Save the ADC configured channel adcChannelConfigured = PIN_MAP[pin].adc_channel; } for(i = 0 ; i < ADC_DMA_BUFFERSIZE ; i++) { ADC_DualConvertedValues[i] = 0; } // Reset the number of data units in the DMA1 Channel1 transfer DMA_SetCurrDataCounter(DMA1_Channel1, ADC_DMA_BUFFERSIZE); // Enable ADC2 external trigger conversion ADC_ExternalTrigConvCmd(ADC2, ENABLE); // Enable DMA1 Channel1 DMA_Cmd(DMA1_Channel1, ENABLE); // Enable ADC1 DMA ADC_DMACmd(ADC1, ENABLE); // Start ADC1 Software Conversion ADC_SoftwareStartConvCmd(ADC1, ENABLE); // Test on Channel 1 DMA1_FLAG_TC flag while(!DMA_GetFlagStatus(DMA1_FLAG_TC1)); // Clear Channel 1 DMA1_FLAG_TC flag DMA_ClearFlag(DMA1_FLAG_TC1); // Disable ADC1 DMA ADC_DMACmd(ADC1, DISABLE); // Disable DMA1 Channel1 DMA_Cmd(DMA1_Channel1, DISABLE); uint16_t ADC1_ConvertedValue = 0; uint16_t ADC2_ConvertedValue = 0; uint32_t ADC_SummatedValue = 0; uint16_t ADC_AveragedValue = 0; for(int i = 0 ; i < ADC_DMA_BUFFERSIZE ; i++) { // Retrieve the ADC2 converted value and add to ADC_SummatedValue ADC2_ConvertedValue = ADC_DualConvertedValues[i] >> 16; ADC_SummatedValue += ADC2_ConvertedValue; // Retrieve the ADC1 converted value and add to ADC_SummatedValue ADC1_ConvertedValue = ADC_DualConvertedValues[i] & 0xFFFF; ADC_SummatedValue += ADC1_ConvertedValue; } ADC_AveragedValue = (uint16_t)(ADC_SummatedValue / (ADC_DMA_BUFFERSIZE * 2)); // Return ADC averaged value return ADC_AveragedValue; }
int main(void) { *SCB_DEMCR = *SCB_DEMCR | 0x01000000; *DWT_CYCCNT = 0; // reset the counter *DWT_CONTROL = *DWT_CONTROL | 1 ; // enable the counter /* System clocks configuration ---------------------------------------------*/ RCC_Configuration(); // Activate I2C1 clock. RCC->APB1ENR |= RCC_APB1ENR_I2C1EN; /* GPIO configuration ------------------------------------------------------*/ //GPIO_Configuration(); /* TIM1 configuration ------------------------------------------------------*/ InitTIM1(); //InitTIM2(); LED_Init1(); /* Accelerometer Configuration ----------------------------------------------*/ //InitACC(); /* DMA1 channel1 configuration ----------------------------------------------*/ DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&SampleBuff1[0]; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = SampleBuffSize; 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_VeryHigh; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel1, &DMA_InitStructure); DMA_ITConfig(DMA1_Channel1, DMA_IT_TC | DMA_IT_HT, ENABLE); /* Enable DMA1 channel1 */ DMA_Cmd(DMA1_Channel1, ENABLE); /* 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_None; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1; //TIMER1 COMANDA ADC1!!!!!!!! ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = NUM_ADC; ADC_Init(ADC1, &ADC_InitStructure); /* ADC1 regular channels configuration */ ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_28Cycles5); // Canale ECG1 ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 2, ADC_SampleTime_28Cycles5); // Canale ECG2 ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_28Cycles5); // Canale Temperatura /* 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)); /* Start ADC1 Software Conversion */ ADC_SoftwareStartConvCmd(ADC1, ENABLE); TN100_InitTypeDef TN100_InitStructure; uint8_t senderID[6]; uint8_t receiverID[6]; uint8_t packetType; uint8_t rxmsg[5]; uint16_t rxmsglen; uint32_t rangingtimer = 0; uint16_t Buffer_Tx[NUM_SAMP+8]; uint16_t *pBuffer_Tx; int8_t Buff_Comp[116]; //Buffer compresso uint8_t *pBuff_Comp, num_loc, y, q, diz[49], CRC_val; int16_t Buff_app[NUM_SAMP]; uint16_t Buffer3_in[NUM_SAMP_ECG]; uint16_t Buffer3_out[NUM_SAMP_ECG]; uint16_t sample, max1, max2, imax1, imax2, Buff[58]; uint16_t m = 0; uint16_t n = 0; uint16_t Temp; int num_pacchetto=0; int i, step; int j=1; int k; int RR_Fill = 0; // float iir_coef[] = {GAIN1, -1.994468725910304, 0.99463933704617047, -1.9983537046882773, 1, -1.9916039050017902, 0.99164560916623756, -1.9886914599162702, 1, -1.9979953458398652, 0.99827402341158644, -1.9990466012362298, 1}; // float iir_coef[] = {GAIN1, -1.9985564208306903, 0.99862589632961685, -1.9995236407524317, 1, -1.996067915503039, 0.99609980456504865, -1.9988120476320312, 1, -0.99746047624731959, 0, 1, 0}; // LPF 5 Hz // float iir_coef[] = {GAIN1, -1.9988611276805377, 0.9988619329900803, -1.9996627164949214, 1, -1.9995421854793711, 0.99954495837831336, -1.9999409520041804, 1}; // LPF 1 Hz // float iir_coef[] = {GAIN1, -1.9977219408097229, 0.99772516021851665, -1.9986512052812304, 1, -1.9990790359606454, 0.9990901250259242, -1.9997638181447535, 1}; // LPF 2 Hz float iir_coef[] = {GAIN1, -1.9995869592235613, 0.99958765723850362, -1.9998923257509362, 1, -0.99958496672120145, 0, 1, 0}; /* Inizializzazione del Timer */ Timer_Init(); /* Inizializzazione dell'interfaccia seriale */ usart_init(230400); // Init usart with 230400 Baud /* Unlock the Flash Program Erase controller */ FLASH_Unlock(); /*Inizializzazione del LED */ /*Configurazione del TN100 */ TN100_InitStructure.srcId[0] = 0x02; // Source address TN100_InitStructure.srcId[1] = 0x00; TN100_InitStructure.srcId[2] = 0x00; TN100_InitStructure.srcId[3] = 0x00; TN100_InitStructure.srcId[4] = 0x00; TN100_InitStructure.srcId[5] = 0x00; TN100_InitStructure.destId[0] = 0x04; // Destination address TN100_InitStructure.destId[1] = 0x00; TN100_InitStructure.destId[2] = 0x00; TN100_InitStructure.destId[3] = 0x00; TN100_InitStructure.destId[4] = 0x00; TN100_InitStructure.destId[5] = 0x00; TN100_InitStructure.syncword[0] = 0xAB; TN100_InitStructure.syncword[1] = 0x2C; TN100_InitStructure.syncword[2] = 0xD5; TN100_InitStructure.syncword[3] = 0x92; TN100_InitStructure.syncword[4] = 0x94; TN100_InitStructure.syncword[5] = 0xCA; TN100_InitStructure.syncword[6] = 0x69; TN100_InitStructure.syncword[7] = 0xAB; TN100_InitStructure.txpacketType = TN100_TxData; TN100_InitStructure.rxpacketType = TN100_RxData; /*set channel (center frequency)*/ TN100_InitStructure.chNo = E1_2412MHZ; // -> Originale per Ranging: TN100_InitStructure.mode = TN100_80MHz_1MS_1us; //TN100_InitStructure.mode = TN100_80MHz_500kS_2us; TN100_InitStructure.mode = TN100_80MHz_250kS_4us; //TN100_InitStructure.mode = TN100_22MHz_1MS_1us; //TN100_InitStructure.mode = TN100_22MHz_500kS_2us; //TN100_InitStructure.mode = TN100_22MHz_250kS_4us; // La potenza in trasmissione va da 1.79 dBm (scrivere nel registro 63 ovvero 0x3F in esadecimale) // a -36.20 dBm (ovvero 0 nel registro 0x00) (vedi datasheet TN100 pag. 96) TN100_InitStructure.txpwr = 0x28; // 40 ovvero -7.31 dBm TN100_InitStructure.txArq = 0x03; TN100_InitStructure.txArqMode = 0x01; TN100_InitStructure.rxArqMode = TN100_RxArqModeCrc2; TN100_InitStructure.addrMatching = ON; #ifdef PA_EN #warning PA is on TN100_PA_Init(TN100_PA_SMD_ANT); // Abilito l'antenna SMD sulla scheda DiZic #endif /* Initialize delay pointer (needed for the TN100_lib)*/ Ptr_Delay_ms = Delay_ms; /* Initialize get time pointer (needed for the TN100_lib)*/ Ptr_GetTime_ms = GetSysTick; /* Initialize the TN100 module */ if(TN100_Init(TN100_INIT_FULL, &TN100_InitStructure) != 1) { myprintf("initialization failed!\n"); myprintf("stop application!\n"); while(1); } /* set source address */ TN100_SetStationAddr(&TN100_InitStructure.srcId[0],&TN100_InitStructure.srcId[0]); rxmsg[0] = 0; rangingtimer = GetSysTick(); //valori massimi e minimi di accelerometro e magnetometro int16_t ax_max=1024; int16_t ay_max=1024; int16_t az_max=1024; int16_t ax_min=-1024; int16_t ay_min=-1024; int16_t az_min=-1024; int16_t mx_max = 101; int16_t mx_min = -104; int16_t my_max = 80; int16_t my_min = -147; int16_t mz_max = 79; int16_t mz_min = -103; /*libreria ufficiale: deinizializza tutto ciò che riguarda la i2c1 tutti i registri*/ I2C_DeInit(I2C1); LSM303DLHC_I2C_InitialConfig(I2C1); /*abilita pb6 e pb7 descritti nella documentazione*/ GPIOB->CRL=0xFF444444; //per i2c1 su pb6 e pb7 /*configurazione LSM303DLHC.c dell'accelerometro e magnetometro*/ LSM303DLHC_I2C_Accelerometer_Config(I2C1); LSM303DLHC_I2C_Magnetometer_Config(I2C1); delay(0x0FFF); //ECGInit(); NVIC_Configuration(); // initialize the filter // firFixedInit(); //TN100_Callibration(); GPIO_SetBits(GPIOC, GPIO_Pin_15); // led2 on // initialize the filter buffer xv[0] = xv[1] = xv[2] = xv[3] = xv[4] = 0x3F; yv[0] = yv[1] = yv[2] = yv[3] = yv[4] = 0x3F; m = max1 = max2 = imax1 = imax2 = 0; while(1){ // TN100_Callibration(); // rxmsglen = TN100_is_Msg_Received(&rxmsg[0], senderID, receiverID, &packetType); /*faccio le letture x y z dell'accellerometro e magnetometro*/ buffer[0]=LSM303DLHC_I2C_Accelerometer_ReadDataAXL(I2C1); buffer[1]=LSM303DLHC_I2C_Accelerometer_ReadDataAXH(I2C1); // Prendo gli 8bit (MSB e LSB), li unisco per ricreare i 16bit del accelerometro // ci tolgo 2^16 cosi da ottenere un numero basso ad accelerometro fermo e 65536 // in movimento (originariamente è all'incontro) // mems[0] = 65536 -( (uint16_t) ((buffer[0] << 8) | buffer[1]) ); mems[0] = buffer[0]; mems[1] = buffer[1]; buffer[2]=LSM303DLHC_I2C_Accelerometer_ReadDataAYL(I2C1); buffer[3]=LSM303DLHC_I2C_Accelerometer_ReadDataAYH(I2C1); // mems[1] = 65536 -( (uint16_t) ((buffer[2] << 8) | buffer[3] )); mems[2] = buffer[2]; mems[3] = buffer[3]; buffer[4]=LSM303DLHC_I2C_Accelerometer_ReadDataAZL(I2C1); buffer[5]=LSM303DLHC_I2C_Accelerometer_ReadDataAZH(I2C1); // mems[2] = 65536 -( (uint16_t) ((buffer[4] << 8) | buffer[5] )); mems[4] = buffer[4]; mems[5] = buffer[5]; buffer[6]=LSM303DLHC_I2C_Magnetometer_ReadDataMXL(I2C1); buffer[7]=LSM303DLHC_I2C_Magnetometer_ReadDataMXH(I2C1); // mems[3] = 65536 -( (uint16_t) ((buffer[6] << 8) | buffer[7] )); buffer[8]=LSM303DLHC_I2C_Magnetometer_ReadDataMYL(I2C1); buffer[9]=LSM303DLHC_I2C_Magnetometer_ReadDataMYH(I2C1); // mems[4] = 65536 -( (uint16_t) ((buffer[8] << 8) | buffer[9] )); buffer[10]=LSM303DLHC_I2C_Magnetometer_ReadDataMZL(I2C1); buffer[11]=LSM303DLHC_I2C_Magnetometer_ReadDataMZH(I2C1); // mems[5] = 65536 -( (uint16_t) ((buffer[10] << 8) | buffer[11]) ); // Aggiusto i dati dell'accelerometro secondo la notazione 12-bit left-justified big endian double ax = ((int16_t)(( (buffer[0]<<8) | buffer[1] )))/16; double ay = ((int16_t)(( (buffer[2]<<8) | buffer[3] )))/16; double az = ((int16_t)(( (buffer[4]<<8) | buffer[5] )))/16; // Aggiusto i dati del Magnetometro secondo la notazione 12-bit right-justified little endian double mx = ((int16_t)(( (buffer[7]<<8) | buffer[6] ))); double my = ((int16_t)(( (buffer[9]<<8) | buffer[8] ))); double mz = ((int16_t)(( (buffer[11]<<8) | buffer[10] ))); // normalizzo i dati utilizzando i massimi ed i minimi, i risultati vanno da -1 a +1 double ax_n = ((ax - ax_min) / (ax_max - ax_min)) * 2 - 1; double ay_n = ((ay - ay_min) / (ay_max - ay_min)) * 2 - 1; double az_n = ((az - az_min) / (az_max - az_min)) * 2 - 1; double mx_n = ((mx - mx_min) / (mx_max - mx_min)) * 2 - 1; double my_n = ((my - my_min) / (my_max - my_min)) * 2 - 1; double mz_n = ((mz - mz_min) / (mz_max - mz_min)) * 2 - 1; // calcolo pitch e roll del piano orizzontale double pitch = asin(-ax_n); double roll = asin(ay_n / cos(pitch)); //formule per calcolare l'angolo in base all'inclinazione double xh = mx_n * cos(pitch) + mz_n * sin(pitch); double yh = mx_n * sin(roll) * sin(pitch) + my_n * cos(roll) - mz_n * sin(roll) * cos(pitch); //angolo sfruttando l'accelerometro double heading = (180 * atan2(yh, xh)/M_PI); //angolo considerando pitch e roll uguali a zero double headingZero = (180 * atan2(my_n, mx_n) / M_PI); //per avere valori da 0 a 360 e non da -180 a +180 if (yh < 0) heading += 360; //per avere valori da 0 a 360 e non da -180 a +180 if (headingZero < 0) headingZero += 360; //inserisce i valori aggiustati utilizzando le notazioni precedenti nel buffer da inviare *(int16_t*)&(buffer[0]) = (int16_t)ax; *(int16_t*)&(buffer[2]) = (int16_t)ay; *(int16_t*)&(buffer[4]) = (int16_t)az; *(int16_t*)&(buffer[6]) = (int16_t)mx; *(int16_t*)&(buffer[8]) = (int16_t)my; *(int16_t*)&(buffer[10])= (int16_t)mz; //inserisco nel buffer i valori dell'angolo e dell'angolo con piano orizzontale nullo *(int16_t*)&(buffer[12]) = (int16_t)heading; *(int16_t*)&(buffer[14]) = (int16_t)headingZero; pBuffer_Tx = &Buffer_Tx[0]; pBuff_Comp = &Buff_Comp[0]; if (Buffer_Ready==1) { step=0; if(pSampleBuff2==&SampleBuff2[0]) k=0; else k=DATA_BUFF_SIZE; if(j<=25) { Buffer_Tx[j] = SampleBuff2[k+step]; p3_in = &Buffer3_in[0]; p3_out = &Buffer3_out[0]; for(i=0; i<DATA_BUFF_SIZE; i++) { if((i%3) == 2) Buffer3_in[i/3]=SampleBuff2[i+k]; // Fill Temperature Buffer } Filter3(p3_in, NUM_SAMP_ECG, p3_out); Temp=Buffer3_out[0]; // Decimation Buffer_Tx[j+25]=SampleBuff2[k+1+step]; j++; step=step+3; } else if(j>25) { num_loc=2; Buff_app[0]= Buffer_Tx[1]; for(i=1; i<NUM_SAMP; i=i+1){ Buff_app[i]= Buffer_Tx[i+1]-Buffer_Tx[i]; } for(i=1; i<NUM_SAMP; i=i+1){ if(Buff_app[i]>127){diz[i-1]=1; num_loc=num_loc+2;} else if(Buff_app[i]<-128){diz[i-1]=1; num_loc=num_loc+2;} else {diz[i-1]=0; num_loc=num_loc+1;} } y=3; Buff_Comp[1]=Buff_app[0]; Buff_Comp[2]=(0xFFFF & Buff_app[0])>>8; for(i=0; i<49; i=i+1){ if(diz[i]==0){Buff_Comp[y]=Buff_app[i+1]; y++;} else{Buff_Comp[y]=Buff_app[i+1]; Buff_Comp[y+1]=(0xFFFF & Buff_app[i+1])>>8; y=y+2;} } Buff_Comp[num_loc+1]=Temp; // Accelerometro X a 16bit con 8bit (LSB) in mems[0] e 8bit (MSB) in mems[1] Buff_Comp[num_loc+2]=mems[0]; Buff_Comp[num_loc+3]=mems[1]; // Accelerometro Y Buff_Comp[num_loc+4]=mems[2]; Buff_Comp[num_loc+5]=mems[3]; // Accelerometro Z Buff_Comp[num_loc+6]=mems[4]; Buff_Comp[num_loc+7]=mems[5]; Buff_Comp[0]=0x00FF & num_pacchetto; q=0; for(i=0; i<41; i=i+8){ Buff_Comp[num_loc+8+q]=((diz[i]&1)<<7)|((diz[i+1]&1)<<6)|((diz[i+2]&1)<<5)|((diz[i+3]&1)<<4)|((diz[i+4]&1)<<3)|((diz[i+5]&1)<<2)|((diz[i+6]&1)<<1)|(diz[i+7]&1); q++; } Buff_Comp[num_loc+14]=diz[48]; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC,ENABLE); CRC->CR = 0x00000001; CRC_val=CRC_CalcBlockCRC((uint32_t *)pBuff_Comp, ((num_loc+15)/4)); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC,DISABLE); Buff_Comp[num_loc+15]=CRC_val; GPIO_SetBits(GPIOC, GPIO_Pin_14); // led1 on // Attendo che il TN100 si svegli. Per svegliarlo cambio lo stato al pin DII0_3 (D03) while(TN100_getWUState() != 1) { TN100_DIIO_3_STROBE(); } Delay_ms(2); // Lo reinizializzo ed invio il dato TN100_Init(TN100_INIT_FULL, &TN100_InitStructure); TN100_Send_Data(&TN100_InitStructure.destId[0], (uint8_t *)pBuff_Comp, (num_loc+16)); // Ad ogni ciclo ED UNA SOLA VOLTA per ciclo devo calibrarlo // TN100_Callibration(); // rxmsglen = TN100_is_Msg_Received(&rxmsg[0], senderID, receiverID, &packetType); // Mando il Tn100 in sleep TN100_Sleep(TN100_WAKEUPDIIO, TN100_PD_FULL, TN100_DIIO_3, NULL); GPIO_ResetBits(GPIOC, GPIO_Pin_14); // led1 off // STOPWATCH_STOP; // STOPWATCH_START; j=1; num_pacchetto++; Buffer_Ready = 0; } }
void adcInit(void) { ADC_InitTypeDef ADC_InitStructure; DMA_InitTypeDef DMA_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; adcSetConstants(); histSize = ADC_HIST_SIZE; // Use STM32's Dual Regular Simultaneous Mode capable of ~ 1.7M samples per second // NOTE: assume that RCC code has already placed all pins into Analog In mode during startup // DMA1 channel1 configuration (ADC1) DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1 + 0x4c; //从这个寄存器读 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&adcRawData[0]; //写入到这个内存 DMA_InitStructure.DMA_BufferSize = sizeof(adcRawData)/4; //传输数据量 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //从外设读 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址不递加 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //存储器地址递加 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;//外设数据宽度32位 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; //存储器数据宽度32位 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //循环模式 DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; //通道优先级最高 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //非存储器到存储器模式 DMA_Init(DMA1_Channel1, &DMA_InitStructure); DMA_ITConfig(DMA1_Channel1, DMA_IT_TC | DMA_IT_HT, ENABLE); DMA_ClearITPendingBit(DMA1_IT_GL1 | DMA1_IT_TC1 | DMA1_IT_HT1); DMA_Cmd(DMA1_Channel1, ENABLE); // Enable the DMA1_Channel1 global Interrupt NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); // ADC1 configuration // ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult; ADC_InitStructure.ADC_Mode = ADC_Mode_RegInjecSimult;//混合的同步规则+注入同步模式 ADC_InitStructure.ADC_ScanConvMode = ENABLE; //使用扫描模式 ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //连续转换模式 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //SWSTART 软件触发模式 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //数据右对齐 ADC_InitStructure.ADC_NbrOfChannel = sizeof(adcRawData)/4;//规则通道序列长度 有8个转换通道 ADC_Init(ADC1, &ADC_InitStructure); #ifdef ADC_FAST_SAMPLE //有8个转换通道 都是规则转换序列 //ADC_SAMPLE_TIME是AD的采样时间 ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SAMPLE_TIME); // SENSE_CURRENT ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 2, ADC_SAMPLE_TIME); // SENSE_CURRENT ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SAMPLE_TIME); // SENSE_B ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 4, ADC_SAMPLE_TIME); // SENSE_B ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 5, ADC_SAMPLE_TIME); // SENSE_VIN ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 6, ADC_SAMPLE_TIME); // SENSE_VIN ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 7, ADC_SAMPLE_TIME); // SENSE_B ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 8, ADC_SAMPLE_TIME); // SENSE_B #else ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SAMPLE_TIME); // SENSE_CURRENT ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 2, ADC_SAMPLE_TIME); // SENSE_B ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 3, ADC_SAMPLE_TIME); // SENSE_VIN ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 4, ADC_SAMPLE_TIME); // SENSE_B #endif ADC_DMACmd(ADC1, ENABLE);//ADC1开启DMA模式 // ADC2 configuration //ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult; ADC_InitStructure.ADC_Mode = ADC_Mode_RegInjecSimult; //混合的同步规则+注入同步模式 ADC_InitStructure.ADC_ScanConvMode = ENABLE; //使用扫描模式 ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //连续转换模式 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //SWSTART 软件触发模式 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //数据右对齐 ADC_InitStructure.ADC_NbrOfChannel = sizeof(adcRawData)/4; //规则通道序列长度 有8个转换通道 ADC_Init(ADC2, &ADC_InitStructure); #ifdef ADC_FAST_SAMPLE ADC_RegularChannelConfig(ADC2, ADC_Channel_1, 1, ADC_SAMPLE_TIME); // SENSE_A ADC_RegularChannelConfig(ADC2, ADC_Channel_1, 2, ADC_SAMPLE_TIME); // SENSE_A ADC_RegularChannelConfig(ADC2, ADC_Channel_3, 3, ADC_SAMPLE_TIME); // SENSE_C ADC_RegularChannelConfig(ADC2, ADC_Channel_3, 4, ADC_SAMPLE_TIME); // SENSE_C ADC_RegularChannelConfig(ADC2, ADC_Channel_1, 5, ADC_SAMPLE_TIME); // SENSE_A ADC_RegularChannelConfig(ADC2, ADC_Channel_1, 6, ADC_SAMPLE_TIME); // SENSE_A ADC_RegularChannelConfig(ADC2, ADC_Channel_3, 7, ADC_SAMPLE_TIME); // SENSE_C ADC_RegularChannelConfig(ADC2, ADC_Channel_3, 8, ADC_SAMPLE_TIME); // SENSE_C #else ADC_RegularChannelConfig(ADC2, ADC_Channel_1, 1, ADC_SAMPLE_TIME); // SENSE_A ADC_RegularChannelConfig(ADC2, ADC_Channel_3, 2, ADC_SAMPLE_TIME); // SENSE_C ADC_RegularChannelConfig(ADC2, ADC_Channel_1, 3, ADC_SAMPLE_TIME); // SENSE_A ADC_RegularChannelConfig(ADC2, ADC_Channel_3, 4, ADC_SAMPLE_TIME); // SENSE_C #endif ADC_ExternalTrigConvCmd(ADC2, ENABLE);//使用外部事件启动转换 // enable and calibrate ADC_Cmd(ADC1, ENABLE); adcCalibrateADC(ADC1); ADC_Cmd(ADC2, ENABLE); adcCalibrateADC(ADC2); nextCrossingDetect = adcMaxPeriod; // setup injection sequence // 设置注入序列 ADC_InjectedSequencerLengthConfig(ADC1, 1);//注入序列只有1个转换 ADC_InjectedSequencerLengthConfig(ADC2, 1); ADC_InjectedChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SAMPLE_TIME);//设置注入序列转换的通道 ADC_InjectedChannelConfig(ADC2, ADC_Channel_4, 1, ADC_SAMPLE_TIME); ADC_ExternalTrigInjectedConvCmd(ADC1, ENABLE);//注入序列 使用外部事件启动转换 ADC_ExternalTrigInjectedConvCmd(ADC2, ENABLE); ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_None);//软件触发 ADC_ExternalTrigInjectedConvConfig(ADC2, ADC_ExternalTrigInjecConv_None); // Start ADC1 / ADC2 Conversions ADC_SoftwareStartConvCmd(ADC1, ENABLE);//开始转换.并设置好外部触发模式 }
/* * @brief Initialize the ADC peripheral. */ void ADC_DMA_Init() { //Using "Dual Slow Interleaved ADC Mode" to achieve higher input impedance ADC_InitTypeDef ADC_InitStructure; DMA_InitTypeDef DMA_InitStructure; // ADCCLK = PCLK2/6 = 72/6 = 12MHz RCC_ADCCLKConfig(RCC_PCLK2_Div6); // Enable DMA1 clock RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); // Enable ADC1 and ADC2 clock RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2, ENABLE); // DMA1 channel1 configuration DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_ADDRESS; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_DualConvertedValues; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = ADC_DMA_BUFFERSIZE; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel1, &DMA_InitStructure); // Enable DMA1 Channel1 DMA_Cmd(DMA1_Channel1, ENABLE); // ADC1 configuration ADC_InitStructure.ADC_Mode = ADC_Mode_SlowInterl; ADC_InitStructure.ADC_ScanConvMode = DISABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 1; ADC_Init(ADC1, &ADC_InitStructure); // ADC2 configuration ADC_InitStructure.ADC_Mode = ADC_Mode_SlowInterl; ADC_InitStructure.ADC_ScanConvMode = DISABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 1; ADC_Init(ADC2, &ADC_InitStructure); // Enable ADC2 external trigger conversion ADC_ExternalTrigConvCmd(ADC2, ENABLE); // Enable ADC1 DMA ADC_DMACmd(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)); // Enable ADC2 ADC_Cmd(ADC2, ENABLE); // Enable ADC2 reset calibration register ADC_ResetCalibration(ADC2); // Check the end of ADC2 reset calibration register while(ADC_GetResetCalibrationStatus(ADC2)); // Start ADC2 calibration ADC_StartCalibration(ADC2); // Check the end of ADC2 calibration while(ADC_GetCalibrationStatus(ADC2)); }