我的想法是采集两个通道的数据,采集1024个数据存入数组,然后再把数组中的数据输入显示屏,我设置的pwm频率为6.25MHZ,ADCCLK为12.5MHZ,采样率即为pwm的频率,可是实际测试结果的采样率只有300K左右,请大神指导一下,下面是我的程序。采样率的设置是在InitAdc1(void); InitEPwm1Example();ADC_cai(void);这三个子函数中
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File
/**************************************宏定义************************************************/
#define DELAY_TIME_min 200 //延时时间(短)
#define DELAY_TIME_max 500000 //延时时间(长)
#define delay_short 300 // 10us
#define delay_long 300000 // 10ms
#define delay_mid 3000 #define SCIC 1
#define ADC_MODCLK 0x3 //ADC_MODCLK=HISPCP, HSPCLK = SYSCLKOUT/2*ADC_MODCLK = 150/(2*3)=25.0 MHz
/*****************************************************************************************************/
//串口C声明
void scic_loopback_init(void);
void scic_fifo_init(void);
void scic_xmit(int a);
void delay(Uint32 t);
void ADC_cai(void);
//串口相关变量
int j=0,w=0,y=0;//w用来设置等待adc采集,w=1表示采完结束。y表示一共执行adc采集中断子程序128次,共采到1024个点
char msg1[6]={0x5A,0xA5,0x05,0x82,0x10,0x05}; //Y_center相关指令
char msg2[6]={0x5A,0xA5,0x05,0x82,0x10,0x06}; //VD_center相关指令 char msg3[6]={0x5A,0xA5,0x05,0x82,0x10,0x09}; //横轴间隔设置相关指令
char msg4[6]={0x5A,0xA5,0x05,0x82,0x10,0x08}; //纵轴放大倍数设置相关指令
char msg[5]={0x5A,0xA5,0x04,0x84,0x01}; //写数据指令
char msg5[6]={0x5A,0xA5,0x03,0x80,0xEB,0x56};
int i=0;
int c_data; //要写的数据值
int c_data1,c_data2,c_data0;//中间转换参量
int dat_max,dat_mid,dat_min,mul;
/*************************************串口*********************************/
// Test 1,SCIC DLB, 8-bit word, baud rate 9.6k, default, 1 STOP bit, no parity
//该例中的全局变量:
Uint16 LoopCount;
Uint16 ConversionCount;
float Voltage1[1024]={0};
float Voltage2[1024]={0};
//unsigned int Voltage_1[100]={0};//unsigned int Voltage_2[100]={0};
float Voltage_1[1024]={0};
float Voltage_2[1024]={0};
void InitAdc1(void);
void InitEPwm1Example();
volatile unsigned int adconvover=0;
interrupt void epwm1_timer_isr(void);//如果中断服务程序放在主函数的下面则在主函数前需要对中断服务程序进行声明,在主函数的上面则不需要。
Uint16 EPwm1TimerIntCount;
float a=4096;float V2_max=0;
main()
{
int i,j;
InitSysCtrl(); //初始化系统函数
//InitGpio(); // 该例中跳过
InitScicGpio(); //选择GPIO口,初始化GPIO口
DINT;
IER = 0x0000; //禁止CPU中断
IFR = 0x0000; //清除CPU中断标志
InitPieCtrl(); //初始化PIE控制寄存器
InitPieVectTable(); //初始化PIE中断向量表
InitAdc1(); //初始化ADC模块
InitEPwm1Example();//初始化EPwm1模块
EnableInterrupts();
scic_fifo_init(); // Initialize the SCI FIFO
scic_loopback_init();//服务程序
EALLOW; // This is needed to write to EALLOW protected register
//PieVectTable.ADCINT = &adc_isr;
SysCtrlRegs.HISPCP.all=ADC_MODCLK;//HISPCP=ADC_MODCLK, HISPCLK=SYSCLKOUT/2*HISPCP
PieVectTable.EPWM1_INT = &epwm1_timer_isr;
EDIS;
//开中断
PieCtrlRegs.PIEIER1.bit.INTx6=1;PieCtrlRegs.PIEIER1.bit.INTx1=1;
PieCtrlRegs.PIEIER3.bit.INTx1 =0;//关PIE中断,EPWM-T1定时器中断位于INT3.1
IER |= M_INT3; //开CPU中断
EINT; // 使能全局中断
ERTM; // 使能实时中断
//epwm1_timer_isr();
// 等待ADC中断 // Initalize SCI dat_max=2000;
dat_mid=1000;
dat_min=0;
mul=440.0*256/(dat_max-dat_min);
#if SCIC
//清屏
for (i=0;i<6;i++)
{
scic_xmit(msg5[i]);
delay(delay_short);
}
delay(delay_long);
delay(delay_long);
//修改VD-Center值
c_data=dat_mid; c_data0=c_data;
c_data2=0xff&c_data0; // data2 为data的低八位数据
c_data0=c_data>>8;
c_data1=0xff&c_data0; // data1 为data的高八位数据
i = 0;
for (i=0;i<6;i++)
{
scic_xmit(msg2[i]);
delay(delay_short);
}
scic_xmit(c_data1);
delay(delay_short);
scic_xmit(c_data2);
delay(delay_short);
delay(delay_long);
delay(delay_long);
//修改纵轴放大倍数
c_data=mul;
c_data0=c_data;
c_data2=0xff&c_data0; // data2 为data的低八位数据
c_data0=c_data>>8;
c_data1=0xff&c_data0; // data1 为data的高八位数据
i = 0;
for (i=0;i<6;i++)
{
scic_xmit(msg4[i]);
delay(delay_short);
}
scic_xmit(c_data1);
delay(delay_short);
scic_xmit(c_data2);
delay(delay_short);
delay(delay_long);
delay(delay_long);
delay(delay_long);
//修改横轴间隔数
c_data=5; c_data0=c_data;
c_data2=0xff&c_data0; // data2 为data的低八位数据
c_data0=c_data>>8;
c_data1=0xff&c_data0; // data1 为data的高八位数据
i = 0;
for (i=0;i<6;i++)
{
scic_xmit(msg3[i]);
delay(delay_short);
}
scic_xmit(c_data1);
delay(delay_short);
scic_xmit(c_data2);
delay(delay_short);
delay(delay_long);
while(ScicRegs.SCIFFTX.bit.TXFFST != 0);
#endif
ConversionCount = 0;
EPwm1TimerIntCount=0;
delay(delay_long);
while(1)
{
ADC_cai();
#if SCIC
for(j=0;j<1024;j++)
{ c_data=Voltage_2[j]*1000-100;
c_data0=c_data;
c_data2=0xff&c_data0; // data2 为data的低八位数据
c_data0=c_data>>8;
c_data1=0xff&c_data0; // data1 为data的高八位数据
i = 0;
for (i=0;i<5;i++)
{
scic_xmit(msg[i]);
delay(delay_short);
}
scic_xmit(c_data1);
delay(delay_short);
scic_xmit(c_data2);
delay(delay_short);
// ConversionCount++;
delay(delay_long);
}
//ConversionCount=0;
// delay(delay_long);
while(ScicRegs.SCIFFTX.bit.TXFFST != 0);
#endif
}
}
void InitEPwm1Example()
{
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;// 在系统初始化函数中已经使能 //EPWM模块,此处只需设置禁止同步。
EDIS;
//1.设置TB模块
EPwm1Regs.TBPRD =12; //18750 //2ms //设置计数周期=600TBCLK//EPwm1Regs.TBPRD = 6000;
EPwm1Regs.CMPA.half.CMPA = 6; // 比较器A = 300TBCLK//EPwm1Regs.CMPA.half.CMPA = 500;EPwm1Regs.CMPB = 20; //比较器 B = 500 TBCLKEPwm1Regs.TBPHS.half.TBPHS = 0x0000; // 设置相位寄存器置零
EPwm1Regs.TBCTR = 0x0000; // 清除TB计数器
// Setup TBCLK = SYSCLKOUT / (HSPCLKDIV * CLKDIV)=150/4*4
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; //计数方式设置00 //Up-count mode;01Down-count mode;10 Up-down-count mode
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // 禁止相位加载
EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW; //从阴影寄存器加载计数值
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;//禁用同步输出,在头文 //件DSP2833x-ePwm-defines.h中有定义
EPwm1Regs.TBCTL.bit.HSPCLKDIV =TB_DIV1;//TB_DIV1=0
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;//TB_DIV1=0
EPwm1Regs.TBCTL.bit.FREE_SOFT = 0x3; //仿真模式位:自由运行
//设置比较模块
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // 映射模式Load registers //every ZERO
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR = Zero
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
// 设置动作模块
EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;
EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;
EPwm1Regs.AQCTLB.bit.CBU = AQ_SET;
EPwm1Regs.AQCTLB.bit.CBD = AQ_CLEAR;
//事件触发子模块设置
//1.开始转换脉冲SOCA设置
EPwm1Regs.ETSEL.bit.SOCAEN = 1; // 使能ADC开始转换A(EPWMxSOCA)脉冲 把1修改成了0,在ADC_cai()中再赋值1触发adc采集
EPwm1Regs.ETSEL.bit.SOCASEL = 4; //设置EPWMxSOCA何时生成,2,TBCTR=TBPRD
EPwm1Regs.ETPS.bit.SOCAPRD = 3; //第三个中断事件A发生,即EPWMxSOCA生成
//2.EPWM中断设置
EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_PRD;//EPWM中断设置,此处设置为周期中断
EPwm1Regs.ETSEL.bit.INTEN = 1; //使能EPWM中断
EPwm1Regs.ETPS.bit.INTPRD = ET_1ST;//第一个事件发生时产生中断
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;// Enable TBCLK within the ePWM
EDIS;
}
void InitAdc1(void)
{
Uint16 i;
AdcRegs.ADCTRL1.bit.RESET=1; //复位AD 模块
for(i=0;i<9;i++)
{asm(" NOP");}
AdcRegs.ADCTRL1.bit.RESET=0;
AdcRegs.ADCTRL1.bit.SUSMOD=0; //仿真暂停方式,0为忽略。
AdcRegs.ADCTRL1.bit.ACQ_PS=0; //控制sSOC的脉冲宽度,同时也决定了采样开关闭合的时间。设定窗口大小SC=ADCTRL1[11:8] + 1 个ADCCLK周期数;AdcRegs.ADCTRL1.bit.CPS=0; //内核时钟预定标器,1为二分频 ADC Core clock divider :HSPCLK/[2*(ADCTRL1[7]:CPS + 1)]
AdcRegs.ADCTRL1.bit.CONT_RUN=1;//连续运行方式,0:敉7绞?1:连续转换方式.
AdcRegs.ADCTRL1.bit.SEQ_CASC=1; //**级联蛄蟹⑸鞴ぷ鞣绞剑? 双序列模 //式;1 级联模式
//ADCTRL3对电源和采样方式进行设置
AdcRegs.ADCTRL3.bit.ADCBGRFDN=3;//带隙参考电路上电
for(i=0;i<10000;i++)
{asm(" NOP");}
AdcRegs.ADCTRL3.bit.ADCPWDN=1;//除带隙参考电路獾钠渌鸄DC模块上电
for(i=0;i<5000;i++)
{asm(" NOP");}
AdcRegs.ADCTRL3.bit.ADCCLKPS=2; // ADCCLK=HISPCLK/[2*ADCCLKPS*(ADCTRL1[7].CPS+1)]
AdcRegs.ADCTRL3.bit.SMODE_SEL=1; //采样方式。顺序采样0/同步采样1
AdcRegs.ADCMAXCONV.bit.MAX_CONV1=0x07; //设定转换数量,共8同步采样(每 //次采样两个通道),共采样16路
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 0x0; //采样ADCINA0和ADCINB0
//ADC状态和标志寄存器ADCST(清除中断标志)
AdcRegs.ADCST.bit.INT_SEQ1_CLR=1;//中断清除位
AdcRegs.ADCST.bit.INT_SEQ2_CLR=1;
//AdcRegs.ADCTRL2.all=0x2800;
AdcRegs.ADCTRL2.bit.EPWM_SOCB_SEQ=0;
AdcRegs.ADCTRL2.bit.RST_SEQ1=1;// 复位序列发生器1
//SEQ1
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1=0;//SEQ1中断使能:0禁止INT SEQ1向CPU发出中断申请,1使能INT SEQ1向CPU发出中断申请
AdcRegs.ADCTRL2.bit.INT_MOD_SEQ1=0;//SEQ1中断方式:0每个SEQ1序列转换 束,置位SEQ1的中断标志
AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1=1;//SEQ1的EPWM SOCA使能位,1使能
AdcRegs.ADCTRL2.bit.EXT_SOC_SEQ1=0;//SEQ1的外部SOC信号位,0:无操作。1:外部ADCSOC引脚信号启动ADC自动转换序列。
AdcRegs.ADCTRL2.bit.SOC_SEQ1=0;//为1时,软件启动ADC转换.
//SEQ2
AdcRegs.ADCTRL2.bit.RST_SEQ2=0; //复位SEQ2
AdcRegs.ADCTRL2.bit.SOC_SEQ2=0; //启动SEQ2的转换触发。仅适用于双序 //列发生器模式
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ2=0;
AdcRegs.ADCTRL2.bit.INT_MOD_SEQ2=0;
AdcRegs.ADCTRL2.bit.EPWM_SOCB_SEQ2=0;
}
void ADC_cai(void)
{
AdcRegs.ADCTRL2.bit.RST_SEQ1=1;
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; PieCtrlRegs.PIEACK.all|=0x0001;
PieCtrlRegs.PIEIER1.bit.INTx1=0;
for(i=0;i<5000;i++)
{asm(" NOP");}
w=0;
PieCtrlRegs.PIEIER1.bit.INTx6=0;//控制ADC中断
// delay(DELAY_TIME_min);
AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;//为1时,软件启动ADC转换//为1时,软件启动ADC转换
//PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
EPwm1Regs.ETSEL.bit.SOCAEN = 1; // 使能ADC开始转换A(EPWMxSOCA)脉冲
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
//EPwm1Regs.ETCLR.bit.INT = 1;
EPwm1Regs.ETSEL.bit.INTEN = 1;//使能ePWM中断产生位;1:使能中断;0:禁止中断
loop: if(w==0)
{
goto loop;
}
// delay(DELAY_TIME_max);
PieCtrlRegs.PIEIER1.bit.INTx6=1; PieCtrlRegs.PIEIER1.bit.INTx1=1;
}
//EPWM1的定时器中断
interrupt void epwm1_timer_isr(void)
{
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;//向该位写1,清除SEQ1中断标志位,INT_SEQ1,该位对EOS_BUF1位无影响。
//AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;//为1时,软件启动ADC转换//为1时,软件启动ADC转换
PieCtrlRegs.PIEACK.all |= PIEACK_GROUP1;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT0 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT1 >>4)*3.0/4096.0;
ConversionCount++;
// Voltage_1[ConversionCount] = AdcRegs.ADCRESULT2;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT2 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT3 >>4)*3.0/4096.0;
ConversionCount++;
//Voltage_1[ConversionCount] = AdcRegs.ADCRESULT4 ;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT4 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT5 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT6 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT7 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT8 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT9 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT10 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT11 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT12 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT13 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT14 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT15 >>4)*3.0/4096.0;
ConversionCount++;
//y++;
if(ConversionCount> 1023)
{
ConversionCount = 0;
w=1;
//y=0;
//ConversionCount = 0;
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;//复位SEQ1为初始状态 CONV00
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1=1;
PieCtrlRegs.PIEIER3.bit.INTx1 = 0;//使能PIE中断,EPWM-T1定时器中断位于INT3.1
EPwm1Regs.ETSEL.bit.INTEN = 0;//使能ePWM中断产生位;1:使能中断;0:禁止中断
//AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1=0;
// AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;
PieCtrlRegs.PIEACK.all= PIEACK_GROUP3;
EPwm1Regs.ETCLR.all = 0xD;//epwm中断标准清除位,0:没有效果;1:清除中断标志位
// AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; // Clear INT SEQ1 bit,清除INT SEQ1标志位
}
else {
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; // Reset SEQ1
EPwm1Regs.ETCLR.bit.INT = 1;
// AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;
//PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
//EPwm1Regs.ETSEL.bit.INTEN = 1;//使能ePWM中断产生位;1:使能中断;0:禁止中断
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
// AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;//为1时,软件启动ADC转换//为1时,软件启动ADC转换
}
}
void scic_loopback_init()
{
// Note: Clocks were turned on to the SCIC peripheral
// in the InitSysCtrl() function
ScicRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback
// No parity,8 char bits,
// async mode, idle-line protocol
ScicRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK,
// Disable RX ERR, SLEEP, TXWAKE
ScicRegs.SCICTL2.all =0x0003;
ScicRegs.SCICTL2.bit.TXINTENA =1;
ScicRegs.SCICTL2.bit.RXBKINTENA =1;
ScicRegs.SCIHBAUD =0x0001;
ScicRegs.SCILBAUD =0x00e7;
ScicRegs.SCICCR.bit.LOOPBKENA =0;// enable loop back
ScicRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset
}
// Transmit a character from the SCI'
void scic_xmit(int a)
{
ScicRegs.SCITXBUF=a;
}
// Initalize the SCI FIFO
void scic_fifo_init()
{
ScicRegs.SCIFFTX.bit.TXFIFOXRESET=0;
ScicRegs.SCIFFRX.bit.RXFIFORESET=0;
ScicRegs.SCIFFTX.all=0xE040;
ScicRegs.SCIFFRX.all=0x204f;
ScicRegs.SCIFFCT.all=0x0;
}
void delay(Uint32 t)
{
Uint32 i = 0;
for (i = 0; i < t; i++);
}
user4528677:
请求指导,是DSP28335的
我的想法是采集两个通道的数据,采集1024个数据存入数组,然后再把数组中的数据输入显示屏,我设置的pwm频率为6.25MHZ,ADCCLK为12.5MHZ,采样率即为pwm的频率,可是实际测试结果的采样率只有300K左右,请大神指导一下,下面是我的程序。采样率的设置是在InitAdc1(void); InitEPwm1Example();ADC_cai(void);这三个子函数中
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File
/**************************************宏定义************************************************/
#define DELAY_TIME_min 200 //延时时间(短)
#define DELAY_TIME_max 500000 //延时时间(长)
#define delay_short 300 // 10us
#define delay_long 300000 // 10ms
#define delay_mid 3000 #define SCIC 1
#define ADC_MODCLK 0x3 //ADC_MODCLK=HISPCP, HSPCLK = SYSCLKOUT/2*ADC_MODCLK = 150/(2*3)=25.0 MHz
/*****************************************************************************************************/
//串口C声明
void scic_loopback_init(void);
void scic_fifo_init(void);
void scic_xmit(int a);
void delay(Uint32 t);
void ADC_cai(void);
//串口相关变量
int j=0,w=0,y=0;//w用来设置等待adc采集,w=1表示采完结束。y表示一共执行adc采集中断子程序128次,共采到1024个点
char msg1[6]={0x5A,0xA5,0x05,0x82,0x10,0x05}; //Y_center相关指令
char msg2[6]={0x5A,0xA5,0x05,0x82,0x10,0x06}; //VD_center相关指令 char msg3[6]={0x5A,0xA5,0x05,0x82,0x10,0x09}; //横轴间隔设置相关指令
char msg4[6]={0x5A,0xA5,0x05,0x82,0x10,0x08}; //纵轴放大倍数设置相关指令
char msg[5]={0x5A,0xA5,0x04,0x84,0x01}; //写数据指令
char msg5[6]={0x5A,0xA5,0x03,0x80,0xEB,0x56};
int i=0;
int c_data; //要写的数据值
int c_data1,c_data2,c_data0;//中间转换参量
int dat_max,dat_mid,dat_min,mul;
/*************************************串口*********************************/
// Test 1,SCIC DLB, 8-bit word, baud rate 9.6k, default, 1 STOP bit, no parity
//该例中的全局变量:
Uint16 LoopCount;
Uint16 ConversionCount;
float Voltage1[1024]={0};
float Voltage2[1024]={0};
//unsigned int Voltage_1[100]={0};//unsigned int Voltage_2[100]={0};
float Voltage_1[1024]={0};
float Voltage_2[1024]={0};
void InitAdc1(void);
void InitEPwm1Example();
volatile unsigned int adconvover=0;
interrupt void epwm1_timer_isr(void);//如果中断服务程序放在主函数的下面则在主函数前需要对中断服务程序进行声明,在主函数的上面则不需要。
Uint16 EPwm1TimerIntCount;
float a=4096;float V2_max=0;
main()
{
int i,j;
InitSysCtrl(); //初始化系统函数
//InitGpio(); // 该例中跳过
InitScicGpio(); //选择GPIO口,初始化GPIO口
DINT;
IER = 0x0000; //禁止CPU中断
IFR = 0x0000; //清除CPU中断标志
InitPieCtrl(); //初始化PIE控制寄存器
InitPieVectTable(); //初始化PIE中断向量表
InitAdc1(); //初始化ADC模块
InitEPwm1Example();//初始化EPwm1模块
EnableInterrupts();
scic_fifo_init(); // Initialize the SCI FIFO
scic_loopback_init();//服务程序
EALLOW; // This is needed to write to EALLOW protected register
//PieVectTable.ADCINT = &adc_isr;
SysCtrlRegs.HISPCP.all=ADC_MODCLK;//HISPCP=ADC_MODCLK, HISPCLK=SYSCLKOUT/2*HISPCP
PieVectTable.EPWM1_INT = &epwm1_timer_isr;
EDIS;
//开中断
PieCtrlRegs.PIEIER1.bit.INTx6=1;PieCtrlRegs.PIEIER1.bit.INTx1=1;
PieCtrlRegs.PIEIER3.bit.INTx1 =0;//关PIE中断,EPWM-T1定时器中断位于INT3.1
IER |= M_INT3; //开CPU中断
EINT; // 使能全局中断
ERTM; // 使能实时中断
//epwm1_timer_isr();
// 等待ADC中断 // Initalize SCI dat_max=2000;
dat_mid=1000;
dat_min=0;
mul=440.0*256/(dat_max-dat_min);
#if SCIC
//清屏
for (i=0;i<6;i++)
{
scic_xmit(msg5[i]);
delay(delay_short);
}
delay(delay_long);
delay(delay_long);
//修改VD-Center值
c_data=dat_mid; c_data0=c_data;
c_data2=0xff&c_data0; // data2 为data的低八位数据
c_data0=c_data>>8;
c_data1=0xff&c_data0; // data1 为data的高八位数据
i = 0;
for (i=0;i<6;i++)
{
scic_xmit(msg2[i]);
delay(delay_short);
}
scic_xmit(c_data1);
delay(delay_short);
scic_xmit(c_data2);
delay(delay_short);
delay(delay_long);
delay(delay_long);
//修改纵轴放大倍数
c_data=mul;
c_data0=c_data;
c_data2=0xff&c_data0; // data2 为data的低八位数据
c_data0=c_data>>8;
c_data1=0xff&c_data0; // data1 为data的高八位数据
i = 0;
for (i=0;i<6;i++)
{
scic_xmit(msg4[i]);
delay(delay_short);
}
scic_xmit(c_data1);
delay(delay_short);
scic_xmit(c_data2);
delay(delay_short);
delay(delay_long);
delay(delay_long);
delay(delay_long);
//修改横轴间隔数
c_data=5; c_data0=c_data;
c_data2=0xff&c_data0; // data2 为data的低八位数据
c_data0=c_data>>8;
c_data1=0xff&c_data0; // data1 为data的高八位数据
i = 0;
for (i=0;i<6;i++)
{
scic_xmit(msg3[i]);
delay(delay_short);
}
scic_xmit(c_data1);
delay(delay_short);
scic_xmit(c_data2);
delay(delay_short);
delay(delay_long);
while(ScicRegs.SCIFFTX.bit.TXFFST != 0);
#endif
ConversionCount = 0;
EPwm1TimerIntCount=0;
delay(delay_long);
while(1)
{
ADC_cai();
#if SCIC
for(j=0;j<1024;j++)
{ c_data=Voltage_2[j]*1000-100;
c_data0=c_data;
c_data2=0xff&c_data0; // data2 为data的低八位数据
c_data0=c_data>>8;
c_data1=0xff&c_data0; // data1 为data的高八位数据
i = 0;
for (i=0;i<5;i++)
{
scic_xmit(msg[i]);
delay(delay_short);
}
scic_xmit(c_data1);
delay(delay_short);
scic_xmit(c_data2);
delay(delay_short);
// ConversionCount++;
delay(delay_long);
}
//ConversionCount=0;
// delay(delay_long);
while(ScicRegs.SCIFFTX.bit.TXFFST != 0);
#endif
}
}
void InitEPwm1Example()
{
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;// 在系统初始化函数中已经使能 //EPWM模块,此处只需设置禁止同步。
EDIS;
//1.设置TB模块
EPwm1Regs.TBPRD =12; //18750 //2ms //设置计数周期=600TBCLK//EPwm1Regs.TBPRD = 6000;
EPwm1Regs.CMPA.half.CMPA = 6; // 比较器A = 300TBCLK//EPwm1Regs.CMPA.half.CMPA = 500;EPwm1Regs.CMPB = 20; //比较器 B = 500 TBCLKEPwm1Regs.TBPHS.half.TBPHS = 0x0000; // 设置相位寄存器置零
EPwm1Regs.TBCTR = 0x0000; // 清除TB计数器
// Setup TBCLK = SYSCLKOUT / (HSPCLKDIV * CLKDIV)=150/4*4
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; //计数方式设置00 //Up-count mode;01Down-count mode;10 Up-down-count mode
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // 禁止相位加载
EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW; //从阴影寄存器加载计数值
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;//禁用同步输出,在头文 //件DSP2833x-ePwm-defines.h中有定义
EPwm1Regs.TBCTL.bit.HSPCLKDIV =TB_DIV1;//TB_DIV1=0
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;//TB_DIV1=0
EPwm1Regs.TBCTL.bit.FREE_SOFT = 0x3; //仿真模式位:自由运行
//设置比较模块
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // 映射模式Load registers //every ZERO
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR = Zero
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
// 设置动作模块
EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;
EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;
EPwm1Regs.AQCTLB.bit.CBU = AQ_SET;
EPwm1Regs.AQCTLB.bit.CBD = AQ_CLEAR;
//事件触发子模块设置
//1.开始转换脉冲SOCA设置
EPwm1Regs.ETSEL.bit.SOCAEN = 1; // 使能ADC开始转换A(EPWMxSOCA)脉冲 把1修改成了0,在ADC_cai()中再赋值1触发adc采集
EPwm1Regs.ETSEL.bit.SOCASEL = 4; //设置EPWMxSOCA何时生成,2,TBCTR=TBPRD
EPwm1Regs.ETPS.bit.SOCAPRD = 3; //第三个中断事件A发生,即EPWMxSOCA生成
//2.EPWM中断设置
EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_PRD;//EPWM中断设置,此处设置为周期中断
EPwm1Regs.ETSEL.bit.INTEN = 1; //使能EPWM中断
EPwm1Regs.ETPS.bit.INTPRD = ET_1ST;//第一个事件发生时产生中断
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;// Enable TBCLK within the ePWM
EDIS;
}
void InitAdc1(void)
{
Uint16 i;
AdcRegs.ADCTRL1.bit.RESET=1; //复位AD 模块
for(i=0;i<9;i++)
{asm(" NOP");}
AdcRegs.ADCTRL1.bit.RESET=0;
AdcRegs.ADCTRL1.bit.SUSMOD=0; //仿真暂停方式,0为忽略。
AdcRegs.ADCTRL1.bit.ACQ_PS=0; //控制sSOC的脉冲宽度,同时也决定了采样开关闭合的时间。设定窗口大小SC=ADCTRL1[11:8] + 1 个ADCCLK周期数;AdcRegs.ADCTRL1.bit.CPS=0; //内核时钟预定标器,1为二分频 ADC Core clock divider :HSPCLK/[2*(ADCTRL1[7]:CPS + 1)]
AdcRegs.ADCTRL1.bit.CONT_RUN=1;//连续运行方式,0:敉7绞?1:连续转换方式.
AdcRegs.ADCTRL1.bit.SEQ_CASC=1; //**级联蛄蟹⑸鞴ぷ鞣绞剑? 双序列模 //式;1 级联模式
//ADCTRL3对电源和采样方式进行设置
AdcRegs.ADCTRL3.bit.ADCBGRFDN=3;//带隙参考电路上电
for(i=0;i<10000;i++)
{asm(" NOP");}
AdcRegs.ADCTRL3.bit.ADCPWDN=1;//除带隙参考电路獾钠渌鸄DC模块上电
for(i=0;i<5000;i++)
{asm(" NOP");}
AdcRegs.ADCTRL3.bit.ADCCLKPS=2; // ADCCLK=HISPCLK/[2*ADCCLKPS*(ADCTRL1[7].CPS+1)]
AdcRegs.ADCTRL3.bit.SMODE_SEL=1; //采样方式。顺序采样0/同步采样1
AdcRegs.ADCMAXCONV.bit.MAX_CONV1=0x07; //设定转换数量,共8同步采样(每 //次采样两个通道),共采样16路
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 0x0; //采样ADCINA0和ADCINB0
//ADC状态和标志寄存器ADCST(清除中断标志)
AdcRegs.ADCST.bit.INT_SEQ1_CLR=1;//中断清除位
AdcRegs.ADCST.bit.INT_SEQ2_CLR=1;
//AdcRegs.ADCTRL2.all=0x2800;
AdcRegs.ADCTRL2.bit.EPWM_SOCB_SEQ=0;
AdcRegs.ADCTRL2.bit.RST_SEQ1=1;// 复位序列发生器1
//SEQ1
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1=0;//SEQ1中断使能:0禁止INT SEQ1向CPU发出中断申请,1使能INT SEQ1向CPU发出中断申请
AdcRegs.ADCTRL2.bit.INT_MOD_SEQ1=0;//SEQ1中断方式:0每个SEQ1序列转换 束,置位SEQ1的中断标志
AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1=1;//SEQ1的EPWM SOCA使能位,1使能
AdcRegs.ADCTRL2.bit.EXT_SOC_SEQ1=0;//SEQ1的外部SOC信号位,0:无操作。1:外部ADCSOC引脚信号启动ADC自动转换序列。
AdcRegs.ADCTRL2.bit.SOC_SEQ1=0;//为1时,软件启动ADC转换.
//SEQ2
AdcRegs.ADCTRL2.bit.RST_SEQ2=0; //复位SEQ2
AdcRegs.ADCTRL2.bit.SOC_SEQ2=0; //启动SEQ2的转换触发。仅适用于双序 //列发生器模式
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ2=0;
AdcRegs.ADCTRL2.bit.INT_MOD_SEQ2=0;
AdcRegs.ADCTRL2.bit.EPWM_SOCB_SEQ2=0;
}
void ADC_cai(void)
{
AdcRegs.ADCTRL2.bit.RST_SEQ1=1;
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; PieCtrlRegs.PIEACK.all|=0x0001;
PieCtrlRegs.PIEIER1.bit.INTx1=0;
for(i=0;i<5000;i++)
{asm(" NOP");}
w=0;
PieCtrlRegs.PIEIER1.bit.INTx6=0;//控制ADC中断
// delay(DELAY_TIME_min);
AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;//为1时,软件启动ADC转换//为1时,软件启动ADC转换
//PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
EPwm1Regs.ETSEL.bit.SOCAEN = 1; // 使能ADC开始转换A(EPWMxSOCA)脉冲
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
//EPwm1Regs.ETCLR.bit.INT = 1;
EPwm1Regs.ETSEL.bit.INTEN = 1;//使能ePWM中断产生位;1:使能中断;0:禁止中断
loop: if(w==0)
{
goto loop;
}
// delay(DELAY_TIME_max);
PieCtrlRegs.PIEIER1.bit.INTx6=1; PieCtrlRegs.PIEIER1.bit.INTx1=1;
}
//EPWM1的定时器中断
interrupt void epwm1_timer_isr(void)
{
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;//向该位写1,清除SEQ1中断标志位,INT_SEQ1,该位对EOS_BUF1位无影响。
//AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;//为1时,软件启动ADC转换//为1时,软件启动ADC转换
PieCtrlRegs.PIEACK.all |= PIEACK_GROUP1;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT0 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT1 >>4)*3.0/4096.0;
ConversionCount++;
// Voltage_1[ConversionCount] = AdcRegs.ADCRESULT2;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT2 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT3 >>4)*3.0/4096.0;
ConversionCount++;
//Voltage_1[ConversionCount] = AdcRegs.ADCRESULT4 ;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT4 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT5 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT6 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT7 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT8 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT9 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT10 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT11 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT12 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT13 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT14 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT15 >>4)*3.0/4096.0;
ConversionCount++;
//y++;
if(ConversionCount> 1023)
{
ConversionCount = 0;
w=1;
//y=0;
//ConversionCount = 0;
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;//复位SEQ1为初始状态 CONV00
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1=1;
PieCtrlRegs.PIEIER3.bit.INTx1 = 0;//使能PIE中断,EPWM-T1定时器中断位于INT3.1
EPwm1Regs.ETSEL.bit.INTEN = 0;//使能ePWM中断产生位;1:使能中断;0:禁止中断
//AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1=0;
// AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;
PieCtrlRegs.PIEACK.all= PIEACK_GROUP3;
EPwm1Regs.ETCLR.all = 0xD;//epwm中断标准清除位,0:没有效果;1:清除中断标志位
// AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; // Clear INT SEQ1 bit,清除INT SEQ1标志位
}
else {
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; // Reset SEQ1
EPwm1Regs.ETCLR.bit.INT = 1;
// AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;
//PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
//EPwm1Regs.ETSEL.bit.INTEN = 1;//使能ePWM中断产生位;1:使能中断;0:禁止中断
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
// AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;//为1时,软件启动ADC转换//为1时,软件启动ADC转换
}
}
void scic_loopback_init()
{
// Note: Clocks were turned on to the SCIC peripheral
// in the InitSysCtrl() function
ScicRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback
// No parity,8 char bits,
// async mode, idle-line protocol
ScicRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK,
// Disable RX ERR, SLEEP, TXWAKE
ScicRegs.SCICTL2.all =0x0003;
ScicRegs.SCICTL2.bit.TXINTENA =1;
ScicRegs.SCICTL2.bit.RXBKINTENA =1;
ScicRegs.SCIHBAUD =0x0001;
ScicRegs.SCILBAUD =0x00e7;
ScicRegs.SCICCR.bit.LOOPBKENA =0;// enable loop back
ScicRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset
}
// Transmit a character from the SCI'
void scic_xmit(int a)
{
ScicRegs.SCITXBUF=a;
}
// Initalize the SCI FIFO
void scic_fifo_init()
{
ScicRegs.SCIFFTX.bit.TXFIFOXRESET=0;
ScicRegs.SCIFFRX.bit.RXFIFORESET=0;
ScicRegs.SCIFFTX.all=0xE040;
ScicRegs.SCIFFRX.all=0x204f;
ScicRegs.SCIFFCT.all=0x0;
}
void delay(Uint32 t)
{
Uint32 i = 0;
for (i = 0; i < t; i++);
}
Eric Ma:
回复 user4528677:
这种情况没办法实现。
首先,F28335的ADC最大的采样速率是12.5MSPS,这是针对ADC时钟为25M的情况。
那么针对你的例子,你使用12.5M的ADC时钟,即使采用连续采样的方式(即ADC一直不停的采样转换),采样转换16个通道,最快的采样率也只是12.5M/16*2 = 390KHz。
Eric
我的想法是采集两个通道的数据,采集1024个数据存入数组,然后再把数组中的数据输入显示屏,我设置的pwm频率为6.25MHZ,ADCCLK为12.5MHZ,采样率即为pwm的频率,可是实际测试结果的采样率只有300K左右,请大神指导一下,下面是我的程序。采样率的设置是在InitAdc1(void); InitEPwm1Example();ADC_cai(void);这三个子函数中
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File
/**************************************宏定义************************************************/
#define DELAY_TIME_min 200 //延时时间(短)
#define DELAY_TIME_max 500000 //延时时间(长)
#define delay_short 300 // 10us
#define delay_long 300000 // 10ms
#define delay_mid 3000 #define SCIC 1
#define ADC_MODCLK 0x3 //ADC_MODCLK=HISPCP, HSPCLK = SYSCLKOUT/2*ADC_MODCLK = 150/(2*3)=25.0 MHz
/*****************************************************************************************************/
//串口C声明
void scic_loopback_init(void);
void scic_fifo_init(void);
void scic_xmit(int a);
void delay(Uint32 t);
void ADC_cai(void);
//串口相关变量
int j=0,w=0,y=0;//w用来设置等待adc采集,w=1表示采完结束。y表示一共执行adc采集中断子程序128次,共采到1024个点
char msg1[6]={0x5A,0xA5,0x05,0x82,0x10,0x05}; //Y_center相关指令
char msg2[6]={0x5A,0xA5,0x05,0x82,0x10,0x06}; //VD_center相关指令 char msg3[6]={0x5A,0xA5,0x05,0x82,0x10,0x09}; //横轴间隔设置相关指令
char msg4[6]={0x5A,0xA5,0x05,0x82,0x10,0x08}; //纵轴放大倍数设置相关指令
char msg[5]={0x5A,0xA5,0x04,0x84,0x01}; //写数据指令
char msg5[6]={0x5A,0xA5,0x03,0x80,0xEB,0x56};
int i=0;
int c_data; //要写的数据值
int c_data1,c_data2,c_data0;//中间转换参量
int dat_max,dat_mid,dat_min,mul;
/*************************************串口*********************************/
// Test 1,SCIC DLB, 8-bit word, baud rate 9.6k, default, 1 STOP bit, no parity
//该例中的全局变量:
Uint16 LoopCount;
Uint16 ConversionCount;
float Voltage1[1024]={0};
float Voltage2[1024]={0};
//unsigned int Voltage_1[100]={0};//unsigned int Voltage_2[100]={0};
float Voltage_1[1024]={0};
float Voltage_2[1024]={0};
void InitAdc1(void);
void InitEPwm1Example();
volatile unsigned int adconvover=0;
interrupt void epwm1_timer_isr(void);//如果中断服务程序放在主函数的下面则在主函数前需要对中断服务程序进行声明,在主函数的上面则不需要。
Uint16 EPwm1TimerIntCount;
float a=4096;float V2_max=0;
main()
{
int i,j;
InitSysCtrl(); //初始化系统函数
//InitGpio(); // 该例中跳过
InitScicGpio(); //选择GPIO口,初始化GPIO口
DINT;
IER = 0x0000; //禁止CPU中断
IFR = 0x0000; //清除CPU中断标志
InitPieCtrl(); //初始化PIE控制寄存器
InitPieVectTable(); //初始化PIE中断向量表
InitAdc1(); //初始化ADC模块
InitEPwm1Example();//初始化EPwm1模块
EnableInterrupts();
scic_fifo_init(); // Initialize the SCI FIFO
scic_loopback_init();//服务程序
EALLOW; // This is needed to write to EALLOW protected register
//PieVectTable.ADCINT = &adc_isr;
SysCtrlRegs.HISPCP.all=ADC_MODCLK;//HISPCP=ADC_MODCLK, HISPCLK=SYSCLKOUT/2*HISPCP
PieVectTable.EPWM1_INT = &epwm1_timer_isr;
EDIS;
//开中断
PieCtrlRegs.PIEIER1.bit.INTx6=1;PieCtrlRegs.PIEIER1.bit.INTx1=1;
PieCtrlRegs.PIEIER3.bit.INTx1 =0;//关PIE中断,EPWM-T1定时器中断位于INT3.1
IER |= M_INT3; //开CPU中断
EINT; // 使能全局中断
ERTM; // 使能实时中断
//epwm1_timer_isr();
// 等待ADC中断 // Initalize SCI dat_max=2000;
dat_mid=1000;
dat_min=0;
mul=440.0*256/(dat_max-dat_min);
#if SCIC
//清屏
for (i=0;i<6;i++)
{
scic_xmit(msg5[i]);
delay(delay_short);
}
delay(delay_long);
delay(delay_long);
//修改VD-Center值
c_data=dat_mid; c_data0=c_data;
c_data2=0xff&c_data0; // data2 为data的低八位数据
c_data0=c_data>>8;
c_data1=0xff&c_data0; // data1 为data的高八位数据
i = 0;
for (i=0;i<6;i++)
{
scic_xmit(msg2[i]);
delay(delay_short);
}
scic_xmit(c_data1);
delay(delay_short);
scic_xmit(c_data2);
delay(delay_short);
delay(delay_long);
delay(delay_long);
//修改纵轴放大倍数
c_data=mul;
c_data0=c_data;
c_data2=0xff&c_data0; // data2 为data的低八位数据
c_data0=c_data>>8;
c_data1=0xff&c_data0; // data1 为data的高八位数据
i = 0;
for (i=0;i<6;i++)
{
scic_xmit(msg4[i]);
delay(delay_short);
}
scic_xmit(c_data1);
delay(delay_short);
scic_xmit(c_data2);
delay(delay_short);
delay(delay_long);
delay(delay_long);
delay(delay_long);
//修改横轴间隔数
c_data=5; c_data0=c_data;
c_data2=0xff&c_data0; // data2 为data的低八位数据
c_data0=c_data>>8;
c_data1=0xff&c_data0; // data1 为data的高八位数据
i = 0;
for (i=0;i<6;i++)
{
scic_xmit(msg3[i]);
delay(delay_short);
}
scic_xmit(c_data1);
delay(delay_short);
scic_xmit(c_data2);
delay(delay_short);
delay(delay_long);
while(ScicRegs.SCIFFTX.bit.TXFFST != 0);
#endif
ConversionCount = 0;
EPwm1TimerIntCount=0;
delay(delay_long);
while(1)
{
ADC_cai();
#if SCIC
for(j=0;j<1024;j++)
{ c_data=Voltage_2[j]*1000-100;
c_data0=c_data;
c_data2=0xff&c_data0; // data2 为data的低八位数据
c_data0=c_data>>8;
c_data1=0xff&c_data0; // data1 为data的高八位数据
i = 0;
for (i=0;i<5;i++)
{
scic_xmit(msg[i]);
delay(delay_short);
}
scic_xmit(c_data1);
delay(delay_short);
scic_xmit(c_data2);
delay(delay_short);
// ConversionCount++;
delay(delay_long);
}
//ConversionCount=0;
// delay(delay_long);
while(ScicRegs.SCIFFTX.bit.TXFFST != 0);
#endif
}
}
void InitEPwm1Example()
{
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;// 在系统初始化函数中已经使能 //EPWM模块,此处只需设置禁止同步。
EDIS;
//1.设置TB模块
EPwm1Regs.TBPRD =12; //18750 //2ms //设置计数周期=600TBCLK//EPwm1Regs.TBPRD = 6000;
EPwm1Regs.CMPA.half.CMPA = 6; // 比较器A = 300TBCLK//EPwm1Regs.CMPA.half.CMPA = 500;EPwm1Regs.CMPB = 20; //比较器 B = 500 TBCLKEPwm1Regs.TBPHS.half.TBPHS = 0x0000; // 设置相位寄存器置零
EPwm1Regs.TBCTR = 0x0000; // 清除TB计数器
// Setup TBCLK = SYSCLKOUT / (HSPCLKDIV * CLKDIV)=150/4*4
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; //计数方式设置00 //Up-count mode;01Down-count mode;10 Up-down-count mode
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // 禁止相位加载
EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW; //从阴影寄存器加载计数值
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;//禁用同步输出,在头文 //件DSP2833x-ePwm-defines.h中有定义
EPwm1Regs.TBCTL.bit.HSPCLKDIV =TB_DIV1;//TB_DIV1=0
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;//TB_DIV1=0
EPwm1Regs.TBCTL.bit.FREE_SOFT = 0x3; //仿真模式位:自由运行
//设置比较模块
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // 映射模式Load registers //every ZERO
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR = Zero
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
// 设置动作模块
EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;
EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;
EPwm1Regs.AQCTLB.bit.CBU = AQ_SET;
EPwm1Regs.AQCTLB.bit.CBD = AQ_CLEAR;
//事件触发子模块设置
//1.开始转换脉冲SOCA设置
EPwm1Regs.ETSEL.bit.SOCAEN = 1; // 使能ADC开始转换A(EPWMxSOCA)脉冲 把1修改成了0,在ADC_cai()中再赋值1触发adc采集
EPwm1Regs.ETSEL.bit.SOCASEL = 4; //设置EPWMxSOCA何时生成,2,TBCTR=TBPRD
EPwm1Regs.ETPS.bit.SOCAPRD = 3; //第三个中断事件A发生,即EPWMxSOCA生成
//2.EPWM中断设置
EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_PRD;//EPWM中断设置,此处设置为周期中断
EPwm1Regs.ETSEL.bit.INTEN = 1; //使能EPWM中断
EPwm1Regs.ETPS.bit.INTPRD = ET_1ST;//第一个事件发生时产生中断
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;// Enable TBCLK within the ePWM
EDIS;
}
void InitAdc1(void)
{
Uint16 i;
AdcRegs.ADCTRL1.bit.RESET=1; //复位AD 模块
for(i=0;i<9;i++)
{asm(" NOP");}
AdcRegs.ADCTRL1.bit.RESET=0;
AdcRegs.ADCTRL1.bit.SUSMOD=0; //仿真暂停方式,0为忽略。
AdcRegs.ADCTRL1.bit.ACQ_PS=0; //控制sSOC的脉冲宽度,同时也决定了采样开关闭合的时间。设定窗口大小SC=ADCTRL1[11:8] + 1 个ADCCLK周期数;AdcRegs.ADCTRL1.bit.CPS=0; //内核时钟预定标器,1为二分频 ADC Core clock divider :HSPCLK/[2*(ADCTRL1[7]:CPS + 1)]
AdcRegs.ADCTRL1.bit.CONT_RUN=1;//连续运行方式,0:敉7绞?1:连续转换方式.
AdcRegs.ADCTRL1.bit.SEQ_CASC=1; //**级联蛄蟹⑸鞴ぷ鞣绞剑? 双序列模 //式;1 级联模式
//ADCTRL3对电源和采样方式进行设置
AdcRegs.ADCTRL3.bit.ADCBGRFDN=3;//带隙参考电路上电
for(i=0;i<10000;i++)
{asm(" NOP");}
AdcRegs.ADCTRL3.bit.ADCPWDN=1;//除带隙参考电路獾钠渌鸄DC模块上电
for(i=0;i<5000;i++)
{asm(" NOP");}
AdcRegs.ADCTRL3.bit.ADCCLKPS=2; // ADCCLK=HISPCLK/[2*ADCCLKPS*(ADCTRL1[7].CPS+1)]
AdcRegs.ADCTRL3.bit.SMODE_SEL=1; //采样方式。顺序采样0/同步采样1
AdcRegs.ADCMAXCONV.bit.MAX_CONV1=0x07; //设定转换数量,共8同步采样(每 //次采样两个通道),共采样16路
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 0x0; //采样ADCINA0和ADCINB0
//ADC状态和标志寄存器ADCST(清除中断标志)
AdcRegs.ADCST.bit.INT_SEQ1_CLR=1;//中断清除位
AdcRegs.ADCST.bit.INT_SEQ2_CLR=1;
//AdcRegs.ADCTRL2.all=0x2800;
AdcRegs.ADCTRL2.bit.EPWM_SOCB_SEQ=0;
AdcRegs.ADCTRL2.bit.RST_SEQ1=1;// 复位序列发生器1
//SEQ1
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1=0;//SEQ1中断使能:0禁止INT SEQ1向CPU发出中断申请,1使能INT SEQ1向CPU发出中断申请
AdcRegs.ADCTRL2.bit.INT_MOD_SEQ1=0;//SEQ1中断方式:0每个SEQ1序列转换 束,置位SEQ1的中断标志
AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1=1;//SEQ1的EPWM SOCA使能位,1使能
AdcRegs.ADCTRL2.bit.EXT_SOC_SEQ1=0;//SEQ1的外部SOC信号位,0:无操作。1:外部ADCSOC引脚信号启动ADC自动转换序列。
AdcRegs.ADCTRL2.bit.SOC_SEQ1=0;//为1时,软件启动ADC转换.
//SEQ2
AdcRegs.ADCTRL2.bit.RST_SEQ2=0; //复位SEQ2
AdcRegs.ADCTRL2.bit.SOC_SEQ2=0; //启动SEQ2的转换触发。仅适用于双序 //列发生器模式
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ2=0;
AdcRegs.ADCTRL2.bit.INT_MOD_SEQ2=0;
AdcRegs.ADCTRL2.bit.EPWM_SOCB_SEQ2=0;
}
void ADC_cai(void)
{
AdcRegs.ADCTRL2.bit.RST_SEQ1=1;
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; PieCtrlRegs.PIEACK.all|=0x0001;
PieCtrlRegs.PIEIER1.bit.INTx1=0;
for(i=0;i<5000;i++)
{asm(" NOP");}
w=0;
PieCtrlRegs.PIEIER1.bit.INTx6=0;//控制ADC中断
// delay(DELAY_TIME_min);
AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;//为1时,软件启动ADC转换//为1时,软件启动ADC转换
//PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
EPwm1Regs.ETSEL.bit.SOCAEN = 1; // 使能ADC开始转换A(EPWMxSOCA)脉冲
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
//EPwm1Regs.ETCLR.bit.INT = 1;
EPwm1Regs.ETSEL.bit.INTEN = 1;//使能ePWM中断产生位;1:使能中断;0:禁止中断
loop: if(w==0)
{
goto loop;
}
// delay(DELAY_TIME_max);
PieCtrlRegs.PIEIER1.bit.INTx6=1; PieCtrlRegs.PIEIER1.bit.INTx1=1;
}
//EPWM1的定时器中断
interrupt void epwm1_timer_isr(void)
{
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;//向该位写1,清除SEQ1中断标志位,INT_SEQ1,该位对EOS_BUF1位无影响。
//AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;//为1时,软件启动ADC转换//为1时,软件启动ADC转换
PieCtrlRegs.PIEACK.all |= PIEACK_GROUP1;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT0 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT1 >>4)*3.0/4096.0;
ConversionCount++;
// Voltage_1[ConversionCount] = AdcRegs.ADCRESULT2;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT2 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT3 >>4)*3.0/4096.0;
ConversionCount++;
//Voltage_1[ConversionCount] = AdcRegs.ADCRESULT4 ;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT4 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT5 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT6 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT7 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT8 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT9 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT10 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT11 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT12 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT13 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT14 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT15 >>4)*3.0/4096.0;
ConversionCount++;
//y++;
if(ConversionCount> 1023)
{
ConversionCount = 0;
w=1;
//y=0;
//ConversionCount = 0;
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;//复位SEQ1为初始状态 CONV00
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1=1;
PieCtrlRegs.PIEIER3.bit.INTx1 = 0;//使能PIE中断,EPWM-T1定时器中断位于INT3.1
EPwm1Regs.ETSEL.bit.INTEN = 0;//使能ePWM中断产生位;1:使能中断;0:禁止中断
//AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1=0;
// AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;
PieCtrlRegs.PIEACK.all= PIEACK_GROUP3;
EPwm1Regs.ETCLR.all = 0xD;//epwm中断标准清除位,0:没有效果;1:清除中断标志位
// AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; // Clear INT SEQ1 bit,清除INT SEQ1标志位
}
else {
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; // Reset SEQ1
EPwm1Regs.ETCLR.bit.INT = 1;
// AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;
//PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
//EPwm1Regs.ETSEL.bit.INTEN = 1;//使能ePWM中断产生位;1:使能中断;0:禁止中断
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
// AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;//为1时,软件启动ADC转换//为1时,软件启动ADC转换
}
}
void scic_loopback_init()
{
// Note: Clocks were turned on to the SCIC peripheral
// in the InitSysCtrl() function
ScicRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback
// No parity,8 char bits,
// async mode, idle-line protocol
ScicRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK,
// Disable RX ERR, SLEEP, TXWAKE
ScicRegs.SCICTL2.all =0x0003;
ScicRegs.SCICTL2.bit.TXINTENA =1;
ScicRegs.SCICTL2.bit.RXBKINTENA =1;
ScicRegs.SCIHBAUD =0x0001;
ScicRegs.SCILBAUD =0x00e7;
ScicRegs.SCICCR.bit.LOOPBKENA =0;// enable loop back
ScicRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset
}
// Transmit a character from the SCI'
void scic_xmit(int a)
{
ScicRegs.SCITXBUF=a;
}
// Initalize the SCI FIFO
void scic_fifo_init()
{
ScicRegs.SCIFFTX.bit.TXFIFOXRESET=0;
ScicRegs.SCIFFRX.bit.RXFIFORESET=0;
ScicRegs.SCIFFTX.all=0xE040;
ScicRegs.SCIFFRX.all=0x204f;
ScicRegs.SCIFFCT.all=0x0;
}
void delay(Uint32 t)
{
Uint32 i = 0;
for (i = 0; i < t; i++);
}
user4528677:
回复 Eric Ma:
谢谢,如果我设置最大转换通道为2,
即AdcRegs.ADCMAXCONV.bit.MAX_CONV1=0x00;
后面的数据存储也是用两个结果寄存器
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT0 >>4)*3.0/4096.0;Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT1 >>4)*3.0/4096.0;
ConversionCount++;
使用A0和B0两个通道来采集,这样采样率是不是就是12.5M/2*2=3.125M了?这里的分母乘以2是什么意思?还有pwm的周期在这里的作用是什么?
是不是因为ADCCLK的频率是PWM的2倍,所以才在分母上乘以2的?
我的想法是采集两个通道的数据,采集1024个数据存入数组,然后再把数组中的数据输入显示屏,我设置的pwm频率为6.25MHZ,ADCCLK为12.5MHZ,采样率即为pwm的频率,可是实际测试结果的采样率只有300K左右,请大神指导一下,下面是我的程序。采样率的设置是在InitAdc1(void); InitEPwm1Example();ADC_cai(void);这三个子函数中
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File
/**************************************宏定义************************************************/
#define DELAY_TIME_min 200 //延时时间(短)
#define DELAY_TIME_max 500000 //延时时间(长)
#define delay_short 300 // 10us
#define delay_long 300000 // 10ms
#define delay_mid 3000 #define SCIC 1
#define ADC_MODCLK 0x3 //ADC_MODCLK=HISPCP, HSPCLK = SYSCLKOUT/2*ADC_MODCLK = 150/(2*3)=25.0 MHz
/*****************************************************************************************************/
//串口C声明
void scic_loopback_init(void);
void scic_fifo_init(void);
void scic_xmit(int a);
void delay(Uint32 t);
void ADC_cai(void);
//串口相关变量
int j=0,w=0,y=0;//w用来设置等待adc采集,w=1表示采完结束。y表示一共执行adc采集中断子程序128次,共采到1024个点
char msg1[6]={0x5A,0xA5,0x05,0x82,0x10,0x05}; //Y_center相关指令
char msg2[6]={0x5A,0xA5,0x05,0x82,0x10,0x06}; //VD_center相关指令 char msg3[6]={0x5A,0xA5,0x05,0x82,0x10,0x09}; //横轴间隔设置相关指令
char msg4[6]={0x5A,0xA5,0x05,0x82,0x10,0x08}; //纵轴放大倍数设置相关指令
char msg[5]={0x5A,0xA5,0x04,0x84,0x01}; //写数据指令
char msg5[6]={0x5A,0xA5,0x03,0x80,0xEB,0x56};
int i=0;
int c_data; //要写的数据值
int c_data1,c_data2,c_data0;//中间转换参量
int dat_max,dat_mid,dat_min,mul;
/*************************************串口*********************************/
// Test 1,SCIC DLB, 8-bit word, baud rate 9.6k, default, 1 STOP bit, no parity
//该例中的全局变量:
Uint16 LoopCount;
Uint16 ConversionCount;
float Voltage1[1024]={0};
float Voltage2[1024]={0};
//unsigned int Voltage_1[100]={0};//unsigned int Voltage_2[100]={0};
float Voltage_1[1024]={0};
float Voltage_2[1024]={0};
void InitAdc1(void);
void InitEPwm1Example();
volatile unsigned int adconvover=0;
interrupt void epwm1_timer_isr(void);//如果中断服务程序放在主函数的下面则在主函数前需要对中断服务程序进行声明,在主函数的上面则不需要。
Uint16 EPwm1TimerIntCount;
float a=4096;float V2_max=0;
main()
{
int i,j;
InitSysCtrl(); //初始化系统函数
//InitGpio(); // 该例中跳过
InitScicGpio(); //选择GPIO口,初始化GPIO口
DINT;
IER = 0x0000; //禁止CPU中断
IFR = 0x0000; //清除CPU中断标志
InitPieCtrl(); //初始化PIE控制寄存器
InitPieVectTable(); //初始化PIE中断向量表
InitAdc1(); //初始化ADC模块
InitEPwm1Example();//初始化EPwm1模块
EnableInterrupts();
scic_fifo_init(); // Initialize the SCI FIFO
scic_loopback_init();//服务程序
EALLOW; // This is needed to write to EALLOW protected register
//PieVectTable.ADCINT = &adc_isr;
SysCtrlRegs.HISPCP.all=ADC_MODCLK;//HISPCP=ADC_MODCLK, HISPCLK=SYSCLKOUT/2*HISPCP
PieVectTable.EPWM1_INT = &epwm1_timer_isr;
EDIS;
//开中断
PieCtrlRegs.PIEIER1.bit.INTx6=1;PieCtrlRegs.PIEIER1.bit.INTx1=1;
PieCtrlRegs.PIEIER3.bit.INTx1 =0;//关PIE中断,EPWM-T1定时器中断位于INT3.1
IER |= M_INT3; //开CPU中断
EINT; // 使能全局中断
ERTM; // 使能实时中断
//epwm1_timer_isr();
// 等待ADC中断 // Initalize SCI dat_max=2000;
dat_mid=1000;
dat_min=0;
mul=440.0*256/(dat_max-dat_min);
#if SCIC
//清屏
for (i=0;i<6;i++)
{
scic_xmit(msg5[i]);
delay(delay_short);
}
delay(delay_long);
delay(delay_long);
//修改VD-Center值
c_data=dat_mid; c_data0=c_data;
c_data2=0xff&c_data0; // data2 为data的低八位数据
c_data0=c_data>>8;
c_data1=0xff&c_data0; // data1 为data的高八位数据
i = 0;
for (i=0;i<6;i++)
{
scic_xmit(msg2[i]);
delay(delay_short);
}
scic_xmit(c_data1);
delay(delay_short);
scic_xmit(c_data2);
delay(delay_short);
delay(delay_long);
delay(delay_long);
//修改纵轴放大倍数
c_data=mul;
c_data0=c_data;
c_data2=0xff&c_data0; // data2 为data的低八位数据
c_data0=c_data>>8;
c_data1=0xff&c_data0; // data1 为data的高八位数据
i = 0;
for (i=0;i<6;i++)
{
scic_xmit(msg4[i]);
delay(delay_short);
}
scic_xmit(c_data1);
delay(delay_short);
scic_xmit(c_data2);
delay(delay_short);
delay(delay_long);
delay(delay_long);
delay(delay_long);
//修改横轴间隔数
c_data=5; c_data0=c_data;
c_data2=0xff&c_data0; // data2 为data的低八位数据
c_data0=c_data>>8;
c_data1=0xff&c_data0; // data1 为data的高八位数据
i = 0;
for (i=0;i<6;i++)
{
scic_xmit(msg3[i]);
delay(delay_short);
}
scic_xmit(c_data1);
delay(delay_short);
scic_xmit(c_data2);
delay(delay_short);
delay(delay_long);
while(ScicRegs.SCIFFTX.bit.TXFFST != 0);
#endif
ConversionCount = 0;
EPwm1TimerIntCount=0;
delay(delay_long);
while(1)
{
ADC_cai();
#if SCIC
for(j=0;j<1024;j++)
{ c_data=Voltage_2[j]*1000-100;
c_data0=c_data;
c_data2=0xff&c_data0; // data2 为data的低八位数据
c_data0=c_data>>8;
c_data1=0xff&c_data0; // data1 为data的高八位数据
i = 0;
for (i=0;i<5;i++)
{
scic_xmit(msg[i]);
delay(delay_short);
}
scic_xmit(c_data1);
delay(delay_short);
scic_xmit(c_data2);
delay(delay_short);
// ConversionCount++;
delay(delay_long);
}
//ConversionCount=0;
// delay(delay_long);
while(ScicRegs.SCIFFTX.bit.TXFFST != 0);
#endif
}
}
void InitEPwm1Example()
{
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;// 在系统初始化函数中已经使能 //EPWM模块,此处只需设置禁止同步。
EDIS;
//1.设置TB模块
EPwm1Regs.TBPRD =12; //18750 //2ms //设置计数周期=600TBCLK//EPwm1Regs.TBPRD = 6000;
EPwm1Regs.CMPA.half.CMPA = 6; // 比较器A = 300TBCLK//EPwm1Regs.CMPA.half.CMPA = 500;EPwm1Regs.CMPB = 20; //比较器 B = 500 TBCLKEPwm1Regs.TBPHS.half.TBPHS = 0x0000; // 设置相位寄存器置零
EPwm1Regs.TBCTR = 0x0000; // 清除TB计数器
// Setup TBCLK = SYSCLKOUT / (HSPCLKDIV * CLKDIV)=150/4*4
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; //计数方式设置00 //Up-count mode;01Down-count mode;10 Up-down-count mode
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // 禁止相位加载
EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW; //从阴影寄存器加载计数值
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;//禁用同步输出,在头文 //件DSP2833x-ePwm-defines.h中有定义
EPwm1Regs.TBCTL.bit.HSPCLKDIV =TB_DIV1;//TB_DIV1=0
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;//TB_DIV1=0
EPwm1Regs.TBCTL.bit.FREE_SOFT = 0x3; //仿真模式位:自由运行
//设置比较模块
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // 映射模式Load registers //every ZERO
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR = Zero
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
// 设置动作模块
EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;
EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;
EPwm1Regs.AQCTLB.bit.CBU = AQ_SET;
EPwm1Regs.AQCTLB.bit.CBD = AQ_CLEAR;
//事件触发子模块设置
//1.开始转换脉冲SOCA设置
EPwm1Regs.ETSEL.bit.SOCAEN = 1; // 使能ADC开始转换A(EPWMxSOCA)脉冲 把1修改成了0,在ADC_cai()中再赋值1触发adc采集
EPwm1Regs.ETSEL.bit.SOCASEL = 4; //设置EPWMxSOCA何时生成,2,TBCTR=TBPRD
EPwm1Regs.ETPS.bit.SOCAPRD = 3; //第三个中断事件A发生,即EPWMxSOCA生成
//2.EPWM中断设置
EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_PRD;//EPWM中断设置,此处设置为周期中断
EPwm1Regs.ETSEL.bit.INTEN = 1; //使能EPWM中断
EPwm1Regs.ETPS.bit.INTPRD = ET_1ST;//第一个事件发生时产生中断
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;// Enable TBCLK within the ePWM
EDIS;
}
void InitAdc1(void)
{
Uint16 i;
AdcRegs.ADCTRL1.bit.RESET=1; //复位AD 模块
for(i=0;i<9;i++)
{asm(" NOP");}
AdcRegs.ADCTRL1.bit.RESET=0;
AdcRegs.ADCTRL1.bit.SUSMOD=0; //仿真暂停方式,0为忽略。
AdcRegs.ADCTRL1.bit.ACQ_PS=0; //控制sSOC的脉冲宽度,同时也决定了采样开关闭合的时间。设定窗口大小SC=ADCTRL1[11:8] + 1 个ADCCLK周期数;AdcRegs.ADCTRL1.bit.CPS=0; //内核时钟预定标器,1为二分频 ADC Core clock divider :HSPCLK/[2*(ADCTRL1[7]:CPS + 1)]
AdcRegs.ADCTRL1.bit.CONT_RUN=1;//连续运行方式,0:敉7绞?1:连续转换方式.
AdcRegs.ADCTRL1.bit.SEQ_CASC=1; //**级联蛄蟹⑸鞴ぷ鞣绞剑? 双序列模 //式;1 级联模式
//ADCTRL3对电源和采样方式进行设置
AdcRegs.ADCTRL3.bit.ADCBGRFDN=3;//带隙参考电路上电
for(i=0;i<10000;i++)
{asm(" NOP");}
AdcRegs.ADCTRL3.bit.ADCPWDN=1;//除带隙参考电路獾钠渌鸄DC模块上电
for(i=0;i<5000;i++)
{asm(" NOP");}
AdcRegs.ADCTRL3.bit.ADCCLKPS=2; // ADCCLK=HISPCLK/[2*ADCCLKPS*(ADCTRL1[7].CPS+1)]
AdcRegs.ADCTRL3.bit.SMODE_SEL=1; //采样方式。顺序采样0/同步采样1
AdcRegs.ADCMAXCONV.bit.MAX_CONV1=0x07; //设定转换数量,共8同步采样(每 //次采样两个通道),共采样16路
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 0x0; //采样ADCINA0和ADCINB0
//ADC状态和标志寄存器ADCST(清除中断标志)
AdcRegs.ADCST.bit.INT_SEQ1_CLR=1;//中断清除位
AdcRegs.ADCST.bit.INT_SEQ2_CLR=1;
//AdcRegs.ADCTRL2.all=0x2800;
AdcRegs.ADCTRL2.bit.EPWM_SOCB_SEQ=0;
AdcRegs.ADCTRL2.bit.RST_SEQ1=1;// 复位序列发生器1
//SEQ1
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1=0;//SEQ1中断使能:0禁止INT SEQ1向CPU发出中断申请,1使能INT SEQ1向CPU发出中断申请
AdcRegs.ADCTRL2.bit.INT_MOD_SEQ1=0;//SEQ1中断方式:0每个SEQ1序列转换 束,置位SEQ1的中断标志
AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1=1;//SEQ1的EPWM SOCA使能位,1使能
AdcRegs.ADCTRL2.bit.EXT_SOC_SEQ1=0;//SEQ1的外部SOC信号位,0:无操作。1:外部ADCSOC引脚信号启动ADC自动转换序列。
AdcRegs.ADCTRL2.bit.SOC_SEQ1=0;//为1时,软件启动ADC转换.
//SEQ2
AdcRegs.ADCTRL2.bit.RST_SEQ2=0; //复位SEQ2
AdcRegs.ADCTRL2.bit.SOC_SEQ2=0; //启动SEQ2的转换触发。仅适用于双序 //列发生器模式
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ2=0;
AdcRegs.ADCTRL2.bit.INT_MOD_SEQ2=0;
AdcRegs.ADCTRL2.bit.EPWM_SOCB_SEQ2=0;
}
void ADC_cai(void)
{
AdcRegs.ADCTRL2.bit.RST_SEQ1=1;
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; PieCtrlRegs.PIEACK.all|=0x0001;
PieCtrlRegs.PIEIER1.bit.INTx1=0;
for(i=0;i<5000;i++)
{asm(" NOP");}
w=0;
PieCtrlRegs.PIEIER1.bit.INTx6=0;//控制ADC中断
// delay(DELAY_TIME_min);
AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;//为1时,软件启动ADC转换//为1时,软件启动ADC转换
//PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
EPwm1Regs.ETSEL.bit.SOCAEN = 1; // 使能ADC开始转换A(EPWMxSOCA)脉冲
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
//EPwm1Regs.ETCLR.bit.INT = 1;
EPwm1Regs.ETSEL.bit.INTEN = 1;//使能ePWM中断产生位;1:使能中断;0:禁止中断
loop: if(w==0)
{
goto loop;
}
// delay(DELAY_TIME_max);
PieCtrlRegs.PIEIER1.bit.INTx6=1; PieCtrlRegs.PIEIER1.bit.INTx1=1;
}
//EPWM1的定时器中断
interrupt void epwm1_timer_isr(void)
{
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;//向该位写1,清除SEQ1中断标志位,INT_SEQ1,该位对EOS_BUF1位无影响。
//AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;//为1时,软件启动ADC转换//为1时,软件启动ADC转换
PieCtrlRegs.PIEACK.all |= PIEACK_GROUP1;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT0 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT1 >>4)*3.0/4096.0;
ConversionCount++;
// Voltage_1[ConversionCount] = AdcRegs.ADCRESULT2;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT2 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT3 >>4)*3.0/4096.0;
ConversionCount++;
//Voltage_1[ConversionCount] = AdcRegs.ADCRESULT4 ;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT4 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT5 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT6 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT7 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT8 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT9 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT10 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT11 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT12 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT13 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT14 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT15 >>4)*3.0/4096.0;
ConversionCount++;
//y++;
if(ConversionCount> 1023)
{
ConversionCount = 0;
w=1;
//y=0;
//ConversionCount = 0;
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;//复位SEQ1为初始状态 CONV00
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1=1;
PieCtrlRegs.PIEIER3.bit.INTx1 = 0;//使能PIE中断,EPWM-T1定时器中断位于INT3.1
EPwm1Regs.ETSEL.bit.INTEN = 0;//使能ePWM中断产生位;1:使能中断;0:禁止中断
//AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1=0;
// AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;
PieCtrlRegs.PIEACK.all= PIEACK_GROUP3;
EPwm1Regs.ETCLR.all = 0xD;//epwm中断标准清除位,0:没有效果;1:清除中断标志位
// AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; // Clear INT SEQ1 bit,清除INT SEQ1标志位
}
else {
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; // Reset SEQ1
EPwm1Regs.ETCLR.bit.INT = 1;
// AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;
//PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
//EPwm1Regs.ETSEL.bit.INTEN = 1;//使能ePWM中断产生位;1:使能中断;0:禁止中断
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
// AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;//为1时,软件启动ADC转换//为1时,软件启动ADC转换
}
}
void scic_loopback_init()
{
// Note: Clocks were turned on to the SCIC peripheral
// in the InitSysCtrl() function
ScicRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback
// No parity,8 char bits,
// async mode, idle-line protocol
ScicRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK,
// Disable RX ERR, SLEEP, TXWAKE
ScicRegs.SCICTL2.all =0x0003;
ScicRegs.SCICTL2.bit.TXINTENA =1;
ScicRegs.SCICTL2.bit.RXBKINTENA =1;
ScicRegs.SCIHBAUD =0x0001;
ScicRegs.SCILBAUD =0x00e7;
ScicRegs.SCICCR.bit.LOOPBKENA =0;// enable loop back
ScicRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset
}
// Transmit a character from the SCI'
void scic_xmit(int a)
{
ScicRegs.SCITXBUF=a;
}
// Initalize the SCI FIFO
void scic_fifo_init()
{
ScicRegs.SCIFFTX.bit.TXFIFOXRESET=0;
ScicRegs.SCIFFRX.bit.RXFIFORESET=0;
ScicRegs.SCIFFTX.all=0xE040;
ScicRegs.SCIFFRX.all=0x204f;
ScicRegs.SCIFFCT.all=0x0;
}
void delay(Uint32 t)
{
Uint32 i = 0;
for (i = 0; i < t; i++);
}
Eric Ma:
回复 user4528677:
如果只有两个通道,那么最快的方式(设置为连续采样的模式)的采样率就为12.5/2*2 = 3.125M. 其中一个2是采样保持时间,至少需要2个ADC clk。
如果你设置为连续采样模式,然后采用软件触发第一次ADC采样,然后接下来ADC就会一直采样转换,不需要其他触发源。
PWM触发的作用更多在于低采样率的情况,比如几十K,几百K,这种情况下不需要连续采样那么快的采样率,就用PWM进行周期性触发就可以了。
Eric
我的想法是采集两个通道的数据,采集1024个数据存入数组,然后再把数组中的数据输入显示屏,我设置的pwm频率为6.25MHZ,ADCCLK为12.5MHZ,采样率即为pwm的频率,可是实际测试结果的采样率只有300K左右,请大神指导一下,下面是我的程序。采样率的设置是在InitAdc1(void); InitEPwm1Example();ADC_cai(void);这三个子函数中
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File
/**************************************宏定义************************************************/
#define DELAY_TIME_min 200 //延时时间(短)
#define DELAY_TIME_max 500000 //延时时间(长)
#define delay_short 300 // 10us
#define delay_long 300000 // 10ms
#define delay_mid 3000 #define SCIC 1
#define ADC_MODCLK 0x3 //ADC_MODCLK=HISPCP, HSPCLK = SYSCLKOUT/2*ADC_MODCLK = 150/(2*3)=25.0 MHz
/*****************************************************************************************************/
//串口C声明
void scic_loopback_init(void);
void scic_fifo_init(void);
void scic_xmit(int a);
void delay(Uint32 t);
void ADC_cai(void);
//串口相关变量
int j=0,w=0,y=0;//w用来设置等待adc采集,w=1表示采完结束。y表示一共执行adc采集中断子程序128次,共采到1024个点
char msg1[6]={0x5A,0xA5,0x05,0x82,0x10,0x05}; //Y_center相关指令
char msg2[6]={0x5A,0xA5,0x05,0x82,0x10,0x06}; //VD_center相关指令 char msg3[6]={0x5A,0xA5,0x05,0x82,0x10,0x09}; //横轴间隔设置相关指令
char msg4[6]={0x5A,0xA5,0x05,0x82,0x10,0x08}; //纵轴放大倍数设置相关指令
char msg[5]={0x5A,0xA5,0x04,0x84,0x01}; //写数据指令
char msg5[6]={0x5A,0xA5,0x03,0x80,0xEB,0x56};
int i=0;
int c_data; //要写的数据值
int c_data1,c_data2,c_data0;//中间转换参量
int dat_max,dat_mid,dat_min,mul;
/*************************************串口*********************************/
// Test 1,SCIC DLB, 8-bit word, baud rate 9.6k, default, 1 STOP bit, no parity
//该例中的全局变量:
Uint16 LoopCount;
Uint16 ConversionCount;
float Voltage1[1024]={0};
float Voltage2[1024]={0};
//unsigned int Voltage_1[100]={0};//unsigned int Voltage_2[100]={0};
float Voltage_1[1024]={0};
float Voltage_2[1024]={0};
void InitAdc1(void);
void InitEPwm1Example();
volatile unsigned int adconvover=0;
interrupt void epwm1_timer_isr(void);//如果中断服务程序放在主函数的下面则在主函数前需要对中断服务程序进行声明,在主函数的上面则不需要。
Uint16 EPwm1TimerIntCount;
float a=4096;float V2_max=0;
main()
{
int i,j;
InitSysCtrl(); //初始化系统函数
//InitGpio(); // 该例中跳过
InitScicGpio(); //选择GPIO口,初始化GPIO口
DINT;
IER = 0x0000; //禁止CPU中断
IFR = 0x0000; //清除CPU中断标志
InitPieCtrl(); //初始化PIE控制寄存器
InitPieVectTable(); //初始化PIE中断向量表
InitAdc1(); //初始化ADC模块
InitEPwm1Example();//初始化EPwm1模块
EnableInterrupts();
scic_fifo_init(); // Initialize the SCI FIFO
scic_loopback_init();//服务程序
EALLOW; // This is needed to write to EALLOW protected register
//PieVectTable.ADCINT = &adc_isr;
SysCtrlRegs.HISPCP.all=ADC_MODCLK;//HISPCP=ADC_MODCLK, HISPCLK=SYSCLKOUT/2*HISPCP
PieVectTable.EPWM1_INT = &epwm1_timer_isr;
EDIS;
//开中断
PieCtrlRegs.PIEIER1.bit.INTx6=1;PieCtrlRegs.PIEIER1.bit.INTx1=1;
PieCtrlRegs.PIEIER3.bit.INTx1 =0;//关PIE中断,EPWM-T1定时器中断位于INT3.1
IER |= M_INT3; //开CPU中断
EINT; // 使能全局中断
ERTM; // 使能实时中断
//epwm1_timer_isr();
// 等待ADC中断 // Initalize SCI dat_max=2000;
dat_mid=1000;
dat_min=0;
mul=440.0*256/(dat_max-dat_min);
#if SCIC
//清屏
for (i=0;i<6;i++)
{
scic_xmit(msg5[i]);
delay(delay_short);
}
delay(delay_long);
delay(delay_long);
//修改VD-Center值
c_data=dat_mid; c_data0=c_data;
c_data2=0xff&c_data0; // data2 为data的低八位数据
c_data0=c_data>>8;
c_data1=0xff&c_data0; // data1 为data的高八位数据
i = 0;
for (i=0;i<6;i++)
{
scic_xmit(msg2[i]);
delay(delay_short);
}
scic_xmit(c_data1);
delay(delay_short);
scic_xmit(c_data2);
delay(delay_short);
delay(delay_long);
delay(delay_long);
//修改纵轴放大倍数
c_data=mul;
c_data0=c_data;
c_data2=0xff&c_data0; // data2 为data的低八位数据
c_data0=c_data>>8;
c_data1=0xff&c_data0; // data1 为data的高八位数据
i = 0;
for (i=0;i<6;i++)
{
scic_xmit(msg4[i]);
delay(delay_short);
}
scic_xmit(c_data1);
delay(delay_short);
scic_xmit(c_data2);
delay(delay_short);
delay(delay_long);
delay(delay_long);
delay(delay_long);
//修改横轴间隔数
c_data=5; c_data0=c_data;
c_data2=0xff&c_data0; // data2 为data的低八位数据
c_data0=c_data>>8;
c_data1=0xff&c_data0; // data1 为data的高八位数据
i = 0;
for (i=0;i<6;i++)
{
scic_xmit(msg3[i]);
delay(delay_short);
}
scic_xmit(c_data1);
delay(delay_short);
scic_xmit(c_data2);
delay(delay_short);
delay(delay_long);
while(ScicRegs.SCIFFTX.bit.TXFFST != 0);
#endif
ConversionCount = 0;
EPwm1TimerIntCount=0;
delay(delay_long);
while(1)
{
ADC_cai();
#if SCIC
for(j=0;j<1024;j++)
{ c_data=Voltage_2[j]*1000-100;
c_data0=c_data;
c_data2=0xff&c_data0; // data2 为data的低八位数据
c_data0=c_data>>8;
c_data1=0xff&c_data0; // data1 为data的高八位数据
i = 0;
for (i=0;i<5;i++)
{
scic_xmit(msg[i]);
delay(delay_short);
}
scic_xmit(c_data1);
delay(delay_short);
scic_xmit(c_data2);
delay(delay_short);
// ConversionCount++;
delay(delay_long);
}
//ConversionCount=0;
// delay(delay_long);
while(ScicRegs.SCIFFTX.bit.TXFFST != 0);
#endif
}
}
void InitEPwm1Example()
{
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;// 在系统初始化函数中已经使能 //EPWM模块,此处只需设置禁止同步。
EDIS;
//1.设置TB模块
EPwm1Regs.TBPRD =12; //18750 //2ms //设置计数周期=600TBCLK//EPwm1Regs.TBPRD = 6000;
EPwm1Regs.CMPA.half.CMPA = 6; // 比较器A = 300TBCLK//EPwm1Regs.CMPA.half.CMPA = 500;EPwm1Regs.CMPB = 20; //比较器 B = 500 TBCLKEPwm1Regs.TBPHS.half.TBPHS = 0x0000; // 设置相位寄存器置零
EPwm1Regs.TBCTR = 0x0000; // 清除TB计数器
// Setup TBCLK = SYSCLKOUT / (HSPCLKDIV * CLKDIV)=150/4*4
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; //计数方式设置00 //Up-count mode;01Down-count mode;10 Up-down-count mode
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // 禁止相位加载
EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW; //从阴影寄存器加载计数值
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;//禁用同步输出,在头文 //件DSP2833x-ePwm-defines.h中有定义
EPwm1Regs.TBCTL.bit.HSPCLKDIV =TB_DIV1;//TB_DIV1=0
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;//TB_DIV1=0
EPwm1Regs.TBCTL.bit.FREE_SOFT = 0x3; //仿真模式位:自由运行
//设置比较模块
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // 映射模式Load registers //every ZERO
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR = Zero
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
// 设置动作模块
EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;
EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;
EPwm1Regs.AQCTLB.bit.CBU = AQ_SET;
EPwm1Regs.AQCTLB.bit.CBD = AQ_CLEAR;
//事件触发子模块设置
//1.开始转换脉冲SOCA设置
EPwm1Regs.ETSEL.bit.SOCAEN = 1; // 使能ADC开始转换A(EPWMxSOCA)脉冲 把1修改成了0,在ADC_cai()中再赋值1触发adc采集
EPwm1Regs.ETSEL.bit.SOCASEL = 4; //设置EPWMxSOCA何时生成,2,TBCTR=TBPRD
EPwm1Regs.ETPS.bit.SOCAPRD = 3; //第三个中断事件A发生,即EPWMxSOCA生成
//2.EPWM中断设置
EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_PRD;//EPWM中断设置,此处设置为周期中断
EPwm1Regs.ETSEL.bit.INTEN = 1; //使能EPWM中断
EPwm1Regs.ETPS.bit.INTPRD = ET_1ST;//第一个事件发生时产生中断
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;// Enable TBCLK within the ePWM
EDIS;
}
void InitAdc1(void)
{
Uint16 i;
AdcRegs.ADCTRL1.bit.RESET=1; //复位AD 模块
for(i=0;i<9;i++)
{asm(" NOP");}
AdcRegs.ADCTRL1.bit.RESET=0;
AdcRegs.ADCTRL1.bit.SUSMOD=0; //仿真暂停方式,0为忽略。
AdcRegs.ADCTRL1.bit.ACQ_PS=0; //控制sSOC的脉冲宽度,同时也决定了采样开关闭合的时间。设定窗口大小SC=ADCTRL1[11:8] + 1 个ADCCLK周期数;AdcRegs.ADCTRL1.bit.CPS=0; //内核时钟预定标器,1为二分频 ADC Core clock divider :HSPCLK/[2*(ADCTRL1[7]:CPS + 1)]
AdcRegs.ADCTRL1.bit.CONT_RUN=1;//连续运行方式,0:敉7绞?1:连续转换方式.
AdcRegs.ADCTRL1.bit.SEQ_CASC=1; //**级联蛄蟹⑸鞴ぷ鞣绞剑? 双序列模 //式;1 级联模式
//ADCTRL3对电源和采样方式进行设置
AdcRegs.ADCTRL3.bit.ADCBGRFDN=3;//带隙参考电路上电
for(i=0;i<10000;i++)
{asm(" NOP");}
AdcRegs.ADCTRL3.bit.ADCPWDN=1;//除带隙参考电路獾钠渌鸄DC模块上电
for(i=0;i<5000;i++)
{asm(" NOP");}
AdcRegs.ADCTRL3.bit.ADCCLKPS=2; // ADCCLK=HISPCLK/[2*ADCCLKPS*(ADCTRL1[7].CPS+1)]
AdcRegs.ADCTRL3.bit.SMODE_SEL=1; //采样方式。顺序采样0/同步采样1
AdcRegs.ADCMAXCONV.bit.MAX_CONV1=0x07; //设定转换数量,共8同步采样(每 //次采样两个通道),共采样16路
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 0x0; //采样ADCINA0和ADCINB0
//ADC状态和标志寄存器ADCST(清除中断标志)
AdcRegs.ADCST.bit.INT_SEQ1_CLR=1;//中断清除位
AdcRegs.ADCST.bit.INT_SEQ2_CLR=1;
//AdcRegs.ADCTRL2.all=0x2800;
AdcRegs.ADCTRL2.bit.EPWM_SOCB_SEQ=0;
AdcRegs.ADCTRL2.bit.RST_SEQ1=1;// 复位序列发生器1
//SEQ1
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1=0;//SEQ1中断使能:0禁止INT SEQ1向CPU发出中断申请,1使能INT SEQ1向CPU发出中断申请
AdcRegs.ADCTRL2.bit.INT_MOD_SEQ1=0;//SEQ1中断方式:0每个SEQ1序列转换 束,置位SEQ1的中断标志
AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1=1;//SEQ1的EPWM SOCA使能位,1使能
AdcRegs.ADCTRL2.bit.EXT_SOC_SEQ1=0;//SEQ1的外部SOC信号位,0:无操作。1:外部ADCSOC引脚信号启动ADC自动转换序列。
AdcRegs.ADCTRL2.bit.SOC_SEQ1=0;//为1时,软件启动ADC转换.
//SEQ2
AdcRegs.ADCTRL2.bit.RST_SEQ2=0; //复位SEQ2
AdcRegs.ADCTRL2.bit.SOC_SEQ2=0; //启动SEQ2的转换触发。仅适用于双序 //列发生器模式
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ2=0;
AdcRegs.ADCTRL2.bit.INT_MOD_SEQ2=0;
AdcRegs.ADCTRL2.bit.EPWM_SOCB_SEQ2=0;
}
void ADC_cai(void)
{
AdcRegs.ADCTRL2.bit.RST_SEQ1=1;
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; PieCtrlRegs.PIEACK.all|=0x0001;
PieCtrlRegs.PIEIER1.bit.INTx1=0;
for(i=0;i<5000;i++)
{asm(" NOP");}
w=0;
PieCtrlRegs.PIEIER1.bit.INTx6=0;//控制ADC中断
// delay(DELAY_TIME_min);
AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;//为1时,软件启动ADC转换//为1时,软件启动ADC转换
//PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
EPwm1Regs.ETSEL.bit.SOCAEN = 1; // 使能ADC开始转换A(EPWMxSOCA)脉冲
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
//EPwm1Regs.ETCLR.bit.INT = 1;
EPwm1Regs.ETSEL.bit.INTEN = 1;//使能ePWM中断产生位;1:使能中断;0:禁止中断
loop: if(w==0)
{
goto loop;
}
// delay(DELAY_TIME_max);
PieCtrlRegs.PIEIER1.bit.INTx6=1; PieCtrlRegs.PIEIER1.bit.INTx1=1;
}
//EPWM1的定时器中断
interrupt void epwm1_timer_isr(void)
{
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;//向该位写1,清除SEQ1中断标志位,INT_SEQ1,该位对EOS_BUF1位无影响。
//AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;//为1时,软件启动ADC转换//为1时,软件启动ADC转换
PieCtrlRegs.PIEACK.all |= PIEACK_GROUP1;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT0 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT1 >>4)*3.0/4096.0;
ConversionCount++;
// Voltage_1[ConversionCount] = AdcRegs.ADCRESULT2;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT2 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT3 >>4)*3.0/4096.0;
ConversionCount++;
//Voltage_1[ConversionCount] = AdcRegs.ADCRESULT4 ;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT4 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT5 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT6 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT7 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT8 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT9 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT10 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT11 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT12 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT13 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT14 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT15 >>4)*3.0/4096.0;
ConversionCount++;
//y++;
if(ConversionCount> 1023)
{
ConversionCount = 0;
w=1;
//y=0;
//ConversionCount = 0;
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;//复位SEQ1为初始状态 CONV00
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1=1;
PieCtrlRegs.PIEIER3.bit.INTx1 = 0;//使能PIE中断,EPWM-T1定时器中断位于INT3.1
EPwm1Regs.ETSEL.bit.INTEN = 0;//使能ePWM中断产生位;1:使能中断;0:禁止中断
//AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1=0;
// AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;
PieCtrlRegs.PIEACK.all= PIEACK_GROUP3;
EPwm1Regs.ETCLR.all = 0xD;//epwm中断标准清除位,0:没有效果;1:清除中断标志位
// AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; // Clear INT SEQ1 bit,清除INT SEQ1标志位
}
else {
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; // Reset SEQ1
EPwm1Regs.ETCLR.bit.INT = 1;
// AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;
//PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
//EPwm1Regs.ETSEL.bit.INTEN = 1;//使能ePWM中断产生位;1:使能中断;0:禁止中断
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
// AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;//为1时,软件启动ADC转换//为1时,软件启动ADC转换
}
}
void scic_loopback_init()
{
// Note: Clocks were turned on to the SCIC peripheral
// in the InitSysCtrl() function
ScicRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback
// No parity,8 char bits,
// async mode, idle-line protocol
ScicRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK,
// Disable RX ERR, SLEEP, TXWAKE
ScicRegs.SCICTL2.all =0x0003;
ScicRegs.SCICTL2.bit.TXINTENA =1;
ScicRegs.SCICTL2.bit.RXBKINTENA =1;
ScicRegs.SCIHBAUD =0x0001;
ScicRegs.SCILBAUD =0x00e7;
ScicRegs.SCICCR.bit.LOOPBKENA =0;// enable loop back
ScicRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset
}
// Transmit a character from the SCI'
void scic_xmit(int a)
{
ScicRegs.SCITXBUF=a;
}
// Initalize the SCI FIFO
void scic_fifo_init()
{
ScicRegs.SCIFFTX.bit.TXFIFOXRESET=0;
ScicRegs.SCIFFRX.bit.RXFIFORESET=0;
ScicRegs.SCIFFTX.all=0xE040;
ScicRegs.SCIFFRX.all=0x204f;
ScicRegs.SCIFFCT.all=0x0;
}
void delay(Uint32 t)
{
Uint32 i = 0;
for (i = 0; i < t; i++);
}
user4528677:
回复 Eric Ma:
非常感谢你的回答,我是初学者因为这个问题困扰我一段时间了,这些回答对我帮助很大,我来实际测试下,若有什么问题的话还请你不吝赐教
我的想法是采集两个通道的数据,采集1024个数据存入数组,然后再把数组中的数据输入显示屏,我设置的pwm频率为6.25MHZ,ADCCLK为12.5MHZ,采样率即为pwm的频率,可是实际测试结果的采样率只有300K左右,请大神指导一下,下面是我的程序。采样率的设置是在InitAdc1(void); InitEPwm1Example();ADC_cai(void);这三个子函数中
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File
/**************************************宏定义************************************************/
#define DELAY_TIME_min 200 //延时时间(短)
#define DELAY_TIME_max 500000 //延时时间(长)
#define delay_short 300 // 10us
#define delay_long 300000 // 10ms
#define delay_mid 3000 #define SCIC 1
#define ADC_MODCLK 0x3 //ADC_MODCLK=HISPCP, HSPCLK = SYSCLKOUT/2*ADC_MODCLK = 150/(2*3)=25.0 MHz
/*****************************************************************************************************/
//串口C声明
void scic_loopback_init(void);
void scic_fifo_init(void);
void scic_xmit(int a);
void delay(Uint32 t);
void ADC_cai(void);
//串口相关变量
int j=0,w=0,y=0;//w用来设置等待adc采集,w=1表示采完结束。y表示一共执行adc采集中断子程序128次,共采到1024个点
char msg1[6]={0x5A,0xA5,0x05,0x82,0x10,0x05}; //Y_center相关指令
char msg2[6]={0x5A,0xA5,0x05,0x82,0x10,0x06}; //VD_center相关指令 char msg3[6]={0x5A,0xA5,0x05,0x82,0x10,0x09}; //横轴间隔设置相关指令
char msg4[6]={0x5A,0xA5,0x05,0x82,0x10,0x08}; //纵轴放大倍数设置相关指令
char msg[5]={0x5A,0xA5,0x04,0x84,0x01}; //写数据指令
char msg5[6]={0x5A,0xA5,0x03,0x80,0xEB,0x56};
int i=0;
int c_data; //要写的数据值
int c_data1,c_data2,c_data0;//中间转换参量
int dat_max,dat_mid,dat_min,mul;
/*************************************串口*********************************/
// Test 1,SCIC DLB, 8-bit word, baud rate 9.6k, default, 1 STOP bit, no parity
//该例中的全局变量:
Uint16 LoopCount;
Uint16 ConversionCount;
float Voltage1[1024]={0};
float Voltage2[1024]={0};
//unsigned int Voltage_1[100]={0};//unsigned int Voltage_2[100]={0};
float Voltage_1[1024]={0};
float Voltage_2[1024]={0};
void InitAdc1(void);
void InitEPwm1Example();
volatile unsigned int adconvover=0;
interrupt void epwm1_timer_isr(void);//如果中断服务程序放在主函数的下面则在主函数前需要对中断服务程序进行声明,在主函数的上面则不需要。
Uint16 EPwm1TimerIntCount;
float a=4096;float V2_max=0;
main()
{
int i,j;
InitSysCtrl(); //初始化系统函数
//InitGpio(); // 该例中跳过
InitScicGpio(); //选择GPIO口,初始化GPIO口
DINT;
IER = 0x0000; //禁止CPU中断
IFR = 0x0000; //清除CPU中断标志
InitPieCtrl(); //初始化PIE控制寄存器
InitPieVectTable(); //初始化PIE中断向量表
InitAdc1(); //初始化ADC模块
InitEPwm1Example();//初始化EPwm1模块
EnableInterrupts();
scic_fifo_init(); // Initialize the SCI FIFO
scic_loopback_init();//服务程序
EALLOW; // This is needed to write to EALLOW protected register
//PieVectTable.ADCINT = &adc_isr;
SysCtrlRegs.HISPCP.all=ADC_MODCLK;//HISPCP=ADC_MODCLK, HISPCLK=SYSCLKOUT/2*HISPCP
PieVectTable.EPWM1_INT = &epwm1_timer_isr;
EDIS;
//开中断
PieCtrlRegs.PIEIER1.bit.INTx6=1;PieCtrlRegs.PIEIER1.bit.INTx1=1;
PieCtrlRegs.PIEIER3.bit.INTx1 =0;//关PIE中断,EPWM-T1定时器中断位于INT3.1
IER |= M_INT3; //开CPU中断
EINT; // 使能全局中断
ERTM; // 使能实时中断
//epwm1_timer_isr();
// 等待ADC中断 // Initalize SCI dat_max=2000;
dat_mid=1000;
dat_min=0;
mul=440.0*256/(dat_max-dat_min);
#if SCIC
//清屏
for (i=0;i<6;i++)
{
scic_xmit(msg5[i]);
delay(delay_short);
}
delay(delay_long);
delay(delay_long);
//修改VD-Center值
c_data=dat_mid; c_data0=c_data;
c_data2=0xff&c_data0; // data2 为data的低八位数据
c_data0=c_data>>8;
c_data1=0xff&c_data0; // data1 为data的高八位数据
i = 0;
for (i=0;i<6;i++)
{
scic_xmit(msg2[i]);
delay(delay_short);
}
scic_xmit(c_data1);
delay(delay_short);
scic_xmit(c_data2);
delay(delay_short);
delay(delay_long);
delay(delay_long);
//修改纵轴放大倍数
c_data=mul;
c_data0=c_data;
c_data2=0xff&c_data0; // data2 为data的低八位数据
c_data0=c_data>>8;
c_data1=0xff&c_data0; // data1 为data的高八位数据
i = 0;
for (i=0;i<6;i++)
{
scic_xmit(msg4[i]);
delay(delay_short);
}
scic_xmit(c_data1);
delay(delay_short);
scic_xmit(c_data2);
delay(delay_short);
delay(delay_long);
delay(delay_long);
delay(delay_long);
//修改横轴间隔数
c_data=5; c_data0=c_data;
c_data2=0xff&c_data0; // data2 为data的低八位数据
c_data0=c_data>>8;
c_data1=0xff&c_data0; // data1 为data的高八位数据
i = 0;
for (i=0;i<6;i++)
{
scic_xmit(msg3[i]);
delay(delay_short);
}
scic_xmit(c_data1);
delay(delay_short);
scic_xmit(c_data2);
delay(delay_short);
delay(delay_long);
while(ScicRegs.SCIFFTX.bit.TXFFST != 0);
#endif
ConversionCount = 0;
EPwm1TimerIntCount=0;
delay(delay_long);
while(1)
{
ADC_cai();
#if SCIC
for(j=0;j<1024;j++)
{ c_data=Voltage_2[j]*1000-100;
c_data0=c_data;
c_data2=0xff&c_data0; // data2 为data的低八位数据
c_data0=c_data>>8;
c_data1=0xff&c_data0; // data1 为data的高八位数据
i = 0;
for (i=0;i<5;i++)
{
scic_xmit(msg[i]);
delay(delay_short);
}
scic_xmit(c_data1);
delay(delay_short);
scic_xmit(c_data2);
delay(delay_short);
// ConversionCount++;
delay(delay_long);
}
//ConversionCount=0;
// delay(delay_long);
while(ScicRegs.SCIFFTX.bit.TXFFST != 0);
#endif
}
}
void InitEPwm1Example()
{
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;// 在系统初始化函数中已经使能 //EPWM模块,此处只需设置禁止同步。
EDIS;
//1.设置TB模块
EPwm1Regs.TBPRD =12; //18750 //2ms //设置计数周期=600TBCLK//EPwm1Regs.TBPRD = 6000;
EPwm1Regs.CMPA.half.CMPA = 6; // 比较器A = 300TBCLK//EPwm1Regs.CMPA.half.CMPA = 500;EPwm1Regs.CMPB = 20; //比较器 B = 500 TBCLKEPwm1Regs.TBPHS.half.TBPHS = 0x0000; // 设置相位寄存器置零
EPwm1Regs.TBCTR = 0x0000; // 清除TB计数器
// Setup TBCLK = SYSCLKOUT / (HSPCLKDIV * CLKDIV)=150/4*4
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; //计数方式设置00 //Up-count mode;01Down-count mode;10 Up-down-count mode
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // 禁止相位加载
EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW; //从阴影寄存器加载计数值
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;//禁用同步输出,在头文 //件DSP2833x-ePwm-defines.h中有定义
EPwm1Regs.TBCTL.bit.HSPCLKDIV =TB_DIV1;//TB_DIV1=0
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;//TB_DIV1=0
EPwm1Regs.TBCTL.bit.FREE_SOFT = 0x3; //仿真模式位:自由运行
//设置比较模块
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // 映射模式Load registers //every ZERO
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR = Zero
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
// 设置动作模块
EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;
EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;
EPwm1Regs.AQCTLB.bit.CBU = AQ_SET;
EPwm1Regs.AQCTLB.bit.CBD = AQ_CLEAR;
//事件触发子模块设置
//1.开始转换脉冲SOCA设置
EPwm1Regs.ETSEL.bit.SOCAEN = 1; // 使能ADC开始转换A(EPWMxSOCA)脉冲 把1修改成了0,在ADC_cai()中再赋值1触发adc采集
EPwm1Regs.ETSEL.bit.SOCASEL = 4; //设置EPWMxSOCA何时生成,2,TBCTR=TBPRD
EPwm1Regs.ETPS.bit.SOCAPRD = 3; //第三个中断事件A发生,即EPWMxSOCA生成
//2.EPWM中断设置
EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_PRD;//EPWM中断设置,此处设置为周期中断
EPwm1Regs.ETSEL.bit.INTEN = 1; //使能EPWM中断
EPwm1Regs.ETPS.bit.INTPRD = ET_1ST;//第一个事件发生时产生中断
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;// Enable TBCLK within the ePWM
EDIS;
}
void InitAdc1(void)
{
Uint16 i;
AdcRegs.ADCTRL1.bit.RESET=1; //复位AD 模块
for(i=0;i<9;i++)
{asm(" NOP");}
AdcRegs.ADCTRL1.bit.RESET=0;
AdcRegs.ADCTRL1.bit.SUSMOD=0; //仿真暂停方式,0为忽略。
AdcRegs.ADCTRL1.bit.ACQ_PS=0; //控制sSOC的脉冲宽度,同时也决定了采样开关闭合的时间。设定窗口大小SC=ADCTRL1[11:8] + 1 个ADCCLK周期数;AdcRegs.ADCTRL1.bit.CPS=0; //内核时钟预定标器,1为二分频 ADC Core clock divider :HSPCLK/[2*(ADCTRL1[7]:CPS + 1)]
AdcRegs.ADCTRL1.bit.CONT_RUN=1;//连续运行方式,0:敉7绞?1:连续转换方式.
AdcRegs.ADCTRL1.bit.SEQ_CASC=1; //**级联蛄蟹⑸鞴ぷ鞣绞剑? 双序列模 //式;1 级联模式
//ADCTRL3对电源和采样方式进行设置
AdcRegs.ADCTRL3.bit.ADCBGRFDN=3;//带隙参考电路上电
for(i=0;i<10000;i++)
{asm(" NOP");}
AdcRegs.ADCTRL3.bit.ADCPWDN=1;//除带隙参考电路獾钠渌鸄DC模块上电
for(i=0;i<5000;i++)
{asm(" NOP");}
AdcRegs.ADCTRL3.bit.ADCCLKPS=2; // ADCCLK=HISPCLK/[2*ADCCLKPS*(ADCTRL1[7].CPS+1)]
AdcRegs.ADCTRL3.bit.SMODE_SEL=1; //采样方式。顺序采样0/同步采样1
AdcRegs.ADCMAXCONV.bit.MAX_CONV1=0x07; //设定转换数量,共8同步采样(每 //次采样两个通道),共采样16路
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 0x0; //采样ADCINA0和ADCINB0
//ADC状态和标志寄存器ADCST(清除中断标志)
AdcRegs.ADCST.bit.INT_SEQ1_CLR=1;//中断清除位
AdcRegs.ADCST.bit.INT_SEQ2_CLR=1;
//AdcRegs.ADCTRL2.all=0x2800;
AdcRegs.ADCTRL2.bit.EPWM_SOCB_SEQ=0;
AdcRegs.ADCTRL2.bit.RST_SEQ1=1;// 复位序列发生器1
//SEQ1
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1=0;//SEQ1中断使能:0禁止INT SEQ1向CPU发出中断申请,1使能INT SEQ1向CPU发出中断申请
AdcRegs.ADCTRL2.bit.INT_MOD_SEQ1=0;//SEQ1中断方式:0每个SEQ1序列转换 束,置位SEQ1的中断标志
AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1=1;//SEQ1的EPWM SOCA使能位,1使能
AdcRegs.ADCTRL2.bit.EXT_SOC_SEQ1=0;//SEQ1的外部SOC信号位,0:无操作。1:外部ADCSOC引脚信号启动ADC自动转换序列。
AdcRegs.ADCTRL2.bit.SOC_SEQ1=0;//为1时,软件启动ADC转换.
//SEQ2
AdcRegs.ADCTRL2.bit.RST_SEQ2=0; //复位SEQ2
AdcRegs.ADCTRL2.bit.SOC_SEQ2=0; //启动SEQ2的转换触发。仅适用于双序 //列发生器模式
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ2=0;
AdcRegs.ADCTRL2.bit.INT_MOD_SEQ2=0;
AdcRegs.ADCTRL2.bit.EPWM_SOCB_SEQ2=0;
}
void ADC_cai(void)
{
AdcRegs.ADCTRL2.bit.RST_SEQ1=1;
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; PieCtrlRegs.PIEACK.all|=0x0001;
PieCtrlRegs.PIEIER1.bit.INTx1=0;
for(i=0;i<5000;i++)
{asm(" NOP");}
w=0;
PieCtrlRegs.PIEIER1.bit.INTx6=0;//控制ADC中断
// delay(DELAY_TIME_min);
AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;//为1时,软件启动ADC转换//为1时,软件启动ADC转换
//PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
EPwm1Regs.ETSEL.bit.SOCAEN = 1; // 使能ADC开始转换A(EPWMxSOCA)脉冲
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
//EPwm1Regs.ETCLR.bit.INT = 1;
EPwm1Regs.ETSEL.bit.INTEN = 1;//使能ePWM中断产生位;1:使能中断;0:禁止中断
loop: if(w==0)
{
goto loop;
}
// delay(DELAY_TIME_max);
PieCtrlRegs.PIEIER1.bit.INTx6=1; PieCtrlRegs.PIEIER1.bit.INTx1=1;
}
//EPWM1的定时器中断
interrupt void epwm1_timer_isr(void)
{
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;//向该位写1,清除SEQ1中断标志位,INT_SEQ1,该位对EOS_BUF1位无影响。
//AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;//为1时,软件启动ADC转换//为1时,软件启动ADC转换
PieCtrlRegs.PIEACK.all |= PIEACK_GROUP1;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT0 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT1 >>4)*3.0/4096.0;
ConversionCount++;
// Voltage_1[ConversionCount] = AdcRegs.ADCRESULT2;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT2 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT3 >>4)*3.0/4096.0;
ConversionCount++;
//Voltage_1[ConversionCount] = AdcRegs.ADCRESULT4 ;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT4 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT5 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT6 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT7 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT8 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT9 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT10 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT11 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT12 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT13 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT14 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT15 >>4)*3.0/4096.0;
ConversionCount++;
//y++;
if(ConversionCount> 1023)
{
ConversionCount = 0;
w=1;
//y=0;
//ConversionCount = 0;
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;//复位SEQ1为初始状态 CONV00
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1=1;
PieCtrlRegs.PIEIER3.bit.INTx1 = 0;//使能PIE中断,EPWM-T1定时器中断位于INT3.1
EPwm1Regs.ETSEL.bit.INTEN = 0;//使能ePWM中断产生位;1:使能中断;0:禁止中断
//AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1=0;
// AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;
PieCtrlRegs.PIEACK.all= PIEACK_GROUP3;
EPwm1Regs.ETCLR.all = 0xD;//epwm中断标准清除位,0:没有效果;1:清除中断标志位
// AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; // Clear INT SEQ1 bit,清除INT SEQ1标志位
}
else {
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; // Reset SEQ1
EPwm1Regs.ETCLR.bit.INT = 1;
// AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;
//PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
//EPwm1Regs.ETSEL.bit.INTEN = 1;//使能ePWM中断产生位;1:使能中断;0:禁止中断
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
// AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;//为1时,软件启动ADC转换//为1时,软件启动ADC转换
}
}
void scic_loopback_init()
{
// Note: Clocks were turned on to the SCIC peripheral
// in the InitSysCtrl() function
ScicRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback
// No parity,8 char bits,
// async mode, idle-line protocol
ScicRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK,
// Disable RX ERR, SLEEP, TXWAKE
ScicRegs.SCICTL2.all =0x0003;
ScicRegs.SCICTL2.bit.TXINTENA =1;
ScicRegs.SCICTL2.bit.RXBKINTENA =1;
ScicRegs.SCIHBAUD =0x0001;
ScicRegs.SCILBAUD =0x00e7;
ScicRegs.SCICCR.bit.LOOPBKENA =0;// enable loop back
ScicRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset
}
// Transmit a character from the SCI'
void scic_xmit(int a)
{
ScicRegs.SCITXBUF=a;
}
// Initalize the SCI FIFO
void scic_fifo_init()
{
ScicRegs.SCIFFTX.bit.TXFIFOXRESET=0;
ScicRegs.SCIFFRX.bit.RXFIFORESET=0;
ScicRegs.SCIFFTX.all=0xE040;
ScicRegs.SCIFFRX.all=0x204f;
ScicRegs.SCIFFCT.all=0x0;
}
void delay(Uint32 t)
{
Uint32 i = 0;
for (i = 0; i < t; i++);
}
user4528677:
回复 Eric Ma:
你好,我设置为两个采样通道(连续采样),但是采样率没有任何的变化,这会是什么原因?
我的想法是采集两个通道的数据,采集1024个数据存入数组,然后再把数组中的数据输入显示屏,我设置的pwm频率为6.25MHZ,ADCCLK为12.5MHZ,采样率即为pwm的频率,可是实际测试结果的采样率只有300K左右,请大神指导一下,下面是我的程序。采样率的设置是在InitAdc1(void); InitEPwm1Example();ADC_cai(void);这三个子函数中
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File
/**************************************宏定义************************************************/
#define DELAY_TIME_min 200 //延时时间(短)
#define DELAY_TIME_max 500000 //延时时间(长)
#define delay_short 300 // 10us
#define delay_long 300000 // 10ms
#define delay_mid 3000 #define SCIC 1
#define ADC_MODCLK 0x3 //ADC_MODCLK=HISPCP, HSPCLK = SYSCLKOUT/2*ADC_MODCLK = 150/(2*3)=25.0 MHz
/*****************************************************************************************************/
//串口C声明
void scic_loopback_init(void);
void scic_fifo_init(void);
void scic_xmit(int a);
void delay(Uint32 t);
void ADC_cai(void);
//串口相关变量
int j=0,w=0,y=0;//w用来设置等待adc采集,w=1表示采完结束。y表示一共执行adc采集中断子程序128次,共采到1024个点
char msg1[6]={0x5A,0xA5,0x05,0x82,0x10,0x05}; //Y_center相关指令
char msg2[6]={0x5A,0xA5,0x05,0x82,0x10,0x06}; //VD_center相关指令 char msg3[6]={0x5A,0xA5,0x05,0x82,0x10,0x09}; //横轴间隔设置相关指令
char msg4[6]={0x5A,0xA5,0x05,0x82,0x10,0x08}; //纵轴放大倍数设置相关指令
char msg[5]={0x5A,0xA5,0x04,0x84,0x01}; //写数据指令
char msg5[6]={0x5A,0xA5,0x03,0x80,0xEB,0x56};
int i=0;
int c_data; //要写的数据值
int c_data1,c_data2,c_data0;//中间转换参量
int dat_max,dat_mid,dat_min,mul;
/*************************************串口*********************************/
// Test 1,SCIC DLB, 8-bit word, baud rate 9.6k, default, 1 STOP bit, no parity
//该例中的全局变量:
Uint16 LoopCount;
Uint16 ConversionCount;
float Voltage1[1024]={0};
float Voltage2[1024]={0};
//unsigned int Voltage_1[100]={0};//unsigned int Voltage_2[100]={0};
float Voltage_1[1024]={0};
float Voltage_2[1024]={0};
void InitAdc1(void);
void InitEPwm1Example();
volatile unsigned int adconvover=0;
interrupt void epwm1_timer_isr(void);//如果中断服务程序放在主函数的下面则在主函数前需要对中断服务程序进行声明,在主函数的上面则不需要。
Uint16 EPwm1TimerIntCount;
float a=4096;float V2_max=0;
main()
{
int i,j;
InitSysCtrl(); //初始化系统函数
//InitGpio(); // 该例中跳过
InitScicGpio(); //选择GPIO口,初始化GPIO口
DINT;
IER = 0x0000; //禁止CPU中断
IFR = 0x0000; //清除CPU中断标志
InitPieCtrl(); //初始化PIE控制寄存器
InitPieVectTable(); //初始化PIE中断向量表
InitAdc1(); //初始化ADC模块
InitEPwm1Example();//初始化EPwm1模块
EnableInterrupts();
scic_fifo_init(); // Initialize the SCI FIFO
scic_loopback_init();//服务程序
EALLOW; // This is needed to write to EALLOW protected register
//PieVectTable.ADCINT = &adc_isr;
SysCtrlRegs.HISPCP.all=ADC_MODCLK;//HISPCP=ADC_MODCLK, HISPCLK=SYSCLKOUT/2*HISPCP
PieVectTable.EPWM1_INT = &epwm1_timer_isr;
EDIS;
//开中断
PieCtrlRegs.PIEIER1.bit.INTx6=1;PieCtrlRegs.PIEIER1.bit.INTx1=1;
PieCtrlRegs.PIEIER3.bit.INTx1 =0;//关PIE中断,EPWM-T1定时器中断位于INT3.1
IER |= M_INT3; //开CPU中断
EINT; // 使能全局中断
ERTM; // 使能实时中断
//epwm1_timer_isr();
// 等待ADC中断 // Initalize SCI dat_max=2000;
dat_mid=1000;
dat_min=0;
mul=440.0*256/(dat_max-dat_min);
#if SCIC
//清屏
for (i=0;i<6;i++)
{
scic_xmit(msg5[i]);
delay(delay_short);
}
delay(delay_long);
delay(delay_long);
//修改VD-Center值
c_data=dat_mid; c_data0=c_data;
c_data2=0xff&c_data0; // data2 为data的低八位数据
c_data0=c_data>>8;
c_data1=0xff&c_data0; // data1 为data的高八位数据
i = 0;
for (i=0;i<6;i++)
{
scic_xmit(msg2[i]);
delay(delay_short);
}
scic_xmit(c_data1);
delay(delay_short);
scic_xmit(c_data2);
delay(delay_short);
delay(delay_long);
delay(delay_long);
//修改纵轴放大倍数
c_data=mul;
c_data0=c_data;
c_data2=0xff&c_data0; // data2 为data的低八位数据
c_data0=c_data>>8;
c_data1=0xff&c_data0; // data1 为data的高八位数据
i = 0;
for (i=0;i<6;i++)
{
scic_xmit(msg4[i]);
delay(delay_short);
}
scic_xmit(c_data1);
delay(delay_short);
scic_xmit(c_data2);
delay(delay_short);
delay(delay_long);
delay(delay_long);
delay(delay_long);
//修改横轴间隔数
c_data=5; c_data0=c_data;
c_data2=0xff&c_data0; // data2 为data的低八位数据
c_data0=c_data>>8;
c_data1=0xff&c_data0; // data1 为data的高八位数据
i = 0;
for (i=0;i<6;i++)
{
scic_xmit(msg3[i]);
delay(delay_short);
}
scic_xmit(c_data1);
delay(delay_short);
scic_xmit(c_data2);
delay(delay_short);
delay(delay_long);
while(ScicRegs.SCIFFTX.bit.TXFFST != 0);
#endif
ConversionCount = 0;
EPwm1TimerIntCount=0;
delay(delay_long);
while(1)
{
ADC_cai();
#if SCIC
for(j=0;j<1024;j++)
{ c_data=Voltage_2[j]*1000-100;
c_data0=c_data;
c_data2=0xff&c_data0; // data2 为data的低八位数据
c_data0=c_data>>8;
c_data1=0xff&c_data0; // data1 为data的高八位数据
i = 0;
for (i=0;i<5;i++)
{
scic_xmit(msg[i]);
delay(delay_short);
}
scic_xmit(c_data1);
delay(delay_short);
scic_xmit(c_data2);
delay(delay_short);
// ConversionCount++;
delay(delay_long);
}
//ConversionCount=0;
// delay(delay_long);
while(ScicRegs.SCIFFTX.bit.TXFFST != 0);
#endif
}
}
void InitEPwm1Example()
{
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;// 在系统初始化函数中已经使能 //EPWM模块,此处只需设置禁止同步。
EDIS;
//1.设置TB模块
EPwm1Regs.TBPRD =12; //18750 //2ms //设置计数周期=600TBCLK//EPwm1Regs.TBPRD = 6000;
EPwm1Regs.CMPA.half.CMPA = 6; // 比较器A = 300TBCLK//EPwm1Regs.CMPA.half.CMPA = 500;EPwm1Regs.CMPB = 20; //比较器 B = 500 TBCLKEPwm1Regs.TBPHS.half.TBPHS = 0x0000; // 设置相位寄存器置零
EPwm1Regs.TBCTR = 0x0000; // 清除TB计数器
// Setup TBCLK = SYSCLKOUT / (HSPCLKDIV * CLKDIV)=150/4*4
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; //计数方式设置00 //Up-count mode;01Down-count mode;10 Up-down-count mode
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // 禁止相位加载
EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW; //从阴影寄存器加载计数值
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;//禁用同步输出,在头文 //件DSP2833x-ePwm-defines.h中有定义
EPwm1Regs.TBCTL.bit.HSPCLKDIV =TB_DIV1;//TB_DIV1=0
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;//TB_DIV1=0
EPwm1Regs.TBCTL.bit.FREE_SOFT = 0x3; //仿真模式位:自由运行
//设置比较模块
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // 映射模式Load registers //every ZERO
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR = Zero
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
// 设置动作模块
EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;
EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;
EPwm1Regs.AQCTLB.bit.CBU = AQ_SET;
EPwm1Regs.AQCTLB.bit.CBD = AQ_CLEAR;
//事件触发子模块设置
//1.开始转换脉冲SOCA设置
EPwm1Regs.ETSEL.bit.SOCAEN = 1; // 使能ADC开始转换A(EPWMxSOCA)脉冲 把1修改成了0,在ADC_cai()中再赋值1触发adc采集
EPwm1Regs.ETSEL.bit.SOCASEL = 4; //设置EPWMxSOCA何时生成,2,TBCTR=TBPRD
EPwm1Regs.ETPS.bit.SOCAPRD = 3; //第三个中断事件A发生,即EPWMxSOCA生成
//2.EPWM中断设置
EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_PRD;//EPWM中断设置,此处设置为周期中断
EPwm1Regs.ETSEL.bit.INTEN = 1; //使能EPWM中断
EPwm1Regs.ETPS.bit.INTPRD = ET_1ST;//第一个事件发生时产生中断
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;// Enable TBCLK within the ePWM
EDIS;
}
void InitAdc1(void)
{
Uint16 i;
AdcRegs.ADCTRL1.bit.RESET=1; //复位AD 模块
for(i=0;i<9;i++)
{asm(" NOP");}
AdcRegs.ADCTRL1.bit.RESET=0;
AdcRegs.ADCTRL1.bit.SUSMOD=0; //仿真暂停方式,0为忽略。
AdcRegs.ADCTRL1.bit.ACQ_PS=0; //控制sSOC的脉冲宽度,同时也决定了采样开关闭合的时间。设定窗口大小SC=ADCTRL1[11:8] + 1 个ADCCLK周期数;AdcRegs.ADCTRL1.bit.CPS=0; //内核时钟预定标器,1为二分频 ADC Core clock divider :HSPCLK/[2*(ADCTRL1[7]:CPS + 1)]
AdcRegs.ADCTRL1.bit.CONT_RUN=1;//连续运行方式,0:敉7绞?1:连续转换方式.
AdcRegs.ADCTRL1.bit.SEQ_CASC=1; //**级联蛄蟹⑸鞴ぷ鞣绞剑? 双序列模 //式;1 级联模式
//ADCTRL3对电源和采样方式进行设置
AdcRegs.ADCTRL3.bit.ADCBGRFDN=3;//带隙参考电路上电
for(i=0;i<10000;i++)
{asm(" NOP");}
AdcRegs.ADCTRL3.bit.ADCPWDN=1;//除带隙参考电路獾钠渌鸄DC模块上电
for(i=0;i<5000;i++)
{asm(" NOP");}
AdcRegs.ADCTRL3.bit.ADCCLKPS=2; // ADCCLK=HISPCLK/[2*ADCCLKPS*(ADCTRL1[7].CPS+1)]
AdcRegs.ADCTRL3.bit.SMODE_SEL=1; //采样方式。顺序采样0/同步采样1
AdcRegs.ADCMAXCONV.bit.MAX_CONV1=0x07; //设定转换数量,共8同步采样(每 //次采样两个通道),共采样16路
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 0x0; //采样ADCINA0和ADCINB0
//ADC状态和标志寄存器ADCST(清除中断标志)
AdcRegs.ADCST.bit.INT_SEQ1_CLR=1;//中断清除位
AdcRegs.ADCST.bit.INT_SEQ2_CLR=1;
//AdcRegs.ADCTRL2.all=0x2800;
AdcRegs.ADCTRL2.bit.EPWM_SOCB_SEQ=0;
AdcRegs.ADCTRL2.bit.RST_SEQ1=1;// 复位序列发生器1
//SEQ1
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1=0;//SEQ1中断使能:0禁止INT SEQ1向CPU发出中断申请,1使能INT SEQ1向CPU发出中断申请
AdcRegs.ADCTRL2.bit.INT_MOD_SEQ1=0;//SEQ1中断方式:0每个SEQ1序列转换 束,置位SEQ1的中断标志
AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1=1;//SEQ1的EPWM SOCA使能位,1使能
AdcRegs.ADCTRL2.bit.EXT_SOC_SEQ1=0;//SEQ1的外部SOC信号位,0:无操作。1:外部ADCSOC引脚信号启动ADC自动转换序列。
AdcRegs.ADCTRL2.bit.SOC_SEQ1=0;//为1时,软件启动ADC转换.
//SEQ2
AdcRegs.ADCTRL2.bit.RST_SEQ2=0; //复位SEQ2
AdcRegs.ADCTRL2.bit.SOC_SEQ2=0; //启动SEQ2的转换触发。仅适用于双序 //列发生器模式
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ2=0;
AdcRegs.ADCTRL2.bit.INT_MOD_SEQ2=0;
AdcRegs.ADCTRL2.bit.EPWM_SOCB_SEQ2=0;
}
void ADC_cai(void)
{
AdcRegs.ADCTRL2.bit.RST_SEQ1=1;
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; PieCtrlRegs.PIEACK.all|=0x0001;
PieCtrlRegs.PIEIER1.bit.INTx1=0;
for(i=0;i<5000;i++)
{asm(" NOP");}
w=0;
PieCtrlRegs.PIEIER1.bit.INTx6=0;//控制ADC中断
// delay(DELAY_TIME_min);
AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;//为1时,软件启动ADC转换//为1时,软件启动ADC转换
//PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
EPwm1Regs.ETSEL.bit.SOCAEN = 1; // 使能ADC开始转换A(EPWMxSOCA)脉冲
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
//EPwm1Regs.ETCLR.bit.INT = 1;
EPwm1Regs.ETSEL.bit.INTEN = 1;//使能ePWM中断产生位;1:使能中断;0:禁止中断
loop: if(w==0)
{
goto loop;
}
// delay(DELAY_TIME_max);
PieCtrlRegs.PIEIER1.bit.INTx6=1; PieCtrlRegs.PIEIER1.bit.INTx1=1;
}
//EPWM1的定时器中断
interrupt void epwm1_timer_isr(void)
{
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;//向该位写1,清除SEQ1中断标志位,INT_SEQ1,该位对EOS_BUF1位无影响。
//AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;//为1时,软件启动ADC转换//为1时,软件启动ADC转换
PieCtrlRegs.PIEACK.all |= PIEACK_GROUP1;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT0 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT1 >>4)*3.0/4096.0;
ConversionCount++;
// Voltage_1[ConversionCount] = AdcRegs.ADCRESULT2;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT2 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT3 >>4)*3.0/4096.0;
ConversionCount++;
//Voltage_1[ConversionCount] = AdcRegs.ADCRESULT4 ;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT4 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT5 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT6 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT7 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT8 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT9 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT10 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT11 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT12 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT13 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT14 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT15 >>4)*3.0/4096.0;
ConversionCount++;
//y++;
if(ConversionCount> 1023)
{
ConversionCount = 0;
w=1;
//y=0;
//ConversionCount = 0;
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;//复位SEQ1为初始状态 CONV00
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1=1;
PieCtrlRegs.PIEIER3.bit.INTx1 = 0;//使能PIE中断,EPWM-T1定时器中断位于INT3.1
EPwm1Regs.ETSEL.bit.INTEN = 0;//使能ePWM中断产生位;1:使能中断;0:禁止中断
//AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1=0;
// AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;
PieCtrlRegs.PIEACK.all= PIEACK_GROUP3;
EPwm1Regs.ETCLR.all = 0xD;//epwm中断标准清除位,0:没有效果;1:清除中断标志位
// AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; // Clear INT SEQ1 bit,清除INT SEQ1标志位
}
else {
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; // Reset SEQ1
EPwm1Regs.ETCLR.bit.INT = 1;
// AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;
//PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
//EPwm1Regs.ETSEL.bit.INTEN = 1;//使能ePWM中断产生位;1:使能中断;0:禁止中断
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
// AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;//为1时,软件启动ADC转换//为1时,软件启动ADC转换
}
}
void scic_loopback_init()
{
// Note: Clocks were turned on to the SCIC peripheral
// in the InitSysCtrl() function
ScicRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback
// No parity,8 char bits,
// async mode, idle-line protocol
ScicRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK,
// Disable RX ERR, SLEEP, TXWAKE
ScicRegs.SCICTL2.all =0x0003;
ScicRegs.SCICTL2.bit.TXINTENA =1;
ScicRegs.SCICTL2.bit.RXBKINTENA =1;
ScicRegs.SCIHBAUD =0x0001;
ScicRegs.SCILBAUD =0x00e7;
ScicRegs.SCICCR.bit.LOOPBKENA =0;// enable loop back
ScicRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset
}
// Transmit a character from the SCI'
void scic_xmit(int a)
{
ScicRegs.SCITXBUF=a;
}
// Initalize the SCI FIFO
void scic_fifo_init()
{
ScicRegs.SCIFFTX.bit.TXFIFOXRESET=0;
ScicRegs.SCIFFRX.bit.RXFIFORESET=0;
ScicRegs.SCIFFTX.all=0xE040;
ScicRegs.SCIFFRX.all=0x204f;
ScicRegs.SCIFFCT.all=0x0;
}
void delay(Uint32 t)
{
Uint32 i = 0;
for (i = 0; i < t; i++);
}
Eric Ma:
回复 user4528677:
你是如何测采样率的呢?
可否用例程测一下呢?
controlSUITE\device_support\f2833x\v141\DSP2833x_examples_ccsv5\adc_seq_ovd_test
Eric
我的想法是采集两个通道的数据,采集1024个数据存入数组,然后再把数组中的数据输入显示屏,我设置的pwm频率为6.25MHZ,ADCCLK为12.5MHZ,采样率即为pwm的频率,可是实际测试结果的采样率只有300K左右,请大神指导一下,下面是我的程序。采样率的设置是在InitAdc1(void); InitEPwm1Example();ADC_cai(void);这三个子函数中
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File
/**************************************宏定义************************************************/
#define DELAY_TIME_min 200 //延时时间(短)
#define DELAY_TIME_max 500000 //延时时间(长)
#define delay_short 300 // 10us
#define delay_long 300000 // 10ms
#define delay_mid 3000 #define SCIC 1
#define ADC_MODCLK 0x3 //ADC_MODCLK=HISPCP, HSPCLK = SYSCLKOUT/2*ADC_MODCLK = 150/(2*3)=25.0 MHz
/*****************************************************************************************************/
//串口C声明
void scic_loopback_init(void);
void scic_fifo_init(void);
void scic_xmit(int a);
void delay(Uint32 t);
void ADC_cai(void);
//串口相关变量
int j=0,w=0,y=0;//w用来设置等待adc采集,w=1表示采完结束。y表示一共执行adc采集中断子程序128次,共采到1024个点
char msg1[6]={0x5A,0xA5,0x05,0x82,0x10,0x05}; //Y_center相关指令
char msg2[6]={0x5A,0xA5,0x05,0x82,0x10,0x06}; //VD_center相关指令 char msg3[6]={0x5A,0xA5,0x05,0x82,0x10,0x09}; //横轴间隔设置相关指令
char msg4[6]={0x5A,0xA5,0x05,0x82,0x10,0x08}; //纵轴放大倍数设置相关指令
char msg[5]={0x5A,0xA5,0x04,0x84,0x01}; //写数据指令
char msg5[6]={0x5A,0xA5,0x03,0x80,0xEB,0x56};
int i=0;
int c_data; //要写的数据值
int c_data1,c_data2,c_data0;//中间转换参量
int dat_max,dat_mid,dat_min,mul;
/*************************************串口*********************************/
// Test 1,SCIC DLB, 8-bit word, baud rate 9.6k, default, 1 STOP bit, no parity
//该例中的全局变量:
Uint16 LoopCount;
Uint16 ConversionCount;
float Voltage1[1024]={0};
float Voltage2[1024]={0};
//unsigned int Voltage_1[100]={0};//unsigned int Voltage_2[100]={0};
float Voltage_1[1024]={0};
float Voltage_2[1024]={0};
void InitAdc1(void);
void InitEPwm1Example();
volatile unsigned int adconvover=0;
interrupt void epwm1_timer_isr(void);//如果中断服务程序放在主函数的下面则在主函数前需要对中断服务程序进行声明,在主函数的上面则不需要。
Uint16 EPwm1TimerIntCount;
float a=4096;float V2_max=0;
main()
{
int i,j;
InitSysCtrl(); //初始化系统函数
//InitGpio(); // 该例中跳过
InitScicGpio(); //选择GPIO口,初始化GPIO口
DINT;
IER = 0x0000; //禁止CPU中断
IFR = 0x0000; //清除CPU中断标志
InitPieCtrl(); //初始化PIE控制寄存器
InitPieVectTable(); //初始化PIE中断向量表
InitAdc1(); //初始化ADC模块
InitEPwm1Example();//初始化EPwm1模块
EnableInterrupts();
scic_fifo_init(); // Initialize the SCI FIFO
scic_loopback_init();//服务程序
EALLOW; // This is needed to write to EALLOW protected register
//PieVectTable.ADCINT = &adc_isr;
SysCtrlRegs.HISPCP.all=ADC_MODCLK;//HISPCP=ADC_MODCLK, HISPCLK=SYSCLKOUT/2*HISPCP
PieVectTable.EPWM1_INT = &epwm1_timer_isr;
EDIS;
//开中断
PieCtrlRegs.PIEIER1.bit.INTx6=1;PieCtrlRegs.PIEIER1.bit.INTx1=1;
PieCtrlRegs.PIEIER3.bit.INTx1 =0;//关PIE中断,EPWM-T1定时器中断位于INT3.1
IER |= M_INT3; //开CPU中断
EINT; // 使能全局中断
ERTM; // 使能实时中断
//epwm1_timer_isr();
// 等待ADC中断 // Initalize SCI dat_max=2000;
dat_mid=1000;
dat_min=0;
mul=440.0*256/(dat_max-dat_min);
#if SCIC
//清屏
for (i=0;i<6;i++)
{
scic_xmit(msg5[i]);
delay(delay_short);
}
delay(delay_long);
delay(delay_long);
//修改VD-Center值
c_data=dat_mid; c_data0=c_data;
c_data2=0xff&c_data0; // data2 为data的低八位数据
c_data0=c_data>>8;
c_data1=0xff&c_data0; // data1 为data的高八位数据
i = 0;
for (i=0;i<6;i++)
{
scic_xmit(msg2[i]);
delay(delay_short);
}
scic_xmit(c_data1);
delay(delay_short);
scic_xmit(c_data2);
delay(delay_short);
delay(delay_long);
delay(delay_long);
//修改纵轴放大倍数
c_data=mul;
c_data0=c_data;
c_data2=0xff&c_data0; // data2 为data的低八位数据
c_data0=c_data>>8;
c_data1=0xff&c_data0; // data1 为data的高八位数据
i = 0;
for (i=0;i<6;i++)
{
scic_xmit(msg4[i]);
delay(delay_short);
}
scic_xmit(c_data1);
delay(delay_short);
scic_xmit(c_data2);
delay(delay_short);
delay(delay_long);
delay(delay_long);
delay(delay_long);
//修改横轴间隔数
c_data=5; c_data0=c_data;
c_data2=0xff&c_data0; // data2 为data的低八位数据
c_data0=c_data>>8;
c_data1=0xff&c_data0; // data1 为data的高八位数据
i = 0;
for (i=0;i<6;i++)
{
scic_xmit(msg3[i]);
delay(delay_short);
}
scic_xmit(c_data1);
delay(delay_short);
scic_xmit(c_data2);
delay(delay_short);
delay(delay_long);
while(ScicRegs.SCIFFTX.bit.TXFFST != 0);
#endif
ConversionCount = 0;
EPwm1TimerIntCount=0;
delay(delay_long);
while(1)
{
ADC_cai();
#if SCIC
for(j=0;j<1024;j++)
{ c_data=Voltage_2[j]*1000-100;
c_data0=c_data;
c_data2=0xff&c_data0; // data2 为data的低八位数据
c_data0=c_data>>8;
c_data1=0xff&c_data0; // data1 为data的高八位数据
i = 0;
for (i=0;i<5;i++)
{
scic_xmit(msg[i]);
delay(delay_short);
}
scic_xmit(c_data1);
delay(delay_short);
scic_xmit(c_data2);
delay(delay_short);
// ConversionCount++;
delay(delay_long);
}
//ConversionCount=0;
// delay(delay_long);
while(ScicRegs.SCIFFTX.bit.TXFFST != 0);
#endif
}
}
void InitEPwm1Example()
{
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;// 在系统初始化函数中已经使能 //EPWM模块,此处只需设置禁止同步。
EDIS;
//1.设置TB模块
EPwm1Regs.TBPRD =12; //18750 //2ms //设置计数周期=600TBCLK//EPwm1Regs.TBPRD = 6000;
EPwm1Regs.CMPA.half.CMPA = 6; // 比较器A = 300TBCLK//EPwm1Regs.CMPA.half.CMPA = 500;EPwm1Regs.CMPB = 20; //比较器 B = 500 TBCLKEPwm1Regs.TBPHS.half.TBPHS = 0x0000; // 设置相位寄存器置零
EPwm1Regs.TBCTR = 0x0000; // 清除TB计数器
// Setup TBCLK = SYSCLKOUT / (HSPCLKDIV * CLKDIV)=150/4*4
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; //计数方式设置00 //Up-count mode;01Down-count mode;10 Up-down-count mode
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // 禁止相位加载
EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW; //从阴影寄存器加载计数值
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;//禁用同步输出,在头文 //件DSP2833x-ePwm-defines.h中有定义
EPwm1Regs.TBCTL.bit.HSPCLKDIV =TB_DIV1;//TB_DIV1=0
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;//TB_DIV1=0
EPwm1Regs.TBCTL.bit.FREE_SOFT = 0x3; //仿真模式位:自由运行
//设置比较模块
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // 映射模式Load registers //every ZERO
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR = Zero
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
// 设置动作模块
EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;
EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;
EPwm1Regs.AQCTLB.bit.CBU = AQ_SET;
EPwm1Regs.AQCTLB.bit.CBD = AQ_CLEAR;
//事件触发子模块设置
//1.开始转换脉冲SOCA设置
EPwm1Regs.ETSEL.bit.SOCAEN = 1; // 使能ADC开始转换A(EPWMxSOCA)脉冲 把1修改成了0,在ADC_cai()中再赋值1触发adc采集
EPwm1Regs.ETSEL.bit.SOCASEL = 4; //设置EPWMxSOCA何时生成,2,TBCTR=TBPRD
EPwm1Regs.ETPS.bit.SOCAPRD = 3; //第三个中断事件A发生,即EPWMxSOCA生成
//2.EPWM中断设置
EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_PRD;//EPWM中断设置,此处设置为周期中断
EPwm1Regs.ETSEL.bit.INTEN = 1; //使能EPWM中断
EPwm1Regs.ETPS.bit.INTPRD = ET_1ST;//第一个事件发生时产生中断
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;// Enable TBCLK within the ePWM
EDIS;
}
void InitAdc1(void)
{
Uint16 i;
AdcRegs.ADCTRL1.bit.RESET=1; //复位AD 模块
for(i=0;i<9;i++)
{asm(" NOP");}
AdcRegs.ADCTRL1.bit.RESET=0;
AdcRegs.ADCTRL1.bit.SUSMOD=0; //仿真暂停方式,0为忽略。
AdcRegs.ADCTRL1.bit.ACQ_PS=0; //控制sSOC的脉冲宽度,同时也决定了采样开关闭合的时间。设定窗口大小SC=ADCTRL1[11:8] + 1 个ADCCLK周期数;AdcRegs.ADCTRL1.bit.CPS=0; //内核时钟预定标器,1为二分频 ADC Core clock divider :HSPCLK/[2*(ADCTRL1[7]:CPS + 1)]
AdcRegs.ADCTRL1.bit.CONT_RUN=1;//连续运行方式,0:敉7绞?1:连续转换方式.
AdcRegs.ADCTRL1.bit.SEQ_CASC=1; //**级联蛄蟹⑸鞴ぷ鞣绞剑? 双序列模 //式;1 级联模式
//ADCTRL3对电源和采样方式进行设置
AdcRegs.ADCTRL3.bit.ADCBGRFDN=3;//带隙参考电路上电
for(i=0;i<10000;i++)
{asm(" NOP");}
AdcRegs.ADCTRL3.bit.ADCPWDN=1;//除带隙参考电路獾钠渌鸄DC模块上电
for(i=0;i<5000;i++)
{asm(" NOP");}
AdcRegs.ADCTRL3.bit.ADCCLKPS=2; // ADCCLK=HISPCLK/[2*ADCCLKPS*(ADCTRL1[7].CPS+1)]
AdcRegs.ADCTRL3.bit.SMODE_SEL=1; //采样方式。顺序采样0/同步采样1
AdcRegs.ADCMAXCONV.bit.MAX_CONV1=0x07; //设定转换数量,共8同步采样(每 //次采样两个通道),共采样16路
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 0x0; //采样ADCINA0和ADCINB0
//ADC状态和标志寄存器ADCST(清除中断标志)
AdcRegs.ADCST.bit.INT_SEQ1_CLR=1;//中断清除位
AdcRegs.ADCST.bit.INT_SEQ2_CLR=1;
//AdcRegs.ADCTRL2.all=0x2800;
AdcRegs.ADCTRL2.bit.EPWM_SOCB_SEQ=0;
AdcRegs.ADCTRL2.bit.RST_SEQ1=1;// 复位序列发生器1
//SEQ1
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1=0;//SEQ1中断使能:0禁止INT SEQ1向CPU发出中断申请,1使能INT SEQ1向CPU发出中断申请
AdcRegs.ADCTRL2.bit.INT_MOD_SEQ1=0;//SEQ1中断方式:0每个SEQ1序列转换 束,置位SEQ1的中断标志
AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1=1;//SEQ1的EPWM SOCA使能位,1使能
AdcRegs.ADCTRL2.bit.EXT_SOC_SEQ1=0;//SEQ1的外部SOC信号位,0:无操作。1:外部ADCSOC引脚信号启动ADC自动转换序列。
AdcRegs.ADCTRL2.bit.SOC_SEQ1=0;//为1时,软件启动ADC转换.
//SEQ2
AdcRegs.ADCTRL2.bit.RST_SEQ2=0; //复位SEQ2
AdcRegs.ADCTRL2.bit.SOC_SEQ2=0; //启动SEQ2的转换触发。仅适用于双序 //列发生器模式
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ2=0;
AdcRegs.ADCTRL2.bit.INT_MOD_SEQ2=0;
AdcRegs.ADCTRL2.bit.EPWM_SOCB_SEQ2=0;
}
void ADC_cai(void)
{
AdcRegs.ADCTRL2.bit.RST_SEQ1=1;
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; PieCtrlRegs.PIEACK.all|=0x0001;
PieCtrlRegs.PIEIER1.bit.INTx1=0;
for(i=0;i<5000;i++)
{asm(" NOP");}
w=0;
PieCtrlRegs.PIEIER1.bit.INTx6=0;//控制ADC中断
// delay(DELAY_TIME_min);
AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;//为1时,软件启动ADC转换//为1时,软件启动ADC转换
//PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
EPwm1Regs.ETSEL.bit.SOCAEN = 1; // 使能ADC开始转换A(EPWMxSOCA)脉冲
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
//EPwm1Regs.ETCLR.bit.INT = 1;
EPwm1Regs.ETSEL.bit.INTEN = 1;//使能ePWM中断产生位;1:使能中断;0:禁止中断
loop: if(w==0)
{
goto loop;
}
// delay(DELAY_TIME_max);
PieCtrlRegs.PIEIER1.bit.INTx6=1; PieCtrlRegs.PIEIER1.bit.INTx1=1;
}
//EPWM1的定时器中断
interrupt void epwm1_timer_isr(void)
{
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;//向该位写1,清除SEQ1中断标志位,INT_SEQ1,该位对EOS_BUF1位无影响。
//AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;//为1时,软件启动ADC转换//为1时,软件启动ADC转换
PieCtrlRegs.PIEACK.all |= PIEACK_GROUP1;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT0 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT1 >>4)*3.0/4096.0;
ConversionCount++;
// Voltage_1[ConversionCount] = AdcRegs.ADCRESULT2;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT2 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT3 >>4)*3.0/4096.0;
ConversionCount++;
//Voltage_1[ConversionCount] = AdcRegs.ADCRESULT4 ;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT4 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT5 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT6 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT7 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT8 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT9 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT10 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT11 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT12 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT13 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT14 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT15 >>4)*3.0/4096.0;
ConversionCount++;
//y++;
if(ConversionCount> 1023)
{
ConversionCount = 0;
w=1;
//y=0;
//ConversionCount = 0;
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;//复位SEQ1为初始状态 CONV00
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1=1;
PieCtrlRegs.PIEIER3.bit.INTx1 = 0;//使能PIE中断,EPWM-T1定时器中断位于INT3.1
EPwm1Regs.ETSEL.bit.INTEN = 0;//使能ePWM中断产生位;1:使能中断;0:禁止中断
//AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1=0;
// AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;
PieCtrlRegs.PIEACK.all= PIEACK_GROUP3;
EPwm1Regs.ETCLR.all = 0xD;//epwm中断标准清除位,0:没有效果;1:清除中断标志位
// AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; // Clear INT SEQ1 bit,清除INT SEQ1标志位
}
else {
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; // Reset SEQ1
EPwm1Regs.ETCLR.bit.INT = 1;
// AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;
//PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
//EPwm1Regs.ETSEL.bit.INTEN = 1;//使能ePWM中断产生位;1:使能中断;0:禁止中断
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
// AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;//为1时,软件启动ADC转换//为1时,软件启动ADC转换
}
}
void scic_loopback_init()
{
// Note: Clocks were turned on to the SCIC peripheral
// in the InitSysCtrl() function
ScicRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback
// No parity,8 char bits,
// async mode, idle-line protocol
ScicRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK,
// Disable RX ERR, SLEEP, TXWAKE
ScicRegs.SCICTL2.all =0x0003;
ScicRegs.SCICTL2.bit.TXINTENA =1;
ScicRegs.SCICTL2.bit.RXBKINTENA =1;
ScicRegs.SCIHBAUD =0x0001;
ScicRegs.SCILBAUD =0x00e7;
ScicRegs.SCICCR.bit.LOOPBKENA =0;// enable loop back
ScicRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset
}
// Transmit a character from the SCI'
void scic_xmit(int a)
{
ScicRegs.SCITXBUF=a;
}
// Initalize the SCI FIFO
void scic_fifo_init()
{
ScicRegs.SCIFFTX.bit.TXFIFOXRESET=0;
ScicRegs.SCIFFRX.bit.RXFIFORESET=0;
ScicRegs.SCIFFTX.all=0xE040;
ScicRegs.SCIFFRX.all=0x204f;
ScicRegs.SCIFFCT.all=0x0;
}
void delay(Uint32 t)
{
Uint32 i = 0;
for (i = 0; i < t; i++);
}
user4528677:
回复 Eric Ma:
好的,我看看,谢谢
我的想法是采集两个通道的数据,采集1024个数据存入数组,然后再把数组中的数据输入显示屏,我设置的pwm频率为6.25MHZ,ADCCLK为12.5MHZ,采样率即为pwm的频率,可是实际测试结果的采样率只有300K左右,请大神指导一下,下面是我的程序。采样率的设置是在InitAdc1(void); InitEPwm1Example();ADC_cai(void);这三个子函数中
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File
/**************************************宏定义************************************************/
#define DELAY_TIME_min 200 //延时时间(短)
#define DELAY_TIME_max 500000 //延时时间(长)
#define delay_short 300 // 10us
#define delay_long 300000 // 10ms
#define delay_mid 3000 #define SCIC 1
#define ADC_MODCLK 0x3 //ADC_MODCLK=HISPCP, HSPCLK = SYSCLKOUT/2*ADC_MODCLK = 150/(2*3)=25.0 MHz
/*****************************************************************************************************/
//串口C声明
void scic_loopback_init(void);
void scic_fifo_init(void);
void scic_xmit(int a);
void delay(Uint32 t);
void ADC_cai(void);
//串口相关变量
int j=0,w=0,y=0;//w用来设置等待adc采集,w=1表示采完结束。y表示一共执行adc采集中断子程序128次,共采到1024个点
char msg1[6]={0x5A,0xA5,0x05,0x82,0x10,0x05}; //Y_center相关指令
char msg2[6]={0x5A,0xA5,0x05,0x82,0x10,0x06}; //VD_center相关指令 char msg3[6]={0x5A,0xA5,0x05,0x82,0x10,0x09}; //横轴间隔设置相关指令
char msg4[6]={0x5A,0xA5,0x05,0x82,0x10,0x08}; //纵轴放大倍数设置相关指令
char msg[5]={0x5A,0xA5,0x04,0x84,0x01}; //写数据指令
char msg5[6]={0x5A,0xA5,0x03,0x80,0xEB,0x56};
int i=0;
int c_data; //要写的数据值
int c_data1,c_data2,c_data0;//中间转换参量
int dat_max,dat_mid,dat_min,mul;
/*************************************串口*********************************/
// Test 1,SCIC DLB, 8-bit word, baud rate 9.6k, default, 1 STOP bit, no parity
//该例中的全局变量:
Uint16 LoopCount;
Uint16 ConversionCount;
float Voltage1[1024]={0};
float Voltage2[1024]={0};
//unsigned int Voltage_1[100]={0};//unsigned int Voltage_2[100]={0};
float Voltage_1[1024]={0};
float Voltage_2[1024]={0};
void InitAdc1(void);
void InitEPwm1Example();
volatile unsigned int adconvover=0;
interrupt void epwm1_timer_isr(void);//如果中断服务程序放在主函数的下面则在主函数前需要对中断服务程序进行声明,在主函数的上面则不需要。
Uint16 EPwm1TimerIntCount;
float a=4096;float V2_max=0;
main()
{
int i,j;
InitSysCtrl(); //初始化系统函数
//InitGpio(); // 该例中跳过
InitScicGpio(); //选择GPIO口,初始化GPIO口
DINT;
IER = 0x0000; //禁止CPU中断
IFR = 0x0000; //清除CPU中断标志
InitPieCtrl(); //初始化PIE控制寄存器
InitPieVectTable(); //初始化PIE中断向量表
InitAdc1(); //初始化ADC模块
InitEPwm1Example();//初始化EPwm1模块
EnableInterrupts();
scic_fifo_init(); // Initialize the SCI FIFO
scic_loopback_init();//服务程序
EALLOW; // This is needed to write to EALLOW protected register
//PieVectTable.ADCINT = &adc_isr;
SysCtrlRegs.HISPCP.all=ADC_MODCLK;//HISPCP=ADC_MODCLK, HISPCLK=SYSCLKOUT/2*HISPCP
PieVectTable.EPWM1_INT = &epwm1_timer_isr;
EDIS;
//开中断
PieCtrlRegs.PIEIER1.bit.INTx6=1;PieCtrlRegs.PIEIER1.bit.INTx1=1;
PieCtrlRegs.PIEIER3.bit.INTx1 =0;//关PIE中断,EPWM-T1定时器中断位于INT3.1
IER |= M_INT3; //开CPU中断
EINT; // 使能全局中断
ERTM; // 使能实时中断
//epwm1_timer_isr();
// 等待ADC中断 // Initalize SCI dat_max=2000;
dat_mid=1000;
dat_min=0;
mul=440.0*256/(dat_max-dat_min);
#if SCIC
//清屏
for (i=0;i<6;i++)
{
scic_xmit(msg5[i]);
delay(delay_short);
}
delay(delay_long);
delay(delay_long);
//修改VD-Center值
c_data=dat_mid; c_data0=c_data;
c_data2=0xff&c_data0; // data2 为data的低八位数据
c_data0=c_data>>8;
c_data1=0xff&c_data0; // data1 为data的高八位数据
i = 0;
for (i=0;i<6;i++)
{
scic_xmit(msg2[i]);
delay(delay_short);
}
scic_xmit(c_data1);
delay(delay_short);
scic_xmit(c_data2);
delay(delay_short);
delay(delay_long);
delay(delay_long);
//修改纵轴放大倍数
c_data=mul;
c_data0=c_data;
c_data2=0xff&c_data0; // data2 为data的低八位数据
c_data0=c_data>>8;
c_data1=0xff&c_data0; // data1 为data的高八位数据
i = 0;
for (i=0;i<6;i++)
{
scic_xmit(msg4[i]);
delay(delay_short);
}
scic_xmit(c_data1);
delay(delay_short);
scic_xmit(c_data2);
delay(delay_short);
delay(delay_long);
delay(delay_long);
delay(delay_long);
//修改横轴间隔数
c_data=5; c_data0=c_data;
c_data2=0xff&c_data0; // data2 为data的低八位数据
c_data0=c_data>>8;
c_data1=0xff&c_data0; // data1 为data的高八位数据
i = 0;
for (i=0;i<6;i++)
{
scic_xmit(msg3[i]);
delay(delay_short);
}
scic_xmit(c_data1);
delay(delay_short);
scic_xmit(c_data2);
delay(delay_short);
delay(delay_long);
while(ScicRegs.SCIFFTX.bit.TXFFST != 0);
#endif
ConversionCount = 0;
EPwm1TimerIntCount=0;
delay(delay_long);
while(1)
{
ADC_cai();
#if SCIC
for(j=0;j<1024;j++)
{ c_data=Voltage_2[j]*1000-100;
c_data0=c_data;
c_data2=0xff&c_data0; // data2 为data的低八位数据
c_data0=c_data>>8;
c_data1=0xff&c_data0; // data1 为data的高八位数据
i = 0;
for (i=0;i<5;i++)
{
scic_xmit(msg[i]);
delay(delay_short);
}
scic_xmit(c_data1);
delay(delay_short);
scic_xmit(c_data2);
delay(delay_short);
// ConversionCount++;
delay(delay_long);
}
//ConversionCount=0;
// delay(delay_long);
while(ScicRegs.SCIFFTX.bit.TXFFST != 0);
#endif
}
}
void InitEPwm1Example()
{
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;// 在系统初始化函数中已经使能 //EPWM模块,此处只需设置禁止同步。
EDIS;
//1.设置TB模块
EPwm1Regs.TBPRD =12; //18750 //2ms //设置计数周期=600TBCLK//EPwm1Regs.TBPRD = 6000;
EPwm1Regs.CMPA.half.CMPA = 6; // 比较器A = 300TBCLK//EPwm1Regs.CMPA.half.CMPA = 500;EPwm1Regs.CMPB = 20; //比较器 B = 500 TBCLKEPwm1Regs.TBPHS.half.TBPHS = 0x0000; // 设置相位寄存器置零
EPwm1Regs.TBCTR = 0x0000; // 清除TB计数器
// Setup TBCLK = SYSCLKOUT / (HSPCLKDIV * CLKDIV)=150/4*4
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; //计数方式设置00 //Up-count mode;01Down-count mode;10 Up-down-count mode
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // 禁止相位加载
EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW; //从阴影寄存器加载计数值
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;//禁用同步输出,在头文 //件DSP2833x-ePwm-defines.h中有定义
EPwm1Regs.TBCTL.bit.HSPCLKDIV =TB_DIV1;//TB_DIV1=0
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;//TB_DIV1=0
EPwm1Regs.TBCTL.bit.FREE_SOFT = 0x3; //仿真模式位:自由运行
//设置比较模块
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; // 映射模式Load registers //every ZERO
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR = Zero
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
// 设置动作模块
EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;
EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;
EPwm1Regs.AQCTLB.bit.CBU = AQ_SET;
EPwm1Regs.AQCTLB.bit.CBD = AQ_CLEAR;
//事件触发子模块设置
//1.开始转换脉冲SOCA设置
EPwm1Regs.ETSEL.bit.SOCAEN = 1; // 使能ADC开始转换A(EPWMxSOCA)脉冲 把1修改成了0,在ADC_cai()中再赋值1触发adc采集
EPwm1Regs.ETSEL.bit.SOCASEL = 4; //设置EPWMxSOCA何时生成,2,TBCTR=TBPRD
EPwm1Regs.ETPS.bit.SOCAPRD = 3; //第三个中断事件A发生,即EPWMxSOCA生成
//2.EPWM中断设置
EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_PRD;//EPWM中断设置,此处设置为周期中断
EPwm1Regs.ETSEL.bit.INTEN = 1; //使能EPWM中断
EPwm1Regs.ETPS.bit.INTPRD = ET_1ST;//第一个事件发生时产生中断
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;// Enable TBCLK within the ePWM
EDIS;
}
void InitAdc1(void)
{
Uint16 i;
AdcRegs.ADCTRL1.bit.RESET=1; //复位AD 模块
for(i=0;i<9;i++)
{asm(" NOP");}
AdcRegs.ADCTRL1.bit.RESET=0;
AdcRegs.ADCTRL1.bit.SUSMOD=0; //仿真暂停方式,0为忽略。
AdcRegs.ADCTRL1.bit.ACQ_PS=0; //控制sSOC的脉冲宽度,同时也决定了采样开关闭合的时间。设定窗口大小SC=ADCTRL1[11:8] + 1 个ADCCLK周期数;AdcRegs.ADCTRL1.bit.CPS=0; //内核时钟预定标器,1为二分频 ADC Core clock divider :HSPCLK/[2*(ADCTRL1[7]:CPS + 1)]
AdcRegs.ADCTRL1.bit.CONT_RUN=1;//连续运行方式,0:敉7绞?1:连续转换方式.
AdcRegs.ADCTRL1.bit.SEQ_CASC=1; //**级联蛄蟹⑸鞴ぷ鞣绞剑? 双序列模 //式;1 级联模式
//ADCTRL3对电源和采样方式进行设置
AdcRegs.ADCTRL3.bit.ADCBGRFDN=3;//带隙参考电路上电
for(i=0;i<10000;i++)
{asm(" NOP");}
AdcRegs.ADCTRL3.bit.ADCPWDN=1;//除带隙参考电路獾钠渌鸄DC模块上电
for(i=0;i<5000;i++)
{asm(" NOP");}
AdcRegs.ADCTRL3.bit.ADCCLKPS=2; // ADCCLK=HISPCLK/[2*ADCCLKPS*(ADCTRL1[7].CPS+1)]
AdcRegs.ADCTRL3.bit.SMODE_SEL=1; //采样方式。顺序采样0/同步采样1
AdcRegs.ADCMAXCONV.bit.MAX_CONV1=0x07; //设定转换数量,共8同步采样(每 //次采样两个通道),共采样16路
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 0x0; //采样ADCINA0和ADCINB0
AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 0x0; //采样ADCINA0和ADCINB0
//ADC状态和标志寄存器ADCST(清除中断标志)
AdcRegs.ADCST.bit.INT_SEQ1_CLR=1;//中断清除位
AdcRegs.ADCST.bit.INT_SEQ2_CLR=1;
//AdcRegs.ADCTRL2.all=0x2800;
AdcRegs.ADCTRL2.bit.EPWM_SOCB_SEQ=0;
AdcRegs.ADCTRL2.bit.RST_SEQ1=1;// 复位序列发生器1
//SEQ1
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1=0;//SEQ1中断使能:0禁止INT SEQ1向CPU发出中断申请,1使能INT SEQ1向CPU发出中断申请
AdcRegs.ADCTRL2.bit.INT_MOD_SEQ1=0;//SEQ1中断方式:0每个SEQ1序列转换 束,置位SEQ1的中断标志
AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1=1;//SEQ1的EPWM SOCA使能位,1使能
AdcRegs.ADCTRL2.bit.EXT_SOC_SEQ1=0;//SEQ1的外部SOC信号位,0:无操作。1:外部ADCSOC引脚信号启动ADC自动转换序列。
AdcRegs.ADCTRL2.bit.SOC_SEQ1=0;//为1时,软件启动ADC转换.
//SEQ2
AdcRegs.ADCTRL2.bit.RST_SEQ2=0; //复位SEQ2
AdcRegs.ADCTRL2.bit.SOC_SEQ2=0; //启动SEQ2的转换触发。仅适用于双序 //列发生器模式
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ2=0;
AdcRegs.ADCTRL2.bit.INT_MOD_SEQ2=0;
AdcRegs.ADCTRL2.bit.EPWM_SOCB_SEQ2=0;
}
void ADC_cai(void)
{
AdcRegs.ADCTRL2.bit.RST_SEQ1=1;
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; PieCtrlRegs.PIEACK.all|=0x0001;
PieCtrlRegs.PIEIER1.bit.INTx1=0;
for(i=0;i<5000;i++)
{asm(" NOP");}
w=0;
PieCtrlRegs.PIEIER1.bit.INTx6=0;//控制ADC中断
// delay(DELAY_TIME_min);
AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;//为1时,软件启动ADC转换//为1时,软件启动ADC转换
//PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
EPwm1Regs.ETSEL.bit.SOCAEN = 1; // 使能ADC开始转换A(EPWMxSOCA)脉冲
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
//EPwm1Regs.ETCLR.bit.INT = 1;
EPwm1Regs.ETSEL.bit.INTEN = 1;//使能ePWM中断产生位;1:使能中断;0:禁止中断
loop: if(w==0)
{
goto loop;
}
// delay(DELAY_TIME_max);
PieCtrlRegs.PIEIER1.bit.INTx6=1; PieCtrlRegs.PIEIER1.bit.INTx1=1;
}
//EPWM1的定时器中断
interrupt void epwm1_timer_isr(void)
{
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;//向该位写1,清除SEQ1中断标志位,INT_SEQ1,该位对EOS_BUF1位无影响。
//AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;//为1时,软件启动ADC转换//为1时,软件启动ADC转换
PieCtrlRegs.PIEACK.all |= PIEACK_GROUP1;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT0 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT1 >>4)*3.0/4096.0;
ConversionCount++;
// Voltage_1[ConversionCount] = AdcRegs.ADCRESULT2;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT2 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT3 >>4)*3.0/4096.0;
ConversionCount++;
//Voltage_1[ConversionCount] = AdcRegs.ADCRESULT4 ;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT4 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT5 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT6 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT7 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT8 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT9 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT10 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT11 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT12 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT13 >>4)*3.0/4096.0;
ConversionCount++;
Voltage_1[ConversionCount] = (AdcRegs.ADCRESULT14 >>4)*3.0/4096.0;
Voltage_2[ConversionCount] =( AdcRegs.ADCRESULT15 >>4)*3.0/4096.0;
ConversionCount++;
//y++;
if(ConversionCount> 1023)
{
ConversionCount = 0;
w=1;
//y=0;
//ConversionCount = 0;
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;//复位SEQ1为初始状态 CONV00
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1=1;
PieCtrlRegs.PIEIER3.bit.INTx1 = 0;//使能PIE中断,EPWM-T1定时器中断位于INT3.1
EPwm1Regs.ETSEL.bit.INTEN = 0;//使能ePWM中断产生位;1:使能中断;0:禁止中断
//AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1=0;
// AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;
PieCtrlRegs.PIEACK.all= PIEACK_GROUP3;
EPwm1Regs.ETCLR.all = 0xD;//epwm中断标准清除位,0:没有效果;1:清除中断标志位
// AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; // Clear INT SEQ1 bit,清除INT SEQ1标志位
}
else {
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; // Reset SEQ1
EPwm1Regs.ETCLR.bit.INT = 1;
// AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;
//PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
//EPwm1Regs.ETSEL.bit.INTEN = 1;//使能ePWM中断产生位;1:使能中断;0:禁止中断
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
// AdcRegs.ADCTRL2.bit.SOC_SEQ1=1;//为1时,软件启动ADC转换//为1时,软件启动ADC转换
}
}
void scic_loopback_init()
{
// Note: Clocks were turned on to the SCIC peripheral
// in the InitSysCtrl() function
ScicRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback
// No parity,8 char bits,
// async mode, idle-line protocol
ScicRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK,
// Disable RX ERR, SLEEP, TXWAKE
ScicRegs.SCICTL2.all =0x0003;
ScicRegs.SCICTL2.bit.TXINTENA =1;
ScicRegs.SCICTL2.bit.RXBKINTENA =1;
ScicRegs.SCIHBAUD =0x0001;
ScicRegs.SCILBAUD =0x00e7;
ScicRegs.SCICCR.bit.LOOPBKENA =0;// enable loop back
ScicRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset
}
// Transmit a character from the SCI'
void scic_xmit(int a)
{
ScicRegs.SCITXBUF=a;
}
// Initalize the SCI FIFO
void scic_fifo_init()
{
ScicRegs.SCIFFTX.bit.TXFIFOXRESET=0;
ScicRegs.SCIFFRX.bit.RXFIFORESET=0;
ScicRegs.SCIFFTX.all=0xE040;
ScicRegs.SCIFFRX.all=0x204f;
ScicRegs.SCIFFCT.all=0x0;
}
void delay(Uint32 t)
{
Uint32 i = 0;
for (i = 0; i < t; i++);
}
user4528677:
回复 Eric Ma:
我判断采样率是看采样的数据,即我采样一个10KHz的正弦波,一个周期内有32个点左右,我觉得是我的程序设置有些问题,但是我没有找出问题在哪里,能帮我看一下我的程序嘛?