1. 程式人生 > 實用技巧 >15-STM32 ADC同步規則模式(3ADC)

15-STM32 ADC同步規則模式(3ADC)

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 }