ADC+DMA中断方式,只要在回调函数中读取了数据结果缓冲,ADC_Value_arr_buff[i]=ADC_Value_arr[i],后续ADC采样结果就不更新,如果不读取数据,采用仿真方式,ADC一直在更新数据,代码如下:
void ADC_Init_One(void)
{
ADC_ChannelConfTypeDef ADC1_ChanConf;
ADC_MultiModeTypeDef multimode;
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_ADC1_CLK_ENABLE(); //ʹÄÜADC1ʱÖÓ
__HAL_RCC_GPIOA_CLK_ENABLE(); //¿ªÆôGPIOAʱÖÓ
__HAL_RCC_GPIOB_CLK_ENABLE(); //¿ªÆôGPIOAʱÖÓ
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=ENABLE;//DISABLE; //·ÇɨÃèģʽ
ADC1_Handler.Init.EOCSelection=DISABLE;//ENABLE;//DISABLE; //¹Ø±ÕEOCÖжÏ
ADC1_Handler.Init.ContinuousConvMode=ENABLE;//ENABLE;//ENABLE; //¹Ø±ÕÁ¬Ðøת»»
ADC1_Handler.Init.NbrOfConversion=7; //1¸öת»»ÔÚ¹æÔòÐòÁÐÖÐ Ò²¾ÍÊÇֻת»»¹æÔòÐòÁÐ1
ADC1_Handler.Init.DiscontinuousConvMode=DISABLE;//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;//DISABLE; //¹Ø±ÕDMAÇëÇó
HAL_ADC_Init(&ADC1_Handler); //³õʼ»¯
GPIO_Initure.Pin=GPIO_PIN_0|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_8|GPIO_PIN_9; //PA5+PA6+PA7+PA8
GPIO_Initure.Mode=GPIO_MODE_ANALOG; //Ä£Äâ
GPIO_Initure.Pull=GPIO_NOPULL; //²»´øÉÏÏÂÀ
HAL_GPIO_Init(GPIOA,&GPIO_Initure);
ADC1_ChanConf.Channel=ADC_CHANNEL_0; //ͨµÀ
ADC1_ChanConf.Rank=1; //1¸öÐòÁÐ
ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES; //²ÉÑùʱ¼ä
ADC1_ChanConf.Offset=0;
HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf); //ͨµÀÅäÖ
ADC1_ChanConf.Channel=ADC_CHANNEL_3; //ͨµÀ
ADC1_ChanConf.Rank=2; //1¸öÐòÁÐ
ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES; //²ÉÑùʱ¼ä
ADC1_ChanConf.Offset=0;
HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf); //ͨµÀÅäÖ
ADC1_ChanConf.Channel=ADC_CHANNEL_4; //ͨµÀ
ADC1_ChanConf.Rank=3; //1¸öÐòÁÐ
ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES; //²ÉÑùʱ¼ä
ADC1_ChanConf.Offset=0;
HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf); //ͨµÀÅäÖÃ
ADC1_ChanConf.Channel=ADC_CHANNEL_5; //ͨµÀ
ADC1_ChanConf.Rank=4; //1¸öÐòÁÐ
ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES; //²ÉÑùʱ¼ä
ADC1_ChanConf.Offset=0;
HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf); //ͨµÀÅäÖÃ
ADC1_ChanConf.Channel=ADC_CHANNEL_6; //ͨµÀ
ADC1_ChanConf.Rank=5; //1¸öÐòÁÐ
ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES; //²ÉÑùʱ¼ä
ADC1_ChanConf.Offset=0;
HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf); //ͨµÀÅäÖÃ
ADC1_ChanConf.Channel=ADC_CHANNEL_8; //ͨµÀ
ADC1_ChanConf.Rank=6; //1¸öÐòÁÐ
ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES; //²ÉÑùʱ¼ä
ADC1_ChanConf.Offset=0;
HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf); //ͨµÀÅäÖÃ
ADC1_ChanConf.Channel=ADC_CHANNEL_9; //ͨµÀ
ADC1_ChanConf.Rank=7; //1¸öÐòÁÐ
ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES; //²ÉÑùʱ¼ä
ADC1_ChanConf.Offset=0;
HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf); //ͨµÀÅäÖÃ
HAL_ADC_Start_DMA(&ADC1_Handler, ADC_Value_arr,14);
}
void DMA_Config(void)
{
__HAL_RCC_DMA2_CLK_ENABLE(); //DMA2ʱÖÓʹÄÜ
__HAL_RCC_DMA1_CLK_ENABLE(); //DMA1ʱÖÓʹÄÜ
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_WORD; //ÍâÉèÊý¾Ý³¤¶È:8λ
ADC1DMA_Handler.Init.MemDataAlignment=DMA_MDATAALIGN_WORD; //´æ´¢Æ÷Êý¾Ý³¤¶È:8λ
ADC1DMA_Handler.Init.Mode=DMA_CIRCULAR;//DMA_NORMAL; //ÍâÉèÁ÷¿Øģʽ
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_LINKDMA(&ADC1_Handler,DMA_Handle,ADC1DMA_Handler); //½«DMAÓëADC1ÁªÏµÆðÀ´
// __HAL_DMA_ENABLE_IT(&ADC1DMA_Handler,DMA_IT_TC)
HAL_NVIC_SetPriority(DMA2_Stream0_IRQn,0,0);
HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
u8 i;
// HAL_ADC_Stop_DMA(&ADC1_Handler);
for(i=0;i<14;i++)
{
ADC_Value_arr_buff[i]=ADC_Value_arr[i];
}
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
关闭cache就正确,多谢楼上的tx。还要在仔细研究。
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
u8 i;
SCB_DisableDCache();
for(i=0;i<14;i++)
{
ADC_Value_arr_buff[i]=ADC_Value_arr[i];
}
SCB_EnableDCache();
//DMA_Config();
//ADC_Init_One();
//HAL_ADC_Start_DMA(&ADC1_Handler, ADC_Value_arr,14);
}
为了避免数据不一致的问题,我们需要做D-CACHE维护操作。一般有如下四种方法:
1、当对一个可缓存的二级存储器做了写数据操作之后,通过软件对D-CACHE进行清除操作,即运行SCB_CleanDCache()。这样将CACHE里的缓存内容写回到二级存储器,比如把那些DIRTY CACHE行的数据写进SRAM1。
2、通过MPU调整可缓存存储器的存储属性,将其CACHE使用方式改为透写模式。这样保证每次写入CACHE里的内容也同时写入二级存储器,比如写进SRAM1。
3、通过MPU调整可缓存存储器的存储属性,将其共享属性改为可共享的【SHAREABLE】。此后该二级存储器将变为不可缓存。
4、通过配置CACR寄存器中的D-CACHE位,强制将所有写操作配置为透写属性。
一周热门 更多>