各位大佬?
? ? ? ?代碼目的? TIM4_CC4作為觸發(fā)單元? 周期性的觸發(fā)ADC1進行轉(zhuǎn)換? ?ADC1在觸發(fā)DMA1 把ADC1獲得的三個通道的數(shù)據(jù)送到一個數(shù)組中,傳送完成后觸發(fā)中斷。
? ? ? ?目前的進度和遇到的問題??
? ? ? ?1.TM4_CC4周期性的觸發(fā)ADC1進行轉(zhuǎn)換? 這一步已完成(開了ADC中斷,測試了下ADC中斷周期和TM4_CC4中斷周期同步)
? ? ? ?2.ADC1觸發(fā)DMA1_CH1傳輸數(shù)據(jù) 并觸發(fā)中斷(此步也完成 發(fā)送的三個通道adc數(shù)據(jù)也準確)
? ? ? ?3.雖然DMA1_CH1能進中斷? 但只能進一次? 具體代碼如下:
? ? ??
? ? ? ?TM4初始化
? ? ? ??
TIM4->CTLR1=1<<7;? ? ? ? ? ? //使能自動重裝載
TIM4->CTLR2=7<<4;? ? ? ? ? ? //比較通道4作為觸發(fā)輸出
TIM4->DMAINTENR=1<<8;? ? ? ? //允許比較4中斷
TIM4->PSC=4800;? ? ? ? ? ? ? //預分頻值
TIM4->ATRLR=400;? ? ? ? ? ? ?//20ms
TIM4->CTLR1|=1<<0;? ? ? ? ? ?//開啟定時器
TIM4->CCER=1<<12;? ? ? ? ? ? //開啟使能CC4輸出
TIM4->CHCTLR2=6<<12;? ? ? ? ?//翻轉(zhuǎn)REF4
TIM4->CH4CVR=200;
TIM4->DMAINTENR=1<<4;? ? ? ? //允許比較4中斷
? ? ? ?ADC初始化
? ? ? ??
? ? GPIO_InitTypeDef GPIO_InitStructure={0};
? ? ADC_InitTypeDef? ADC_InitStructure={0};
? ? RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1 , ENABLE ); //使能GPIOA時鐘和ADC
? ? RCC_ADCCLKConfig(RCC_PCLK2_Div8); //設置ADC時鐘分頻為6分頻
? ? GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_5|GPIO_Pin_7;? ?//
? ? GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //GPIO模式為模擬輸入
? ? GPIO_Init(GPIOA, &GPIO_InitStructure);
? ? ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;? //配置ADC為獨立模式
? ? ADC_InitStructure.ADC_ScanConvMode = ENABLE;? ? ? ? //多通道模式下開啟掃描模式
? ? ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;? //設置開啟連續(xù)轉(zhuǎn)換模式
? ? ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T4_CC4; //由T4_CC4觸發(fā)
? ? ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //設置ADC數(shù)據(jù)右對齊
? ? ADC_InitStructure.ADC_NbrOfChannel = 3;? ? ? ? ? ? ? ? //規(guī)則轉(zhuǎn)換的ADC通道的數(shù)目
? ? ADC_Init(ADC1, &ADC_InitStructure);? ? ? ? ? ? ? ? ? ? //根據(jù)ADC_InitStructure中指定的參數(shù)初始化ADC1寄存器
?
? ? ADC1->CTLR1|=1<<5;? ?//開啟ADC轉(zhuǎn)換結(jié)束中斷
? ? ADC1->CTLR2|=1<<20;? ? //開啟外部觸發(fā)功能
? ? ADC_Cmd(ADC1, ENABLE);? ? ? //使能ADC1
? ? ADC_ResetCalibration(ADC1); //重置ADC1校準寄存器。
? ? while(ADC_GetResetCalibrationStatus(ADC1)); //等待復位校準結(jié)束
? ? ADC_StartCalibration(ADC1); //開啟AD校準
? ? while(ADC_GetCalibrationStatus(ADC1));? ? ? //等待校準結(jié)束
? ? ADC_BufferCmd(ADC1, DISABLE); //disable buffer??
? ?DMA初始化
? ?
DMA_InitTypeDef DMA_InitStructure={0};
? ? RCC_AHBPeriphClockCmd( RCC_AHBPeriph_DMA1, ENABLE ); //使能開啟DMA時鐘
? ? DMA_DeInit(DMA1_Channel1); //復位DMA控制器
? ? DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&ADC1->RDATAR;? //配置外設地址為ADC數(shù)據(jù)寄存器地址
? ? DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_ConvertedValue; //配置存儲器地址為讀取ADC值地址
? ? DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;? ? ? ? ? ? ?//配置數(shù)據(jù)源為外設,即DMA傳輸方式為外設到存儲器
? ? DMA_InitStructure.DMA_BufferSize = 3;? ? ? ? ? ? ? ? ? ? ? //設置DMA數(shù)據(jù)緩沖區(qū)大小,此處設置為length
? ? DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//設置DMA外設遞增模式關閉
? ? DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;? ? ? ? ?//設置DMA存儲器遞增模式開啟
? ? DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //設置外設數(shù)據(jù)大小為半字,即兩個字節(jié)
? ? DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;? ? ? ? ?//設置存儲器數(shù)據(jù)大小為半字,即兩個字節(jié)
? ? DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;? ? ? ? ?//設置DMA模式為正常模式
? ? DMA_InitStructure.DMA_Priority = DMA_Priority_High; //設置DMA傳輸通道優(yōu)先級為高,當使用一 DMA通道時,優(yōu)先級設置不影響
? ? DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;? ? ? ? //因為此DMA傳輸方式為外設到存儲器,因此禁用存儲器到存儲器傳輸方式
? ? DMA_Init( DMA1_Channel1, &DMA_InitStructure );? ? ? //初始化DMA
? ? DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);? //使能DMA傳輸完成中斷
DMA_Cmd(DMA1_Channel1 , ENABLE);? //使能DMA
中斷配置部分
?
//NVIC->IENR[0]|=1<<27;? ? ? ? ? //開啟DMA中斷
? NVIC->IENR[1]|=1<<2;? ? ? ? ?//開啟ADC 34號中斷? ? ? ? ? ? ? ? ? ? ?DMA_CH1中斷號? 27? ?ADC1_2中斷號 34
? //NVIC->IENR[1]|=1<<14;? ? ? ? //允許TIM4中斷
DMA中斷處理部分
?
if(DMA_GetITStatus(DMA1_IT_TC1))
? ? ? ?{
? ? ? ? ? ?//printf("\r\n Enter DMA Interrupt \r\n");
?
? ? ? ? ? DMA_ClearITPendingBit(DMA1_IT_TC1); //清除全部中斷標志
? ?
? ? ? ?}