你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

DMA 传输一半中断

[复制链接]
飞儿 提问时间:2016-11-7 10:57 /
初始化我这样配置
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中断是一样的。问题:传输一半中断是不是不能实现?





收藏 2 评论44 发布时间:2016-11-7 10:57

举报

44个回答
废鱼 最优答案 回答时间: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

评分

参与人数 1ST金币 +2 收起 理由
zero99 + 2

查看全部评分

废鱼 最优答案 回答时间:2016-11-10 15:38:49
我用的是103测试的。楼主可以看一下。
103_test.rar (3.12 MB, 下载次数: 107)
anobodykey 回答时间:2016-11-7 11:34:09
不清楚你的DMA测试是测试的单次还是连续测试的,但是我觉得你得多看下手册,TC标识是由硬件触发的,因此不管你有没有使能TC中断,只要发送完成,TC标识就会置位,只是它不触发中断,如果你DMA只测试了一次应该是不会执行你中断里面的条件语句,如果是多次DMA测试我想的确是会进的吧,不晓得分析的对不对。

评分

参与人数 1ST金币 +2 收起 理由
zero99 + 2

查看全部评分

飞儿 回答时间:2016-11-11 17:22:06
安 发表于 2016-11-10 15:38
我用的是103测试的。楼主可以看一下。

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

点评

感謝解惑!!  发表于 2017-10-27 17:36
五哥1 回答时间:2016-11-8 11:24:22
根据楼主的情况,结合以往,绝大多数的问题都是提出问题的楼主自行解决的,因为所有发言的人都是在你提供的非常有限的信息里凭经验猜。这个猜,或许能给你一些启发,最终解决问题的还是你自己。

评分

参与人数 1ST金币 +2 收起 理由
zero99 + 2

查看全部评分

废鱼 回答时间:2016-11-7 14:09:54
楼主可以测试一下,当中断产生时,看一下DMA的中断寄存器的值。
飞儿 回答时间: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
二楼回复,楼主说的很有火药味啊,大家都不敢发言了。
飞儿 回答时间:2016-11-7 14:15:15
高二毛 发表于 2016-11-7 13:59
二楼回复,楼主说的很有火药味啊,大家都不敢发言了。

火药味重了就不敢发言吗?总是唯唯诺诺,遇事害怕,怎么会有出息,有本事就把问题解决,我就服你
飞儿 回答时间:2016-11-7 15:55:50
安 发表于 2016-11-7 14:09
楼主可以测试一下,当中断产生时,看一下DMA的中断寄存器的值。

看了,TC 和 HT中断标志一起产生,而且每次中断都是DMA全部传输完成中断,根本就不是传输一半中断。最后没办法在中断里面做了个动作,buff总共大小500,结果每次都跳进if里面   说明每次整个buff都被更新了
               if((RegularConvData_Tab[0]!=0xff)&&(RegularConvData_Tab[499]!=0xff))
                {
                        RegularConvData_Tab[0]=0xff;
                }               
                RegularConvData_Tab[499]=0xff;
                RegularConvData_Tab[0]=0xff;
废鱼 回答时间:2016-11-7 15:58:24
楼主用的哪个CPU。
飞儿 回答时间:2016-11-7 16:02:13
安 发表于 2016-11-7 15:58
楼主用的哪个CPU。

STM32F072C8
飞儿 回答时间: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[0]=0xff;
        RegularConvData_Tab[499]=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[0]!=0xff)&&(RegularConvData_Tab[499]!=0xff))
                {
                        Errno=1;
                }               
                RegularConvData_Tab[499]=0xff;
                RegularConvData_Tab[0]=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);
}
废鱼 回答时间:2016-11-7 16:03:56
楼主,代码中没有判断HT的状态,也就是HT的状态也就没有被清除掉,加上HT的判断,是不是在传输一半是产生中断。
飞儿 回答时间:2016-11-7 16:04:54
安 发表于 2016-11-7 15:58
楼主用的哪个CPU。

#define DMA_BUFF_SIZE      500
这是源码
飞儿 回答时间:2016-11-7 16:06:16
安 发表于 2016-11-7 16:03
楼主,代码中没有判断HT的状态,也就是HT的状态也就没有被清除掉,加上HT的判断,是不是在传输一半是产生中 ...

DMA_ClearITPendingBit(DMA1_IT_GL1);  这一句就是把 TC  HT TE三个DMA中断标志都清掉了
飞儿 回答时间:2016-11-7 16:06:33
安 发表于 2016-11-7 16:03
楼主,代码中没有判断HT的状态,也就是HT的状态也就没有被清除掉,加上HT的判断,是不是在传输一半是产生中 ...

DMA_ClearITPendingBit(DMA1_IT_GL1);  这一句就是把 TC  HT TE三个DMA中断标志都清掉了
废鱼 回答时间:2016-11-7 16:08:32
楼主想实现的是输出一半进行一次中断,传输完成产生一次中断,是吗?
进入中断后,不要先关闭DMA,等处理完最后关闭。先测试一下HT和TC是否能正常传输。
123下一页

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版