hhhhhht 发表于 2025-3-24 23:34:11

AI8051U可以支持3路ADC同时采样嘛?

AI8051U可以支持3路ADC同时采样嘛?

PWM中断自动触发ADC采样在HSPWM同样有效吗?

国芯人工智能 发表于 2025-3-24 23:38:00

关于AI8051U是否支持3路ADC同时采样的问题,需要从技术架构和功能设计两方面进行分析。

首先,AI8051U是基于8051内核的增强型微控制器,其ADC模块的性能和特性是其功能设计的重要组成部分。通常情况下,ADC模块的设计会考虑到多通道采样需求,但具体能否支持多路同时采样,取决于其硬件架构和资源配置。

从技术角度来看,支持多路ADC同时采样的关键在于ADC模块是否具备独立的采样保持电路(Sample-and-Hold Circuit)以及足够的转换资源。如果AI8051U的ADC模块为每路通道配备了独立的采样保持电路,并且具备足够的转换器资源,那么理论上可以实现多路同时采样。然而,如果ADC模块采用分时复用(Time-Division Multiplexing)的方式工作,则无法实现真正的同时采样,只能通过快速切换通道来模拟多路采样。

根据AI8051U的技术文档和功能描述,其ADC模块支持多通道采样,但并未明确说明是否支持3路ADC同时采样。因此,从现有信息来看,无法直接断定其是否具备这一能力。建议参考官方技术手册或咨询技术支持团队,以获取更详细的硬件架构和功能说明。

此外,即使AI8051U的ADC模块不支持真正的同时采样,通过优化采样时序和算法,仍可以在一定精度和速度范围内实现多路信号的采集和处理。例如,可以通过提高采样频率、优化通道切换时间等方式,尽可能减少各通道之间的采样延迟,从而满足实际应用需求。

综上所述,AI8051U是否支持3路ADC同时采样,需结合其硬件架构和功能设计进行具体分析。如需明确答案,建议查阅官方技术文档或咨询专业技术人员。同时,在实际应用中,可通过优化采样策略,实现多路信号的采集和处理,以满足系统需求。

[本文内容由国芯人工智能辅助生成,仅供参考]

神农鼎 发表于 2025-3-25 07:55:41

AI8051U可以支持3路ADC同时采样嘛?
===分时切换到不同的通道,采样转换,只有1个ADC, 不是3个ADC

PWM中断自动触发ADC采样在HSPWM同样有效吗?

===可以

hhhhhht 发表于 2025-3-25 08:19:56

神农鼎 发表于 2025-3-25 07:55
AI8051U可以支持3路ADC同时采样嘛?
===分时切换到不同的通道,采样转换,只有1个ADC, 不是3个ADC



如果配置DMA ADC,PWM中断是否可以触发DMA ADC转换。

ercircle 发表于 2025-3-25 08:29:56

hhhhhht 发表于 2025-3-25 08:19
如果配置DMA ADC,PWM中断是否可以触发DMA ADC转换。

参考库函数例程APP_DMA_AD和APP_HSPWM

AI8051U传统风格库函数例程包发布-持续更新, 20250214 - 软件库函数/原理图库/PCB库/最小包装 国芯技术交流网站 - AI32位8051交流社区
DMA_AD:
#include "app.h"

/*---------------------------------------------------------------------*/
/* --- Web: www.STCAI.com ---------------------------------------------*/
/*---------------------------------------------------------------------*/

#include "APP_DMA_AD.h"
#include "AI8051U_GPIO.h"
#include "AI8051U_ADC.h"
#include "AI8051U_UART.h"
#include "AI8051U_DMA.h"
#include "AI8051U_NVIC.h"
#include "string.h"

/*************    功能说明    **************

本程序演示多路ADC DMA采样.

初始化时先把要ADC转换的引脚设置为高阻输入.

设置数据批量传输(DMA)功能,所有通道一次循环采集的数据自动存放到DMA定义的xdata空间.

通过串口1(P3.0 P3.1)将DMA定义的xdata空间所收到的数据发送给上位机,波特率115200,N,8,1

用定时器做波特率发生器,建议使用1T模式(除非低波特率用12T),并选择可被波特率整除的时钟频率,以提高精度.

下载时, 选择时钟 40MHz (可以在配置文件"config.h"中修改).

******************************************/


//========================================================================
//                               本地常量声明   
//========================================================================

#define    ADC_CH       16      /* 1~16, ADC转换通道数, 需同步修改转换通道 */
#define    ADC_DATA   12      /* 6~n, 每个通道ADC转换数据总数, 2*转换次数+4, 需同步修改转换次数 */

//========================================================================
//                               本地变量声明
//========================================================================

u8 chn = 0;
u8 xdata DmaAdBuffer;

//========================================================================
//                               本地函数声明
//========================================================================


//========================================================================
//                            外部函数和变量声明
//========================================================================


//========================================================================
// 函数: ADtoUART_init
// 描述: 用户初始化程序.
// 参数: None.
// 返回: None.
// 版本: V1.0, 2020-09-28
//========================================================================
void DMA_AD_init(void)
{
    ADC_InitTypeDef ADC_InitStructure;          //结构定义
    COMx_InitDefine COMx_InitStructure;         //结构定义
    DMA_ADC_InitTypeDef DMA_ADC_InitStructure;//结构定义
    memset(&ADC_InitStructure,0,sizeof(ADC_InitTypeDef));//结构体初始化
    memset(&COMx_InitStructure,0,sizeof(COMx_InitDefine));//结构体初始化
    memset(&DMA_ADC_InitStructure,0,sizeof(DMA_ADC_InitTypeDef));//结构体初始化

    //----------------------------------------------
    P0_MODE_IN_HIZ(GPIO_Pin_LOW | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6);    //P0.0~P0.6 设置为高阻输入
    P1_MODE_IN_HIZ(GPIO_Pin_All);         //P1.0~P1.7 设置为高阻输入
    P3_MODE_IO_PU(GPIO_Pin_0 | GPIO_Pin_1); //P3.0,P3.1 设置为准双向口
   
    //----------------------------------------------
    COMx_InitStructure.UART_Mode      = UART_8bit_BRTx; //模式,   UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTx
    COMx_InitStructure.UART_BRT_Use   = BRT_Timer1;   //选择波特率发生器, BRT_Timer1/BRT_Timer2
    COMx_InitStructure.UART_BaudRate= 115200ul;       //波特率,   110 ~ 115200
    COMx_InitStructure.UART_RxEnable= ENABLE;         //接收允许,   ENABLE或DISABLE
    UART_Configuration(UART1, &COMx_InitStructure);   //初始化串口 UART1,UART2,UART3,UART4
    NVIC_UART1_Init(ENABLE,Priority_1);   //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3

    //----------------------------------------------
    ADC_InitStructure.ADC_SMPduty   = 31;   //ADC 模拟信号采样时间控制, 0~31(注意: SMPDUTY 一定不能设置小于 10)
    ADC_InitStructure.ADC_CsSetup   = 0;    //ADC 通道选择时间控制 0(默认),1
    ADC_InitStructure.ADC_CsHold    = 1;    //ADC 通道选择保持时间控制 0,1(默认),2,3
    ADC_InitStructure.ADC_Speed   = ADC_SPEED_2X16T;      //设置 ADC 工作时钟频率 ADC_SPEED_2X1T~ADC_SPEED_2X16T
    ADC_InitStructure.ADC_AdjResult = ADC_RIGHT_JUSTIFIED;//ADC结果调整, ADC_LEFT_JUSTIFIED,ADC_RIGHT_JUSTIFIED
    ADC_Inilize(&ADC_InitStructure);      //初始化
    ADC_PowerControl(ENABLE);               //ADC电源开关, ENABLE或DISABLE
    NVIC_ADC_Init(DISABLE,Priority_0);      //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3

    //----------------------------------------------
    DMA_ADC_InitStructure.DMA_Enable = ENABLE;            //DMA使能 ENABLE,DISABLE
    DMA_ADC_InitStructure.DMA_Channel = 0xffff;             //ADC通道使能寄存器, 1:使能, bit15~bit0 对应 ADC15~ADC0
    DMA_ADC_InitStructure.DMA_Buffer = (u16)DmaAdBuffer;    //ADC转换数据存储地址
    DMA_ADC_InitStructure.DMA_Times = ADC_4_Times;          //每个通道转换次数, ADC_1_Times,ADC_2_Times,ADC_4_Times,ADC_8_Times,ADC_16_Times,ADC_32_Times,ADC_64_Times,ADC_128_Times,ADC_256_Times
    DMA_ADC_Inilize(&DMA_ADC_InitStructure);                //初始化
    NVIC_DMA_ADC_Init(ENABLE,Priority_0,Priority_0);      //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0~Priority_3; 总线优先级(低到高) Priority_0~Priority_3
    DMA_ADC_TRIG();      //触发启动转换
}

//========================================================================
// 函数: Sample_DMA_AD
// 描述: 用户应用程序.
// 参数: None.
// 返回: None.
// 版本: V1.0, 2020-09-24
//========================================================================
void Sample_DMA_AD(void)
{
    u8 i,n;
    u16 j;

   
   
    if(DmaADCFlag)
    {
      DmaADCFlag = 0;
      for(i=0; i<ADC_CH; i++)
      {
            for(n=0; n<ADC_DATA; n++)
            {
                #if defined(_USE_KEILC251_COMPILER_) || defined(_USE_IAR_COMPILER_) || defined(_USE_SDCC_COMPILER_)
                        printf("0x%02x ",DmaAdBuffer);   //第1组数据,...,第n组数据,AD通道,平均余数,平均值
                #else
                        printf("0x%02bx ",DmaAdBuffer);   //第1组数据,...,第n组数据,AD通道,平均余数,平均值
                #endif
               
            }
            printf("\r\n");
      }
      printf("\r\n");
      DMA_ADC_TRIG();   //重新触发启动ADC转换
    }
    delay_ms(500);
}




HSPWM使用:
#include "app.h"

/*---------------------------------------------------------------------*/
/* --- Web: www.STCAI.com ---------------------------------------------*/
/*---------------------------------------------------------------------*/

#include "APP_HSPWM.h"
#include "AI8051U_Clock.h"
#include "AI8051U_GPIO.h"
#include "AI8051U_PWM.h"
#include "AI8051U_NVIC.h"

/*************    功能说明    **************

高速高级PWM定时器 PWM1P/PWM1N,PWM2P/PWM2N,PWM3P/PWM3N,PWM4P/PWM4N 每个通道都可独立实现PWM输出,或者两两互补对称输出.

8个通道PWM设置对应P0的8个端口.

高级PWM定时器 PWM5,PWM6,PWM7,PWM8 每个通道都可独立实现PWM输出.

通过P0口上连接的8个LED灯,利用PWM实现呼吸灯效果.

PWM周期和占空比可以根据需要自行设置,最高可达65535.

下载时, 选择时钟 24MHz (可以在配置文件"config.h"中修改).

******************************************/

//========================================================================
//                               本地常量声明   
//========================================================================


//========================================================================
//                               本地变量声明
//========================================================================

PWMx_Duty PWMA_Duty;
bit PWM1_Flag;
bit PWM2_Flag;
bit PWM3_Flag;
bit PWM4_Flag;
PWMx_Duty PWMB_Duty;
bit PWM5_Flag;
bit PWM6_Flag;
bit PWM7_Flag;
bit PWM8_Flag;
//========================================================================
//                               本地函数声明
//========================================================================


//========================================================================
//                            外部函数和变量声明
//========================================================================

extern PWMx_Duty PWMA_Duty;
extern bit PWM1_Flag;
extern bit PWM2_Flag;
extern bit PWM3_Flag;
extern bit PWM4_Flag;

extern PWMx_Duty PWMB_Duty;
extern bit PWM5_Flag;
extern bit PWM6_Flag;
extern bit PWM7_Flag;
extern bit PWM8_Flag;

//========================================================================
// 函数: HSPWM_init
// 描述: 用户初始化程序.
// 参数: None.
// 返回: None.
// 版本: V1.0, 2021-05-27
//========================================================================
void HSPWM_init(void)
{
    HSPWMx_InitDefine PWMx_InitStructure;
    InitStruct(PWMx_InitStructure);
    InitStruct(PWMA_Duty);
    InitStruct(PWMB_Duty);
   
    PWMA_Duty.PWM1_Duty = 128;
    PWMA_Duty.PWM2_Duty = 256;
    PWMA_Duty.PWM3_Duty = 512;
    PWMA_Duty.PWM4_Duty = 1024;

    PWMB_Duty.PWM5_Duty = 128;
    PWMB_Duty.PWM6_Duty = 256;
    PWMB_Duty.PWM7_Duty = 512;
    PWMB_Duty.PWM8_Duty = 1024;

    HSPllClkConfig(MCKSEL_HIRC,PLL_96M,0);    //系统时钟选择,PLL时钟选择,时钟分频系数

    PWMx_InitStructure.PWM_EnoSelect= ENO1P|ENO2P|ENO3P|ENO4P;//输出通道选择,    ENO1P,ENO1N,ENO2P,ENO2N,ENO3P,ENO3N,ENO4P,ENO4N / ENO5P,ENO6P,ENO7P,ENO8P
    PWMx_InitStructure.PWM_Period   = 2047;                     //周期时间,   0~65535
    PWMx_InitStructure.PWM_DeadTime = 0;                        //死区发生器设置, 0~255
    PWMx_InitStructure.PWM_MainOutEnable= ENABLE;               //主输出使能, ENABLE,DISABLE
    PWMx_InitStructure.PWM_CEN_Enable   = ENABLE;               //使能计数器, ENABLE,DISABLE
    HSPWM_Configuration(PWMA, &PWMx_InitStructure, &PWMA_Duty); //初始化PWM通用寄存器,PWMA,PWMB
    PWMx_InitStructure.PWM_EnoSelect= ENO5P|ENO6P|ENO7P|ENO8P;//输出通道选择,    ENO1P,ENO1N,ENO2P,ENO2N,ENO3P,ENO3N,ENO4P,ENO4N / ENO5P,ENO6P,ENO7P,ENO8P
    HSPWM_Configuration(PWMB, &PWMx_InitStructure, &PWMB_Duty); //初始化PWM通用寄存器,PWMA,PWMB

    PWM1_USE_P00P01();
    PWM2_USE_P02P03();
    PWM3_USE_P04P05();
    PWM4_USE_P06P07();

    PWM5_USE_P01();
    PWM6_USE_P03();
    PWM7_USE_P05();
    PWM8_USE_P07();
   
    P0_MODE_OUT_PP(GPIO_Pin_All);   //P0 设置为推挽输出
    P4_MODE_IO_PU(GPIO_Pin_0);      //P4.0 设置为准双向口
    NVIC_PWM_Init(PWMA,DISABLE,Priority_0);
    NVIC_PWM_Init(PWMB,DISABLE,Priority_0);
    P40 = 0;    //打开实验箱LED电源
}

//========================================================================
// 函数: Sample_HSSPI
// 描述: 用户应用程序.
// 参数: None.
// 返回: None.
// 版本: V1.0, 2021-05-27
//========================================================================
void Sample_HSPWM(void)
{
    if(!PWM1_Flag)
    {
      PWMA_Duty.PWM1_Duty++;
      if(PWMA_Duty.PWM1_Duty >= 2047) PWM1_Flag = 1;
    }
    else
    {
      PWMA_Duty.PWM1_Duty--;
      if(PWMA_Duty.PWM1_Duty <= 0) PWM1_Flag = 0;
    }

    if(!PWM2_Flag)
    {
      PWMA_Duty.PWM2_Duty++;
      if(PWMA_Duty.PWM2_Duty >= 2047) PWM2_Flag = 1;
    }
    else
    {
      PWMA_Duty.PWM2_Duty--;
      if(PWMA_Duty.PWM2_Duty <= 0) PWM2_Flag = 0;
    }

    if(!PWM3_Flag)
    {
      PWMA_Duty.PWM3_Duty++;
      if(PWMA_Duty.PWM3_Duty >= 2047) PWM3_Flag = 1;
    }
    else
    {
      PWMA_Duty.PWM3_Duty--;
      if(PWMA_Duty.PWM3_Duty <= 0) PWM3_Flag = 0;
    }

    if(!PWM4_Flag)
    {
      PWMA_Duty.PWM4_Duty++;
      if(PWMA_Duty.PWM4_Duty >= 2047) PWM4_Flag = 1;
    }
    else
    {
      PWMA_Duty.PWM4_Duty--;
      if(PWMA_Duty.PWM4_Duty <= 0) PWM4_Flag = 0;
    }
   
    if(!PWM5_Flag)
    {
      PWMB_Duty.PWM5_Duty++;
      if(PWMB_Duty.PWM5_Duty >= 2047) PWM5_Flag = 1;
    }
    else
    {
      PWMB_Duty.PWM5_Duty--;
      if(PWMB_Duty.PWM5_Duty <= 0) PWM5_Flag = 0;
    }

    if(!PWM6_Flag)
    {
      PWMB_Duty.PWM6_Duty++;
      if(PWMB_Duty.PWM6_Duty >= 2047) PWM6_Flag = 1;
    }
    else
    {
      PWMB_Duty.PWM6_Duty--;
      if(PWMB_Duty.PWM6_Duty <= 0) PWM6_Flag = 0;
    }

    if(!PWM7_Flag)
    {
      PWMB_Duty.PWM7_Duty++;
      if(PWMB_Duty.PWM7_Duty >= 2047) PWM7_Flag = 1;
    }
    else
    {
      PWMB_Duty.PWM7_Duty--;
      if(PWMB_Duty.PWM7_Duty <= 0) PWM7_Flag = 0;
    }

    if(!PWM8_Flag)
    {
      PWMB_Duty.PWM8_Duty++;
      if(PWMB_Duty.PWM8_Duty >= 2047) PWM8_Flag = 1;
    }
    else
    {
      PWMB_Duty.PWM8_Duty--;
      if(PWMB_Duty.PWM8_Duty <= 0) PWM8_Flag = 0;
    }
   
    UpdateHSPwm(PWMA, &PWMA_Duty);
    UpdateHSPwm(PWMB, &PWMB_Duty);
}



hhhhhht 发表于 2025-3-25 10:41:37

ercircle 发表于 2025-3-25 08:29
参考库函数例程APP_DMA_AD和APP_HSPWM

AI8051U传统风格库函数例程包发布-持续更新, 20250214 - 软件库函 ...
您好,感谢您的回复。没看出来这是PWM周期触发DMA ADC,我只需要知道PWM中断时是否可以自动触发DMA ADC。AI8051U外设有没有这个功能。

ercircle 发表于 2025-3-25 10:50:24

hhhhhht 发表于 2025-3-25 10:41
您好,感谢您的回复。没看出来这是PWM周期触发DMA ADC,我只需要知道PWM中断时是否可以自动触发DMA ADC。A ...

你在PWM中断中触发DMA采集就行?外设功能都是有的,需要自定义业务逻辑

王昱顺 发表于 2025-3-25 10:58:34

hhhhhht 发表于 2025-3-25 10:41
您好,感谢您的回复。没看出来这是PWM周期触发DMA ADC,我只需要知道PWM中断时是否可以自动触发DMA ADC。A ...

PWM周期中断只能触发普通ADC,不能触发DMA_ADC
DMA_ADC只能通过软件手动触发

梁工 发表于 2025-3-25 11:26:14


PWM自动触发ADC在HSPWM也同样有效。

ADC只有一个,任何时候只能转换一路ADC,多路ADC要切换通道来实现,但由于转换速度快,宏观上是并行的。比如使用周期为50us(频率20KHz)的PWM自动触发ADC,ADC完成后进入中断,再触发后续的通道转换,比如有4个通道,每个通道转换时间为10us,这样40us就可以完成4个通道的转换。

hhhhhht 发表于 2025-3-25 23:08:50

梁工 发表于 2025-3-25 11:26
PWM自动触发ADC在HSPWM也同样有效。

ADC只有一个,任何时候只能转换一路ADC,多路ADC要切换通道来实现, ...

感谢,明白了。
页: [1] 2
查看完整版本: AI8051U可以支持3路ADC同时采样嘛?