DSP的GPIO控制步进电机和定时器使用,芯片是TMS320F28335

主要功能:

 利用定时器做延时效果控制步进电机。(利用定时器做延时效果以控制步进电机是一种精确且可靠的方法。这种方法的核心在于借助定时器的精确计时功能,实现对步进电机转动时间间隔和顺序的严格把控,从而达到精确控制电机动作的目的。)

报告:

一、实验目的及要求

了解 GPIO 口工作原理;

了解步进电机 28BYJ48 电机详细使用说明; 

二、实验原理与内容

1、实验原理

利用DSP的高速数据处理能力,生成和控制脉冲信号,这些脉冲信号通过驱动器驱动步进电机转动。通过调整脉冲信号的频率和数量,DSP能够实现对步进电机速度和位置的精确控制。这一实验展示了DSP在电机控制领域的强大应用潜力。

GPIO2/EPWM2A、GPIO3/EPWM2B管脚分别与U20的Pin6(IA)、Pin7(IB)连接和GPIO4/EPWM3A、GPIO5/EPWM3B管脚分别与U21的Pin6(IA)、Pin7(IB)连接。如果让步进电机正转,GPIO2~GPIO5依次输出高电平(每次仅有一个管脚输出高电平)。

图 1   步进电机驱动电路

2、实验内容(要求)

  利用定时器做延时效果控制步进电机。(利用定时器做延时效果以控制步进电机是一种精确且可靠的方法。这种方法的核心在于借助定时器的精确计时功能,实现对步进电机转动时间间隔和顺序的严格把控,从而达到精确控制电机动作的目的。)

图 2  工作流程图

三、实验软硬件环境

1、计算机(已安装CCSv6.1.3开发环境)

2、SXD28335_SYS_PRO_III 开发板

3、5V 2A(或3A)DC电源

4、仿真器(XDS100v2仿真器一套)

5、步进电机一个

四、实验过程(实验步骤、记录、数据、分析)

1. 连接实验设备;

² 连接仿真器和开发板

插入外部+5V 电源

2.打开CCSv6.1.3

图 3  CCS 工程目录

3. 点击菜单 Project->Import CCS Projects...;点击 browse;选择

D:\ti\workspace\Example_2833x_Step_Motor和Example_2833xCpuTimer,点击确定;

图 4  CCS 导入工程方法

4. 复制Example_2833xCpuTimer项目;

图 5  拷贝项目

5. 粘贴Example_2833xCpuTimer项目并把项目名称改为Example_2833xCpuTimer_Motor;

图 6  粘贴工程项目

图 7  粘贴工程项目同时修改项目名称

6. 在此基础上添加和修改文件及程序;

图 8  添加和修改文件及程序部分展示图

7. 连接仿真器与设备并上电;

8. 进行仿真器配置,由于CCS支持很多处理器和仿真器,它不知道用户目前用的是哪个仿真器和DSP,所以要通过配置文件告诉 CCS 软件。在此详细讲解下仿真器的配置步骤。这里以XDS100V2为例,其余仿真器型号配置与此类似:

(1)File->New Target Configuration File,设置 File Name:XDS100V2_F28335.ccxml

(2)Use Share Location:复选,点 Finish。

图 9  配置文件的命名

图 10  配置文件的设置

进行如上设置,点击右侧的 Save,其变为灰色后,点击高亮的 Test Connect,在弹出的 TXT

文件的最后一行为:The JTAG DR Integrity scan-test has succeeded.,则说明仿真器正

常连接目标板;

图 11  测试链接成功

6. 在 CCS6.1.3 的菜单栏 View->Target Configuration,在 Target Configuration 栏下有

User Defined,选择 XDS100V3_28335,右键点击 Set As Default,自此我们建立了一

个针对 28335 的配置,以后不需要每个工程都进行此配置;

图 12  设置为默认的配置文件

7. 在线调试工程,载入调试界面;

图 13  调试工程

五、测试/调试及实验结果分析

实验结果:

实验现象观察,电机会进行正向旋转和反向旋转

24BYJ48 步进电机简介:

步进电机是将电脉冲信号转变为角位移或线位移的开环控制元件。在非超载的情

况下,电机的转速、停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载

变化的影响,即给电机加一个脉冲信号,电机则转过一个步距角。这一线性关系

的存在,加上步进电机只有周期性的误差而无累积误差等特点。使得在速度、位

置等控制领域用步进电机来控制变的非常的简单。为此,三兄弟开发板套件中首

次引入了步进电机技术,采用扩展的方式,方便用户应用掌握。

虽然步进电机已被广泛地应用,但步进电机并不能象普通的直流电机,交流

电机在常规下使用。它必须由双环形脉冲信号、功率驱动电路等组成控制系统方

可使用。因此用好步进电机却非易事,它涉及到机械、电机、电子及计算机等许

多专业知识。

步进电机的主要特性:

1、步进电机必须加驱动才可以运转, 驱动信号必须为脉冲信号,没有脉冲的

时候,步进电机静止, 如果加入适当的脉冲信号, 就会以一定的角度(称为步角)转

动。转动的速度和脉冲的频率成正比。

2、我们用的是28BYJ48  5V驱动的4相5线的步进电机,而且是减速步进电机,减速比为 1:64,步进角为5.625/64度。如果需要转动1圈,那么需要360/5.625*64=4096个脉冲信号。

3、步进电机具有瞬间启动和急速停止的优越特性。

4、改变脉冲的顺序,可以方便的改变转动的方向。

程序解析:

main.c

// ###########################################################################

#include  "DSP28x_Project.h"      // 设备头文件和示例包括文件

extern void Step_dianji_test(void);

extern void step_Gpio_select();

extern void Step_dianji_test2(void);

Uint16 Timer_1ms_flag;

Uint16 Timer_10ms_flag;

Uint16 Timer_100ms_flag;

Uint16 Buzzer_flag;

Uint16 Timer_10ms_Count;

Uint16 Timer_100ms_Count;

Uint32 Timer_1000ms_Count;

Uint32 Timer_5000ms_Count;

// 为了Buzzer_On1000ms()函数的可移植性,使用了宏定义。

// 蜂鸣器的接通与断开要参考实际驱动电路硬件,本次使用蜂鸣器驱动电路是低电平接通并工作

#define  Buzzer_Pin_On    GpioDataRegs.GPBDAT.bit.GPIO53 = 0    //打开蜂鸣器

#define  Buzzer_Pin_Off   GpioDataRegs.GPBDAT.bit.GPIO53 = 1    //关闭蜂鸣器

// 蜂鸣器响一秒钟触发条件

#define  Buzzer_On1000ms_Trigger    Buzzer_flag = 1     //蜂鸣器响一秒钟触发条件

// 函数初始化

void GPIO_Init(void);

void Buzzer_On1000ms(void);

// Prototype statements for functions found within this file.

__interrupt void cpu_timer0_isr(void);

__interrupt void cpu_timer1_isr(void);

__interrupt void cpu_timer2_isr(void);

void main(void)

{

    // Step 1. 初始化系统控制:

    // PLL, WatchDog, 启用外围时钟

       InitSysCtrl();

        //变量初始化

   Timer_1ms_flag = 0;

       Timer_10ms_flag = 0;

       Timer_100ms_flag = 0;

       Timer_10ms_Count = 0;

       Timer_100ms_Count = 0;

       Timer_1000ms_Count = 0;

       Timer_5000ms_Count = 0;

       Buzzer_flag = 0;

    // Step 2. 初始化GPIO:

       GPIO_Init();

       step_Gpio_select();

    // Step 3. 清除所有中断并初始化PIE向量表:

    // 禁用CPU中断

       DINT;

    // 将PIE控制寄存器初始化为其默认状态.

    // 默认状态是禁用所有PIE中断并清除标志

       InitPieCtrl();

    // 禁用CPU中断并清除所有CPU中断标志:

       IER = 0x0000;

       IFR = 0x0000;

    // 用指向shell Interrupt的指针初始化PIE向量表

    // 服务程序(ISR).

       InitPieVectTable();

    .

   EALLOW;
       // 这是写入EALLOW保护寄存器所必需的

   PieVectTable.TINT0 = &cpu_timer0_isr;

       PieVectTable.XINT13 = &cpu_timer1_isr;

       PieVectTable.TINT2 = &cpu_timer2_isr;

       EDIS;
         // 这需要禁用对EALLOW保护寄存器的写操作

        // Step 4. 初始化设备外设.

   InitCpuTimers();
        // 对于本例,只初始化Cpu计时器

#if  (CPU_FRQ_150MHZ)

        // 配置CPU-Timer 0、1、2分别为每1ms、1s、1s中断一次:

   ConfigCpuTimer(&CpuTimer0, 150, 1000);

       ConfigCpuTimer(&CpuTimer1, 150, 1000000);

       ConfigCpuTimer(&CpuTimer2, 150, 1000000);

#endif

#if  (CPU_FRQ_100MHZ)

    // 配置CPU-Timer 0、1、2分别为每1ms、1s、1s中断一次:

       ConfigCpuTimer(&CpuTimer0, 100, 1000);

       ConfigCpuTimer(&CpuTimer1, 100, 1000000);

       ConfigCpuTimer(&CpuTimer2, 100, 1000000);

#endif

    // 为了确保精确的计时,请使用只写指令来写入整个寄存器。

       CpuTimer0Regs.TCR.all = 0x4000;
      // 使用只写指令设置TSS位 = 0

   CpuTimer1Regs.TCR.all = 0x4000;
      // 使用只写指令设置TSS位 = 0

   CpuTimer2Regs.TCR.all = 0x4000;
      // 使用只写指令设置TSS位 = 0

        // Step 5. 用户特定代码,启用中断:

        // 使能与CPU- timer 0相连的CPU int1、与CPU- timer 1相连的CPU int13和与CPU- timer 2相连的CPU int14:

   IER |= M_INT1;

       IER |= M_INT13;

       IER |= M_INT14;

    // 使能PIE: Group 1中断7中的TINT0

       PieCtrlRegs.PIEIER1.bit.INTx7 = 1;

    // 启用全局中断和更高优先级的实时调试事件:

       EINT;
        // 启用全局中断INTM

   ERTM;
        // 启用全局实时中断DBGM

        // Step 6. 空闲循环或用户代码:

   while (1)

   
    {

           if (Timer_1ms_flag)  //1ms进去执行一次

   
        {

               Timer_1ms_flag = 0;

               Step_dianji_test2();

               if (++Timer_10ms_Count >= 10)

   
            {

                   Timer_10ms_Count = 0;

                   Timer_10ms_flag = 1;

                   
            }

               
        }

           if (Timer_10ms_flag)  //10ms进去执行一次

   
        {

               Timer_10ms_flag = 0;

               if (++Timer_100ms_Count >= 10)

   
            {

                   Timer_100ms_Count = 0;

                   Timer_100ms_flag = 1;

                   
            }

               
        }

           if (Timer_100ms_flag)  //100ms进去执行一次

   
        {

               Timer_100ms_flag = 0;

                //Buzzer_On1000ms();



   
        }

           if (Timer_1000ms_Count >= 50)  //500ms进去执行一次

   
        {

               Timer_1000ms_Count = 0;

                //GpioDataRegs.GPATOGGLE.bit.GPIO0 = 1;  //LED



   
        }

           if (Timer_5000ms_Count >= 5)  //5000ms进去执行一次

   
        {

               Timer_5000ms_Count = 0;

                //Buzzer_flag=1;

   Buzzer_On1000ms_Trigger;

               
        }

           
    }
}

__interrupt void cpu_timer0_isr(void)

{

       CpuTimer0.InterruptCount++;

       Timer_1ms_flag = 1;

       Timer_1000ms_Count++;

        // 确认此中断以接收来自组1的更多中断

   PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}

__interrupt void cpu_timer1_isr(void)

{

       CpuTimer1.InterruptCount++;

       Timer_5000ms_Count++;

        // CPU确认中断.

   EDIS;
}

__interrupt void cpu_timer2_isr(void)

{
      EALLOW;

       CpuTimer2.InterruptCount++;

        // CPU确认中断

   EDIS;
}

Step_Motor.c


/*

 * Step_Motor.c

 *

 *  Created on: 2024年3月19日

 *      Author: yhr

 */

#include  "DSP2833x_Device.h"      // DSP2833x头文件

#include  "DSP2833x_Examples.h"    // DSP2833x示例包括文件

void step_Gpio_select(void);

unsigned char Step_table[] = {0x0004, 0x0008, 0x0010, 0x0020};

unsigned char Step_table1[] = {0x0020, 0x0010, 0x0008, 0x0004};

void Step_dianji_test(void);

void Step_dianji_test2(void);

// 初始化GPIO

void step_Gpio_select(void)

{

        EALLOW;

    GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 0;
       // All GPIO

        GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 0;
       // All GPIO

        GpioCtrlRegs.GPAMUX1.bit.GPIO4 = 0;
       // All GPIO

        GpioCtrlRegs.GPAMUX1.bit.GPIO5 = 0;
       // All GPIO



    GpioCtrlRegs.GPADIR.bit.GPIO2 = 1;
        // All outputs

    GpioCtrlRegs.GPADIR.bit.GPIO3 = 1;
        // All outputs

    GpioCtrlRegs.GPADIR.bit.GPIO4 = 1;
        // All outputs

    GpioCtrlRegs.GPADIR.bit.GPIO5 = 1;
        // All outputs





  //GPIO0-GPIO31输出低电平

   GpioDataRegs.GPADAT.bit.GPIO2 = 0;

       GpioDataRegs.GPADAT.bit.GPIO3 = 0;

       GpioDataRegs.GPADAT.bit.GPIO4 = 0;

       GpioDataRegs.GPADAT.bit.GPIO5 = 0;

        EDIS;
}

void Step_dianji_test2(void)

{

    static Uint16 j;

    static Uint16 flag;

    static Uint16 timer_Count;

    if (++timer_Count >= 5)

    {

        timer_Count = 0;

        if (j < 2048)

        {

            if (flag == 1)
                  //正转

                {

                    // 以下两步操作为了除GPIO2-GPIO5之外的同组IO口操作不受影响

                    GpioDataRegs.GPADAT.all = GpioDataRegs.GPADAT.all & 0xffc3;
                      GPIO2-GPIO5全设置为零,清零操作

                        GpioDataRegs.GPADAT.all = GpioDataRegs.GPADAT.all | Step_table[j % 4];
                      //GPIO2-GPIO5依次输出高电平
                }

            else
                   //反转

                {

                    // 以下两步操作为了除GPIO2-GPIO5之外的同组IO口操作不受影响

                    GpioDataRegs.GPADAT.all = GpioDataRegs.GPADAT.all & 0xffc3;
                      GPIO2-GPIO5全设置为零,清零操作

                        GpioDataRegs.GPADAT.all = GpioDataRegs.GPADAT.all | Step_table1[j % 4];
                      //GPIO2-GPIO5依次输出高电平
                }

            j++;
        }

        else

        {

            j = 0;

            if (flag == 0)

            {

                flag = 1;
            }

            else

            {

                flag = 0;
            }
        }
    }
}

六、实验结论

步进电机能够精确地按照给定的脉冲信号进行转动,其转速和停止位置可以通过调整脉冲信号的频率和数量来控制。

DSP作为一种强大的数字信号处理器,能够产生精确的控制信号,实现对步进电机的精确控制。通过调整DSP的控制参数,可以方便地改变步进电机的运动状态。

实验中的程序流程设计合理,能够有效地实现步进电机的控制。通过优化程序设计和算法,可以进一步提高步进电机的控制精度和响应速度。

参考资料:

1、三兄弟嵌入式 ,网址:  http://sxdembed.taobao.com 

2、硬件:玻尔电子宙斯盾板之SXD28335B_QFP

注意:其它缺失文件请参考三兄弟嵌入式的玻尔电子宙斯盾板之SXD28335B_QFP软件例程,本次只是对主要功能的要求进行验证。

  • 22
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值