如何使用ad的硬件触发方式,请以dsp28335为例写出代码
时间: 2024-03-21 10:40:38 浏览: 106
DSP28335片内AD实验例程
下面是DSP28335的AD硬件触发方式的代码示例,假设需要使用Timer0作为ADC的硬件触发源:
```c
#include "DSP2833x_Device.h"
#include "DSP2833x_GlobalPrototypes.h"
#include "DSP2833x_EPwm_defines.h"
// 定义ADC采样结果存储数组
#pragma DATA_SECTION(AdcResult, "AdcResultSection")
uint16_t AdcResult[NUM_ADC_CHANNELS];
// 定义ADC采样序列
ADC_SEQSEL_BITS seq_config;
ADC_SEQ_CTRL_BITS seq_ctrl;
// 定义ADC触发源
ADC_EVT_SRCSEL_BITS evt_config;
// 定义硬件触发源
EPwmRegs *TimerRegs[6] = { &EPwm1Regs, &EPwm2Regs, &EPwm3Regs, &EPwm4Regs, &EPwm5Regs, &EPwm6Regs };
EPwmRegs *Timer = TimerRegs[0];
// 初始化ADC模块
void InitAdc(void)
{
// 使能ADC时钟
EALLOW;
SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1;
EDIS;
// 复位ADC模块
AdcRegs.ADCCTL1.bit.ADCRESET = 1;
AdcRegs.ADCCTL1.bit.ADCRESET = 0;
// 配置ADC采样时钟源和分频系数,设置采样率为50kHz
AdcRegs.ADCCTL1.bit.ADCCLKPS = 0;
AdcRegs.ADCCTL1.bit.ADCBGPWD = 1;
AdcRegs.ADCCTL1.bit.ADCPWDN = 1;
AdcRegs.ADCCTL1.bit.ADCENABLE = 1;
// 配置ADC采样序列,采样通道为ADCINA0、ADCINA1、ADCINA2、ADCINA3
AdcRegs.ADCCTL2.bit.ADCNONOVERLAP = 1;
AdcRegs.ADCCTL2.bit.CLKDIV2EN = 1;
AdcRegs.ADCCTL2.bit.ADCRES = 0;
AdcRegs.ADCTRL2.bit.INTPULSEPOS = 1;
AdcRegs.ADCTRL3.bit.ADCBGRFDN = 0xF;
AdcRegs.ADCTRL3.bit.ADCCLKPS = 0;
AdcRegs.ADCTRL3.bit.SMODE_SEL = 1;
AdcRegs.ADCTRL1.all = 0;
AdcRegs.ADCTRL3.all = 0;
AdcRegs.ADCMAXCONV.all = 0;
AdcRegs.ADCCHSELSEQ1.all = 0;
AdcRegs.ADCCHSELSEQ2.all = 0;
AdcRegs.ADCCHSELSEQ3.all = 0;
AdcRegs.ADCCHSELSEQ4.all = 0;
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0;
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1;
AdcRegs.ADCCHSELSEQ2.bit.CONV02 = 0x2;
AdcRegs.ADCCHSELSEQ2.bit.CONV03 = 0x3;
// 配置ADC触发模式为硬件触发模式,设置触发源为EPWMx_SOCA
seq_ctrl.bit.SEQ_CASC = 0;
seq_ctrl.bit.SEQ_OVRD = 1;
seq_ctrl.bit.SEQ_MODE = 1;
seq_ctrl.bit.SEQ_STOP = 0;
seq_ctrl.bit.SEQ_START = 0;
seq_ctrl.bit.SEQ_CTUVIS = 0;
seq_ctrl.bit.SEQ_SYNC = 0;
seq_ctrl.bit.SEQ_CONT = 1;
seq_ctrl.bit.SEQ_RES = 0;
seq_ctrl.bit.SEQ_TRIGSEL = 0x0;
seq_ctrl.bit.SEQ_TRIGSEL |= 0x1 << 0;
seq_ctrl.bit.SEQ_TRIGSEL |= 0x1 << 1;
seq_ctrl.bit.SEQ_TRIGSEL |= 0x1 << 2;
seq_ctrl.bit.SEQ_TRIGSEL |= 0x1 << 3;
AdcRegs.ADCTRL2.all = seq_ctrl.all;
seq_config.bit.SEQ1_MUX = 0x0;
seq_config.bit.SEQ2_MUX = 0x1;
seq_config.bit.SEQ3_MUX = 0x2;
seq_config.bit.SEQ4_MUX = 0x3;
AdcRegs.ADCSEQSEL1.all = seq_config.all;
// 配置ADC事件触发源为EPWMx_SOCA
evt_config.bit.EVT_SEL = 0x0;
evt_config.bit.EVT_SEL |= 0x1 << 0;
evt_config.bit.EVT_SEL |= 0x1 << 1;
evt_config.bit.EVT_SEL |= 0x1 << 2;
evt_config.bit.EVT_SEL |= 0x1 << 3;
AdcRegs.ADCTRL2.bit.EVBUSY = 0;
AdcRegs.ADCTRL2.all |= (1 << 13);
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;
AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1;
AdcRegs.ADC_EVTSEL.all = evt_config.all;
// 使能ADC转换器
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1;
AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1;
}
// 初始化硬件触发源
void InitTimer(void)
{
// 使能Timer0时钟
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
EDIS;
// 配置Timer0为周期性计数模式,设置计数周期为1ms
Timer->TBCTL.bit.CTRMODE = 0;
Timer->TBCTL.bit.PHSEN = 0;
Timer->TBCTL.bit.PRDLD = 0;
Timer->TBCTL.bit.SYNCOSEL = 0;
Timer->TBCTL.bit.HSPCLKDIV = 0;
Timer->TBCTL.bit.CLKDIV = 0;
Timer->TBPRD = 15000;
Timer->TBCTR = 0;
// 配置EPWMx_SOCA作为ADC的硬件触发源
Timer->ETSEL.bit.SOCAEN = 1;
Timer->ETSEL.bit.SOCASEL = 1;
Timer->ETPS.bit.SOCAPRD = 1;
}
// ADC采样中断服务函数
interrupt void AdcIsr(void)
{
// 读取ADC采样结果
AdcResult[0] = AdcRegs.ADCRESULT0;
AdcResult[1] = AdcRegs.ADCRESULT1;
AdcResult[2] = AdcRegs.ADCRESULT2;
AdcResult[3] = AdcRegs.ADCRESULT3;
// 清除ADC采样中断标志位
AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;
// 处理ADC采样结果
// ...
}
// 主函数
int main(void)
{
// 初始化系统时钟和GPIO引脚
InitSysCtrl();
InitGpio();
// 初始化ADC模块和硬件触发源
InitAdc();
InitTimer();
// 配置ADC采样中断
EALLOW;
PieVectTable.ADCINT1 = &AdcIsr;
PieCtrlRegs.PIEIER1.bit.INTx1 = 1;
EDIS;
// 启用全局中断
EnableInterrupts();
// 启动Timer0计数
Timer->TBCTR = 0;
Timer->TBCTL.bit.CTRMODE = 0x2;
// 主循环
while (1)
{
// 等待ADC采样中断
// ...
}
}
```
以上代码仅供参考,具体的AD硬件触发方式的使用流程和代码实现需要根据实际情况进行调整。
阅读全文