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

2020-12-25 14:56 1630 12 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 2021-03-02 10:42
BUCK DC-DC 开关管占空比为什么不能是 100%
  buck dc-dc 或 step-down dc-dc 经常使用。在给电池充电时,有的时候希望DC-DC能像LDO一样输入输出低压差。但实际上能做到的几乎没有。  原因在于开...
southcreek 2021-02-04 09:02
单片机矢量图形显示方法.
罗昊 摘要 使用图形界面会提高产品的外观及操作便利性,而图形数据需要占用大量的存储空间。对比按像素方式与矢量方式图像。将图形矢量化存储能节省空间。使用SVG格式将图形编码存储,顺序解析矢量图形...
southcreek 2021-01-21 15:41
N76E003 使用bandgap测量供电电压
N76E003 可以使用单节锂电池直接供电。不需要使用任何AD通道,利用内部集成的带隙参考源可以测量供电电压带隙参考源 bandgap 标称电压为 1.22V,ADC的参考源为单片机供电电压,当供电电...
southcreek 2021-01-17 07:50
N76E003 改选为MS51FB9AE
如果在Keil C51中没有MS51的支持,需要下载最新的NULINK驱动安装在Device 选项中,由N76E003改选为MS51FB9AE在Target选项上将时钟改为16M如果程序中有与FLAS...
southcreek 2020-12-21 14:59
EEPROM 中存入不同格式数据
    设备运行参数,需要保存到EEPROM中。运行参数数据类型不确定,有可能正负,也有可能不同长度。而EEPROM只能字节寻址。 不同编译器,数据类型的表示方法各异,且字节...
广告
我要评论
2
12
1
2
3
4
5
6
7
8
9
0
广告
关闭 热点推荐上一条 /8 下一条