(三)DSP28335基础教程——系统定时器CPUTimer(定时中断)

0 前言

本期的实验目的为:使用核心板上的CPU系统定时器,实现3个LED分别以0.1s,0.5s和1s的间隔闪烁。


1 DSP代码

注意:查看代码时双击点进去看,否则会内容不全)。

main.c

/**
 *  ********************************************************************************************
 *  @file                 main.c
 *  @file                 SK Electronics
 *  @version           V1.0
 *  @date               2020-xx-xx
 *  @brief               系统定时器
 *  *******************************************************************************************
 *  @attention
 *  实验平台:SK-F28335Mini   核心板
 *  CSDN博客:https://blog.csdn.net/weixin_46556696
 *  淘宝:https://shop409670932.taobao.com
 */

#include "DSP28x_Project.h"
#include "bsp_led.h"
#include "bsp_cpu.h"
#define FLASH_RUN 1
#define SRAM_RUN 2
#define RUN_TYPE FLASH_RUN
#if RUN_TYPE==FLASH_RUN
extern Uint16 RamfuncsLoadStart;
extern Uint16 RamfuncsLoadEnd;
extern Uint16 RamfuncsRunStart;
#endif
interrupt void cpu_timer0_isr(void);//定时器0中断服务子程序
interrupt void cpu_timer1_isr(void);//定时器1中断服务子程序
interrupt void cpu_timer2_isr(void);//定时器2中断服务子程序
void delay_1ms(Uint16 t);
/**
 *  @brief                           主函数
 *  @parameter                  无
 *  @return_value               无
 */
void main(void)
{
/*第一步:初始化系统控制:*/
    InitSysCtrl();

/*第二步:初始化GPIO口*/
    InitGpio();

/* 第三步:清除所有中断 和初始化 PIE 向量表:*/
    DINT;// 禁用CPU中断
    InitPieCtrl();// 初始化 PIE 控制寄存器到默认状态,默认状态是全部 PIE 中断被禁用和标志位被清除
    IER = 0x0000;// 禁用 CPU 中断和清除所有 CPU 中断标志位:
    IFR = 0x0000;
    InitPieVectTable();// 初始化 PIE 中断向量表
    // 中断重映射,注册中断程序入口(用户按需求添加)
    EALLOW;
    PieVectTable.TINT0=&cpu_timer0_isr;//将定时器中断服务子程序的地址存放到相应的向量地址中
    PieVectTable.XINT13=&cpu_timer1_isr;
    PieVectTable.TINT2=&cpu_timer2_isr;
    EDIS;
    //

/*程序烧录入28335(可选的)*/
#if RUN_TYPE==FLASH_RUN
    MemCopy(&RamfuncsLoadStart,&RamfuncsLoadEnd,&RamfuncsRunStart);
    InitFlash();
#endif

/* 第四步: 初始化所有外设*/
    // InitPeripherals();  //初始化所有外设(本例程不需要)
    CPU_Timer_Config();//初始化和配置CPU


/* 第五步:添加用户具体代码*/
    LED_GPIO_Config();//LED端口初始化

    EINT;//使能全局中断
    ERTM;//使能全局实时中断
/*第六步:进入主循环*/
    for(;;)
    {

    }
}

/**
 *  @brief                           1ms延迟函数
 *  @parameter                  t
 *  @return_value               无
 */
void delay_1ms(Uint16 t)
{
    while(t--)
    {
        DELAY_US(1000);
    }
}

/***************中断服务子函数**********************************/
interrupt void cpu_timer0_isr(void)
{
    LED0_TOGGLE;//1s反转一次LED0
    CpuTimer0.InterruptCount++;
    PieCtrlRegs.PIEACK.all=PIEACK_GROUP1;//中断已应答,可以从组1接收更多中断
}

interrupt void cpu_timer1_isr(void)
{
    LED1_TOGGLE;//0.5s反转一次LED1
    CpuTimer1.InterruptCount++;
    EDIS;//直接确认,无需PIE
}

interrupt void cpu_timer2_isr(void)
{
    LED2_TOGGLE;//0.1s反转一次LED2
    CpuTimer2.InterruptCount++;
    EDIS;//直接确认,无需PIE
}

bsp_cpu.h

/**
 *  ********************************************************************************************
 *  @file                 bsp_cpu.h
 *  @file                 SK Electronics
 *  @version           V1.0
 *  @date               2020-xx-xx
 *  @brief               系统时钟应用函数接口头文件
 *  *******************************************************************************************
 *  @attention
 *  实验平台:SK-F28335Mini   核心板
 *  CSDN博客:https://blog.csdn.net/weixin_46556696
 *  淘宝:https://shop409670932.taobao.com
 */

#ifndef _BSP_CPU_H_
#define _BSP_CPU_H_
#include "DSP28x_Project.h"

void CPU_Timer_Config(void);
#endif /*_BSP_CPU_H_ */

bsp_cpu.c

/**
 *  ********************************************************************************************
 *  @file                 bsp.cpu.c
 *  @file                 SK Electronics
 *  @version           V1.0
 *  @date               2020-xx-xx
 *  @brief               系统时钟应用函数接口
 *  *******************************************************************************************
 *  @attention
 *  实验平台:SK-F28335Mini   核心板
 *  CSDN博客:https://blog.csdn.net/weixin_46556696
 *  淘宝:https://shop409670932.taobao.com
 */
#include "bsp_cpu.h"
void CPU_Timer_Config(void)
{
    InitCpuTimers();//CPU初始化

    /*配置CPU参数*/
    #if(CPU_FRQ_150MHZ)
    ConfigCpuTimer(&CpuTimer0,150,1000000);//<定时器x,系统时钟频率MHZ,时间us>,1s中断一次
    ConfigCpuTimer(&CpuTimer1,150,500000);//<定时器x,系统时钟频率MHZ,时间us>,0.5s中断一次
    ConfigCpuTimer(&CpuTimer2,150,100000);//<定时器x,系统时钟频率MHZ,时间us>,0.1s中断一次
    #endif

    #if(CPU_FRQ_100MHZ)
    ConfigCpuTimer(&CpuTimer0,100,1000000);//<定时器x,系统时钟频率MHZ,时间us>,1s中断一次
    ConfigCpuTimer(&CpuTimer1,100,500000);//<定时器x,系统时钟频率MHZ,时间us>,0.5s中断一次
    ConfigCpuTimer(&CpuTimer2,100,100000);//<定时器x,系统时钟频率MHZ,时间us>,0.1s中断一次
    #endif

    /*系统定时器开始运行*/
    CpuTimer0Regs.TCR.all=0x4001;
    CpuTimer1Regs.TCR.all=0x4001;
    CpuTimer2Regs.TCR.all=0x4001;

    /*使能CPU级中断*/
    IER|=M_INT1;//使能CPU的INT1中断
    IER|=M_INT13;//使能CPU的INT13中断
    IER|=M_INT14;//使能CPU的INT14中断

    /*使能PIE级中断,只需Timer0的,其他不需要*/
    PieCtrlRegs.PIEIER1.bit.INTx7=1;
}

bsp_led.h

/**
 *  ********************************************************************************************
 *  @file                 bsp_led.h
 *  @file                 SK Electronics
 *  @version           V1.0
 *  @date               2020-xx-xx
 *  @brief               LED应用函数接口头文件
 *  *******************************************************************************************
 *  @attention
 *  实验平台:SK-F28335Mini   核心板
 *  CSDN博客:https://blog.csdn.net/weixin_46556696
 *  淘宝:https://shop409670932.taobao.com
 */

#ifndef _BSP_LED_H_
#define _BSP_LED_H_
#include "DSP28x_Project.h"

/* 宏带参,可以像内联函数一样使用,低电平亮灯*/
#define LED0(a) if (a)  \
                    GpioDataRegs. GPACLEAR.bit.GPIO0=1;\
                    else        \
                    GpioDataRegs. GPASET.bit.GPIO0=1

#define LED1(a) if (a)  \
                    GpioDataRegs. GPACLEAR.bit.GPIO1=1;\
                    else        \
                    GpioDataRegs. GPASET.bit.GPIO1=1

#define LED2(a) if (a)  \
                    GpioDataRegs. GPACLEAR.bit.GPIO2=1;\
                    else        \
                    GpioDataRegs. GPASET.bit.GPIO2=1

#define LED3(a) if (a)  \
                    GpioDataRegs. GPACLEAR.bit.GPIO3=1;\
                    else        \
                    GpioDataRegs. GPASET.bit.GPIO3=1

#define LED4(a) if (a)  \
                    GpioDataRegs. GPACLEAR.bit.GPIO4=1;\
                    else        \
                    GpioDataRegs. GPASET.bit.GPIO4=1

/*定义IO口的宏*/
#define LED0_TOGGLE     GpioDataRegs. GPATOGGLE.bit.GPIO0=1
#define LED0_OFF        GpioDataRegs. GPASET.bit.GPIO0=1
#define LED0_ON         GpioDataRegs. GPACLEAR.bit.GPIO0=1

#define LED1_TOGGLE     GpioDataRegs. GPATOGGLE.bit.GPIO1=1
#define LED1_OFF        GpioDataRegs. GPASET.bit.GPIO1=1
#define LED1_ON         GpioDataRegs. GPACLEAR.bit.GPIO1=1

#define LED2_TOGGLE     GpioDataRegs. GPATOGGLE.bit.GPIO2=1
#define LED2_OFF        GpioDataRegs. GPASET.bit.GPIO2=1
#define LED2_ON         GpioDataRegs. GPACLEAR.bit.GPIO2=1

#define LED3_TOGGLE     GpioDataRegs. GPATOGGLE.bit.GPIO3=1
#define LED3_OFF        GpioDataRegs. GPASET.bit.GPIO3=1
#define LED3_ON         GpioDataRegs. GPACLEAR.bit.GPIO3=1

#define LED4_TOGGLE     GpioDataRegs. GPATOGGLE.bit.GPIO4=1
#define LED4_OFF        GpioDataRegs. GPASET.bit.GPIO4=1
#define LED4_ON         GpioDataRegs. GPACLEAR.bit.GPIO4=1

void LED_GPIO_Config(void);
#endif /*_BSP_LED_H_ */

bsp_led.c

/**
 *  ********************************************************************************************
 *  @file                 bsp.led.c
 *  @file                 SK Electronics
 *  @version           V1.0
 *  @date               2020-xx-xx
 *  @brief               LED应用函数接口
 *  *******************************************************************************************
 *  @attention
 *  实验平台:SK-F28335Mini   核心板
 *  CSDN博客:https://blog.csdn.net/weixin_46556696
 *  淘宝:https://shop409670932.taobao.com
 */
#include "bsp_led.h"
void LED_GPIO_Config(void)
{
    EALLOW;
    GpioCtrlRegs.GPAMUX1.bit.GPIO0=0;//普通IO模式
    GpioCtrlRegs.GPAPUD.bit.GPIO0=0;//使能内部上拉
    GpioCtrlRegs.GPADIR.bit.GPIO0=1;//配置成输出

    GpioCtrlRegs.GPAMUX1.bit.GPIO1=0;//普通IO模式
    GpioCtrlRegs.GPAPUD.bit.GPIO1=0;//使能内部上拉
    GpioCtrlRegs.GPADIR.bit.GPIO1=1;//配置成输出

    GpioCtrlRegs.GPAMUX1.bit.GPIO2=0;//普通IO模式
    GpioCtrlRegs.GPAPUD.bit.GPIO2=0;//使能内部上拉
    GpioCtrlRegs.GPADIR.bit.GPIO2=1;//配置成输出

    GpioCtrlRegs.GPAMUX1.bit.GPIO3=0;//普通IO模式
    GpioCtrlRegs.GPAPUD.bit.GPIO3=0;//使能内部上拉
    GpioCtrlRegs.GPADIR.bit.GPIO3=1;//配置成输出

    GpioCtrlRegs.GPAMUX1.bit.GPIO4=0;//普通IO模式
    GpioCtrlRegs.GPAPUD.bit.GPIO4=0;//使能内部上拉
    GpioCtrlRegs.GPADIR.bit.GPIO4=1;//配置成输出

    GpioDataRegs. GPASET.bit.GPIO0=1;
    GpioDataRegs. GPASET.bit.GPIO1=1;
    GpioDataRegs. GPASET.bit.GPIO2=1;
    GpioDataRegs. GPASET.bit.GPIO3=1;
    GpioDataRegs. GPASET.bit.GPIO4=1;
    EDIS;
}

2 结论

通过此例程,初始化CPUTimer0为1s中断一次,Timer1为0.5s中断一次,Timer2为0.1s中断一次,每中断一次对应的LED电平状态反转。最终核心板可以观察到LED以不同的频率闪烁,大家可以尝试看看,不清楚欢迎留言讨论。

  • 13
    点赞
  • 82
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
对SRM电机的驱动程序 #include "DSP281x_Device.h" // DSP281x Headerfile Include File #include "DSP281x_Examples.h" // DSP281x Examples Include File #include "IQmathLib.h" #include "UserVariable.h" #include "math.h" int rpmreal=0,te=0,te1=0; long key=0,key2=0,key3=0,key4=0,key11=0; int speed_flag=0,loci_flag=0,speed_flag1=0; _iq a=0;//转速标志 unsigned int Sci_VarRx[100]; unsigned int i=0,j=0; unsigned long a1=40000; int tem1=0,temp,k2,k3,start=0; void calrpm1(){ if(Rpm<300) rpmreal=0; else rpmreal=Rpm; } void main2() { // LCD_GotoXY(2, 80); // Sendchar(" "); LCD_GotoXY(4, 80); Sendchar("1."); LCD_GotoXY(4, 96); Sendchar("2."); LCD_GotoXY(4, 112); Sendchar("3."); LCD_GotoXY(10, 16); SendStr("第十二届挑战杯作品"); LCD_GotoXY(7, 48);//16为一行,0为列,112为最大行代码 SendStr("高速磁悬浮开关磁阻电机系统"); WriteReg(0xF1, 0x0F); LCD_GotoXY(6, 80);//16为一行,0为列,112为最大行代码//共八行 SendStr("作品简介"); LCD_GotoXY(6, 96);//16为一行,0为列,112为最大行代码 SendStr("运行状态显示"); LCD_GotoXY(6, 112);//16为一行,0为列,112为最大行代码 SendStr("轴心轨迹显示"); LCD_GotoXY(6, 144);//16为一行,0为列,112为最大行代码 SendStr("南京航空航天大学高速实验室"); LCD_GotoXY(13, 160);//16为一行,0为列,112为最大行代码 Sendchar("2011/10/20"); } void main1() { LCD_GotoXY(10, 16); SendStr("第十二届挑战杯作品"); LCD_GotoXY(7, 48);//16为一行,0为列,112为最大行代码 SendStr("高速磁悬浮开关磁阻电机系统"); LCD_GotoXY(1, 80);//16为一行,0为列,112为最大行代码 SendStr("电压: 伏"); LCD_GotoXY(1, 96);//16为一行,0为列,112为最大行代码//共八行 SendStr("设定的转速: 转 分"); LCD_GotoXY(1, 112);//16为一行,0为列,112为最大行代码 SendStr("实际的转速: 转 分"); LCD_GotoXY(5, 144);//16为一行,0为列,112为最大行代码 SendStr("南京航空航天大学高速电机实验室"); LCD_GotoXY(26, 96); Sendchar("/"); LCD_GotoXY(26, 112); Sendchar("/"); disint(8,80,(unsigned long)200,0); // disint(15,96,(unsigned long)52700,0);//功能转换很重要! disint(15,112,(unsigned long)Rpm11,1);//功能转换很重要! } void main3() { WriteReg(0x10,0x68); while(loci_flag==1) { key=keyscan(); if(key=='*') { LcdClear(); LCD_ON(); main2(); loci_flag=0; } else if(key==16) { GUI_Point(x_trace[k1],y_trace[k1],1); a6=0;//zhouxin loci sample flag delay_ms(100); if(k1==200) { // LcdClear(); ClearBig(0,0);//clear 32/160 delay_ms(100); k1=0; } } } } void main4() { /* if((k1<100)&&(a5==0)) { // GUI_Point(x_trace[k1],y_trace[k1],1); a6=0;//zhouxin loci sample flag } else { */ // a5=1; k3=k1-1; if(k3<0) k3=k1+49; GUI_Point(x_trace[k3],y_trace[k3],1); if(k325)||(k3==25)) { k2=k3-25; } a5=0; delayms(100); GUI_Point(x_trace[k2],y_trace[k2],0); a6=0;//zhouxin loci sample flag // k1++; // } } void main5() { // WriteReg(0x00, 0xC5); GUI_Point(x_trace[k1],y_trace[k1],1); delay_ms(100); if(k1100)||(k1==100)) { k2=k1-100; } // WriteReg(0x00, 0xC5); GUI_Point(x_trace[k2],y_trace[k2],1); a6=0;//zhouxin loci sample flag // delay_ms(100); k1++; if(k1==200) k1=0; } void menu1() { key=keyscan(); // delayms(1); // key11=keyscan(); if(key!=16) { if(key=='A') { LcdClear(); main2(); speed_flag=0; loci_flag=0; } else if(key=='D') {start=1;speed_flag=1;LCD_ON();main1();} else if(key!='B') key2=key2*10+key; else { key3=key2; key2=0; switch(key3) { case 1:LcdClear();LCD_ON();main1();speed_flag1=1;break; case 2:LcdClear();speed_flag=1;LCD_ON();main1();speed_flag1=1;break; case 3:LcdClear();loci_flag=1;main3();speed_flag1=1;break; case 4:LcdClear();speed_flag=1;LCD_ON();main1();speed_flag1=1;break; case 5:LcdClear();speed_flag=1;LCD_ON();main1();speed_flag1=1;break; case 6:LcdClear();speed_flag=1;LCD_ON();main1();speed_flag1=1;break; } //disint(9,128,key3,0);//赋值额定转速 } } } void menu2() { int i=0; while(speed_flag==1) { delayms(1000); disint(15,112,(unsigned long)Rpm11++,1); key=keyscan(); if(key!=16) { if(key=='A') { LcdClear(); main2(); speed_flag=0; } else if(key!='B') { // disint(15+(i++),96,(unsigned long)key,0); } } } } void main(void) { // voltage=270; InitSysCtrl(); // FILE: DSP281x_SysCtrl.c DINT;//屏蔽全局中断 InitPieCtrl(); // FILE: DSP281x_PieCtrl.c pie默认状态为pie所有的中断都禁止,且标志位清零 IER = 0x0000;//禁止cpu中断并清除所有的cpu中断标志位 IFR = 0x0000; InitPieVectTable(); //piecrtl.enpie已定义 EALLOW; // This is needed to write to EALLOW protected registers PieVectTable.TINT0 = &TINT0_ISR; EDIS; // Define PIE interrupt PieCtrlRegs.PIEIER1.all=0x0043; // PDPINTA(EV-A) interrupt //对应向量表中的各位,使能位p62 PieCtrlRegs.PIEIFR1.all=0x0000; //标志寄存器,中断时自动置位 PieCtrlRegs.PIEIER2.all=0x0008; // T1PINT(EV-A) interrupt PieCtrlRegs.PIEIFR2.all=0x0000; PieCtrlRegs.PIEIER3.all=0x0001; // T2PINT(EV-A) interrupt PieCtrlRegs.PIEIFR3.all=0x0000; PieCtrlRegs.PIEIER4.all=0x0008; // T3PINT(EV-B) interrupt PieCtrlRegs.PIEIFR4.all=0x0000; PieCtrlRegs.PIEIER5.all=0x0070; // CAPINT4,CAPINT5,CAPINT6 interrupt PieCtrlRegs.PIEIFR5.all=0x0000; PieCtrlRegs.PIEIER9.all=0x0003; //sci send and recieve interrupt PieCtrlRegs.PIEIFR9.all=0x0000; IER=0x011F; // level1,level2,level3,level4,level5; //int1,2,3,4,5,9 p57 InitCpuTimers(); ConfigCpuTimer(&CpuTimer0, 150, 100); StartCpuTimer0(); InitEv(); InitTimer(); InitAdc(); // InitSci(); InitGpio(); Init_LCD(); delay_ms(10000); LCD_ON(); delay_ms(100); main2(); //the reg 0x10 never set up before // LcdClear(); // WriteReg(0x00, 0xC5);//photo point!!!!!!!!! //temp = lcd_read(0x00); // ClearBig(0,0); //176,24//320240--30/240(row and line) (+64,+8)(line,row) while(1) { EINT; delayms(200); menu1(); menu2(); // delayms(100); // WriteReg(0x00, 0xC5);// // temp = lcd_read(0x00);//正式程序不能加 // tem1 = lcd_read(0xF0); /* delayms(100); main4(); */ /* if(start==1) { while(ii<200) { selfstart(); } } */ } }
DSPF28335芯片中,有个可编程定时器Timer0、Timer1和Timer2),每个定时器都可以用来产生定时中断。以下是使用Timer1产生1秒定时的步骤: 1. 配置时钟源:使用CPU时钟作为定时器时钟源。可以通过以下代码实现: ``` EALLOW; SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // 停止定时器时钟 EDIS; CpuTimer1Regs.TCR.bit.TSS = 1; // 停止定时器1 CpuTimer1Regs.TCR.bit.TRB = 1; // 复位定时器1 CpuTimer1Regs.TCR.bit.TIE = 0; // 禁用定时器1中断 CpuTimer1Regs.TCR.bit.TIF = 0; // 清除定时器中断标志位 CpuTimer1Regs.PRD.all = 150000000; // 1秒钟产生一个中断 CpuTimer1Regs.TCR.bit.TSS = 0; // 启动定时器1 EALLOW; SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // 启动定时器时钟 EDIS; ``` 2. 配置中断:将Timer1的中断向量映射到ISR函数并使能中断。可以通过以下代码实现: ``` EALLOW; PieVectTable.TIMER1_INT = &Timer1_ISR; EDIS; PieCtrlRegs.PIEIER1.bit.INTx7 = 1; // 使能Timer1中断 IER |= M_INT1; // 使能CPU中断1 ``` 3. 实现中断服务程序:编写一个名为Timer1_ISR的函数,用于在定时器中断时执行任务。例如: ``` __interrupt void Timer1_ISR(void) { // 执行任务 // ... CpuTimer1Regs.TCR.bit.TIF = 1; // 清除定时器中断标志位 PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // 确认中断已经完成 } ``` 以上步骤完成后,每当Timer1达到计数值150000000时,就会触发一个中断,执行Timer1_ISR函数中的任务。因此,Timer1被配置为每秒触发一次中断

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Sk Electronics

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

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

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

打赏作者

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

抵扣说明:

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

余额充值