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

TMS320F28034 是德州仪器(TI)生产的一款高性能数字信号处理器(DSP)。它具有多种时钟源,可以灵活地配置系统时钟,以满足不同应用场景的需求。
系统时钟源
TMS320F28034 提供了多个时钟源供用户选择,包括:
TMS320F28034 芯片官方时钟库函数说明
TMS320F28034 是德州仪器(TI)生产的一款高性能数字信号处理器(DSP),用于嵌入式控制应用。TI 提供了丰富的库函数,以简化开发过程。以下是一些常用的与时钟配置相关的官方库函数说明。
库函数
InitSysCtrl(); pllMult: PLL 的倍频系数。 clkDiv: 系统时钟分频系数。 使用示例:
InitPll(10, 2); // 设置 PLL 倍频系数为 10,系统时钟分频系数为 2 div: VCLK 的分频系数。 使用示例:
SetVCLK(2); // 设置 VCLK 分频系数为 2 InitPeripheralClocks(); peripheral: 需要禁用时钟的外设。 使用示例:
DisablePeripheralClocks(SYSCTL_PERIPH_CLK_SPIA); // 禁用 SPI A 的时钟 peripheral: 需要启用时钟的外设。 使用示例:
EnablePeripheralClocks(SYSCTL_PERIPH_CLK_SPIA); // 启用 SPI A 的时钟 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 官方提供的文档和示例代码。
我们通过定时器配置,实现在主频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级中断应答 } (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 ; } delay_flag = 0; delay_cnt = 0; } 在定时器1中进行计时
//时间计数的代码程序 if(delay_flag) { delay_cnt++; if(delay_cnt>65500) { delay_cnt = 65500; } else { ; } } else { delay_cnt = 0; } 
/*
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(); } } /*
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; } /*
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_ */ /*
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 ; } 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级中断应答 } /*
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_ */ ***配套代码工程***
TMS320F28034 提供了多种定时器模块,包括 CPU 定时器、eCAP、ePWM 和 eQEP 等。通过合理配置和使用这些定时器模块,可以实现各种定时任务,例如周期性任务、输入捕获、PWM 信号生成等。掌握这些定时器的使用方法,对于开发高性能嵌入式控制系统至关重要。
***配套代码工程***