DSP28335学习记录(四)——ADC、DMA

本文记录一下仿真模式下的printf()的使用,ADC,DMA,


目录

一、仿真模式下的printf()

二、ADC

 2.1 ADC模式

2.2 触发源,中断,覆盖功能

2.3 如何初始化配置

三、DMA


一、仿真模式下的printf()

这块推荐这个:CCS中printf()的使用

其实想找一下用仿真器的COM口做串口的方法,没有找到。这个在CCS仿真模式下直接用printf的方式,还挺方便的。

二、ADC

F28335 的 ADC 模块主要包括以下特点:

  • --12 位模数转换
  • --2 个采样保持器(S/H)
  • --同时或顺序采样
  • --模拟电压输入范围 0-3V
  • --ADC 转换时钟频率最高可配置为 25MHz,采样带宽 12.5MHz
  • --16 通道模拟输入
  • --排序器支持 16 通道独立循环“自动转换”,每次转换通道可以软件编程 选择。
  • --16 个结果寄存器存放 ADC 转换的结果,转换后的数字量表示为: 数字值=4095*(输入模拟值-ADCLO)/3,输入模拟值在 0-3V 之间
  • --多个触发源启动 ADC 转换(SOC): 

    ①S/W--软件立即启动

    ②外部引脚

    ③ePWMx SOCA 启动

    ④ePWMx SOCB 启动

  • --灵活的中断控制,允许每个或者每隔一个序列转换结束产生中断请求
  • --排序器可工作在启动/停止模式
  • --采样保持(S/H)采集时间窗口有独立的预定标控制

在使用 ADC 转换模块时,特别要注意的是 F28335 的 AD 的输入范围 0-3V,若 输入负电压或高于 3V 的电压就会烧坏 AD 模块,这一点要务必引起重视。超出输 入范围的电压可在前级电路,通过电阻进行分压,或经运放比例电路进行处理后 再输入。连接到 ADCINxx 引脚的模拟输入信号要尽可能的远离数字电路信号线, ADC 模块的电源供电要与数字电源电源隔离开,避免数字电源的高频干扰,ADC 的参考源是影响 AD 精度的一个重要因数,注意 ADC 参考源的电压纹波处理

ADC的内部框图:16个输入通道,分AB两组,两个采样保持器,一个转换模块,两个排序器。

由于有两个采样保持器,所以根据工作方式分:顺序采样,同步采样。后面讲。

双排序器根据工作方式分:级联模式,双排序器模式。

以上两个模块排列组合,ADC共有4中模式。

 2.1 ADC模式

1,级联模式

在级联排序器操作方式下,2 个 8 状态排序器(SEQ1 和 SEQ2)构成一个 16状态的排序SEQ。只能设置一个触发源,按照顺序转换。

2,双排序器模式

两个排序器独立运行,分别独立设置一个触发源,只有一个AD转换模块,所以分时复用,转换顺序下图。 

3,顺序采样

和级联排序模式下一样,就是按照顺序转换。级联排序其顺序采样也是最常用的模式。

4,同步采样

如果一个输入来自 ADCINA0-ADCINA7,另一个输入来自 ADCINB0-ADCINB7, ADC 能够实现 2 个 ADCINxx 输入的同时采样。此外,要求 2 个输入必须有同样的 采样和保持偏移量(比如 ADCINA4 和 ADCINB4,不能是 ADCINA7 和 ADCINA6)。 为了让 ADC 模块工作在同步采样模式,必须设置 ADCTRL3 寄存器中的 SMODE_SEL 位为 1。

在同步采样模式下,CONVxx 寄存器的最高位不起作用,每个采样和保持缓冲 器对 CONVxx 寄存器低 3 位确定的引脚进行采样。例如,如果 CONVxx 寄存器的值 是 0110b,ADCINA6 就由采样保持器 A 采样,ADCINB6 有采样保持器 B 采样,和 1110b 的效果是一样的,如果 CONVxx 寄存器的值是 1001b,ADCINA1 由采样和保 持器 A 采样,ADCINB1 由采样和保持器 B 采样。采样保持两路可以同步进行,因 为有两个采样保持器,但是转换不可能同时进行。转换器首先转换采样保持器 A 中锁存的电压量,然后转换采样保持器 B 中锁存的电压量。采样保持器 A 转换的 结果保存到当前的 ADCRESULTn 寄存器(如果排序器已经复位,SEQ1 的结果放到 ADCRESULT0),采样保持器 B 转换的结果保存到下一个(顺延)ADCRESULTn 寄 存器(如果排序器已经复位,SEQ1 的结果放到 ADCRESULT1),结果寄存器指针 每次增加 2。

2.2 触发源,中断,覆盖功能

1,触发源

2,中断

 在不同工作模式下如何使用中断模式 1 和中断模式 2。

情形 1:在第 1 个和第 2 个序列中采样的数量不相等。

(1)中断模式 1(每个 EOS 到来时产生中断请求)

①排序器用 MAX_CONVn=1 初始化,转换 I1 和 I2。

②在中断服务子程序 a 中,通过软件将 MAX_CONVn 的值设为 2,转换 V1、V2 和 V3。

③在中断服务子程序 b 中,完成下列任务:

--将 MAX_CONVn 的值再次设置为 1,转换 I1 和 I2。

--从 ADC 结果寄存器中读出 I1、I2、V1、V2 和 V3 的值。

--复位排序器。

④重复操作第②、③步。每次 SEQ_CNTRn 等于 0 时产生中断,并且中断能够 被识别。

情形 2:在第 1 个和第 2 个序列中采样的数量相等。

(2)中断模式 2 操作(每隔一个 EOS 信号产生中断请求)

①排序器设置 MAX_CONVn=2 初始化,转换 I1、I2、I3 或 V1、V2 和 V3。

②在服务子程序 b 和 d 中,完成下列任务。

--从 ADC 结果寄存器中读出 I1、I2、I3 或者 V1、V2 和 V3 的值。

--复位排序器。

--重复第②步。

情形 3:两个序列的采样个数是相等的(带空读)

(3)中断模式 2(隔一个 EOS 信号产生中断请求)

①MAX_CONVn=2,初始化序列器,转换 I1、I2 和 x(空采样)。

②在中断服务子程序 b 和 d 中,完成下列任务:

--从 ADC 结果寄存器中读出 I1、I2、x、V1、V2 和 V3 的值。

--复位排序器。

--重复第②步。在①中,I1、I2 后的 X 采样为一个空的采样,其实并没有要求采样。然而利用模式 2 间隔产生中断请求的特性,可以减小中断服务子程序和 CPU 的开销。

3,排序器覆盖功能:(开DMA时,需要使能)

通常在运行模式下,排序器 SEQ1、SEQ2 或者级联 SEQ 用于选择 ADC 通道, 并将转换的结果存储在相应的 ADCRESULTn 寄存器中。在 MAX_CONVn 设置的转换 结束时,排序器自动返回 0。在使用排序器覆盖功能时,排序器的自动返回可通 过软件控制,这由 ADC 控制寄存器 1(ADCCTRL1)的第 5 位控制。例如假定 SEQOVRD 位为 0,ADC 工作在级联模式下的连续转换模式,MAX_CONV1 设置为 7,通常情况 下,排序器会递增并将 ADC 转换结果更新结果寄存器到 ADCRESULT7 寄存器,然 后返回到 0,。当 ADCRESULT7 寄存器更新完成后,相应的中断标志位被置位。当 SEQ_OVRD 位被重新置位,排序器在更新 7 个结果寄存器后不再回绕到 0,而将继 续增加,并更新 ADCRESULT8 寄存器,直到 ADCRESULT15 为止。ADCRESULT15 寄 存器更新完毕再返回到 0。这可以将结果寄存器看成 FIFO,用于 ADC 对连续数据 的捕捉。当 ADC 在最高数据速率下进行转换时,这个功能有助于捕捉 ADC 的数据

2.3 如何初始化配置

ADC有8个设置寄存器,不过使用起来很简单。

ADC配置步骤:

1,ADC外设时钟使能

2,高速外设时钟分频。从系统时钟进入ADC模块的,最高25M。

3,ADC初始化。

4,ADC内核时钟分频。用于ADC转换的。

5,采样持续时间。

6,排序器模式

7,采样方式。

8,设置输入通道,开几个口就设置几个。

9,设置最大通道数。

10,设置是否连续转换。

(11,排序器覆盖模式使能,开DMA时)

(12,使能SOC触发。用SOC信号触发模式时)

13,使能排序器。

例程,非DMA模式


#define ADC_MODCLK 3
#define ADC_CKPS   0x1   // ADC module clock = HSPCLK/2*ADC_CKPS   = 25.0MHz/(1*2) = 12.5MHz
#define ADC_SHCLK  0xf   // S/H width in ADC module periods                        = 16 ADC clocks






void ADC_Init(void)
{
    // Specific clock setting for this example:
    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1;    // ADC
    EDIS;

    // Specific clock setting for this example:
    EALLOW;
    SysCtrlRegs.HISPCP.all = ADC_MODCLK;    // HSPCLK = SYSCLKOUT/(2*ADC_MODCLK) 25M
    EDIS;

    InitAdc();  // For this example, init the ADC

    // Specific ADC setup for this example:
    AdcRegs.ADCTRL3.bit.ADCCLKPS = ADC_CKPS;  //时钟分频25/(ADC_CKPS+1)=12.5M
    AdcRegs.ADCTRL1.bit.ACQ_PS = ADC_SHCLK;   //采样持续时间,最大值
    AdcRegs.ADCTRL1.bit.SEQ_CASC = 1;        // 级联模式
    AdcRegs.ADCTRL3.bit.SMODE_SEL = 0;       //顺序采样

    AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0;  //ADC通道0配置AIN0
    AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 1;  //ADC通道0配置AIN1
    AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 2;  //ADC通道0配置AIN2
    AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 2;  //最大转换通道数


    AdcRegs.ADCTRL1.bit.CONT_RUN = 0;       // 非连续转换模式
    AdcRegs.ADCTRL1.bit.SEQ_OVRD = 1;    //

    // Start SEQ1
    AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;  //使能epwm_SOCA信号的触发SQE1
    AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1;  //使能SEQ1

}

Uint16 Read_ADCValue(void)
{
    while (AdcRegs.ADCST.bit.INT_SEQ1== 0);
    AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;
    return AdcRegs.ADCRESULT0>>4;
}

三、DMA

28335的DMA用起来很简单,只是几个功能函数参数可能有点不好理解。

DMA配置方式:

1,使能DMA外设时钟,

2,初始化DMA。

3,配置下面几个函数:

        DMACH1AddrConfig

        DMACH1BurstConfig
        DMACH1TransferConfig
        DMACH1WrapConfig
        DMACH1ModeConfig

4,启动DMA。

  1. DMACH1AddrConfig:两个参数:源指针,目的指针。
  2. DMACH1BurstConfig:帧函数,一个触发信号执行一次

    三个参数:

    数据个数(类型Uint16),

    每传一个数据,源指针增加量,

    每传一个数据,目的指针增加量。

  3. DMACH1TransferConfig:传输函数,主要设置几帧数据产生一个中断

    三个参数:

    帧个数,达到数会产生中断,

    每传一帧,源指针增加量,

    每传一帧,目的指针增加量。

  4.  DMACH1WrapConfig:打包函数,主要设置返回步长。

    四个参数:

    执行多少帧,源指针将返回,

    源指针返回之后,加上一个偏移量。

    执行多少帧,目的指针将返回,

    目的指针返回之后,加上一个偏移量。

    (其实不难理解,我们看一下寄存器的说明就清楚了。)

  5. 细心的可能发现 DMACH1TransferConfig 和 DMACH1WrapConfig 指针偏移量某些情况下好像有功能重合。数据手册中提到过,DMACH1WrapConfig设置偏移量时,会忽略DMACH1TransferConfig的偏移量。DMACH1WrapConfig的打包帧个数大于DMACH1TransferConfig时,DMACH1WrapConfig将失效。 

  6. DMACH1ModeConfig是DMA配置寄存器:

    ①persel--选择触发源,值为下列选项:

            DMA_SEQ1INT--------ADC

            DMA_SEQ2INT--------ADC

            DMA_XINT1 --------外部中断

            DMA_XINT2 --------外部中断

            DMA_XINT3 --------外部中断

            DMA_XINT4 --------外部中断

            DMA_XINT5 --------外部中断

            DMA_XINT6 --------外部中断

            DMA_XINT7 --------外部中断

            DMA_XINT13 --------外部中断

            DMA_TINT0 --------CPU 时钟

            DMA_TINT1 --------CPU 时钟

            DMA_TINT2 --------CPU 时钟

            DMA_MXEVTA --------McBSP-A

            DMA_MREVTA --------McBSP-A

            DMA_MXREVTB --------McBSP-B

            DMA_MREVTB --------McBSP-B

    ②perinte--使能触发源,值为 PERINT_DISABLE 或 PERINT_ENABLE。

    ③oneshot--使能 oneshot 模式,值为 ONESHOT_DISABLE 或 ONESHOT_ENABLE。此模式下,一次触发完成全部 burst。

    ④cont--使能 Continuous 模式,值为 CONT_DISABLE 或 CONT_ENABLE。此模 式下,传送完毕后 DMA 重新被初始化,并等待触发源。

    ⑤synce--使能外围设备同步,值为 SYNC_DISABLE 或 SYNC_ENABLE。

    ⑥syncsel--同步选择。值为 SYNC_SRC 或 SYNC_DST。

    ⑦ovrinte--使能溢出中断。值为 OVRFLOW_DISABLE 或 OVEFLOW_ENABLE。

    ⑧datasize--每次传送位数。值为 SIXTEEN_BIT 或 THIRTYTWO_BIT。

    ⑨chintmode--通道中断产生模式。CHINT_BEGIN:传送开始发中断。 CHINT_END:传送结束发中断。

    ⑩chinte--使能通道中断。值为 CHINT_DISABLE 或 CHINT_ENABL

上例程,

void DMACH1_ADC_Init(volatile Uint16 *DMA_Dest,volatile Uint16 *DMA_Source)
{
    EALLOW;
    SysCtrlRegs.PCLKCR3.bit.DMAENCLK = 1;       // DMA Clock
    EDIS;
    // Initialize DMA
    DMAInitialize();

    // Configure DMA Channel
    DMACH1AddrConfig(DMA_Dest,DMA_Source);
    DMACH1BurstConfig(3,1,1);         //每帧传4个数,每传一个数指针加1

    DMACH1TransferConfig(9,1,1);      //传10帧数据触发中断,每帧之间指针加1

    DMACH1WrapConfig(0ffff,0,0ffff,0);  //关闭打包
    

    DMACH1ModeConfig(DMA_SEQ1INT,      //触发源SEQ1
                     PERINT_ENABLE,    //使能触发源
                     ONESHOT_DISABLE,  //关闭单次运行
                     CONT_ENABLE,      //使能连续运行
                     SYNC_DISABLE,     //关闭同步
                     SYNC_SRC,         //和源设备同步
                     OVRFLOW_DISABLE,  //关闭溢出中断
                     SIXTEEN_BIT,      //16位传送
                     CHINT_END,        //传送结束产生中断
                     CHINT_ENABLE);    //使能中断通道

    StartDMACH1(); //启动DMA

}


interrupt void local_DINTCH1_ISR(void)     // DMA Channel 1
{



    // To receive more interrupts from this PIE group, acknowledge this interrupt
    PieCtrlRegs.PIEACK.bit.ACK7 = 1;

//  asm ("      ESTOP0");//ok
//  for(;;);
}

待续。。

  • 18
    点赞
  • 108
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想法很奇特

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值