风铃草2 发表于 2016-11-7 10:57:20

DMA 传输一半中断

初始化我这样配置
DMA_ITConfig(DMA1_Channel1, DMA_IT_HT, ENABLE);
DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, DISABLE);
DMA_ClearITPendingBit(DMA_IT_HT);
DMA_ClearITPendingBit(DMA_IT_TC);


中断我这样做
u8 Test_Flag=0;
void DMA1_Channel1_IRQHandler(void)          
{           

        if(DMA_GetITStatus(DMA_IT_TC)==SET)
        {
                DMA_ClearITPendingBit(DMA_IT_TC);                                         
                if(Test_Flag)
                {
                        Test_Flag=0;
                        SDA_H;
                }
                else
                {
                        Test_Flag=1;
                        SDA_L;                       
                }       
                       
        }   
}
结果就是它执行了中断里面的TC中断程序。问题:为什么关了TC中断,只开HT中断,也会产生TC中断?

然后我经过测试,发现 HT的TC的中断执行时间是一样的,得出一个结果HT中断和TC中断是一样的。问题:传输一半中断是不是不能实现?





发表于 2016-11-10 11:07:32

我测试1us下,HT和TC产生的中断和下次产生的间隔相差为500us,我用的是1000组采集。定时器为10us。如下:
ADC_ConvHalfCp:9029,496
ConvCplt:9029,0
ADC_ConvHalfCp:9079,496
ConvCplt:9079,0
ADC_ConvHalfCp:9130,496
ConvCplt:9130,0
TC情况下测试的是1000us,定时器为10us,如下:
ConvCplt:190,0
ConvCplt:290,0
ConvCplt:391,0
ConvCplt:492,0
ConvCplt:593,0
ConvCplt:694,0
ConvCplt:794,0

发表于 2016-11-10 15:38:49

我用的是103测试的。楼主可以看一下。

anobodykey 发表于 2016-11-7 11:34:09

不清楚你的DMA测试是测试的单次还是连续测试的,但是我觉得你得多看下手册,TC标识是由硬件触发的,因此不管你有没有使能TC中断,只要发送完成,TC标识就会置位,只是它不触发中断,如果你DMA只测试了一次应该是不会执行你中断里面的条件语句,如果是多次DMA测试我想的确是会进的吧,不晓得分析的对不对。

风铃草2 发表于 2016-11-11 17:22:06

安 发表于 2016-11-10 15:38
我用的是103测试的。楼主可以看一下。

我明白了,我们的程序没问题。    是我误会了其中的意思了,半传输中断,只在DMA传输到一半时才产生。第一次中断是在传输了BUFF/2之时,第二次中断也是在传输了BUFF/2之时。两次中断间隔之间,其实传输了整个BUFF。 也就是说每中断一次需要的时间是传输整个BUFF的时间。也就是说TC中断时间=HT中断时间。

五哥1 发表于 2016-11-8 11:24:22

根据楼主的情况,结合以往,绝大多数的问题都是提出问题的楼主自行解决的,因为所有发言的人都是在你提供的非常有限的信息里凭经验猜。这个猜,或许能给你一些启发,最终解决问题的还是你自己。

发表于 2016-11-7 14:09:54

楼主可以测试一下,当中断产生时,看一下DMA的中断寄存器的值。

风铃草2 发表于 2016-11-7 13:44:52

anobodykey 发表于 2016-11-7 11:34
不清楚你的DMA测试是测试的单次还是连续测试的,但是我觉得你得多看下手册,TC标识是由硬件触发的,因此不管 ...

手册里面是这么说的 the TC flag is set and an interrupt is generated if the TCIE bit is set。到底是你熟悉还是我不熟悉,你自己看看

高二毛 发表于 2016-11-7 13:59:04

二楼回复,楼主说的很有火药味啊,大家都不敢发言了。

风铃草2 发表于 2016-11-7 14:15:15

高二毛 发表于 2016-11-7 13:59
二楼回复,楼主说的很有火药味啊,大家都不敢发言了。

火药味重了就不敢发言吗?总是唯唯诺诺,遇事害怕,怎么会有出息,有本事就把问题解决,我就服你

风铃草2 发表于 2016-11-7 15:55:50

安 发表于 2016-11-7 14:09
楼主可以测试一下,当中断产生时,看一下DMA的中断寄存器的值。

看了,TC 和 HT中断标志一起产生,而且每次中断都是DMA全部传输完成中断,根本就不是传输一半中断。最后没办法在中断里面做了个动作,buff总共大小500,结果每次都跳进if里面   说明每次整个buff都被更新了
               if((RegularConvData_Tab!=0xff)&&(RegularConvData_Tab!=0xff))
                {
                        RegularConvData_Tab=0xff;
                }               
                RegularConvData_Tab=0xff;
                RegularConvData_Tab=0xff;

发表于 2016-11-7 15:58:24

楼主用的哪个CPU。

风铃草2 发表于 2016-11-7 16:02:13

安 发表于 2016-11-7 15:58
楼主用的哪个CPU。

STM32F072C8

风铃草2 发表于 2016-11-7 16:03:07

安 发表于 2016-11-7 15:58
楼主用的哪个CPU。

void ADC_Config(MEA_RANGE_TypeDef MeaRange)
{
ADC_InitTypeDef   ADC_InitStructure;
GPIO_InitTypeDef    GPIO_InitStructure;
               
        Clear_Buff((u8*)RegularConvData_Tab,DMA_BUFF_SIZE*2);
        RegularConvData_Tab=0xff;
        RegularConvData_Tab=0xff;       
/* ADC1 DeInit */
ADC_DeInit(ADC1);

   /* ADC1 Periph clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

        //把要AD的口配置为模拟输入其它两个配置为高阻这里要测试输入超过4V怎么办
        switch(MeaRange)
        {
                case RANG_70DB:
                                GPIO_InitStructure.GPIO_Pin = GPIO_PIN_70DB ;
                                GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
                                GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
                                GPIO_Init(GPIO_PORT_70DB, &GPIO_InitStructure);
                                               
                                GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
                                GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;//高阻态                               
                                GPIO_InitStructure.GPIO_Pin = GPIO_PIN_100DB ;               
                                GPIO_Init(GPIO_PORT_100DB, &GPIO_InitStructure);               
                                GPIO_InitStructure.GPIO_Pin = GPIO_PIN_130DB ;               
                                GPIO_Init(GPIO_PORT_130DB, &GPIO_InitStructure);                               
                        break;
                case RANG_100DB:
                                GPIO_InitStructure.GPIO_Pin = GPIO_PIN_100DB ;
                                GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
                                GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
                                GPIO_Init(GPIO_PORT_100DB, &GPIO_InitStructure);
                                               
                                GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
                                GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;//高阻态                               
                                GPIO_InitStructure.GPIO_Pin = GPIO_PIN_70DB ;               
                                GPIO_Init(GPIO_PORT_70DB, &GPIO_InitStructure);               
                                GPIO_InitStructure.GPIO_Pin = GPIO_PIN_130DB ;               
                                GPIO_Init(GPIO_PORT_130DB, &GPIO_InitStructure);                                       
                        break;
                case RANG_130DB:
                                GPIO_InitStructure.GPIO_Pin = GPIO_PIN_130DB ;
                                GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
                                GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
                                GPIO_Init(GPIO_PORT_130DB, &GPIO_InitStructure);
                                               
                                GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
                                GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;//高阻态                               
                                GPIO_InitStructure.GPIO_Pin = GPIO_PIN_100DB ;               
                                GPIO_Init(GPIO_PORT_100DB, &GPIO_InitStructure);               
                                GPIO_InitStructure.GPIO_Pin = GPIO_PIN_70DB ;               
                                GPIO_Init(GPIO_PORT_70DB, &GPIO_InitStructure);                                       
                        break;               
        }

/* Initialize ADC structure */
ADC_StructInit(&ADC_InitStructure);

/* Configure the ADC1 in continuous mode withe a resolution equal to 12 bits*/
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;
ADC_Init(ADC1, &ADC_InitStructure);

        //把要AD的口配置为模拟输入其它两个配置为高阻这里要测试输入超过4V怎么办
        switch(MeaRange)
        {
                case RANG_70DB:
                        /* Convert the ADC1 Channel11 and channel10 with 28 Cycles as sampling time */
                        ADC_ChannelConfig(ADC1, ADC_Channel_1 , ADC_SampleTime_13_5Cycles);                
                        break;
                case RANG_100DB:
                        /* Convert the ADC1 Channel11 and channel10 with 28 Cycles as sampling time */
                        ADC_ChannelConfig(ADC1, ADC_Channel_2 , ADC_SampleTime_13_5Cycles);                
                        break;
                case RANG_130DB:
                        /* Convert the ADC1 Channel11 and channel10 with 28 Cycles as sampling time */
                        ADC_ChannelConfig(ADC1, ADC_Channel_3 , ADC_SampleTime_13_5Cycles);                        
                        break;               
        }       

/* ADC Calibration */
ADC_GetCalibrationFactor(ADC1);

/* ADC DMA request in circular mode */
ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular);

/* Enable ADC_DMA */
ADC_DMACmd(ADC1, ENABLE);

/* Enable the ADC peripheral */
ADC_Cmd(ADC1, ENABLE);   

/* Wait the ADRDY flag */
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADRDY));

/* ADC1 regular Software Start Conv */
ADC_StartOfConversion(ADC1);
}


void DMA_Config(void)
{
DMA_InitTypeDef   DMA_InitStructure;
/* DMA1 clock enable */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE);
       
NVIC_DMA_Config();   
/* DMA1 Channel1 Config */
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)RegularConvData_Tab;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = DMA_BUFF_SIZE;
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);
       
        DMA_ITConfig(DMA1_Channel1, DMA_IT_HT, ENABLE);
        DMA_ClearITPendingBit(DMA_IT_HT);

/* DMA1 Channel1 enable */
DMA_Cmd(DMA1_Channel1, ENABLE);

       
}


void NVIC_DMA_Config(void)
{
        NVIC_InitTypeDef NVIC_InitStructure;
       
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;   
NVIC_InitStructure.NVIC_IRQChannelPriority = 0;                                     
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}

u8 Test_Flag=0,Errno;
void DMA1_Channel1_IRQHandler(void)          
{           
        ADC_StopOfConversion(ADC1);
DMA_Cmd(DMA1_Channel1, DISABLE);
        if(DMA_GetITStatus(DMA_IT_HT)==SET)
        {
                if((RegularConvData_Tab!=0xff)&&(RegularConvData_Tab!=0xff))
                {
                        Errno=1;
                }               
                RegularConvData_Tab=0xff;
                RegularConvData_Tab=0xff;
               
                DMA_ClearITPendingBit(DMA1_IT_GL1);                                         
                if(Test_Flag)
                {
                        Test_Flag=0;
                        SDA_H;
                }
                else
                {
                        Test_Flag=1;
                        SDA_L;                       
                }                               
        }
        DMA_Cmd(DMA1_Channel1, ENABLE);
        ADC_StartOfConversion(ADC1);
}
页: [1] 2 3 4 5
查看完整版本: DMA 传输一半中断