初级会员

- 积分
- 145
- 金钱
- 145
- 注册时间
- 2017-7-25
- 在线时间
- 44 小时
|
5金钱
如题,原来整个系统运行是没问题的,然后在一次烧录之后程序就一直卡死了,程序本身并没有变。。。。。。(这个就很头疼)
debug了后发现进入了HardFault,使用show caller code查看后发现是在freertos的 taskSELECT_HIGHEST_PRIORITY_TASK();
主程序也发现一旦使用了DMA+ADC就会出现上述问题,如果加了DMA 程序会一直运行到freertos的任务调度那后才会死掉,希望大佬能帮忙看下问题在哪。。
下面附上DMA+ADC的代码:
void adcDMAInit(void)
{
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_ADC1, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
//gpio set
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
GPIO_Init(GPIOB, &GPIO_InitStructure);
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_BufferSize = 256; //cache size
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //send data direction
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //disable RAM to RAM
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&adValue; //target address
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //16-bit width
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //target address increase
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //cycle mode
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&ADC1->DR; //peripheral's address
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //16-bit width
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //unchange peripheral's address
DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA has high priority
DMA_Init(DMA1_Channel1,&DMA_InitStructure);
DMA_ITConfig(DMA1_Channel1,DMA_IT_TC,ENABLE); //enable DMA's interrupt
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
ADC_DeInit(ADC1);
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //right align
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_NbrOfChannel = dmaWays; //need to conver x channels
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_Init(ADC1, &ADC_InitStructure);
//2 channels
ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 1, ADC_SampleTime_55Cycles5);
// ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 2, ADC_SampleTime_55Cycles5);
ADC_DMACmd(ADC1,ENABLE);
ADC_Cmd(ADC1,ENABLE);
ADC_ResetCalibration(ADC1); //start the reseting of the calibration
while(ADC_GetResetCalibrationStatus(ADC1)); //waiting for reseting the calibration
ADC_StartCalibration(ADC1); //start the calibration
while(ADC_GetCalibrationStatus(ADC1)); //waiting for calibration
DMA_Cmd(DMA1_Channel1,ENABLE); //until ADC already setted, enable the DMA
ADC_SoftwareStartConvCmd(ADC1,ENABLE); //start ADC's auto-converion
}
void DMA1_Channel1_IRQHandler(void)
{
u16 i,j;
u32 sum = 0;
if(DMA_GetITStatus(DMA1_IT_TC1) != RESET)
{
DMA_ClearITPendingBit(DMA1_IT_TC1);
for(j=0;j<dmaWays;j++)
{
sum = 0;
for(i=j;i<128*dmaWays;i+=dmaWays)
{
sum += adValue[i];
}
averValue[j] = ((sum>>7)*33)>>12;
}
}
}
|
最佳答案
查看完整内容[请看2#楼]
把DMA中断优先级调到5至15这个范围,我记得FreeRTOS可管理 的中断是在这个范围。同时在DMA中断中不要有太多处理,定义一个事件标志组来处理。同时 你的DMA应该数据处理,要注意把你的任务堆栈大小改大一点,避免任务切换时溢出,这样同样会进入HardFault。这个情况我遇到 过。
|