AI8051U可以支持3路ADC同时采样嘛?
AI8051U可以支持3路ADC同时采样嘛?PWM中断自动触发ADC采样在HSPWM同样有效吗?
关于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同时采样,需结合其硬件架构和功能设计进行具体分析。如需明确答案,建议查阅官方技术文档或咨询专业技术人员。同时,在实际应用中,可通过优化采样策略,实现多路信号的采集和处理,以满足系统需求。
[本文内容由国芯人工智能辅助生成,仅供参考] AI8051U可以支持3路ADC同时采样嘛?
===分时切换到不同的通道,采样转换,只有1个ADC, 不是3个ADC
PWM中断自动触发ADC采样在HSPWM同样有效吗?
===可以
神农鼎 发表于 2025-3-25 07:55
AI8051U可以支持3路ADC同时采样嘛?
===分时切换到不同的通道,采样转换,只有1个ADC, 不是3个ADC
如果配置DMA ADC,PWM中断是否可以触发DMA ADC转换。 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);
}
ercircle 发表于 2025-3-25 08:29
参考库函数例程APP_DMA_AD和APP_HSPWM
AI8051U传统风格库函数例程包发布-持续更新, 20250214 - 软件库函 ...
您好,感谢您的回复。没看出来这是PWM周期触发DMA ADC,我只需要知道PWM中断时是否可以自动触发DMA ADC。AI8051U外设有没有这个功能。
hhhhhht 发表于 2025-3-25 10:41
您好,感谢您的回复。没看出来这是PWM周期触发DMA ADC,我只需要知道PWM中断时是否可以自动触发DMA ADC。A ...
你在PWM中断中触发DMA采集就行?外设功能都是有的,需要自定义业务逻辑 hhhhhht 发表于 2025-3-25 10:41
您好,感谢您的回复。没看出来这是PWM周期触发DMA ADC,我只需要知道PWM中断时是否可以自动触发DMA ADC。A ...
PWM周期中断只能触发普通ADC,不能触发DMA_ADC
DMA_ADC只能通过软件手动触发
PWM自动触发ADC在HSPWM也同样有效。
ADC只有一个,任何时候只能转换一路ADC,多路ADC要切换通道来实现,但由于转换速度快,宏观上是并行的。比如使用周期为50us(频率20KHz)的PWM自动触发ADC,ADC完成后进入中断,再触发后续的通道转换,比如有4个通道,每个通道转换时间为10us,这样40us就可以完成4个通道的转换。
梁工 发表于 2025-3-25 11:26
PWM自动触发ADC在HSPWM也同样有效。
ADC只有一个,任何时候只能转换一路ADC,多路ADC要切换通道来实现, ...
感谢,明白了。
页:
[1]
2