test_adc.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /*
  2. * Copyright (c) 2022-2024, Xiaohua Semiconductor Co., Ltd.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2024-12-30 CDT first version
  9. */
  10. /*
  11. * 程序清单: ADC 设备使用例程
  12. * 例程导出了 adc_vol_sample 命令到控制终端
  13. * 命令调用格式:adc_vol_sample 参数选择:adc1 | adc2 | adc3
  14. * 程序功能:通过 ADC 设备采样电压值并转换为数值。
  15. * 示例代码参考电压为3.3V,转换位数为12位。
  16. */
  17. #include <rtthread.h>
  18. #include <rtdevice.h>
  19. #include "board_config.h"
  20. #include "drv_adc.h"
  21. #ifdef BSP_USING_ADC
  22. #define REFER_VOLTAGE 3300 /* 参考电压 3.3V,单位mv */
  23. #define CONVERT_BITS (1 << 12) /* 转换位数为12位 */
  24. /* ADC Channel Max */
  25. #if defined (HC32F460)
  26. #define ADC1_CH_MAX (16U)
  27. #define ADC2_CH_MAX (8U)
  28. #elif defined (HC32F472)
  29. #define ADC1_CH_MAX (21U)
  30. #define ADC2_CH_MAX (21U)
  31. #define ADC3_CH_MAX (22U)
  32. #elif defined (HC32F4A0) || defined (HC32F4A8)
  33. #define ADC1_CH_MAX (16U)
  34. #define ADC2_CH_MAX (16U)
  35. #define ADC3_CH_MAX (20U)
  36. #elif defined (HC32F448)
  37. #define ADC1_CH_MAX (16U)
  38. #define ADC2_CH_MAX (8U)
  39. #define ADC3_CH_MAX (12U)
  40. #elif defined (HC32F334)
  41. #define ADC1_CH_MAX (16U)
  42. #define ADC2_CH_MAX (12U)
  43. #define ADC3_CH_MAX (10U)
  44. #endif
  45. #if defined(BSP_ADC1_USING_DMA) || defined(BSP_ADC2_USING_DMA) || defined(BSP_ADC3_USING_DMA)
  46. static struct adc_dev_priv_params adc_priv;
  47. static struct adc_dev_dma_priv_ops priv_ops;
  48. /* Timer的配置需与文件 “adc_config.h”中的 ADC1_EOCA_DMA_CONFIG 对应 */
  49. /* 这里使用Timer01 B通道作为ADC的触发源 */
  50. rt_err_t adc_dma_trig_config(void)
  51. {
  52. stc_tmr0_init_t stcTmr0Init;
  53. #if defined(HC32F460) || defined(HC32F4A0) || defined(HC32F472) || defined(HC32F448) || defined(HC32F4A8) || defined (HC32F334)
  54. FCG_Fcg2PeriphClockCmd(FCG2_PERIPH_TMR0_1, ENABLE);
  55. #endif
  56. (void)TMR0_StructInit(&stcTmr0Init);
  57. (void)TMR0_Init(CM_TMR0_1, TMR0_CH_B, &stcTmr0Init);
  58. return 0;
  59. }
  60. rt_err_t adc_dma_trig_start(void)
  61. {
  62. TMR0_SetCountValue(CM_TMR0_1, TMR0_CH_B, 0x0);
  63. TMR0_SetCompareValue(CM_TMR0_1, TMR0_CH_B, 0x7FFF);
  64. TMR0_Start(CM_TMR0_1, TMR0_CH_B);
  65. return 0;
  66. }
  67. rt_err_t adc_dma_trig_stop(void)
  68. {
  69. TMR0_Stop(CM_TMR0_1, TMR0_CH_B);
  70. TMR0_ClearStatus(CM_TMR0_1, TMR0_FLAG_CMP_B);
  71. return 0;
  72. }
  73. #endif
  74. static int adc_vol_sample(int argc, char **argv)
  75. {
  76. rt_adc_device_t adc_dev; /* ADC 设备句柄 */
  77. rt_uint32_t value;
  78. rt_uint32_t vol;
  79. rt_uint8_t adc_channel;
  80. char adc_device[] = "adc1";
  81. rt_uint8_t adc_max_channel = ADC1_CH_MAX;
  82. /* 参数无输入或者输入错误按照默认值处理 */
  83. if (argc == 2)
  84. {
  85. if (0 == rt_strcmp(argv[1], "adc1"))
  86. {
  87. rt_strcpy(adc_device, "adc1");
  88. adc_max_channel = ADC1_CH_MAX;
  89. }
  90. else if (0 == rt_strcmp(argv[1], "adc2"))
  91. {
  92. rt_strcpy(adc_device, "adc2");
  93. adc_max_channel = ADC2_CH_MAX;
  94. }
  95. #if defined (HC32F472) || defined (HC32F4A0) || defined (HC32F448) || defined (HC32F4A8) || defined (HC32F334)
  96. else if (0 == rt_strcmp(argv[1], "adc3"))
  97. {
  98. rt_strcpy(adc_device, "adc3");
  99. adc_max_channel = ADC3_CH_MAX;
  100. }
  101. #endif
  102. else
  103. {
  104. rt_kprintf("The chip hasn't the adc unit!\r\n");
  105. return -RT_ERROR;
  106. }
  107. }
  108. /* 查找设备 */
  109. adc_dev = (rt_adc_device_t)rt_device_find(adc_device);
  110. if (adc_dev == RT_NULL)
  111. {
  112. rt_kprintf("adc sample run failed! can't find %s device!\r\n", adc_device);
  113. return -RT_ERROR;
  114. }
  115. #if defined(BSP_ADC1_USING_DMA) || defined(BSP_ADC2_USING_DMA) || defined(BSP_ADC3_USING_DMA)
  116. /* DMA配置 */
  117. adc_priv.flag = ADC_USING_EOCA_DMA_FLAG;
  118. priv_ops.dma_trig_config = &adc_dma_trig_config;
  119. priv_ops.dma_trig_start = &adc_dma_trig_start;
  120. priv_ops.dma_trig_stop = &adc_dma_trig_stop;
  121. adc_priv.ops = &priv_ops;
  122. adc_dev->parent.user_data = &adc_priv;
  123. #endif
  124. /* 遍历所有通道 */
  125. for (adc_channel = 0; adc_channel < adc_max_channel; adc_channel++)
  126. {
  127. /* 使能设备 */
  128. rt_adc_enable(adc_dev, adc_channel);
  129. /* 读取采样值 */
  130. value = rt_adc_read(adc_dev, adc_channel);
  131. rt_kprintf("Channel: %d, value is :%d 0x%x\r\n", adc_channel, value, value);
  132. /* 转换为对应电压值 */
  133. vol = value * REFER_VOLTAGE / CONVERT_BITS;
  134. rt_kprintf("Simulate voltage is :%d mv\r\n", vol);
  135. vol = rt_adc_voltage(adc_dev, adc_channel);
  136. rt_kprintf("Read voltage is :%d mv\r\n", vol);
  137. rt_kprintf("*********************\r\n");
  138. }
  139. rt_kprintf("*******The %s all channel have be tested**********\r\n", adc_device);
  140. return RT_EOK;
  141. }
  142. /* 导出到 msh 命令列表中 */
  143. MSH_CMD_EXPORT(adc_vol_sample, adc convert sample: select < adc1 | adc2 | adc3 >);
  144. #endif