原创 STM32 动态改变ADC采样通道

2020-12-25 14:56 6167 32 8 分类: MCU/ 嵌入式 文集: STM32 软件
使用DMA 进行AD采样很方便,但需要事先设置好通道。如果有过程中希望修改通道,可以先做一个DeInit 然后设置不同的Rank

  1. // Adc 通道配置 选择 vdc vbat preu pred
  2. void ADC1_misc_Init(void)
  3. {
  4. ADC_ChannelConfTypeDef sConfig;
  5. HAL_ADC_DeInit(&hadc1);
  6. /**Common config
  7. */
  8. hadc1.Instance = ADC1;
  9. hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
  10. hadc1.Init.ContinuousConvMode = ENABLE;
  11. hadc1.Init.DiscontinuousConvMode = DISABLE;
  12. hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  13. hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  14. hadc1.Init.NbrOfConversion = 4;
  15. if (HAL_ADC_Init(&hadc1) != HAL_OK)
  16. {
  17. _Error_Handler(__FILE__, __LINE__);
  18. }
  19. /**Configure Regular Channel
  20. */
  21. sConfig.Channel = ADC_CHANNEL_12; // bdc
  22. sConfig.Rank = ADC_REGULAR_RANK_1;
  23. sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
  24. if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  25. {
  26. _Error_Handler(__FILE__, __LINE__);
  27. }
  28. /**Configure Regular Channel
  29. */
  30. sConfig.Channel = ADC_CHANNEL_13; // vbat
  31. sConfig.Rank = ADC_REGULAR_RANK_2;
  32. if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  33. {
  34. _Error_Handler(__FILE__, __LINE__);
  35. }
  36. /**Configure Regular Channel
  37. */
  38. sConfig.Channel = ADC_CHANNEL_1; // preu
  39. sConfig.Rank = ADC_REGULAR_RANK_3;
  40. if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  41. {
  42. _Error_Handler(__FILE__, __LINE__);
  43. }
  44. /**Configure Regular Channel
  45. */
  46. sConfig.Channel = ADC_CHANNEL_7; // pred
  47. sConfig.Rank = ADC_REGULAR_RANK_4;
  48. if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  49. {
  50. _Error_Handler(__FILE__, __LINE__);
  51. }
  52. }
  53. // adc1 通道配置 bub pos
  54. void ADC1_ir_Init(void)
  55. {
  56. ADC_ChannelConfTypeDef sConfig;
  57. HAL_ADC_DeInit(&hadc1);
  58. /**Common config
  59. */
  60. hadc1.Instance = ADC1;
  61. hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
  62. hadc1.Init.ContinuousConvMode = ENABLE;
  63. hadc1.Init.DiscontinuousConvMode = DISABLE;
  64. hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  65. hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  66. hadc1.Init.NbrOfConversion = 2;
  67. if (HAL_ADC_Init(&hadc1) != HAL_OK)
  68. {
  69. _Error_Handler(__FILE__, __LINE__);
  70. }
  71. /**Configure Regular Channel
  72. */
  73. sConfig.Channel = ADC_CHANNEL_5; // position
  74. sConfig.Rank = ADC_REGULAR_RANK_1;
  75. sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
  76. if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  77. {
  78. _Error_Handler(__FILE__, __LINE__);
  79. }
  80. /**Configure Regular Channel
  81. */
  82. sConfig.Channel = ADC_CHANNEL_6; // bubble
  83. sConfig.Rank = ADC_REGULAR_RANK_2;
  84. if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  85. {
  86. _Error_Handler(__FILE__, __LINE__);
  87. }
  88. }

在启动转换时,依据设置的通道数,选择不同的DMA空间
  1. void StartADC1Misc(void){
  2. HAL_ADC_Start_DMA(&hadc1, ADC1Buf.ValMem,ADCCNT*4);
  3. }
  4. void StartADC1IR(void){
  5. HAL_ADC_Start_DMA(&hadc1, IRBuf.ValMem,ADCCNT*2);
  6. }

获取采样值的时候,找到对应的缓冲区
  1. uint32_t AdcGetValue(uint8_t ch){
  2. uint32_t temp,i;
  3. temp = 0;
  4. for(i = ADCCNT/2-5;i< ADCCNT/2+5;i++){
  5. temp = temp+ (ADC1Buf.Val[i][ch]&0xFFF);
  6. }
  7. temp /= 10;
  8. return temp;
  9. }
  10. uint32_t AdcGetIRValue(uint8_t ch){
  11. uint32_t temp,i;
  12. temp = 0;
  13. for(i = ADCCNT/2-5;i< ADCCNT/2+5;i++){
  14. temp = temp+ (IRBuf.Val[i][ch]&0xFFF);
  15. }
  16. temp /= 10;
  17. return temp;
  18. }

作者: southcreek, 来源:面包板社区

链接: https://mbb.eet-china.com/blog/uid-me-408807.html

版权声明:本文为博主原创,未经本人允许,禁止转载!

文章评论2条评论)

登录后参与讨论

southcreek 2021-1-17 07:38

冰点1128: 嗯,我一般都是一次采样N个通道,然后到DMA的地址查看.曾经有一段时间看AD的资料,才知道它有注入组,规则组.
这两个组是有不同的功能,参见正点原子的说明.说的很详 ...
这个还真没注意到,分注入组和规则组。

冰点1128 2021-1-4 17:53

嗯,我一般都是一次采样N个通道,然后到DMA的地址查看.曾经有一段时间看AD的资料,才知道它有注入组,规则组.
这两个组是有不同的功能,参见正点原子的说明.说的很详细.
相关推荐阅读
southcreek 2024-12-04 16:32
PWM输出隔离DAC设计
这个设计的目标是产生一个隔离的DAC输出。12V供电,产生0~5V的输出。达到10000约13.3位的分辨率。要求DAC输出在改变设置后1S内能稳定。需要能长时间保持稳定和低噪声。能达到要求的DAC只...
southcreek 2024-12-04 15:23
一个基于HAL库的串口控制框架
将串口接收配置为 DMA方式,DMA 使用 DMA_CIRCULAR 模式工作。串口接收的数据实际上构成循环队列。 定义一个结构Comm_typedef 结构体中包含指向接收到的第一字节位置chrc...
southcreek 2024-07-08 11:38
接地不良导致的故障分析
这个电路的控制板需要连接显示板和识别板。5V 供电和串行控制连到显示板,显示板再连接到识别板。识别板上电位器使用一个LDO供电,将输入的5V转成3.3V。当电位器滑动时,输出电压在0~3.3V之间。...
southcreek 2024-06-26 09:15
【EMC整改】带辅助加热的滴速控制器辐射抗扰整改
这个滴速式的输液泵使用一个红外线发射和接收装置,当有液滴通过时,会扰动检测信号,识别这个扰动检测到液滴滴下,获得滴壶中的液滴速度,调整阀门大小,实现输液速度控制。控制器还配备一根加热条,用于输液时对药...
southcreek 2024-06-06 08:52
QT 使用QSettings 操作ini文件配合表格操作
这个项目可以演示 使用QSetting 读取或写入 ini文件。并使用tablewidget 显示。Ini文件的格式如下,这个文件可以事先编写。也可以在程序中生成。有一个大类,下面有一个小类使用等号设...
southcreek 2024-05-27 16:18
差分输入ADC的单端到差分转换器驱动设计
单端信号需要转换成差分信号,以便使用ADC进行转换。这个就所谓的ADC驱动电路。需要的结果为Vp = Vcm + Vi/2Vn = Vcm – Vi/2这样 Vp – Vn = Vi使用简单的加法器和...
我要评论
2
32
关闭 站长推荐上一条 /2 下一条