/*************  2021.12.20    *******************
    --------   主要功能: 16路ADC顺序采样  ---------
    1. 定时中断0,驱动48口LED闪烁,低电平有效;
    2. 在IO2和IO4口上产生125Hz,占空比为50%的方波;
    3. 将IO2与ADC1口连接,IO4与ADC2口连接,脉搏传感器的s端与ADC0连接,-端与33脚连接,+与3V3连接;
    4. A0口采集脉搏信号,A1和A2口分别采集不同频率的方波;
    5. 采用1500Hz频率进行采样,将产生的方波连接到不同的端子上,即可采集不同的信号。
*************  end   *******************/

#include "DSP2833x_Device.h"               // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h"             // DSP2833x Examples Include File

interrupt void AdcIsr(void);        //ADC中断服务子函数声明
interrupt void cpu_timer0_isr(void); //定时器0中断服务子函数声明
void InitMyGpio();               //GPIO48口初始化函数声明,LED闪烁
void InitEPWM();                   //EPWM2初始化函数声明
void InitMyAdc(void);               //ADC初始化函数声明
#define startCpuTimer0() CpuTimer0Regs.TCR.bit.TSS=0 //定时器0启动指令宏定义
#define BUF_SIZE   256  // 信号缓存区长度
#define TimerPeriod 1000  //定时器1000us=1ms
// ADC时钟初始参数设置,对SYSCLKOUT分频后形成HSPCLK,用于ADC
#if (CPU_FRQ_150MHZ)     // Default - 150 MHz SYSCLKOUT
  #define ADC_MODCLK 0x0 // 当ADC_MODCLK2=3,HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3)   = 25.0 MHz
                        //  当ADC_MODCLK2=0,HSPCLK = SYSCLKOUT
#endif
#if (CPU_FRQ_100MHZ)
  #define ADC_MODCLK 0x0 // 当ADC_MODCLK2=2, HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 100/(2*2)   = 25.0 MHz
#endif
#define ADC_SHCLK  0x1   // S/H width in ADC module periods

float SampleTable0[BUF_SIZE];
float SampleTable1[BUF_SIZE];
float SampleTable2[BUF_SIZE];
float SampleTable3[BUF_SIZE];
float SampleTable4[BUF_SIZE];
float SampleTable5[BUF_SIZE];
float SampleTable6[BUF_SIZE];
float SampleTable7[BUF_SIZE];

float SampleTable8[BUF_SIZE];
float SampleTable9[BUF_SIZE];
float SampleTable10[BUF_SIZE];
float SampleTable11[BUF_SIZE];
float SampleTable12[BUF_SIZE];
float SampleTable13[BUF_SIZE];
float SampleTable14[BUF_SIZE];
float SampleTable15[BUF_SIZE];

Uint16 SampleDone=0;
void main(void)

{
    Uint16 i;
//-----1.系统和中断向量表初始化
    InitSysCtrl();
    DINT;
    InitPieCtrl();
    IER = 0x0000;
    IFR = 0x0000;
    InitPieVectTable();
//-----2.中断服务地址重新映射
    //2.1 中断映射
    EALLOW;
    PieVectTable.TINT0 = &cpu_timer0_isr;//定时器0中断映射
    PieVectTable.ADCINT = &AdcIsr;//ADC中断映射
  //PieVectTable.XINT13 = &cpu_timer1_isr;
  //PieVectTable.TINT2 = &cpu_timer2_isr;
    EDIS;

//-----3.在PIE级和CPU级,开全局中断
    PieCtrlRegs.PIEIER1.bit.INTx6 = 1;//使能ADC中断(INT1.6)
    PieCtrlRegs.PIEIER1.bit.INTx7 = 1;//定时器0中断(INT1.6)
    IER |= M_INT1;
    EINT;   // Enable Global interrupt INTM
    ERTM;   // Enable Global realtime interrupt DBGM
//------4.ADC初始化
    //4.1.ADC初始时钟设置
    EALLOW;
      SysCtrlRegs.HISPCP.all = ADC_MODCLK; // HSPCLK = SYSCLKOUT/(2*ADC_MODCLK)  ;复位默认,HSPCLK=SysCLKOUT/2
    EDIS;
    //4.2使能AD时钟、完成AD校准及上电,该程序可见TI例程DSP2833x_Adc.c文件
    InitAdc();
    //4.3 详细配置ADC
    InitMyAdc();
//------5.GPIO初始化
    InitMyGpio();                //配置GPIO48为IOs输出功能,GPIO2为PWM模式
//------6.定时器初始化及启动
    //6.1 定时器初始化
    InitCpuTimers();   // For this example, only initialize the Cpu Timers
    //6.2 定时器定时周期初始化
    #if (CPU_FRQ_150MHZ)
        // Configure CPU-Timer 0, 1, and 2 to interrupt every 1000 usecond:
        // 150MHz CPU Freq, 1 second Period (in uSeconds)
         ConfigCpuTimer(&CpuTimer0, 150, TimerPeriod);
         //ConfigCpuTimer(&CpuTimer1, 150, 1000000);
         //ConfigCpuTimer(&CpuTimer2, 150, 1000000);
    #endif
    #if (CPU_FRQ_100MHZ)
         // Configure CPU-Timer 0, 1, and 2 to interrupt every 100 usecond:
         // 100MHz CPU Freq, 1 second Period (in uSeconds)
             ConfigCpuTimer(&CpuTimer0, 100, TimerPeriod)
           //ConfigCpuTimer(&CpuTimer1, 100, 1000000);
           //ConfigCpuTimer(&CpuTimer2, 100, 1000000);
    #endif

//6.3 启动定时器
    startCpuTimer0();
//------7.初始化PWM2模块
    InitEPWM();                    //配置ePWM2模块
//------8.清空缓存区
    for (i=0; i<BUF_SIZE; i++)
      {
          SampleTable0[i] = 0;
          SampleTable1[i] = 0;
          SampleTable2[i] = 0;
          SampleTable3[i] = 0;
          SampleTable4[i] = 0;
          SampleTable5[i] = 0;
          SampleTable6[i] = 0;
          SampleTable7[i] = 0;
          SampleTable8[i] = 0;
          SampleTable9[i] = 0;
          SampleTable10[i] = 0;
          SampleTable11[i] = 0;
          SampleTable12[i] = 0;
          SampleTable13[i] = 0;
          SampleTable14[i] = 0;
          SampleTable15[i] = 0;
      }
    while(1)
    {
     if  (SampleDone==1)
     {   for ( i=0; i<BUF_SIZE-1; i++)
       {
         SampleTable0[i] = SampleTable0[i+1];
         SampleTable1[i] = SampleTable1[i+1];
         SampleTable2[i] = SampleTable2[i+1];
         SampleTable3[i] = SampleTable3[i+1];
         SampleTable4[i] = SampleTable4[i+1];
         SampleTable5[i] = SampleTable5[i+1];
         SampleTable6[i] = SampleTable6[i+1];
         SampleTable7[i] = SampleTable7[i+1];
         SampleTable8[i] = SampleTable8[i+1];
         SampleTable9[i] = SampleTable9[i+1];
         SampleTable10[i] = SampleTable10[i+1];
         SampleTable11[i] = SampleTable11[i+1];
         SampleTable12[i] = SampleTable12[i+1];
         SampleTable13[i] = SampleTable13[i+1];
         SampleTable14[i] = SampleTable14[i+1];
         SampleTable15[i] = SampleTable15[i+1];
       }
         SampleDone=0;
     }
    }
}

interrupt void cpu_timer0_isr(void)
{
    CpuTimer0.InterruptCount++;  //中断计数器,用于计算中断的响应次数
    if(CpuTimer0.InterruptCount==500)  //每个1sLED闪烁一次
       {
       GpioDataRegs.GPBTOGGLE.bit.GPIO48 = 1;
       CpuTimer0.InterruptCount=0;
       }
    // Acknowledge this interrupt to receive more interrupts from group 1
     PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
     CpuTimer0Regs.TCR.bit.TIF=1;//清除中断标志位
     CpuTimer0Regs.TCR.bit.TRB=1;//重新装载初值
}

void InitMyGpio()
{
    EALLOW;
    // 配置GPIO48为普通IO口输出功能
    GpioCtrlRegs.GPBMUX2.all=0x00000000;    //功能选择寄存器 普通IO使用,GPIO48属于GPBMUX2
    GpioCtrlRegs.GPBDIR.all=0xFFFFFFFF;     //设置为输出模式

//配置GPIO2为EPWM2a功能
    GpioCtrlRegs.GPAPUD.bit.GPIO2 = 0;          //使能上拉
    GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 1;         //作为EPWM2a功能
    //配置GPIO4为EPWM3a功能
    GpioCtrlRegs.GPAPUD.bit.GPIO4 = 0;          //使能上拉
    GpioCtrlRegs.GPAMUX1.bit.GPIO4 = 1;         //作为EPWM3a功能

EDIS;
}

void InitEPWM()
{
    EPwm2Regs.TBCTL.bit.CTRMODE = 0;            //连续增计数模式
    EPwm2Regs.TBCTL.bit.HSPCLKDIV = 3;          //配置高速时钟/6分频;=2*k,k=1-7,k=0时1分频
    EPwm2Regs.TBCTL.bit.CLKDIV = 2;             //对输入时钟/4分频,2的k次方,k=0-7
    EPwm2Regs.AQCTLA.bit.ZRO = 2;               //计数值为0时,EPWM2a输出高电平
    EPwm2Regs.AQCTLA.bit.CAU = 1;               //计数值为比较值时,EPWM2a输出低电平
    EPwm2Regs.TBPRD = 49999;                    //配置周期值,信号频率为150M / (6*4)/ (TBPRD+1) = 1250Hz
    EPwm2Regs.CMPA.half.CMPA = (EPwm2Regs.TBPRD+1)/2;//配置比较值

EPwm3Regs.TBCTL.bit.CTRMODE = 0;            //连续增计数模式
    EPwm3Regs.TBCTL.bit.HSPCLKDIV = 3;          //配置高速时钟/6分频
    EPwm3Regs.TBCTL.bit.CLKDIV = 2;             //对输入时钟/4分频
    EPwm3Regs.AQCTLA.bit.ZRO = 2;               //计数值为0时,EPWM3a输出高电平
    EPwm3Regs.AQCTLA.bit.CAU = 1;               //计数值为比较值时,EPWM3a输出低电平
    EPwm3Regs.TBPRD = 49999;                    //配置周期值,信号频率为150M / (6*4)/ (TBPRD+1) = 1250Hz
    EPwm3Regs.CMPA.half.CMPA= (EPwm2Regs.TBPRD+1)/2;//配置比较值
 }

void InitMyAdc(void)
{
    AdcRegs.ADCTRL1.bit.ACQ_PS = ADC_SHCLK;  // Sequential mode: Sample rate   = 1/[(2+ACQ_PS)*ADC clock in ns]
                         //                     = 1/(3*6.67ns) =49.97MHz (for 150 MHz SYSCLKOUT)
                         //                     = 1/(3*10ns) =33.33MHz (for 100 MHz SYSCLKOUT)
                         // If Simultaneous mode enabled: Sample rate = 1/[(3+ACQ_PS)*ADC clock in ns]
    AdcRegs.ADCTRL1.bit.CPS = 1;                //内核时钟/2分频=75MHz
    AdcRegs.ADCTRL3.bit.ADCCLKPS = 1;           //AdcClk =75MHz/(2*(1+1))=18.75Mhz
    AdcRegs.ADCTRL3.bit.SMODE_SEL= 0;        //设置为顺序采样
    AdcRegs.ADCTRL1.bit.CONT_RUN= 0;         //设置为非连续运行方式
    AdcRegs.ADCTRL1.bit.SEQ_CASC = 1;        //设置为级联工作方式
    AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 15;   //设置最大通道数
    AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0;   //SEQ1对应CONV00-03
    AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1;
    AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x2;
    AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x3;
    AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0x4;   //SEQ2对应CONV04-07
    AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x5;
    AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 0x6;
    AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 0x7;
    AdcRegs.ADCCHSELSEQ3.bit.CONV08 = 0x8;   //SEQ3对应CONV08-11
    AdcRegs.ADCCHSELSEQ3.bit.CONV09 = 0x9;
    AdcRegs.ADCCHSELSEQ3.bit.CONV10 = 0xA;
    AdcRegs.ADCCHSELSEQ3.bit.CONV11 = 0xB;
    AdcRegs.ADCCHSELSEQ4.bit.CONV12 = 0xC;   //SEQ4对应CONV012-15
    AdcRegs.ADCCHSELSEQ4.bit.CONV13 = 0xD;
    AdcRegs.ADCCHSELSEQ4.bit.CONV14 = 0xE;
    AdcRegs.ADCCHSELSEQ4.bit.CONV15 = 0xF;

AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 0x1;     //打开SEQ1中断
    AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 0x1;   //使能 PWMA SOC触发

// 配置ePWM1触发ADC
    EPwm1Regs.ETSEL.bit.SOCAEN = 1;             // 使能ePWMa触发AD转换
    EPwm1Regs.ETSEL.bit.SOCASEL = 4;            // 选择当计数值递增至CMPA作为触发事件
    EPwm1Regs.ETPS.bit.SOCAPRD = 1;             // 在第一个触发事件后即产生触发脉冲
    EPwm1Regs.TBCTL.bit.CTRMODE = 0;            // 增计数模式
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = 1;          //HSPCLKDIV选择2分频
    EPwm1Regs.TBCTL.bit.CLKDIV = 0;             //CLKDIV选择不分频
    EPwm1Regs.TBPRD = 49999;                    //设置周期值,采样频率为150M / (1*2)/ (TBPRD+1) = 1500Hz
    EPwm1Regs.CMPA.half.CMPA = EPwm1Regs.TBPRD /2;    // 设置比较值
}
interrupt void AdcIsr(void)
{
    SampleDone=1;
    SampleTable0[BUF_SIZE-1] = 3.0*(AdcRegs.ADCRESULT0 >>4)/4095;
    SampleTable1[BUF_SIZE-1] = 3.0*(AdcRegs.ADCRESULT1 >>4)/4095;
    SampleTable2[BUF_SIZE-1] = 3.0*(AdcRegs.ADCRESULT2 >>4)/4095;
    SampleTable3[BUF_SIZE-1] = 3.0*(AdcRegs.ADCRESULT3 >>4)/4095;
    SampleTable4[BUF_SIZE-1] = 3.0*(AdcRegs.ADCRESULT4 >>4)/4095;
    SampleTable5[BUF_SIZE-1] = 3.0*(AdcRegs.ADCRESULT5 >>4)/4095;
    SampleTable6[BUF_SIZE-1] = 3.0*(AdcRegs.ADCRESULT6 >>4)/4095;
    SampleTable7[BUF_SIZE-1] = 3.0*(AdcRegs.ADCRESULT7 >>4)/4095;

SampleTable8[BUF_SIZE-1] = 3.0*(AdcRegs.ADCRESULT8 >>4)/4095;
    SampleTable9[BUF_SIZE-1] = 3.0*(AdcRegs.ADCRESULT9 >>4)/4095;
    SampleTable10[BUF_SIZE-1] = 3.0*(AdcRegs.ADCRESULT10 >>4)/4095;
    SampleTable11[BUF_SIZE-1] = 3.0*(AdcRegs.ADCRESULT11 >>4)/4095;
    SampleTable12[BUF_SIZE-1] = 3.0*(AdcRegs.ADCRESULT12 >>4)/4095;
    SampleTable13[BUF_SIZE-1] = 3.0*(AdcRegs.ADCRESULT13 >>4)/4095;
    SampleTable14[BUF_SIZE-1] = 3.0*(AdcRegs.ADCRESULT14 >>4)/4095;
    SampleTable15[BUF_SIZE-1] = 3.0*(AdcRegs.ADCRESULT15 >>4)/4095;

AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;           // 复位排序器至CONV00
    AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;         // 清除SEQ1中断标志位
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;     // 应答PIE分组中断
}

Tms320F28335中PWM触发ADC16路级联顺序采样相关推荐

  1. Tms320F28335中软件触发信号采样(ADC)

    //该程序用于信号ADC,其中,采用定时器0中断读取采样结果  // //该程序ADC触发源为软件触发(S/w),然后,通过AdcRegs.ADCST.bit.INT_SEQ1标志位为1判断转换结果 ...

  2. F28335 PWM触发ADC采样 代码+注释

    程序功能: 1 PWM生成 2 PWM触发3路采样 注:主要是对EPWM模块里的事件触发模块进行配置,然后把这些采样读取 数据的程序写到PWM中断里面去. #include "DSP2833 ...

  3. STM8单片机通过PWM触发ADC同步采样

      在做数字开关电源开发过程中使用最多的就是PWM功能和ADC采样功能.ADC采样时采样的时间点很重要,必须在PWM输出高电平的时候取采样,这样采样出来的数据才是最准确的.在STM8单片机中,可以通过 ...

  4. videojs如何获取请求消息_消息队列中,如何保证消息的顺序性?

    点击?蓝色" 深入原理",关注并"设为星标" 技术干货,第一时间推送 消息无序产生的原因 消息队列,既然是队列就能保证消息在进入队列,以及出队列的时候保证消息的 ...

  5. C# 关于dgv中DataGridViewComboBoxCell触发事件

    cell触发事件的先后顺序: ①不进行cell编辑情况时: CellEnter-->CellLeave-->CellValidating-->CellValidated ②对cell ...

  6. FileTracker : error FTK1013: 在以下文件跟踪日志文件中,未能找到 unicode 字节顺序标记: E:\HT-Mobile\cocos2d-project\MobileP

    最近在做项目中遇到了 FileTracker : error FTK1013: 在以下文件跟踪日志文件中,未能找到 unicode 字节顺序标记:  E:\HT-Mobile\cocos2d-proj ...

  7. 在python中用于触发异常的是_下列选项中,用于触发异常的是()。 (3.0分)_学小易找答案...

    [填空题]当使用序列中不存在的____时,会引发IndexError异常. (3.0分) [简答题]2017国考地市级: (三)假如你是某报社记者,请根据"给定资料3",以&quo ...

  8. WinForm中KeyDown,KeyPress和KeyUp的顺序与区别解析 PreviewKeyDown

    PreviewKeyDown:在焦点位于此控件上的情况下,当有按键动作时发生(在 KeyDown 事件之前发生). 小注: 某些按键,比如 Tab.Return.Esc 和箭头键,通常会被某些控件忽略 ...

  9. 【dsPIC33】PWM系列之PWM触发ADC

    前言 PWM触发ADC进行采样,是对于电机控制来说非常重要的一环,做矢量控制,能否运行,电流采样是重中之重,因此电流采样的时刻控制非常重要,本节就接着上篇文章的中心对齐模式,讲解,中心对齐模式下的PW ...

最新文章

  1. Tomcat unable to start within 45 seconds.
  2. python cv2.imencode()(将图像编码到内存缓冲区中。)(图像压缩原理)
  3. 纯Python包发布setup脚本编写示例
  4. .NET 2.0 RC的一个Bug
  5. 【小白学习PyTorch教程】十七、 PyTorch 中 数据集torchvision和torchtext
  6. C++学习笔记4[循环语句]
  7. Windows系统下oracle数据库每天定时备份
  8. 缩放手势 ScaleGestureDetector 源码解析,这一篇就够了
  9. Android之java.lang.UnsatisfiedLinkError(Failed to register native method ***callMethod1())解决办法
  10. java我的世界1.14.4_我的世界1.14.4国际版下载
  11. VC++ 6.0 C8051F340 USB 通信 CAN 数据解析
  12. 10-Python-mapfilter
  13. 全国车辆限行查询api 全国限行限号数据服务
  14. 高等数学-向量代数与空间解析几何
  15. 在Windows 10 64 位机器上安装Debug
  16. 斐波那契数列C语言设计步骤,斐波那契数列c语言函数
  17. Should be compatible with WP_Widget::widget($args, $instance)
  18. Automatic Targetless LiDAR-CameraCalibration: A Survey论文解读
  19. 【CLAA系列】CLAA协议学习(CS方向)
  20. 计算机论文的致谢部分写什么,论文的致谢部分怎么写

热门文章

  1. 腾讯高工保姆级“Java成长手册”,层层递进,全是精华 Github上都没有
  2. 分布式架构设计中的CAP原理
  3. OpenGL Android 安卓 入门 GLES20 初学者 初级 官方
  4. 【测试工程师】关于软件测试的10条建议
  5. 邮箱的规则、正则表达式【亲测有效】
  6. 零基础学C++Note
  7. 中国城市码cityCode映射
  8. win2d CanvasCommandList 使用方法
  9. 【声明】DPDK开源社区更名为“DPDK与SPDK开源社区”
  10. 复合索引 /多列索引 /联合索引 /组合索引?????