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