想法: 开启TIM3中断 每50us进行一次ADC转换 ,转换的数据用DMA发送,当采集到200个数据时,主程序中进行一次处理 我将ADC和DAC接到一次,发现测得的电压示数一直为0,
好像并没有进入到DMA中断中处理,也没有进行DMA传输,这是怎么回事
部分程序如下
ADC部分:
//初始化ADC
//ch: ADC_channels
//通道值 0~16取值范围为:ADC_CHANNEL_0~ADC_CHANNEL_16
void MY_ADC_Init(void)
{
ADC1_Handler.Instance=ADC1;
ADC1_Handler.Init.ClockPrescaler=ADC_CLOCK_SYNC_PCLK_DIV4; //4分频,ADCCLK=PCLK2/4=108/4=27MHZ
ADC1_Handler.Init.Resolution=ADC_RESOLUTION_12B; //12位模式
ADC1_Handler.Init.DataAlign=ADC_DATAALIGN_RIGHT; //右对齐
ADC1_Handler.Init.ScanConvMode=DISABLE; //非扫描模式
ADC1_Handler.Init.EOCSelection=DISABLE; //关闭EOC
ADC1_Handler.Init.ContinuousConvMode=DISABLE; //关闭连续转换
ADC1_Handler.Init.NbrOfConversion=1; //1个转换在规则序列中 也就是只转换规则序列1
ADC1_Handler.Init.DiscontinuousConvMode=DISABLE; //禁止不连续采样模式
ADC1_Handler.Init.NbrOfDiscConversion=0; //不连续采样通道数为0
ADC1_Handler.Init.ExternalTrigConv=ADC_SOFTWARE_START; //软件触发
ADC1_Handler.Init.ExternalTrigConvEdge=ADC_EXTERNALTRIGCONVEDGE_NONE;//使用软件触发
ADC1_Handler.Init.DMAContinuousRequests=ENABLE; //开启DMA请求
HAL_ADC_Init(&ADC1_Handler); //初始化
HAL_ADC_Start_IT(&ADC1_Handler); //开启中断
}
//ADC底层驱动,引脚配置,时钟使能
//此函数会被HAL_ADC_Init()调用
//hadc:ADC句柄
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_ADC1_CLK_ENABLE(); //使能ADC1时钟
__HAL_RCC_GPIOA_CLK_ENABLE(); //开启GPIOA时钟
GPIO_Initure.Pin=GPIO_PIN_5; //PA5
GPIO_Initure.Mode=GPIO_MODE_ANALOG; //模拟
GPIO_Initure.Pull=GPIO_NOPULL; //不带上下拉
HAL_GPIO_Init(GPIOA,&GPIO_Initure);
HAL_NVIC_SetPriority(ADC_IRQn, 3, 3);
HAL_NVIC_EnableIRQ(ADC_IRQn);
}
void ADC_IRQHandler(void)
{
HAL_ADC_IRQHandler(&ADC1_Handler);
}
void HAL_ADC_ErrorCallback(ADC_HandleTypeDef* hadc) //DMA溢出回调函数
好像并没有进入这个中断,实验发现LED0不变
{
一直为灭。
HAL_ADC_Stop_DMA(&ADC1_Handler); //重新初始化DMA
ADC_Flag=1; //FLAG置位,表示已经采集完成,主程序中进行处理,处理完成后再开启DMA
LED0_Toggle;
}
void Start_Adc(u32 ch) //开启ADC的转换,在定时器中断中调用
{
ADC_ChannelConfTypeDef ADC1_ChanConf;
ADC1_ChanConf.Channel=ch; //通道
ADC1_ChanConf.Rank=1; //1个序列
ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES; //采样时间
ADC1_ChanConf.Offset=0;
HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf); //通道配置
HAL_ADC_Start(&ADC1_Handler); //开启ADC转换
}
DMA配置如下
DMA_HandleTypeDef ADC1DMA_Handler; //DMA句柄
//DMAx的各通道配置
//这里的传输形式是固定的,这点要根据不同的情况来修改
//从存储器->外设模式/8位数据宽度/存储器增量模式
//DMA_Streamx
MA数据流,DMA1_Stream0~7/DMA2_Stream0~7
//chx
MA通道选择,@ref DMA_channel DMA_CHANNEL_0~DMA_CHANNEL_7
void MYDMA_Config(DMA_Stream_TypeDef *DMA_Streamx,u32 chx)
{
if((u32)DMA_Streamx>(u32)DMA2)//得到当前stream是属于DMA2还是DMA1
{
__HAL_RCC_DMA2_CLK_ENABLE();//DMA2时钟使能
}else
{
__HAL_RCC_DMA1_CLK_ENABLE();//DMA1时钟使能
}
__HAL_LINKDMA(&ADC1_Handler,DMA_Handle,ADC1DMA_Handler); //将DMA与ADC1联系起来(发送DMA)
//Tx DMA配置
ADC1DMA_Handler.Instance=DMA_Streamx; //数据流选择
ADC1DMA_Handler.Init.Channel=chx; //通道选择
ADC1DMA_Handler.Init.Direction=DMA_PERIPH_TO_MEMORY; //外设到存储器
ADC1DMA_Handler.Init.PeriphInc=DMA_PINC_DISABLE; //外设非增量模式
ADC1DMA_Handler.Init.MemInc=DMA_MINC_ENABLE; //存储器增量模式
ADC1DMA_Handler.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD; //外设数据长度:16位
ADC1DMA_Handler.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD; //存储器数据长度:16位
ADC1DMA_Handler.Init.Mode=DMA_PFCTRL; //外设触发模式
ADC1DMA_Handler.Init.Priority=DMA_PRIORITY_MEDIUM; //中等优先级
ADC1DMA_Handler.Init.FIFOMode=DMA_FIFOMODE_DISABLE;
ADC1DMA_Handler.Init.FIFOThreshold=DMA_FIFO_THRESHOLD_FULL;
ADC1DMA_Handler.Init.MemBurst=DMA_MBURST_SINGLE; //存储器突发单次传输
ADC1DMA_Handler.Init.PeriphBurst=DMA_PBURST_SINGLE; //外设突发单次传输
HAL_DMA_DeInit(&ADC1DMA_Handler);
HAL_DMA_Init(&ADC1DMA_Handler);
__HAL_DMA_ENABLE_IT(&ADC1DMA_Handler,DMA_IT_TC); //开启发送完成中断
HAL_NVIC_SetPriority(DMA2_Stream0_IRQn,1,0); //接收DMA中断优先级
HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
}
//DMA2数据流0中断服务函数
void DMA2_Stream0_IRQHandler(void) //开启后应该回调ADC溢出中断函数
{
HAL_DMA_IRQHandler(ADC1_Handler.DMA_Handle);
}
定时器溢出中断:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) //实现ADC的定时采样
{
if(htim==(&TIM3_Handler))
{
Start_Adc(ADC_CHANNEL_5); //每50us开启一次ADC转换,DMA自动传送
}
}
主程序部分代码)
MYDMA_Config(DMA2_Stream0,DMA_CHANNEL_0); //初始化DMA
MY_ADC_Init(); //初始化ADC1
DAC1_Init(); //初始化DAC1
TIM3_Init(50-1,108-1); //50us中断一次
HAL_DAC_SetValue(&DAC1_Handler,DAC_CHANNEL_1,DAC_ALIGN_12B_R,4095);//初始值为3.3V
HAL_ADC_Start_DMA(&ADC1_Handler, (u32*)MYADC_GET, Samp_Times); //开启第一次DMA传送
while(1)
{
KeyDriver();
if(ADC_Flag==1) //DMA已经传送200个数据
{
ADC_Flag=0;
for(j=0;j<Samp_Times;j++)
SUM+=MYADC_GET[j]; //求平均
adcx=SUM/Samp_Times;
SUM=0;
HAL_ADC_Start_DMA(&ADC1_Handler, (u32*)MYADC_GET, Samp_Times); //数据处理完成,重新开启DMA传送
。。。。。。(之后将adcx值显示在液晶屏上)
}
}
{
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_ADC1_CLK_ENABLE(); //使能ADC1时钟
/* ADC1 GPIO Configuration */
GPIO_Initure.Pin=GPIO_PIN_5; //PA5
GPIO_Initure.Mode=GPIO_MODE_ANALOG; //模拟
GPIO_Initure.Pull=GPIO_NOPULL; //不带上下拉
HAL_GPIO_Init(GPIOA,&GPIO_Initure);
/* Peripheral DMA init */
ADC1DMA_Handler.Instance= DMA2_Stream0; //数据流选择
ADC1DMA_Handler.Init.Channel=DMA_CHANNEL_0; //通道选择
ADC1DMA_Handler.Init.Direction=DMA_PERIPH_TO_MEMORY; //外设到存储器
ADC1DMA_Handler.Init.PeriphInc=DMA_PINC_DISABLE; //外设非增量模式
ADC1DMA_Handler.Init.MemInc=DMA_MINC_ENABLE; //存储器增量模式
ADC1DMA_Handler.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD; //外设数据长度:16位
ADC1DMA_Handler.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD; //存储器数据长度:16位
ADC1DMA_Handler.Init.Mode= DMA_CIRCULAR; //外设触发模式
ADC1DMA_Handler.Init.Priority= DMA_PRIORITY_LOW; //中等优先级
ADC1DMA_Handler.Init.FIFOMode=DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&ADC1DMA_Handler) !=HAL_OK) // 配置DMA
{
Error_Handler();
}
__HAL_LINKDMA(&ADC1_Handler,DMA_Handle,ADC1DMA_Handler); //将DMA与ADC1联系起来(发送DMA)
}
一周热门 更多>