打印
[AT32L021]

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

[复制链接]
114|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主

【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基础操作流程

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 串口绘图功能获取电压数值监测数据曲线

ADC.gif

2. 六位分辨率采样

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

数据转换如下

  • adc1_ordinary_valuetabn ---> adc1_channel_4
  • adc1_ordinary_valuetabn ---> adc1_channel_5
  • adc1_ordinary_valuetabn ---> 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][0] = 0x%x\r\n", index, adc1_ordinary_valuetab[index][0]);
    printf("adc1_ordinary_valuetab[%d][1] = 0x%x\r\n", index, adc1_ordinary_valuetab[index][1]);
    printf("adc1_ordinary_valuetab[%d][2] = 0x%x\r\n", index, adc1_ordinary_valuetab[index][2]);
  }
  at32_led_on(LED2);
  while(1)
  {
  }
}

效果

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

resolution_6bit 
adc1_ordinary_valuetab[0][0] = 0x1d
adc1_ordinary_valuetab[0][1] = 0x1a
adc1_ordinary_valuetab[0][2] = 0x1a
adc1_ordinary_valuetab[1][0] = 0x1a
adc1_ordinary_valuetab[1][1] = 0x1a
adc1_ordinary_valuetab[1][2] = 0x1a
adc1_ordinary_valuetab[2][0] = 0x1a
adc1_ordinary_valuetab[2][1] = 0x1a
adc1_ordinary_valuetab[2][2] = 0x1a
adc1_ordinary_valuetab[3][0] = 0x1a
adc1_ordinary_valuetab[3][1] = 0x1a
adc1_ordinary_valuetab[3][2] = 0x1a
adc1_ordinary_valuetab[4][0] = 0x1a
adc1_ordinary_valuetab[4][1] = 0x1a
adc1_ordinary_valuetab[4][2] = 0x1a
adc1_ordinary_valuetab[5][0] = 0x1a
adc1_ordinary_valuetab[5][1] = 0x1a
adc1_ordinary_valuetab[5][2] = 0x1a
adc1_ordinary_valuetab[6][0] = 0x1a
adc1_ordinary_valuetab[6][1] = 0x1a
adc1_ordinary_valuetab[6][2] = 0x1a
adc1_ordinary_valuetab[7][0] = 0x1a
adc1_ordinary_valuetab[7][1] = 0x1a
adc1_ordinary_valuetab[7][2] = 0x1a
adc1_ordinary_valuetab[8][0] = 0x1a
adc1_ordinary_valuetab[8][1] = 0x1a
adc1_ordinary_valuetab[8][2] = 0x1a
adc1_ordinary_valuetab[9][0] = 0x1a
adc1_ordinary_valuetab[9][1] = 0x1a
adc1_ordinary_valuetab[9][2] = 0x1a

3. 电压监测器

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

数据转换如下

  • adc1_ordinary_valuetab[0] ---> adc1_channel_4
  • adc1_ordinary_valuetab[1] ---> adc1_channel_5
  • adc1_ordinary_valuetab[2] ---> 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[1]);
    }
    adc_ordinary_software_trigger_enable(ADC1, TRUE);
  }
}

效果

UART_Voltage.gif

板载 LED2 和 LED3 循环点亮。

使用特权

评论回复
沙发
guijial511| | 2024-12-2 18:55 | 只看该作者
MCU要是能集成16位的ADC就好了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

11

主题

23

帖子

0

粉丝