无垠的广袤 发表于 2024-12-2 01:36

【AT-START-L021 测评】ADC采样

# 【AT-START-L021 测评】ADC采样

**ADC 是一个将模拟输入信号转换为12位、10位、8位、6位的数字信号的外设。采样率最高可达2MSPS。多达19个通道源可进行采样及转换。**

### ADC 主要特征

**模拟方面有以下特征:**

* **支持分辨率12 位、10 位、8 位、6 位的转换**
* **自校准时间: 154 个ADC 时钟周期**
* **ADC 转换时间**
* **ADC时钟在最大频率28MHz时转换时间为0.50 μs(分辨率12位时)**
* **ADC时钟在最大频率28MHz时转换时间为0.28 μs(分辨率6位时)**
* **ADC 供电要求:参考Datasheet**
* **ADC 输入范围:VSSA ≤ VIN ≤ VDDA**

**数字控制方面有以下特征:**

* **通道管理区分优先权不同的普通通道与抢占通道**
* **普通通道与抢占通道具备各自独立的触发侦测电路**
* **各通道均可独立配置采样时间**
* **转换顺序管理支持多种不同的多通道转换**
* **过采样器:硬件过采样最高可实现16 位分辨率**
* **可选择的数据对齐方式**
* **可配置的电压监测边界**
* **支持DMA 传输的普通通道数据**
* **可设定以下事件发生时响应中断**
* **抢占通道组转换结束**
* **通道转换结束**
* **电压监测超出范围**

### 通道管理

#### 模拟信号通道输入

**每个ADC 拥有多达19个模拟信号通道输入,以ADC\_INx 表示,x=0至18。** **ADC\_IN0至ADC\_IN14为外部模拟输入,ADC\_IN15、ADC\_IN16为V**~SSA~**,ADC\_IN17为内部参考电压,ADC\_IN18为V**~DDA~**。**

### 通道转换

**转换区分为普通通道转换与抢占通道转换,抢占通道的转换优先权高于普通通道。**

**抢占通道触发若发生于普通通道转换途中,优先进行抢占通道的转换,普通通道于抢占通道转换结束后重新开始转换被打断的通道。普通通道触发若发生于抢占通道转换途中,普通通道的转换会等待抢占通道转换完成后才开始。**

**将通道(ADC\_INx)编排进普通通道序列(ADC\_OSQx)以及抢占通道序列(ADC\_PSQ),相同通道可重复编排,序列总数由OCLEN 与PCLEN 定义,接着即可启动普通通道转换或抢占通道转换。**

### ADC基础操作流程

![](file:///D:/SoftwarePackage/31Pre-test/Artery_AT32L021_Board/fig/ADC_FlowChart.png?lastModify=1733074323)
!(data/attachment/forum/202412/02/013440c6e3smaxek1m461g.png "ADC_FlowChart.png")

## 工程测试

### 1. 参考电压检测

**使用 ADC1 内部通道17 监测 VREF 电压值**

**数据转换如下**

* **adc1\_ordinary\_value ---> adc1\_channel\_17**

#### 代码

**主函数代码**

```
int main(void)
{
 __IO uint32_t index = 0;
 system_clock_config();
 at32_board_init();
 at32_led_off(LED2);
 at32_led_off(LED3);
 at32_led_off(LED4);
 uart_print_init(115200);
 dma_config();
 adc_config();
 printf("adc1_vref_check \r\n");
 while(1)
{
   at32_led_on(LED2);
   delay_ms(200);
   adc_ordinary_software_trigger_enable(ADC1, TRUE);
   while(dma_flag_get(DMA1_FDT1_FLAG) == RESET);
   dma_flag_clear(DMA1_FDT1_FLAG);
   printf("vref_value = %f V\r\n", ((double)1.2 * 4095) / adc1_ordinary_value);
}
}
```

#### 效果

**使用 Arduino IDE 串口绘图功能获取电压数值监测数据曲线**

![](file:///D:/SoftwarePackage/31Pre-test/Artery_AT32L021_Board/fig/ADC.gif?lastModify=1733071407)
!(data/attachment/forum/202412/02/013505uapapcdkz1rddvpu.gif "ADC.gif")

### 2. 六位分辨率采样

**本项目展示了如何使用 6 位分辨率转换数据。 触发源设为软件。**

**数据转换如下**

* **adc1\_ordinary\_valuetab**(#) ---> adc1\_channel\_4
* **adc1\_ordinary\_valuetab**(#) ---> adc1\_channel\_5
* **adc1\_ordinary\_valuetab**(#) ---> adc1\_channel\_6

#### 代码

```
int main(void)
{
 __IO uint32_t index = 0;
 system_clock_config();
 at32_board_init();
 at32_led_off(LED2);
 at32_led_off(LED3);
 at32_led_off(LED4);
 uart_print_init(115200);
 gpio_config();
 dma_config();
 adc_config();
 printf("resolution_6bit \r\n");
 adc_ordinary_software_trigger_enable(ADC1, TRUE);
 while(dma_trans_complete_flag == 0);
 for(index = 0; index < 10; index++)
{
   printf("adc1_ordinary_valuetab[%d] = 0x%x\r\n", index, adc1_ordinary_valuetab);
   printf("adc1_ordinary_valuetab[%d] = 0x%x\r\n", index, adc1_ordinary_valuetab);
   printf("adc1_ordinary_valuetab[%d] = 0x%x\r\n", index, adc1_ordinary_valuetab);
}
 at32_led_on(LED2);
 while(1)
{
}
}
```

#### 效果

**短按 Reset 键,串口输出六位 ADC 采样值**

```
resolution_6bit
adc1_ordinary_valuetab = 0x1d
adc1_ordinary_valuetab = 0x1a
adc1_ordinary_valuetab = 0x1a
adc1_ordinary_valuetab = 0x1a
adc1_ordinary_valuetab = 0x1a
adc1_ordinary_valuetab = 0x1a
adc1_ordinary_valuetab = 0x1a
adc1_ordinary_valuetab = 0x1a
adc1_ordinary_valuetab = 0x1a
adc1_ordinary_valuetab = 0x1a
adc1_ordinary_valuetab = 0x1a
adc1_ordinary_valuetab = 0x1a
adc1_ordinary_valuetab = 0x1a
adc1_ordinary_valuetab = 0x1a
adc1_ordinary_valuetab = 0x1a
adc1_ordinary_valuetab = 0x1a
adc1_ordinary_valuetab = 0x1a
adc1_ordinary_valuetab = 0x1a
adc1_ordinary_valuetab = 0x1a
adc1_ordinary_valuetab = 0x1a
adc1_ordinary_valuetab = 0x1a
adc1_ordinary_valuetab = 0x1a
adc1_ordinary_valuetab = 0x1a
adc1_ordinary_valuetab = 0x1a
adc1_ordinary_valuetab = 0x1a
adc1_ordinary_valuetab = 0x1a
adc1_ordinary_valuetab = 0x1a
adc1_ordinary_valuetab = 0x1a
adc1_ordinary_valuetab = 0x1a
adc1_ordinary_valuetab = 0x1a
```

### 3. 电压监测器

**本项目展示了如何监视 ADC 频道的电压。 **

**数据转换如下**

* **adc1\_ordinary\_valuetab ---> adc1\_channel\_4**
* **adc1\_ordinary\_valuetab ---> adc1\_channel\_5**
* **adc1\_ordinary\_valuetab ---> adc1\_channel\_6**

**电压监测通道为:adc1\_channel\_5**

#### 代码

**主函数代码如下**

```
int main(void)
{
 __IO uint32_t index = 0;
 system_clock_config();
 at32_board_init();
 at32_led_off(LED2);
 at32_led_off(LED3);
 at32_led_off(LED4);
 uart_print_init(115200);
 gpio_config();
 dma_config();
 adc_config();
 printf("voltage_monitoring \r\n");
 while(1)
{
   at32_led_toggle(LED2);
   delay_ms(200);
   if(vmor_flag_index == 1)
 {
     vmor_flag_index = 0;
     printf("out of range:adc1_channel_5 value is = %x!\r\n", adc1_ordinary_valuetab);
 }
   adc_ordinary_software_trigger_enable(ADC1, TRUE);
}
}
```

#### 效果

![](file:///D:/SoftwarePackage/31Pre-test/Artery_AT32L021_Board/fig/UART_Voltage.gif?lastModify=1733073334)
!(data/attachment/forum/202412/02/013535dyo63qv5ywa3w5oo.gif "UART_Voltage.gif")

**板载 LED2 和 LED3 循环点亮。**

guijial511 发表于 2024-12-2 18:55

MCU要是能集成16位的ADC就好了

无垠的广袤 发表于 2024-12-3 00:15

guijial511 发表于 2024-12-2 18:55
MCU要是能集成16位的ADC就好了

上 64 位 MCU 应该可以 {:titter:}

lcdi 发表于 2024-12-5 17:37

看起来还比较稳定~
页: [1]
查看完整版本: 【AT-START-L021 测评】ADC采样