0
点赞
收藏
分享

微信扫一扫

Python零基础入门教程

***配套代码工程***

LLC数字控制TMS320F28034,3-DSP的timer定时器配置介绍

  • LLC数字控制TMS320F28034,3-DSP的timer定时器配置介绍
  • 1 TMS320F28034
    • 1.1 系统时钟大小
    • 1.2 TMS320F28034 芯片系统时钟源介绍
  • 2 时钟库函数说明示例
  • 3 TMS320F28034手写定时器功能
  • 4 定时器运用
  • 5 工程代码
  • 6 定时器中断总结


***配套代码工程***

LLC数字控制TMS320F28034,3-DSP的timer定时器配置介绍

***配套代码工程***

1 TMS320F28034

1.1 系统时钟大小

TMS320F28034 的系统时钟即为其主频。根据第一节手册的介绍,该系统时钟的最大值为 60MHz。在实际工程应用中,为了防止系统在满频时出现不稳定的运行状况,通常会将时钟频率降低一些,例如配置为 56MHz 或 40MHz。当然,具体的配置需要根据各功能模块的需求,合理地设定主频大小。
在某些数字高速控制 PWM 的情况下,主频使用会比较高;
在某些高速通讯的情况下,主频使用也会比较高;
在需要系统快速响应的功能设计时,主频使用同样会比较高。

1.2 TMS320F28034 芯片系统时钟源介绍

在这里插入图片描述

TMS320F28034 是德州仪器(TI)生产的一款高性能数字信号处理器(DSP)。它具有多种时钟源,可以灵活地配置系统时钟,以满足不同应用场景的需求。
系统时钟源
TMS320F28034 提供了多个时钟源供用户选择,包括:

  1. 内部振荡器(Internal Oscillator)
    内部低频振荡器 (INTOSC1 和 INTOSC2):
    芯片内置两个低频振荡器,通常工作在 10MHz 左右。它们可以作为系统时钟的备用或低功耗模式下的时钟源。
  2. 外部晶振(External Crystal Oscillator)
    外部晶振:
    支持外部晶振输入,可以通过外部晶体或振荡器产生高精度的时钟信号。常用频率有 20MHz、25MHz 等。
  3. 外部时钟输入(External Clock Input)
    外部时钟输入 (XCLKIN):
    可以直接从外部输入时钟信号,灵活性较高,适用于对时钟源有特殊要求的应用场景。
  4. 零等待状态片上振荡器(Zero Wait-State On-Chip Oscillator)
    零等待状态片上振荡器:
    提供高性能的时钟源,适用于需要快速响应和高性能的应用。
    时钟配置
    为了满足不同应用的需求,TMS320F28034 提供了灵活的时钟配置选项:
    锁相环 (PLL):
    TMS320F28034 集成了一个锁相环 (PLL),可以将输入时钟频率倍增,以生成高频系统时钟。PLL 的倍频系数可以编程配置,以满足不同的频率需求。
    时钟分频器 (Clock Dividers):
    时钟分频器可以将高频系统时钟分频,生成适合不同模块使用的时钟信号。这使得系统能够在不同的功能模块之间合理分配时钟资源。
    应用场景
    高性能控制应用:
    在需要高性能和快速响应的控制应用中,可以使用外部晶振加锁相环的组合,生成高频系统时钟,以满足性能需求。
    低功耗应用:
    在低功耗应用中,可以使用内部振荡器或外部低频时钟源,减少功耗。
    灵活配置:
    根据具体应用需求,灵活配置系统时钟源和时钟频率,以实现最佳的系统性能和功耗平衡。
    以上是 TMS320F28034 芯片系统时钟源的简要介绍。通过合理配置时钟源和时钟频率,可以充分发挥该芯片的性能,满足各种应用场景的需求。

2 时钟库函数说明示例

TMS320F28034 芯片官方时钟库函数说明
TMS320F28034 是德州仪器(TI)生产的一款高性能数字信号处理器(DSP),用于嵌入式控制应用。TI 提供了丰富的库函数,以简化开发过程。以下是一些常用的与时钟配置相关的官方库函数说明。
库函数

  1. InitSysCtrl
    功能:初始化系统控制寄存器,包括启用时钟、配置PLL、设置系统时钟频率等。
    使用示例:
InitSysCtrl();
  1. InitPll
    功能:配置并启用锁相环 (PLL)。
    参数:
pllMult: PLL 的倍频系数。
clkDiv: 系统时钟分频系数。

使用示例:

InitPll(10, 2);  // 设置 PLL 倍频系数为 10,系统时钟分频系数为 2
  1. SetVCLK
    功能:设置外设时钟 (VCLK) 的分频系数。
    参数:
div: VCLK 的分频系数。

使用示例:

SetVCLK(2);  // 设置 VCLK 分频系数为 2
  1. InitPeripheralClocks
    功能:初始化外设时钟,启用所需的外设时钟。
    使用示例:
InitPeripheralClocks();
  1. DisablePeripheralClocks
    功能:禁用特定外设的时钟,以节省功耗。
    参数:
peripheral: 需要禁用时钟的外设。

使用示例:

DisablePeripheralClocks(SYSCTL_PERIPH_CLK_SPIA);  // 禁用 SPI A 的时钟
  1. EnablePeripheralClocks
    功能:启用特定外设的时钟。
    参数:
peripheral: 需要启用时钟的外设。

使用示例:

EnablePeripheralClocks(SYSCTL_PERIPH_CLK_SPIA);  // 启用 SPI A 的时钟
  1. SysClkOutConfig
    功能:配置系统时钟输出到外部引脚。
    参数:
clkOutDiv: 系统时钟输出的分频系数。

使用示例:

SysClkOutConfig(2);  // 设置系统时钟输出的分频系数为 2

示例代码
以下是一个完整的示例代码,展示如何使用上述库函数来配置系统时钟:

#include "F2803x_Device.h"
#include "F2803x_Examples.h"

void main(void)
{
    // 初始化系统控制
    InitSysCtrl();

    // 配置并启用 PLL
    InitPll(10, 2);  // 设置 PLL 倍频系数为 10,系统时钟分频系数为 2

    // 初始化外设时钟
    InitPeripheralClocks();

    // 启用特定外设时钟
    EnablePeripheralClocks(SYSCTL_PERIPH_CLK_SPIA);

    // 配置系统时钟输出到外部引脚
    SysClkOutConfig(2);  // 设置系统时钟输出的分频系数为 2

    while (1)
    {
        // 主循环
    }
}

通过使用这些库函数,开发者可以方便地配置 TMS320F28034 的时钟系统,以满足各种应用需求。详细的函数说明和更多使用示例可以参考 TI 官方提供的文档和示例代码。

3 TMS320F28034手写定时器功能

我们通过定时器配置,实现在主频60M情况下的两个定时器溢出中断功能,定时市场分别为20us和1ms定时器。
(1)首先我们选择内部时钟振荡器
(2)配置分频倍频系数

// Defines
//
//#define DSP28_DIVSEL   0      // Enable /4 for SYSCLKOUT
//#define DSP28_DIVSEL   1      // Disable /4 for SYSCKOUT
#define DSP28_DIVSEL   2      // Enable /2 for SYSCLKOUT
//#define DSP28_DIVSEL   3      // Enable /1 for SYSCLKOUT

#define DSP28_PLLCR   12    //Uncomment for 60 MHz devs [60 MHz=(10MHz * 12)/2]
//#define DSP28_PLLCR   11
//#define DSP28_PLLCR   10
//#define DSP28_PLLCR    9
//#define DSP28_PLLCR    8  //Uncomment for 40 MHz devs [40 MHz=(10MHz * 8)/2]
//#define DSP28_PLLCR    7
//#define DSP28_PLLCR    6
//#define DSP28_PLLCR    5
//#define DSP28_PLLCR    4
//#define DSP28_PLLCR    3
//#define DSP28_PLLCR    2
//#define DSP28_PLLCR    1
//#define DSP28_PLLCR    0  // PLL is bypassed in this mode
//

(3)定时器配置和中断配置

void FunTimerInit(void)
{
    EALLOW;  // This is needed to write to EALLOW protected registers
    //打开对应定时器时钟
    SysCtrlRegs.PCLKCR3.bit.CPUTIMER0ENCLK = 1;
    SysCtrlRegs.PCLKCR3.bit.CPUTIMER1ENCLK = 1;

    // CPU 定时器 0
    // 寄存器地址指针和各自计时器初始化:
    CpuTimer0.RegsAddr = &CpuTimer0Regs;
    // 定时器周期寄存器最大值初始化:
    CpuTimer0Regs.PRD.all  = 0xFFFFFFFF;
    // 预分频寄存器初始化为1 (SYSCLKOUT):
    CpuTimer0Regs.TPR.all  = 0;
    CpuTimer0Regs.TPRH.all = 0;
    // 确保定时器0停止:
    CpuTimer0Regs.TCR.bit.TSS = 1;
    // 重加载计数器周期值:
    CpuTimer0Regs.TCR.bit.TRB = 1;
    // 复位中断计时器:
    CpuTimer0.InterruptCount = 0;

    // CPU 定时器 1
    // 寄存器地址指针和各自计时器初始化:
    CpuTimer1.RegsAddr = &CpuTimer1Regs;
    // 定时器周期寄存器最大值初始化:
    CpuTimer1Regs.PRD.all  = 0xFFFFFFFF;
    // 预分频寄存器初始化为1 (SYSCLKOUT):
    CpuTimer1Regs.TPR.all  = 0;
    CpuTimer1Regs.TPRH.all = 0;
    // 确保定时器1停止:
    CpuTimer1Regs.TCR.bit.TSS = 1;
    // 重加载计数器周期值:
    CpuTimer1Regs.TCR.bit.TRB = 1;
    // 复位中断计时器:
    CpuTimer1.InterruptCount = 0;

    //定时器时长配置
    //60:代表主频60M,
    //20:代表20us,
    //1000:代表1ms
    ConfigCpuTimer(&CpuTimer0,60,20);
    ConfigCpuTimer(&CpuTimer1,60,1000);
    StartCpuTimer0();
    StartCpuTimer1();

    PieVectTable.TINT0 = &CpuTimer0Isr;//往中断矢量表中填写定时器0一个指针
    PieVectTable.TINT1 = &CpuTimer1Isr;//往中断矢量表中填写定时器1一个指针


    //打开PIE组对应中断
    PieCtrlRegs.PIEIER1.bit.INTx7 = 1; //使能第一组7通道定时器0
    IER |= M_INT1;  // Enable CPU INT
    IER |= M_INT13; //根据中断向量表使能定时器1

    EDIS;   // This is needed to disable write to EALLOW protected registers
}

//定时器中断0的中断服务函数
interrupt void CpuTimer0Isr(void)
{
    //============================================================
    CpuTimer0Regs.TCR.bit.TIF  = 1; //清除外设级中断标志位
    PieCtrlRegs.PIEACK.bit.ACK1= 1; //清除PIE级中断应答
}


//定时器中断0的中断服务函数
interrupt void CpuTimer1Isr(void)
{
    //============================================================
    CpuTimer1Regs.TCR.bit.TIF  = 1; //清除外设级中断标志位
    PieCtrlRegs.PIEACK.bit.ACK1= 1; //清除PIE级中断应答
}

4 定时器运用

(1)使用定时器0实现板子一个灯的1S闪烁功能

//定时器中断0的中断服务函数==20us
static unsigned int  timercnt= 0;
interrupt void CpuTimer0Isr(void)
{
    timercnt++;
    //1S时长
    if(timercnt>50000)
    {
        timercnt = 0;
        //指示灯的引脚状态进行反转
        LEDRTOGGLE();
        LEDYTOGGLE();

    }
    //============================================================
    CpuTimer0Regs.TCR.bit.TIF  = 1; //清除外设级中断标志位
    PieCtrlRegs.PIEACK.bit.ACK1= 1; //清除PIE级中断应答
}

(2)使用定时器1实现精准的毫秒级计时函数

//delay_ms时间函数
static unsigned char delay_flag = 0;
static unsigned int delay_cnt = 0;
void delay_ms(unsigned int timer)
{
    delay_flag = 1;
    delay_cnt = 0;
    while(delay_cnt<timer)
    {
        ;
    }
    delay_flag = 0;
    delay_cnt = 0;
}

在定时器1中进行计时

//时间计数的代码程序
    if(delay_flag)
    {
        delay_cnt++if(delay_cnt>65500)
        {
            delay_cnt = 65500;
        }
        else
        {
            ;
        }
    }
    else
    {
        delay_cnt = 0;
    }

5 工程代码

在这里插入图片描述

/*

  • includes.h
  • Created on: 2024年7月29日
  •  Author:
    

*/

#ifndef APP_INCLUDES_H_
#define APP_INCLUDES_H_

#include "Flash2803x_API_Library.h"
#include "Flash2803x_API_Config.h"

#include "DSP28x_Project.h"
#include "DSP2803x_DefaultISR.h"
#include "DSP2803x_Adc.h"

#include "Flash2803x_API_Config.h"
#include "string.h"

#include "sys_gpio.h"
#include "sys_timer.h"

//------------------------------------------
void MemCopy(Uint16 *SourceAddr, Uint16* SourceEndAddr, Uint16* DestAddr);



extern void Init_system(void);
extern void Init_system_end(void);


#endif /* APP_INCLUDES_H_ */

//Main.c文件中

#include "includes.h"


/********************************************************
* 函数名称:Init_system
* 功 能:   系统初始化
* 入口参数:
* 出口参数:
* 修 改:
********************************************************/
void Init_system(void)
{
    InitSysCtrl();

    DINT;
    InitPieCtrl();
    IER = 0x0000;
    IFR = 0x0000;
    InitPieVectTable();

    EALLOW;
    Flash_CPUScaleFactor = SCALE_FACTOR;
    Flash_CallbackPtr=NULL;
    EDIS;

    MemCopy(&RamfuncsLoadStart,&RamfuncsLoadEnd, &RamfuncsRunStart);

    InitFlash();
}
/********************************************************
* 函数名称:void Init_system_end(void)
* 功 能:   系统初始化结束
* 入口参数:
* 出口参数:
* 修 改:
********************************************************/
void Init_system_end(void)
{
    EALLOW;  // This is needed to write to EALLOW protected registers
    PieCtrlRegs.PIECTRL.bit.ENPIE = 1;   // Enable the PIE block
    EDIS;    // This is needed to disable write to EALLOW protected registers
    //================================================================================
    EINT;
    ERTM;

}

/********************************************************
函数名称:main
函数功能:主程序
入口参数:
出口参数:
修    改:
********************************************************/
void main(void)
{
    Init_system();

    FunTimerInit();

    FunGpioInit();

    Init_system_end();
//
    while(1)
    {
        //计时200ms
        delay_ms(200);
        //指示灯的引脚状态进行反转
        LEDGTOGGLE();
    }
}

/*

  • sys_gpio.c
  • Created on: 2024年7月30日
  •  Author:
    

*/

#include "includes.h"


void FunGpioInit(void)
{
    GpioDataRegs.GPADAT.all = 0ul;
    GpioDataRegs.GPBDAT.all = 0ul;

    //GPIO初始化
    //开始寄存器配置前执行指令
    EALLOW;
    // GPIOA DATA数据全清0
    GpioDataRegs.GPADAT.all = 0ul;
    // GPIOB DATA数据全清0
    GpioDataRegs.GPBDAT.all = 0ul;
    //LED G
    GpioCtrlRegs.GPAMUX2.bit.GPIO24=0;
    GpioCtrlRegs.GPADIR.bit.GPIO24=1;
    //LED Y
    GpioCtrlRegs.GPAMUX2.bit.GPIO21=0;
    GpioCtrlRegs.GPADIR.bit.GPIO21=1;
    //LED R
    GpioCtrlRegs.GPAMUX2.bit.GPIO20=0;
    GpioCtrlRegs.GPADIR.bit.GPIO20=1;

    // GPIO0 <-> EPWM1A == 0:GPIO功能 1:PWM功能
    GpioCtrlRegs.GPAMUX1.bit.GPIO0=0;
    // GPIO1 <-> EPWM1B == 0:GPIO功能 1:PWM功能
    GpioCtrlRegs.GPAMUX1.bit.GPIO1=0;
    // GPIO0 <-> EPWM1A == 0:输出功能 1:输入功能
    GpioCtrlRegs.GPADIR.bit.GPIO0=1;
    // GPIO1 <-> EPWM1B == 0:输出功能 1:输入功能
    GpioCtrlRegs.GPADIR.bit.GPIO1=1;
    // GPIO0 <-> EPWM1A == 1:输出0
    GpioDataRegs.GPACLEAR.bit.GPIO0=1;
    // GPIO1 <-> EPWM1B == 1:输出0
    GpioDataRegs.GPACLEAR.bit.GPIO1=1;

    // COMP_OUT GPIO42 <-> OPP_COMP1_OUT
    GpioCtrlRegs.GPBMUX1.bit.GPIO42 = 3;
    // AI02<-> COPM1+ ==2:比较器功能
    GpioCtrlRegs.AIOMUX1.bit.AIO2 = 2;
    // GPIO15 <-> TZ1
    GpioCtrlRegs.GPAMUX1.bit.GPIO15 = 1;

    //寄存器配置结束后执行指令
    EDIS;
}

/*

  • sys_gpio.h
  • Created on: 2024年7月30日
  •  Author:
    

*/

#ifndef APP_SYS_GPIO_H_
#define APP_SYS_GPIO_H_

//===========================================================================


#define LEDRGPIO        GPIO20
#define LEDRMUX         GpioCtrlRegs.GPAMUX2.bit.LEDRGPIO
#define LEDRDIR         GpioCtrlRegs.GPADIR.bit.LEDRGPIO
#define LEDRTOGGLE()    GpioDataRegs.GPATOGGLE.bit.LEDRGPIO = 1
#define LEDRON()        GpioDataRegs.GPASET.bit.LEDRGPIO =1
#define LEDRLOW()       GpioDataRegs.GPACLEAR.bit.LEDRGPIO =1


#define LEDYGPIO        GPIO21
#define LEDYMUX         GpioCtrlRegs.GPAMUX2.bit.LEDYGPIO
#define LEDYDIR         GpioCtrlRegs.GPADIR.bit.LEDYGPIO
#define LEDYTOGGLE()    GpioDataRegs.GPATOGGLE.bit.LEDYGPIO = 1
#define LEDYON()        GpioDataRegs.GPASET.bit.LEDYGPIO =1
#define LEDYLOW()       GpioDataRegs.GPACLEAR.bit.LEDYGPIO =1


#define LEDGGPIO        GPIO24
#define LEDGMUX         GpioCtrlRegs.GPAMUX2.bit.LEDGGPIO
#define LEDGDIR         GpioCtrlRegs.GPADIR.bit.LEDGGPIO
#define LEDGTOGGLE()    GpioDataRegs.GPATOGGLE.bit.LEDGGPIO = 1
#define LEDGON()        GpioDataRegs.GPASET.bit.LEDGGPIO =1
#define LEDGLOW()       GpioDataRegs.GPACLEAR.bit.LEDGGPIO =1


extern void FunGpioInit(void);

#endif /* APP_SYS_GPIO_H_ */

/*

  • sys_timer.c
  • Created on: 2024年8月1日
  •  Author:
    

*/

#include "includes.h"


void FunTimerInit(void)
{
    EALLOW;  // This is needed to write to EALLOW protected registers
    //打开对应定时器时钟
    SysCtrlRegs.PCLKCR3.bit.CPUTIMER0ENCLK = 1;
    SysCtrlRegs.PCLKCR3.bit.CPUTIMER1ENCLK = 1;

    // CPU 定时器 0
    // 寄存器地址指针和各自计时器初始化:
    CpuTimer0.RegsAddr = &CpuTimer0Regs;
    // 定时器周期寄存器最大值初始化:
    CpuTimer0Regs.PRD.all  = 0xFFFFFFFF;
    // 预分频寄存器初始化为1 (SYSCLKOUT):
    CpuTimer0Regs.TPR.all  = 0;
    CpuTimer0Regs.TPRH.all = 0;
    // 确保定时器0停止:
    CpuTimer0Regs.TCR.bit.TSS = 1;
    // 重加载计数器周期值:
    CpuTimer0Regs.TCR.bit.TRB = 1;
    // 复位中断计时器:
    CpuTimer0.InterruptCount = 0;

    // CPU 定时器 1
    // 寄存器地址指针和各自计时器初始化:
    CpuTimer1.RegsAddr = &CpuTimer1Regs;
    // 定时器周期寄存器最大值初始化:
    CpuTimer1Regs.PRD.all  = 0xFFFFFFFF;
    // 预分频寄存器初始化为1 (SYSCLKOUT):
    CpuTimer1Regs.TPR.all  = 0;
    CpuTimer1Regs.TPRH.all = 0;
    // 确保定时器1停止:
    CpuTimer1Regs.TCR.bit.TSS = 1;
    // 重加载计数器周期值:
    CpuTimer1Regs.TCR.bit.TRB = 1;
    // 复位中断计时器:
    CpuTimer1.InterruptCount = 0;

    //定时器时长配置
    //60:代表主频60M,
    //20:代表20us,
    //1000:代表1ms
    ConfigCpuTimer(&CpuTimer0,60,20);
    ConfigCpuTimer(&CpuTimer1,60,1000);
    StartCpuTimer0();
    StartCpuTimer1();

    PieVectTable.TINT0 = &CpuTimer0Isr;//往中断矢量表中填写定时器0一个指针
    PieVectTable.TINT1 = &CpuTimer1Isr;//往中断矢量表中填写定时器1一个指针


    //打开PIE组对应中断
    PieCtrlRegs.PIEIER1.bit.INTx7 = 1; //使能第一组7通道定时器0
    IER |= M_INT1;  // Enable CPU INT
    IER |= M_INT13; //根据中断向量表使能定时器1

    EDIS;   // This is needed to disable write to EALLOW protected registers
}

//delay_ms时间函数
static unsigned char delay_flag = 0;
static unsigned int delay_cnt = 0;
void delay_ms(unsigned int timer)
{
    delay_flag = 1;
    delay_cnt = 0;
    while(delay_cnt<timer)
    {
        ;
    }
    delay_flag = 0;
    delay_cnt = 0;
}


//定时器中断0的中断服务函数==20us
static unsigned int  timercnt= 0;
interrupt void CpuTimer0Isr(void)
{
    timercnt++;
    //1S时长
    if(timercnt>50000)
    {
        timercnt = 0;
        //指示灯的引脚状态进行反转
        LEDRTOGGLE();
        LEDYTOGGLE();

    }
    //============================================================
    CpuTimer0Regs.TCR.bit.TIF  = 1; //清除外设级中断标志位
    PieCtrlRegs.PIEACK.bit.ACK1= 1; //清除PIE级中断应答
}


//定时器中断1的中断服务函数==1000us
interrupt void CpuTimer1Isr(void)
{
    //时间计数的代码程序
    if(delay_flag)
    {
        delay_cnt++;
        if(delay_cnt>65500)
        {
            delay_cnt = 65500;
        }
        else
        {
            ;
        }
    }
    else
    {
        delay_cnt = 0;
    }

    //============================================================
    CpuTimer1Regs.TCR.bit.TIF  = 1; //清除外设级中断标志位
    PieCtrlRegs.PIEACK.bit.ACK1= 1; //清除PIE级中断应答
}

/*

  • sys_timer.h
  • Created on: 2024年8月1日
  •  Author:
    

*/

#ifndef APP_SYS_TIMER_H_
#define APP_SYS_TIMER_H_

extern void FunTimerInit(void);

extern void delay_ms(unsigned int timer);

extern interrupt void CpuTimer0Isr(void);
extern interrupt void CpuTimer1Isr(void);

#endif /* APP_SYS_TIMER_H_ */

***配套代码工程***

6 定时器中断总结

TMS320F28034 提供了多种定时器模块,包括 CPU 定时器、eCAP、ePWM 和 eQEP 等。通过合理配置和使用这些定时器模块,可以实现各种定时任务,例如周期性任务、输入捕获、PWM 信号生成等。掌握这些定时器的使用方法,对于开发高性能嵌入式控制系统至关重要。

***配套代码工程***

举报

相关推荐

0 条评论