STM32L011D4芯片用SWD无法下载程序
求助:STM32L0系列标准库哪里下?
STM32L051低温时LPUART串口波特率异常
STM32L051单片机ADC如何彻底关闭?
STM32L051C8进入低功耗模式电流偏大
STM32L052C8T6通过I2C模拟读16位数
STM32L0的VLCD外接5V会有问题吗
求助!!使用STM32L073 IO口模拟IIC接口读写AT24CM01 程序不停...
STM32L072RB写Bank2 EEPROM不响应中断
STM32L031无法进入boot
* @file ADC_Configuration
* @brief 完成ADC和DMA的初始化
* @param 无
* @retval 无
*/
void ADC_Configuration(uint32_t _ulFreq)
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
TIM_TimeBaseInitTypeDef timer_init_structure;
NVIC_InitTypeDef NVIC_InitStructure;
uint16_t usPeriod;
uint16_t usPrescaler;
uint32_t uiTIMxCLK;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
/*设置ADC分频因子为4 ,ADC最大时间不能超过14M*/
RCC_ADCCLKConfig(RCC_ADCCLK_PCLK_Div4);
/* ADC1 Periph clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
/* 使能DMA时钟 */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_5 | GPIO_Pin_6 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/*-----------------------------------------------------------------------
system_stm32f4xx.c 文件中 void SetSysClock(void) 函数对时钟的配置如下:
HCLK = SYSCLK / 1 (AHB1Periph)
PCLK2 = HCLK / 2 (APB2Periph)
PCLK1 = HCLK / 4 (APB1Periph)
因为APB1 prescaler != 1, 所以 APB1上的TIMxCLK = PCLK1 x 2 = SystemCoreClock / 2;
因为APB2 prescaler != 1, 所以 APB2上的TIMxCLK = PCLK2 x 2 = SystemCoreClock;
APB1 定时器有 TIM2, TIM3 ,TIM4, TIM5, TIM6, TIM6, TIM12, TIM13,TIM14
APB2 定时器有 TIM1, TIM8 ,TIM9, TIM10, TIM11
----------------------------------------------------------------------- */
uiTIMxCLK = SystemCoreClock;
if (_ulFreq < 100)
{
usPrescaler = 10000 - 1; /* 分频比 = 10000 */
usPeriod = (uiTIMxCLK / 10000) / _ulFreq - 1; /* 自动重装的值 */
}
else if (_ulFreq < 3000)
{
usPrescaler = 100 - 1; /* 分频比 = 100 */
usPeriod = (uiTIMxCLK / 100) / _ulFreq - 1; /* 自动重装的值 */
}
else /* 大于4K的频率,无需分频 */
{
usPrescaler = 0; /* 分频比 = 1 */
usPeriod = uiTIMxCLK / _ulFreq - 1; /* 自动重装的值 */
}
/*复位TIM2*/
TIM_DeInit(TIM2);
/*初始化TIMBASE结构体*/
TIM_TimeBaseStructInit(&timer_init_structure);
/*系统时钟,不分频,48M*/
timer_init_structure.TIM_ClockDivision = TIM_CKD_DIV1;
/*向上计数模式*/
timer_init_structure.TIM_CounterMode = TIM_CounterMode_Up;
/*每312 uS触发一次中断,开启ADC*/
timer_init_structure.TIM_Period = usPeriod;
/*计数时钟预分频,f=1M,systick=1 uS */
timer_init_structure.TIM_Prescaler = usPrescaler;
/*发生0+1次update事件产生中断 */
timer_init_structure.TIM_RepetitionCounter = 0x00;
TIM_TimeBaseInit(TIM2, &timer_init_structure);
/*使能TIM2中断 */
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
/*选择TIM2的update事件更新为触发源*/
TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);
/*使能TIM2*/
TIM_Cmd(TIM2, ENABLE);
/* ADC1 DeInit */
ADC_DeInit(ADC1);
/*初始化ADC结构体,此句必须加,不加的话多路ADC数据会交换*/
ADC_StructInit(&ADC_InitStructure);
/*配置ADC分辨率为12位*/
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
/*开启连续转换*/
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
/*禁止触发检测,使用软件触发*/
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConv_T2_TRGO;
/*ADC采集数据右对齐*/
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
/*向上扫描*/
ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;
/*ADC初始化*/
ADC_Init(ADC1, &ADC_InitStructure);
/*配置采样通道及时间*/
ADC_ChannelConfig(ADC1, GPIO_Pin_2 | ADC_Channel_3 | ADC_Channel_5 | GPIO_Pin_6 , ADC_SampleTime_28_5Cycles);
/* ADC 校准 */
ADC_GetCalibrationFactor(ADC1);
/* 循环模式下的 ADC DMA 请求 */
ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular);
/* 使能 ADC_DMA */
ADC_DMACmd(ADC1, ENABLE);
/* 使能 ADC1 */
ADC_Cmd(ADC1, ENABLE);
/* 等待 ADCEN 标志 */
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN));
/* ADC1 常规软件启动转换 */
ADC_StartOfConversion(ADC1);
/* 复位DMA1_Channel1 */
DMA_DeInit(DMA1_Channel1);
/*DMA外设ADC基地址*/
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address;
/*DMA内存基地址*/
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_ConvertedValue;
/*外设作为数据传输源*/
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
/*DMA通道的DMA缓存的大小*/
DMA_InitStructure.DMA_BufferSize = 4 * AD_Count;
/*外设地址寄存器不变*/
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循环模式,即完成后重新开始覆盖*/
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
/*DMA优先级设置为高*/
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
/*DMA通道x禁用内存到内存传输*/
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
/*DMA初始化*/
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
/*清除一次DMA中断标志*/
DMA_ClearITPendingBit(DMA1_IT_TC1);
/*使能DMA传输完成中断*/
DMA_ITConfig(DMA1_Channel1, DMA1_IT_TC1, ENABLE);
/*选择DMA1通道中断*/
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
/*中断使能*/
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
/*优先级设为0 */
NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
/*使能 DMA 中断*/
NVIC_Init(&NVIC_InitStructure);
/* DMA1 Channel1 enable */
DMA_Cmd(DMA1_Channel1, ENABLE);
}
/**
* @brief ADC滤波
* @param 无
* @retval 无
*/
void ADC_Filter(void)
{
uint8_t i, j;
/*从DMA缓存中取出AD数据*/
for(i=0; i<4; i++)
{
for(j=0; j<AD_Count; j++)
{
ADCresults[i][j] = ADC_ConvertedValue[j][i];
}
}
/*取值求和取平均*/
for(i=0; i<4; i++)
{
AD_Data[i] = 0;
for(j=0; j<AD_Count; j++)
{
AD_Data[i] += ADCresults[i][j];
}
AD_Data[i] =(AD_Temp[i]*75 + ((AD_Data[i])/ (AD_Count))*25)/100;
AD_Temp[i] = AD_Data[i];
}
// printf("\r\n AD_value1=%d AD_value2=%d \r\n",AD_Data[0], AD_Data[1]);
}
/**
* @brief DMA1_Channel1中断服务函数
* @param 无
* @retval 无
*/
void DMA1_Channel1_IRQHandler()
{
/*判断DMA传输完成中断*/
if(DMA_GetITStatus(DMA1_IT_TC1) != RESET)
{
// AD_Count_flag++;
// if(AD_Count_flag==64)
flag_ADC = 1;
}
/*清除DMA中断标志位*/
DMA_ClearITPendingBit(DMA1_IT_TC1);
}
不用 DMA 可以使用 ADC 断续模式 例如选用 内部软件触发,一个序列 每触发一次 转换一个通道,检测EOC标志 就好了,读取出数据。手册上有的
使用 DMA很简单的 不复杂 使用 cube