初始化我这样配置 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中断是一样的。问题:传输一半中断是不是不能实现? |
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
评分
查看全部评分
评分
查看全部评分
我明白了,我们的程序没问题。 是我误会了其中的意思了,半传输中断,只在DMA传输到一半时才产生。第一次中断是在传输了BUFF/2之时, 第二次中断也是在传输了BUFF/2之时。 两次中断间隔之间,其实传输了整个BUFF。 也就是说每中断一次需要的时间是传输整个BUFF的时间。也就是说TC中断时间=HT中断时间。
点评
评分
查看全部评分
手册里面是这么说的 the TC flag is set and an interrupt is generated if the TCIE bit is set。 到底是你熟悉还是我不熟悉,你自己看看
火药味重了就不敢发言吗?总是唯唯诺诺,遇事害怕,怎么会有出息,有本事就把问题解决,我就服你
看了,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;
STM32F072C8
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);
}
#define DMA_BUFF_SIZE 500
这是源码
DMA_ClearITPendingBit(DMA1_IT_GL1); 这一句就是把 TC HT TE三个DMA中断标志都清掉了
DMA_ClearITPendingBit(DMA1_IT_GL1); 这一句就是把 TC HT TE三个DMA中断标志都清掉了
进入中断后,不要先关闭DMA,等处理完最后关闭。先测试一下HT和TC是否能正常传输。