STM32 ADC同步規則模式(3ADC)
1 #define ADC_CHANNEL_SAMPLE_TIME 2 u32 Temp; 3 4 //右牆RX:----------------PA0----------23---------ADC1->0 ADC采集 5 //左跳崖RX:------------PA1----------24-----------ADC1->CH1 ADC采集 6 //右跳崖RX:------------PA2----------25-----------ADC1->CH2 ADC采集 7 //Hardware:--------------PA3----------26---------ADC1->CH3 ADC采集 8 //中左跳崖RX:----------PA4----------29-----------ADC1->CH4 ADC采集 9 //中免碰RX:------------PA5----------30-----------ADC1->CH5 10 //左免碰RX:------------PA6----------31-----------ADC1->CH6 11 //右免碰RX:------------PA7----------32-----------ADC1->CH7 12 //中右跳崖RX:----------PB0----------35--------- ADC1->CH8 ADC采集 13 //MUX_Y:------------------PB1----------36---------ADC1->CH9 ADC采集 14 //右刷電流檢測:--------PC0----------15-----------ADC1->CH10 ADC采集 15 //主刷電流檢測:--------PC1----------16-----------ADC3->CH11 ADC采集 16 //左牆RX:----------------PC2----------17---------ADC1->12 ADC采集 17 //主左輪電流檢測:------PC3----------18-----------ADC1->CH13 ADC采集 18 //主右輪電流檢測:------PC4----------33-----------ADC1->CH14 ADC采集 19 //左刷電流檢測:--------PC5----------34-----------ADC1->CH15 ADC采集 20 21 22 23 24 void ADCDMAInitForIR(void) 25 { 26 ADC_InitTypeDef ADC_InitStructure; 27 DMA_InitTypeDef DMA_InitStructure; 28 NVIC_InitTypeDef NVIC_InitStructure; 29 30 memset((void *)(&uwADCValue), 0, sizeof(uwADCValue)); //數組初始化 31 RCC_ADCCLKConfig(RCC_PCLK2_Div6); //最大時鍾不能超過14M 本項目中的頻率為12M 32 33 //DMA Initiation 34 //ADC1_BASE==(APB2PERIPH_BASE + 0x2400)ADC1是掛在APB2總線上,ADC1在APB2上偏移0x2400 35 //APB2PERIPH_BASE==(PERIPH_BASE + 0x10000)//APB2總線地址 36 //PERIPH_BASE==((uint32_t)0x40000000) 37 //0x40012400+0x4c 0x4C是DR寄存器的偏移 38 DMA_DeInit(DMA1_Channel1);//DMA1通道1 39 DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_BASE + 0x4C; //ADC數據寄存器的地址 寄存器里面存儲的值時16位 40 DMA_InitStructure.DMA_MemoryBaseAddr = (u32)uwADCValue; //內存首地址uwADCValue[15][16] 15是采集次數,16是通道數 41 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; // 外設 -> 內存 42 43 //每次傳輸的數據的字節數480*2(15次*16通道*4每次傳輸4字節)個字節,傳輸完時觸發中斷 44 DMA_InitStructure.DMA_BufferSize = MAX_ADC_SAMPLE_TIMES*ADC_SAMPLE_SUB_SUM;//設置DMA在傳輸時緩沖區的長度 15 * 16 這個和數組uwADCValue[15][16]大小一致 45 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; //內存數據寬度(雙ADC模式下,ADC_DR是32位都使用的) 46 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;//設置DMA在訪問時每次操作的數據長度 以32位為單位進行數據的傳輸(高16位是ADC2,低16位是ADC1) 47 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外設地址固定 48 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //內存地址自增 49 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //循環傳輸的方式,這里必須為循環傳輸方式,否則會導致DMA只能傳輸一次 50 DMA_InitStructure.DMA_Priority = DMA_Priority_High; //當多路DMA通道同時用的時候會用到,將決定先處理那個通道的數據 51 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //設置DMA的2個memory中的變量互相訪問的 失能內存到內存的傳輸方式 52 DMA_Init(DMA1_Channel1, &DMA_InitStructure); 53 DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE); //DMA通道1傳輸完成中斷,如果有這句話,則當傳輸完成的時候會產生中斷,如果屏蔽掉這句話 54 DMA_Cmd(DMA1_Channel1, ENABLE); //那么傳輸完成的時候,不會產生中斷 55 56 //NVIC 配置DMA通道 57 NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn; 58 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 59 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; 60 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; 61 NVIC_Init(&NVIC_InitStructure); 62 63 ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult; //regular mode 雙ADC同步規則模式 64 ADC_InitStructure.ADC_ScanConvMode = ENABLE; //打開掃描模式,由於這里有16個通道要采集,所以開始用掃描模式 65 ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //連續轉換開啟(所有數據傳輸完才停止) 66 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//軟件觸發 ADC_SoftwareStartConvCmd(ADC1, ENABLE);//軟件觸發一定要調用這個語句 67 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; 68 ADC_InitStructure.ADC_NbrOfChannel = ADC_SAMPLE_SUB_SUM; //16通道 69 ADC_Init(ADC1, &ADC_InitStructure); 70 71 72 //------------------------滾刷電流采集 ADC3->CH11 DMA2->CH5 73 //--------ADC->DR(16位)-------DMA--------長度為60的buff 74 #ifdef ROLLER_CURRENT_CHECK_IN_ADC3 75 //==================== ADC 3 =========================================== 76 //NVIC 配置DMA通道 77 NVIC_InitStructure.NVIC_IRQChannel = DMA2_Channel4_5_IRQn; 78 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 79 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; 80 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; 81 NVIC_Init(&NVIC_InitStructure); 82 83 //DMA Initiation 84 DMA_DeInit(DMA2_Channel5);//DMA2通道5 85 DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&(ADC3->DR); //ADC數據寄存器的地址 寄存器里面存儲的值時16位 86 DMA_InitStructure.DMA_MemoryBaseAddr = (u32)uwADC3Value; //u16 uwADC3Value[60]; 87 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; // 外設 -> 內存 88 89 //這里占用了120(60次*1個通道*2每次傳輸兩個字節)個字節 90 DMA_InitStructure.DMA_BufferSize = MAX_ADC3_SAMPLE_TIMES; //采集60次 91 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外設地址固定 92 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //內存地址自增 93 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//半字傳輸 94 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//半字傳輸 95 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // DMA_Mode_Normal; 96 DMA_InitStructure.DMA_Priority = DMA_Priority_High; //當多路DMA通道同時用的時候會用到,將決定先處理那個通道的數據 97 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //設置DMA的2個memory中的變量互相訪問的 失能 98 99 DMA_Init(DMA2_Channel5, &DMA_InitStructure); 100 DMA_ITConfig(DMA2_Channel5, DMA_IT_TC, ENABLE); 101 DMA_Cmd(DMA2_Channel5, ENABLE); 102 103 104 ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//獨立模式 105 ADC_InitStructure.ADC_ScanConvMode = DISABLE;//只有一個通道,不掃描 106 ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //連續轉換開啟 DISABLE 107 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//軟件觸發 108 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; 109 ADC_InitStructure.ADC_NbrOfChannel = 1; //1個通道 110 ADC_Init(ADC3, &ADC_InitStructure); 111 112 ADC_RegularChannelConfig(ADC3, ADC_Channel_11, 1, ADC_SampleTime_7Cycles5);//主刷電流檢測:--------PC1----------16-----------ADC3->CH11 ADC采集 113 ADC_Cmd(ADC3, ENABLE); 114 ADC_DMACmd(ADC3, ENABLE); 115 __nop(); 116 __nop(); 117 __nop(); 118 __nop(); //at least two ADC clock cycles Before starting a calibration, 119 ADC_ResetCalibration(ADC3); //calibration for first time 120 while(ADC_GetCalibrationStatus(ADC3)); 121 122 ADC_StartCalibration(ADC3); //calibration for second time 123 while(ADC_GetCalibrationStatus(ADC3)); 124 ADC_SoftwareStartConvCmd(ADC3, ENABLE);//軟件觸發一定要調用這個語句 125 //軟件觸發----不定時任意時刻的采集信號 126 #endif 127 128 129 130 131 132 133 134 //============================================================================== 135 ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;//ADC同步規則模式 136 ADC_InitStructure.ADC_ScanConvMode = ENABLE;//掃描模式 137 ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //連續轉換開啟 DISABLE 138 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//軟件觸發 139 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; 140 ADC_InitStructure.ADC_NbrOfChannel = ADC_SAMPLE_SUB_SUM; //16通道的 141 ADC_Init(ADC2, &ADC_InitStructure); 142 /* Enable ADC2 external trigger conversion */ 143 ADC_ExternalTrigConvCmd(ADC2, ENABLE);//規則通道的外部觸發轉換模式必須開啟(雙ADC下,軟件啟動的時候也要) 144 145 ADC_TempSensorVrefintCmd(ENABLE);//開啟溫度傳感器及 Vref 通道 146 147 148 //采樣時間7.5個周期 轉換時間7.5+12.5個周期 T=1/12M*20=1.67us 16個通道總共要轉換時間為26.667us 149 //周期越長采樣后的值越精確 最大轉換時間為17.21us 150 //ADC1采樣配置 151 ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_CHANNEL_SAMPLE_TIME);//右牆RX:-------PA0----------23---------ADC1->0 ADC采集 152 ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_CHANNEL_SAMPLE_TIME);//左跳崖RX:-----PA1----------24-----------ADC1->CH1 ADC采集 153 ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_CHANNEL_SAMPLE_TIME);//右跳崖RX:-----PA2----------25-----------ADC1->CH2 ADC采集 154 ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_CHANNEL_SAMPLE_TIME);//Hardware:-----PA3----------26---------ADC1->CH3 ADC采集 155 ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 5, ADC_CHANNEL_SAMPLE_TIME);//中左跳崖RX:---PA4----------29-----------ADC1->CH4 ADC采集 156 ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 6, ADC_CHANNEL_SAMPLE_TIME);//中免碰RX:-----PA5----------30-----------ADC1->CH5 157 ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 7, ADC_CHANNEL_SAMPLE_TIME);//左免碰RX:-----PA6----------31-----------ADC1->CH6 158 ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 8, ADC_CHANNEL_SAMPLE_TIME);//右免碰RX:-----PA7----------32-----------ADC1->CH7 159 ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 9, ADC_CHANNEL_SAMPLE_TIME);//中右跳崖RX:---PB0----------35--------- ADC1->CH8 ADC采集 160 ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 10, ADC_CHANNEL_SAMPLE_TIME);//MUX_Y:--------PB1----------36---------ADC1->CH9 ADC采集 161 ADC_RegularChannelConfig(ADC1, ADC_Channel_10,11, ADC_CHANNEL_SAMPLE_TIME);//右刷電流檢測:PC0----------15-----------ADC1->CH10 ADC采集 162 //ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 12, ADC_CHANNEL_SAMPLE_TIME);//滾刷電流,ADC3采集 163 ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 13, ADC_CHANNEL_SAMPLE_TIME);//左牆RX:------PC2----------17---------ADC1->12 ADC采集 164 ADC_RegularChannelConfig(ADC1, ADC_Channel_13, 14, ADC_CHANNEL_SAMPLE_TIME);//主左輪電流檢測:--PC3----------18-----ADC1->CH13 ADC采集 165 ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 15, ADC_CHANNEL_SAMPLE_TIME);//主右輪電流檢測:--PC4----------33-----ADC1->CH14 ADC采集 166 ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 16, ADC_CHANNEL_SAMPLE_TIME);//左刷電流檢測:----PC5----------34-----ADC1->CH15 ADC采集 167 168 //ADC2采樣配置 169 //各路采集通道順序要和ADC1相反,不允許ADC1和ADC2同時進行采集同一個通道 170 //雙ADC模式,ADC1,2同時采樣,低16位放ADC1的數據,高16位放ADC2的數據 171 ADC_RegularChannelConfig(ADC2, ADC_Channel_0, 16, ADC_CHANNEL_SAMPLE_TIME); 172 ADC_RegularChannelConfig(ADC2, ADC_Channel_1, 15, ADC_CHANNEL_SAMPLE_TIME); 173 ADC_RegularChannelConfig(ADC2, ADC_Channel_2, 14, ADC_CHANNEL_SAMPLE_TIME);//ADC_SampleTime_7Cycles5); //免碰發射是16ms關2ms開 174 ADC_RegularChannelConfig(ADC2, ADC_Channel_3, 13, ADC_CHANNEL_SAMPLE_TIME); 175 ADC_RegularChannelConfig(ADC2, ADC_Channel_4, 12, ADC_CHANNEL_SAMPLE_TIME); 176 ADC_RegularChannelConfig(ADC2, ADC_Channel_5, 11, ADC_CHANNEL_SAMPLE_TIME); 177 ADC_RegularChannelConfig(ADC2, ADC_Channel_6, 10, ADC_CHANNEL_SAMPLE_TIME); 178 ADC_RegularChannelConfig(ADC2, ADC_Channel_7, 9, ADC_CHANNEL_SAMPLE_TIME); 179 ADC_RegularChannelConfig(ADC2, ADC_Channel_8, 8, ADC_CHANNEL_SAMPLE_TIME); 180 ADC_RegularChannelConfig(ADC2, ADC_Channel_9, 7, ADC_CHANNEL_SAMPLE_TIME); 181 ADC_RegularChannelConfig(ADC2, ADC_Channel_10,6, ADC_CHANNEL_SAMPLE_TIME); 182 //ADC_RegularChannelConfig(ADC2, ADC_Channel_10, 5, ADC_CHANNEL_SAMPLE_TIME);//滾刷電流,ADC3采集 183 ADC_RegularChannelConfig(ADC2, ADC_Channel_12, 4, ADC_CHANNEL_SAMPLE_TIME); 184 ADC_RegularChannelConfig(ADC2, ADC_Channel_13, 3, ADC_CHANNEL_SAMPLE_TIME); 185 ADC_RegularChannelConfig(ADC2, ADC_Channel_14, 2, ADC_CHANNEL_SAMPLE_TIME); 186 ADC_RegularChannelConfig(ADC2, ADC_Channel_15, 1, ADC_CHANNEL_SAMPLE_TIME); 187 188 //ADC1開啟采樣 189 ADC_Cmd(ADC1, ENABLE); 190 ADC_DMACmd(ADC1, ENABLE); 191 192 193 //ADC1校准 194 ADC_ResetCalibration(ADC1); 195 while(ADC_GetResetCalibrationStatus(ADC1)); 196 ADC_StartCalibration(ADC1); //calibration for first time 197 while(ADC_GetCalibrationStatus(ADC1)); 198 199 //ADC2開啟采樣 200 ADC_Cmd(ADC2,ENABLE);//ADC2不能觸發DMA, 在雙ADC同步規則模式下,ADC1開啟DMA即可 201 202 //ADC2校准 203 ADC_ResetCalibration(ADC2); 204 while(ADC_GetResetCalibrationStatus(ADC2)); 205 ADC_StartCalibration(ADC2); //calibration for first time 206 while(ADC_GetCalibrationStatus(ADC2)); 207 208 ADC_SoftwareStartConvCmd(ADC1, ENABLE);//ADC1軟件觸發使能 209 }