STM32F103C8T6的ADC1和ADC2同步采样

本文从21ic上转载http://bbs.21ic.com/icview-1609452-1-3.html

 程序1 根据官方例子写的:

  1. #include"adc.h"
  2.  
  3. __IO uint32_t ADC_DualConvertedValueTab[ADC_BufferLength];
  4. void ADC1_2_Init(void)
  5. {
  6. ADC_InitTypeDef ADC_InitStructure;
  7. DMA_InitTypeDef DMA_InitStructure; 
  8. GPIO_InitTypeDef GPIO_InitStructure;
  9.  
  10. RCC_ADCCLKConfig(RCC_PCLK2_Div4);
  11. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
  12. RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2 | RCC_APB2Periph_GPIOA, ENABLE);
  13.  
  14. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_4;
  15. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  16. GPIO_Init(GPIOA, &GPIO_InitStructure);
  17.  
  18. DMA_DeInit(DMA1_Channel1);                                                   //DMA通道1恢复到默认状态
  19. DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address;        //设置数据来源地址
  20. DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_DualConvertedValueTab;  //设置copy目标地址
  21. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;                           //设置copy方向
  22. DMA_InitStructure.DMA_BufferSize = 16;                                       //设置数组大小
  23. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;             //数据来源不变
  24. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                      //数据保存的数组地址自增
  25. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;      //DMA操作字长 32位
  26. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;              //DMA操作字长 32位
  27. DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                                //普通的DMA操作模式:当DMA操作转移够 数组大小                                                                                 //所限定的数据总量后,则不再进行DMA操作
  28. DMA_InitStructure.DMA_Priority = DMA_Priority_High;                          //DMA优先级
  29. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                                 //关闭mTM
  30. DMA_Init(DMA1_Channel1, &DMA_InitStructure);                                 //使能dma
  31. /* Enable DMA1 Channel1 */
  32. DMA_Cmd(DMA1_Channel1, ENABLE);
  33.  
  34. /* ADC1 configuration ------------------------------------------------------*/
  35. ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;                              //ADC1同步规则组模式
  36. ADC_InitStructure.ADC_ScanConvMode = ENABLE;                                  //启动扫描
  37. ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;                            //连续转换
  38. ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;           //无外部触发
  39. ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;                        //结果右对齐
  40. ADC_InitStructure.ADC_NbrOfChannel = 1;                                       //转换通道数2
  41. ADC_Init(ADC1, &ADC_InitStructure);                                           //配置ADC1
  42. /* ADC1 regular channels configuration */ 
  43. ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5); //通道配置    
  44. /* Enable ADC1 DMA */
  45. ADC_DMACmd(ADC1, ENABLE); 
  46.  
  47. /* ADC2 configuration ------------------------------------------------------*/
  48. ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;                              //ADC2同步规则组模式
  49. ADC_InitStructure.ADC_ScanConvMode = ENABLE;                                  //启动扫描
  50. ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;                            //连续转换
  51. ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;           //无外部触发
  52. ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;                        //结果右对齐
  53. ADC_InitStructure.ADC_NbrOfChannel = 1;                                       //转换通道数
  54. ADC_Init(ADC2, &ADC_InitStructure);                                           //配置ADC2
  55. /* ADC2 regular channels configuration */ 
  56. ADC_RegularChannelConfig(ADC2, ADC_Channel_4, 1, ADC_SampleTime_239Cycles5); //通道配置
  57. /* Enable ADC2 external trigger conversion */
  58. ADC_ExternalTrigConvCmd(ADC2, ENABLE);                                        //使能ADC2的外部触发模式 
  59.  
  60.  
  61. /* Enable ADC1 */
  62. ADC_Cmd(ADC1, ENABLE);                                                        //使能ADC1
  63. /* Enable Vrefint channel17 */
  64. // ADC_TempSensorVrefintCmd(ENABLE);                                             // 使能温度传感器内部参考电压通道
  65.  
  66. /* Enable ADC1 reset calibration register */   
  67. ADC_ResetCalibration(ADC1);                                                   //ADC1的校准 
  68. /* Check the end of ADC1 reset calibration register */
  69. while(ADC_GetResetCalibrationStatus(ADC1));
  70.  
  71. /* Start ADC1 calibration */
  72. ADC_StartCalibration(ADC1);
  73. /* Check the end of ADC1 calibration */
  74. while(ADC_GetCalibrationStatus(ADC1));
  75.  
  76. /* Enable ADC2 */
  77. ADC_Cmd(ADC2, ENABLE);                                                      //使能ADC2
  78.  
  79. /* Enable ADC2 reset calibration register */   
  80. ADC_ResetCalibration(ADC2);                                                 //ADC2的校准
  81. /* Check the end of ADC2 reset calibration register */
  82. while(ADC_GetResetCalibrationStatus(ADC2));
  83.  
  84. /* Start ADC2 calibration */
  85. ADC_StartCalibration(ADC2);
  86. /* Check the end of ADC2 calibration */
  87. while(ADC_GetCalibrationStatus(ADC2));
  88.  
  89. /* Start ADC1 Software Conversion */                                        //软件启动ADC1,开始转换
  90. ADC_SoftwareStartConvCmd(ADC1, ENABLE);
  91.  
  92. /* Test on DMA1 channel1 transfer complete flag */                          //等待一组DMA存储转换完成
  93. while(!DMA_GetFlagStatus(DMA1_FLAG_TC1));
  94. /* Clear DMA1 channel1 transfer complete flag */
  95. DMA_ClearFlag(DMA1_FLAG_TC1);
  96. DMA_Done = 1;
  97. }
  98. 两个ADC采出来的数据存在32位数组ADC_DualConvertedValueTab[ADC_BufferLength]中,其中ADC1对应低16位,ADC2对应高16位。可通过以下程序读出:
  99. uint16_t adc1_val[1000];
  100. uint16_t adc2_val[1000];
  101. for(i=0;i<1000;i++)
  102. {
  103. adc1_val[i] = ADC_DualConvertedValueTab[i];
  104. adc2_val[i] = ADC_DualConvertedValueTab[i]>>16;
  105. }

 

程序2:用TIM3触发采样的程序,可以自己调用来设置采样率。

  1. void ADC1_2_Config(u16 SampleFreq,u16 DMA_BufferSizer)
  2. {
  3. ADC_InitTypeDef ADC_InitStructure;
  4. DMA_InitTypeDef DMA_InitStructure; 
  5. GPIO_InitTypeDef GPIO_InitStructure;
  6. TIM_TimeBaseInitTypeDef   TIM_TimeBaseStructure;
  7. NVIC_InitTypeDef NVIC_InitStructure;
  8.  
  9. RCC_ADCCLKConfig(RCC_PCLK2_Div2);
  10. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
  11. RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2, ENABLE);
  12. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  13. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
  14.  
  15. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_4;
  16. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  17. GPIO_Init(GPIOA, &GPIO_InitStructure);
  18.  
  19. //定时器3控制采样率
  20. TIM_TimeBaseStructure.TIM_Prescaler= 0;
  21. TIM_TimeBaseStructure.TIM_CounterMode= TIM_CounterMode_Up;
  22. TIM_TimeBaseStructure.TIM_Period= 72000000 / SampleFreq - 1;
  23. TIM_TimeBaseStructure.TIM_ClockDivision= 0;
  24. TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
  25. TIM_TimeBaseInit( TIM3, &TIM_TimeBaseStructure);
  26. TIM_SelectOutputTrigger( TIM3, TIM_TRGOSource_Update ); 
  27.  
  28. TIM_ARRPreloadConfig(TIM3,ENABLE);
  29. TIM_Cmd( TIM3, ENABLE );
  30.  
  31. DMA_DeInit(DMA1_Channel1);                                                   //DMA通道1恢复到默认状态
  32. DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address;        //设置数据来源地址
  33. DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_DualConvertedValueTab;  //设置copy目标地址
  34. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;                           //设置copy方向
  35. DMA_InitStructure.DMA_BufferSize = ADC_BufferLength;                                       //设置数组大小
  36. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;             //数据来源不变
  37. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                      //数据保存的数组地址自增
  38. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;      //DMA操作字长 32位
  39. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;              //DMA操作字长 32位
  40. DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                                //普通的DMA操作模式:当DMA操作转移够 数组大小                                                                                 //所限定的数据总量后,则不再进行DMA操作
  41. DMA_InitStructure.DMA_Priority = DMA_Priority_High;                          //DMA优先级
  42. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                                 //关闭mTM
  43. DMA_Init(DMA1_Channel1, &DMA_InitStructure);                                 //使能dma
  44. /* Enable DMA1 Channel1 */ 
  45.  
  46. DMA_Cmd(DMA1_Channel1, ENABLE);
  47.  
  48. /* DMA Transfer Complete Interrupt enable */
  49. NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;   //通道
  50. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //占先级
  51. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;        //响应级
  52. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;           //启动
  53. NVIC_Init(&NVIC_InitStructure);                           //初始化
  54.  
  55. DMA_ITConfig(DMA1_Channel1,DMA_IT_TC,ENABLE);
  56.  
  57.  
  58.  
  59. /* ADC1 configuration ------------------------------------------------------*/
  60. ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;                              //ADC1同步规则组模式
  61. ADC_InitStructure.ADC_ScanConvMode = ENABLE;                                  //启动扫描
  62. ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;                            //连续转换
  63. ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T3_TRGO;           //无外部触发
  64. ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;                        //结果右对齐
  65. ADC_InitStructure.ADC_NbrOfChannel = 1;                                       //转换通道数2
  66. ADC_Init(ADC1, &ADC_InitStructure);                                           //配置ADC1
  67. /* ADC1 regular channels configuration */ 
  68. ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_28Cycles5); //通道配置    
  69. /* Enable ADC1 DMA */
  70. ADC_DMACmd(ADC1, ENABLE); 
  71.  
  72. /* ADC2 configuration ------------------------------------------------------*/
  73. ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;                              //ADC2同步规则组模式
  74. ADC_InitStructure.ADC_ScanConvMode = ENABLE;                                  //启动扫描
  75. ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;                            //连续转换
  76. ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;           //无外部触发
  77. ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;                        //结果右对齐
  78. ADC_InitStructure.ADC_NbrOfChannel = 1;                                       //转换通道数
  79. ADC_Init(ADC2, &ADC_InitStructure);                                           //配置ADC2
  80. /* ADC2 regular channels configuration */ 
  81. ADC_RegularChannelConfig(ADC2, ADC_Channel_4, 1, ADC_SampleTime_28Cycles5); //通道配置
  82. /* Enable ADC2 external trigger conversion */
  83. ADC_ExternalTrigConvCmd(ADC2, ENABLE);                                        //使能ADC2的外部触发模式 
  84.  
  85.  
  86. /* Enable ADC1 */
  87. ADC_Cmd(ADC1, ENABLE);                                                        //使能ADC1
  88. /* Enable Vrefint channel17 */
  89. // ADC_TempSensorVrefintCmd(ENABLE);                                             // 使能温度传感器内部参考电压通道
  90.  
  91. /* Enable ADC1 reset calibration register */   
  92. ADC_ResetCalibration(ADC1);                                                   //ADC1的校准 
  93. /* Check the end of ADC1 reset calibration register */
  94. while(ADC_GetResetCalibrationStatus(ADC1));
  95.  
  96. /* Start ADC1 calibration */
  97. ADC_StartCalibration(ADC1);
  98. /* Check the end of ADC1 calibration */
  99. while(ADC_GetCalibrationStatus(ADC1));
  100.  
  101. /* Enable ADC2 */
  102. ADC_Cmd(ADC2, ENABLE);                                                      //使能ADC2
  103.  
  104. /* Enable ADC2 reset calibration register */   
  105. ADC_ResetCalibration(ADC2);                                                 //ADC2的校准
  106. /* Check the end of ADC2 reset calibration register */
  107. while(ADC_GetResetCalibrationStatus(ADC2));
  108.  
  109. /* Start ADC2 calibration */
  110. ADC_StartCalibration(ADC2);
  111. /* Check the end of ADC2 calibration */
  112. while(ADC_GetCalibrationStatus(ADC2));
  113.  
  114. /* Start ADC1 Software Conversion */                                        //软件启动ADC1,开始转换
  115. ADC_SoftwareStartConvCmd(ADC1, ENABLE); 
  116. // while(!DMA_GetFlagStatus(DMA1_FLAG_TC1));
  117. // /* Clear DMA1 channel1 transfer complete flag */
  118. // DMA_ClearFlag(DMA1_FLAG_TC1);
  119. // DMA_Done = 1;
  120. }
  121. void DMA1_Channel1_IRQHandler(void)
  122. {
  123. if(DMA_GetITStatus(DMA1_IT_TC1) != RESET)
  124. {
  125. DMA_ClearITPendingBit(DMA1_IT_TC1);
  126. DMA_ITConfig(DMA1_Channel1,DMA_IT_TC,DISABLE);
  127. ADC_Cmd(ADC1,DISABLE); 
  128. ADC_Cmd(ADC2,DISABLE); 
  129. DMA_Done =1; 
  130. }
  131. }

你可能感兴趣的:(STM32F103C8T6的ADC1和ADC2同步采样)