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 }