DSP28335 多通道ADC采样程序实现
基于 TI DSP28335 芯片的多通道 ADC 采样程序,支持顺序采样和同步采样两种模式,并包含 DMA 传输功能。
程序概述
这个程序实现了以下功能:
- 多通道ADC初始化配置(支持顺序和同步采样模式)
- 中断服务程序处理采样数据
- DMA配置实现自动数据传输
- PWM触发ADC采样配置
- 数据转换与处理
核心代码实现
#include "DSP2833x_Device.h"
#include "DSP2833x_Examples.h"
#include "math.h"
// 宏定义
#define ADC_MODCLK 0x3 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK = 150/(2*3) = 25.0 MHz
#define ADC_CKPS 0x0 // ADC模块时钟 = HSPCLK/1 = 25.0 MHz
#define ADC_SHCLK 0x1 // 采样保持时间 = 2个ADC周期
#define SAMPLE_NUM 1024 // 采样点数
#define CH_NUM 6 // 采样通道数
// 全局变量
volatile Uint16 AdcBuf[CH_NUM][SAMPLE_NUM]; // ADC采样缓冲区
volatile Uint16 sample_count = 0; // 采样计数
float32 AdcVoltage[CH_NUM]; // 转换后的电压值
// ADC初始化函数
void Adc_Init(void)
{
EALLOW;
// 配置系统时钟
SysCtrlRegs.HISPCP.all = ADC_MODCLK; // HSPCLK = SYSCLKOUT/ADC_MODCLK
// 初始化ADC
InitAdc();
// ADC特定配置
AdcRegs.ADCTRL1.bit.ACQ_PS = ADC_SHCLK; // 采样时间选择
AdcRegs.ADCTRL3.bit.ADCCLKPS = ADC_CKPS; // ADC内核时钟分频
AdcRegs.ADCTRL1.bit.SEQ_CASC = 1; // 1=级联模式(16通道)
AdcRegs.ADCTRL3.bit.SMODE_SEL = 0; // 0=顺序采样模式,1=同步采样模式
// 配置采样通道 - 使用6个通道: A0, A1, A2, A3, B0, B1
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; // ADCINA0
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1; // ADCINA1
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x2; // ADCINA2
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x3; // ADCINA3
AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0x4; // ADCINB0
AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x5; // ADCINB1
AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = CH_NUM-1; // 设置转换通道数(0起计)
// 中断配置
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // 使能SEQ1中断
AdcRegs.ADCTRL2.bit.INT_MOD_SEQ1 = 0; // 每个序列结束时产生中断
// 运行模式配置
AdcRegs.ADCTRL1.bit.CONT_RUN = 1; // 连续运行模式
AdcRegs.ADCTRL1.bit.SEQ_OVRD = 1; // 允许排序器覆盖
EDIS;
}
// DMA初始化函数(用于自动传输ADC数据)
void Dma_Init(void)
{
volatile Uint16 *DMADest, *DMASource;
// 指向ADC结果寄存器和目标缓冲区
DMADest = &AdcBuf[0][0];
DMASource = &AdcMirror.ADCRESULT0; // 注意:使用ADC镜像寄存器
// DMA通道配置
DMACH1AddrConfig(DMADest, DMASource); // 配置DMA源地址和目的地址
DMACH1BurstConfig(15, 1, 1); // 突发配置:每次触发传输16个字
DMACH1TransferConfig(9, 0, 1); // 传输配置
DMACH1WrapConfig(1, 0, 0, 1); // 环绕配置
// DMA模式配置
DMACH1ModeConfig(DMA_SEQ1INT, PERINT_ENABLE, ONESHOT_DISABLE,
CONT_DISABLE, SYNC_DISABLE, SYNC_SRC,
OVRFLOW_DISABLE, SIXTEEN_BIT, CHINT_END, CHINT_ENABLE);
}
// PWM触发ADC采样配置
void PWM_Trigger_Config(void)
{
// 配置ePWM1作为ADC触发源
EPwm1Regs.ETSEL.bit.SOCAEN = 1; // 使能SOCA
EPwm1Regs.ETSEL.bit.SOCASEL = 4; // 选择CMPA作为触发源
EPwm1Regs.ETPS.bit.SOCAPRD = 1; // 第一次事件产生触发脉冲
EPwm1Regs.CMPA.half.CMPA = 0x0080; // 设置比较值
EPwm1Regs.TBPRD = 0xFFFF; // 设置周期值
// 关联PWM触发到ADC
AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1; // 使能ePWM SOCA触发SEQ1
}
// ADC中断服务程序
interrupt void ADC_ISR(void)
{
// 读取ADC结果(如果未使用DMA)
for(int i = 0; i < CH_NUM; i++)
{
AdcBuf[i][sample_count] = AdcRegs.ADCRESULT0 >> 4; // 右移4位获取12位数据
}
sample_count++;
if(sample_count >= SAMPLE_NUM)
{
sample_count = 0;
}
// 清除中断标志
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // 确认PIE中断
}
// 电压值转换函数
void Convert_To_Voltage(void)
{
for(int ch = 0; ch < CH_NUM; ch++)
{
Uint32 sum = 0;
// 计算平均值
for(int i = 0; i < SAMPLE_NUM; i++)
{
sum += AdcBuf[ch][i];
}
Uint16 average = sum / SAMPLE_NUM;
// 转换为电压值(假设3.0V参考电压)
AdcVoltage[ch] = (float)average * 3.0 / 4096.0;
}
}
// 主函数
void main(void)
{
// 初始化系统控制
InitSysCtrl();
// 初始化GPIO(注意:ADC引脚通常不需要特别初始化)
InitGpio();
// 初始化PIE和中断
DINT;
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
// 注册ADC中断
EALLOW;
PieVectTable.ADCINT = &ADC_ISR;
EDIS;
// 使能ADC中断
PieCtrlRegs.PIECTRL.bit.ENPIE = 1;
PieCtrlRegs.PIEIER1.bit.INTx6 = 1;
IER |= M_INT1;
EINT;
// 初始化ADC
Adc_Init();
// 初始化DMA(可选)
Dma_Init();
// 配置PWM触发(可选)
PWM_Trigger_Config();
// 启动第一个ADC转换
AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1;
// 主循环
while(1)
{
// 处理采样数据
if(sample_count == 0)
{
Convert_To_Voltage();
// 这里可以添加数据处理代码
// 例如:发送数据到上位机、执行控制算法等
// 延时一段时间
DELAY_US(10000); // 10ms延时
}
}
}
关键配置说明
-
采样模式选择:
- 顺序采样模式 (
SMODE_SEL = 0):通道依次采样,适用于大多数应用场景。 - 同步采样模式 (
SMODE_SEL = 1):ADCINAx和ADCINBx同时采样,适合需要相位一致性的应用(如电机控制)。
- 顺序采样模式 (
-
DMA配置:
使用DMA可以将ADC结果自动传输到内存,减少CPU开销。配置时需要注意源地址应指向ADC结果镜像寄存器。 -
PWM触发:
配置ePWM模块触发ADC采样,非常适合电力电子和电机控制应用。 -
中断处理:
ADC转换完成后产生中断,在中断服务程序中读取数据或处理DMA传输完成标志。
多通道采样配置表
| 通道编号 | ADC引脚 | 结果寄存器 | 典型应用 |
|---|---|---|---|
| CONV00 | ADCINA0 | ADCRESULT0 | 电压检测 |
| CONV01 | ADCINA1 | ADCRESULT1 | 电流检测 |
| CONV02 | ADCINA2 | ADCRESULT2 | 温度检测 |
| CONV03 | ADCINA3 | ADCRESULT3 | 保留 |
| CONV04 | ADCINB0 | ADCRESULT4 | 保留 |
| CONV05 | ADCINB1 | ADCRESULT5 | 保留 |
参考代码 TI的 DSP28335 多通道ADC采样程序 www.youwenfan.com/contentcnh/56837.html
注意
-
ADC精度与校准:
- DSP28335的ADC模块可能存在固定的偏移误差(约0.2V),在实际应用中需要进行软件校准。
- 使用内部参考电压时,建议定期进行自校准。
-
硬件设计考虑:
- ADC输入引脚不应悬空,悬空引脚会产生噪声并影响其他通道的测量精度。
- 对于未使用的ADC通道,建议接地或通过电阻连接到固定电压。
- 前端添加RC滤波电路(如51Ω电阻+2.2nF电容)可以提高抗噪声性能。
-
采样速率计算:
- ADC时钟最高为25MHz,单通道转换时间约为80ns(12.5MSPS)。
- 多通道采样时,总吞吐量会随通道数增加而降低。
- 实际采样率 = 1 / (采样时间 + 转换时间 × 通道数)
-
同步采样限制:
- 真正的同步采样只能发生在A组和B组对应的通道上(如ADCINA0和ADCINB0)。
- 同步采样模式需要配置
SMODE_SEL = 1和相应的通道选择寄存器。
-
DMA使用提示:
- 确保DMA源地址指向ADC结果镜像寄存器(
AdcMirror.ADCRESULT0)而不是直接访问ADCRESULT0。 - 配置适当的突发大小和传输次数以匹配ADC采样序列。
- 确保DMA源地址指向ADC结果镜像寄存器(
这个程序提供了一个完整的多通道ADC采样框架。特别是在电力电子和电机控制应用中,结合PWM触发和DMA传输可以实现高效的数据采集和处理。
浙公网安备 33010602011771号