JIU JIANG UNIVERSITYDSP应用课程设计报告题目利用按键任意输入一个数值控制的转动角度院系电子工程学院专业电子信息工程姓名班级 1211 学号 35 日期 2015.5.22- I -内容提要步进电机作为一种电脉冲—角位移的转换元件,由于具有价格低廉、易于控制、无积累误差和计算机接口方便等优点,在机械、仪表、工业控制等领域中获得了广泛的应用。
通过DSP 对步进电机的控制可以实现系统实时、精确、高效、安全的设计要求,从而实现了自动化生产过程。
作为重要部件的DSP是否实现控制要求是应用系统能否可靠工作的关键。
许多研究机构和电机生产厂家对于用单片机和用功率器件来设计步进电机驱动系统作了大量的研究,如把MCS-51系列的8031单片机、美国Microchip公司的PIC系列的PIC16C5X、各类PLC和VMOS管等功率器件作为控制系统都是比较成熟的。
这些方面的资料和经验对于将更高速的DSP器件用在驱动系统上都是很有帮助的。
现在流行的方法是将一系列外围设备如数模转换器(A/D)、脉宽调制发生器(PWM)和数字信号处理器(DSP)内核集成在一起,就获得一个强大又非常经济的电机控制专用的的DSP。
许多厂家开发出了电机专用的DSP器件和支持各种通用算法的模拟软件。
不仅芯片的运算速度越来越快,且软件中集成和固化在硬件中的算法模块越来越多,使得实现各种功能和进行电机性能研究变得现实和容易,能够实现更加理想的控制要求,随着对步进电机的研究更加深入与芯片价格的降低和功能的增加以及随着半导体工艺,尤其是高密度CMOS工艺的发展和进步,芯片的价格日益下降,而性能却不断提高,软件和开发工具越来越多,越来越好,应用范围日益广泛。
DSP作为一种高速处理器件在驱动系统中的应用也会更加广泛和普及,研究DSP在控制领域中的应用也有着重大现实意义。
目录一课程设计要求 (4)二总体方案 (5)三硬件系统设计 (6)四软件系统设计 (10)五系统调试及结果分析 (34)六总结 (34)- III -一课程设计要求设计要求:一、利用开发板上的3*3的矩阵键盘的S1~S6的6个按键实现输入1~360之间任意给定的一个整数,用4位数码管依序显示输入的整数。
二、按键S7表示“退格”键。
按下此键:若数码管当前显示的数值是两位及以上的数时,删除所显示数据最后的一位;若当前显示的数是一位数时,则显示数据变成0。
三、按键S8表示“+/-”符号键。
按下此键,改变显示数据的符号:若当前显示的数值是正数时,则在显示的数前加“-”号;若当前显示的数是负数时,则去掉显示的数前的“-”号。
四、按键S9代表“确认”。
按下此键,步进电机根据数码管显示数值进行相应的动作。
规则如下:1、如果数码管显示的是正数,则步进电机顺时针旋转显示数字的角度。
如:数码管显示125,则步进电机顺时针转动至与起始位置成125度的位置停下。
步进电机转动完成后,蜂鸣器“嘀-嘀-嘀”响三声。
2、如果数码管显示的是负数,则步进电机逆时针旋转显示数字的角度。
如:数码管显示-125,则步进电机逆时针转动至与起始位置成125度的位置停下。
步进电机转动完成后,蜂鸣器“嘀-嘀-嘀”响三声。
3、步进电机的转动角度和所设定的角度的误差控制在15度以内,如果误差超过15度,可以利用按键输入一个数值让步进电机再转动一次进行角度修正。
但修正之后的误差要控制在8度以内。
4二总体方案按照设计要求可以把设计分为4个部分。
首先是对按键电路的设计、数码管电路的设计、步进电机的设计、蜂鸣器响应的设计。
下面分别介绍这4个部分的详细方案。
按键电路:采用3*3的键盘。
S1键为数码管数值+1,S2键为数码管数值+10,S3键为数码管数值+100,S4键为数码管数值-1,S5键为数码管数值-10,S6键为数码管数值-100,S7为退格键,S8为负号键,S9为确定键。
数码管显示电路:采用共阳极四位七段数码管。
由按键控制显示值,显示值为(0~正负360)。
步进电机:由按键S9控制。
数码管显示的数值即为电机需要转动的角度,按键按下S9电机转动。
按键S8控制电机正转(正数)或反转(负数)电机所转的角度计算过程:。
蜂鸣器:步进电机转完,蜂鸣器响3声。
三硬件系统设计本设计用到了DSPF28335开发板上的数码管、3*3按键、蜂鸣器还有电机。
1.数码管本开发板上的数码管采用的是共阳极四位七段数码管。
每个数码管内部共有12个引脚,分别是内部四个数码管共用a~dp这8根数据线(也称段选线)和四个数码管的四个公共端SEG1~SEG4(也称位选线)。
7段数码管是指数码管里有7个小LED发光二极管,通过控制不同的LED的亮灭来显示出不同的字形。
除了7段式以外常用的还有8段式,8段比7段多了一个小数点,其他基本相同。
一个7段或8段数码管称为一位,多个数码管并列在一起可构成多位数码管,如本开发板是4个数码管并在一起,所以叫4位数码管。
图3 数码管控制电路3.按键61.3*3矩阵键盘的工作原理和扫描确认方式当键盘中按键数量较多时,为了减少对I/O口的占用,通常将按键排列成矩阵形式,也称为行列键盘。
矩阵式键盘接口如图4所示,它由行线和列线组成,按键位于行、列的交叉点上。
当按键按下时,其交点的行线和列线接通,相应的行线或列线的电平发生变化,DSP通过检测行或列线上的电平变化可以确定哪个按键被按下。
图4 F28335键盘接口图在矩阵键盘的软件接口程序中,经常使用的按键识别方法有行列扫描法和线反转法,本项目采用列扫描法对矩阵键盘进行判别。
图1中GPIO53、GPIO52、GPIO51为3根行线,作为键盘的输入口(工作于输入方式);GPIO50、GPIO49、GPIO48为3根列线,作为输出口(工作于输出方式),由DSP控制其输出的电平值。
按键识别的过程如下。
1)将全部列线GPIO50、GPIO49、GPIO48置低电平输出,然后读GPIO53、GPIO52、GPIO51三根输入行线中有无低电平出现。
只要有低电平出现,则说明有按键按下(实际编程时,还要考虑按键的消抖);如果读到的电平都是高电平,则表示无按键按下。
2)在确认某行有按键按下后,需要确定具体是哪一列的按键按下。
其思路是:依次将列线置为高电平,并检测行线的输入,如果行线的电平值由低电平变为高电平,则该列对应的按键处于闭合状态。
由此,DSP对矩阵键盘的按键识别是,采用扫描方式控制列线的输出信号和检测行线输入的信号相配合实现。
4.电机采用的是步进电机。
步进电机是一种将电脉冲转化为角位移的执行机构。
通俗一点讲:当步进驱动器接收到一个脉冲信号,它就驱动步进电机按设定的方向转动一个固定的角度(及步进角)。
步进电机是将电脉冲信号转变为角位移或线位移的开环控制元件。
在非超载情况下,电机的转速、停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载变化的影响。
这一线性关系的存在,加上步进电机只有周期性的误差而无累积误差等特点,使得步进电机在速度、位置等控制领域的控制操作非常简单。
对于步进电机可以通过控制脉冲个数来控制角位移量,从而达到准确定位的目的;同时可以通过控制脉冲频率来控制电机转动的速度和加速度,从而达调速的目的。
图步进电机接口85.蜂鸣器图蜂鸣器与DSP的硬件连接图开发板采用三极管来控制峰鸣器的发声,输入的控制信号是DSP的GPIO35管脚,经J23跳线选择。
四软件系统设计1.软件流程主程序流程图:10按键设置流程图:数码管显示流程图电机流程图:蜂鸣器响应流程图:中断流程图:2.完整程序清单/******************************************************************** * 文件名:数码管显示程序* 描述: 执行该程序,数码管显示数字从0000~9999递增**********************************************************************/ /******************************************************************** 程序说明:更换控制平台,仅需更改IO口初始化、宏定义以及spi初始化********************************************************************/#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File#include "DSP2833x_Examples.h" // DSP2833x Examples Include File#define SET_KY3 GpioDataRegs.GPBSET.bit.GPIO48 = 1 //Y3拉高#define RST_KY3 GpioDataRegs.GPBCLEAR.bit.GPIO48 = 1 //Y3拉低#define SET_KY2 GpioDataRegs.GPBSET.bit.GPIO49 = 1 //Y2拉高#define RST_KY2 GpioDataRegs.GPBCLEAR.bit.GPIO49 = 1 //Y2拉低#define SET_KY1 GpioDataRegs.GPBSET.bit.GPIO50 = 1 //Y1拉高#define RST_KY1 GpioDataRegs.GPBCLEAR.bit.GPIO50 = 1 //Y1拉低#define KX3_STATUS GpioDataRegs.GPBDAT.bit.GPIO51 //X3状态#define KX2_STATUS GpioDataRegs.GPBDAT.bit.GPIO52 //X2状态#define KX1_STATUS GpioDataRegs.GPBDAT.bit.GPIO53 //X1状态//数据第3位,SEG1,GPIO16#define SET_BIT4 GpioDataRegs.GPASET.bit.GPIO16 = 1//与外设板8_LEDS 端子的IO16 对应#define RST_BIT4 GpioDataRegs.GPACLEAR.bit.GPIO16 = 1//与外设板8_LEDS 端子的IO16对应//数据第2位,SEG2,GPIO17#define SET_BIT3 GpioDataRegs.GPASET.bit.GPIO17 = 1//与外设板8_LEDS 端子的IO17 对应#define RST_BIT3 GpioDataRegs.GPACLEAR.bit.GPIO17 = 1//与外设板8_LEDS 端子的IO17 对应//数据第1位,SEG3#define SET_BIT2 GpioDataRegs.GPBSET.bit.GPIO62 = 1//与外设板8_LEDS 端子的IO62 对应#define RST_BIT2 GpioDataRegs. GPBCLEAR.bit.GPIO62 = 1//与外设板8_LEDS 端子的IO62 对应//数据第0位,SEG4#define SET_BIT1 GpioDataRegs.GPBSET.bit.GPIO63 = 1//与外设板8_LEDS 端子的IO63 对应#define RST_BIT1 GpioDataRegs.GPBCLEAR.bit.GPIO63 = 1//与外设板8_LEDS 端子的IO63 对应/*****************电机宏定义*********************/#define PHA_ON GpioDataRegs.GPASET.bit.GPIO8 = 1 //A相输出高电平#define PHA_OFF GpioDataRegs.GPACLEAR.bit.GPIO8 = 1 //A相输出低电平#define PHB_ON GpioDataRegs.GPASET.bit.GPIO10 = 1 //B相输出高电平#define PHB_OFF GpioDataRegs.GPACLEAR.bit.GPIO10 = 1 //B相输出低电平#define PHC_ON GpioDataRegs.GPASET.bit.GPIO13 = 1 //C相输出高电平#define PHC_OFF GpioDataRegs.GPACLEAR.bit.GPIO13 = 1 //C相输出低电平#define PHD_ON GpioDataRegs.GPASET.bit.GPIO14 = 1 //D相输出高电平#define PHD_OFF GpioDataRegs.GPACLEAR.bit.GPIO14 = 1 //D相输出低电平#define DELAY_TIME 100 //延时时间#define STEP_TIME 15000/*******************宏定义蜂鸣器相关操作******************/#define BUZZ_CLK_GENER GpioDataRegs.GPBTOGGLE.bit.GPIO35 = 1; //蜂鸣器控制IO,IO电平翻转,产生控制脉冲#define BUZZ_OFF GpioDataRegs.GPBSET.bit.GPIO35 = 1; //关闭蜂鸣器/**********************函数申明************************/void DisData_Trans(Uint16 data);// 4位数拆分为4个数,保存到数组DisData_Trans[4],DisData_Trans[0]为个位void Sellect_Bit(Uint16 i); // 数码管位选函数,i为0~3,对应SEG1~4void Init_LEDS_Gpio(void); // 设置SEG1~4为I/O输出,并初始化为Lvoid spi_xmit(Uint16 a); // 将数据a发送到SPITXBUFvoid spi_fifo_init(void); // 使能FIFO发送功能,接收功能未开启void spi_init(void);void delay2(Uint32 t);void MotionControl1(void);/***********************************************//**********************定义相关变量******************///unsigned int Count,Flag;unsigned int k=0;interrupt void cpu_timer0_isr(void);unsigned char msg[12]={0xC0,0xf9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xbf,0xff};//共阳段码:0~9unsigned int DisData_Bit[4] = {0}; //存放拆分后的四位数字Uint16 DisData = 0; //显示的数字Uint16 Loop = 0; //循环扫描变量Uint16 Loop2 = 0;Uint16 Keys[3][3] = {1,2,3,4,5,6,7,8,9}; //数据表,与9个按键对应Uint16 Key = 0; //实时按键信息变量Uint16 KX_On = 0;Uint16 KY_On = 0;Uint16 KX_Tim[4] = {0};Uint16 KX_Status[4]={0};unsigned int Count,Flag; //时钟变量Uint16 alarm_flag=0;Uint16 Flash;Const Uint16 Step Mode1[8]= {0x0D0A,0x0D0A,0x0A0B,0x0A0B,0x0B0C,0x0B0C,0x0C0D,0x0C0D};//单四拍时序A-B-C-D-A//电机正反转标志'0'为反转,'1'为正转const Uint16 StepMode1_N[8] = {0x0C0D,0x0C0D,0x0B0C,0x0B0C,0x0A0B,0x0A0B,0x0D0A,0x0D0A}; //单四拍时序A-B-C-D-Aconst Uint16 StepMode3[8] = {0x0D0A,0x0DAB,0x0A0B,0x0ABC,0x0B0C,0x0BCD,0x0C0D,0x0CDA};//八拍时序A-AB-B-BC-C-CD-D-DA-Aconst Uint16 StepMode3_N[8] = {0x0CDA,0x0C0D,0x0BCD,0x0B0C,0x0ABC,0x0A0B,0x0DAB,0x0D0A};void Init_KeyGpio(void); //初始化按键IOvoid ResetAllKY(void); //3列全部输出低电平void KX_AllStatus(void); //读取3行IO电平状态void Read_KX(Uint16 x); //读取按键所在行void Set_KY(Uint16 x); //设置任意列输出高电平void Rst_KY(Uint16 x); //设置任意列输出低电平void Read_KY(Uint16 x); //读取按键所在列void Read_KY(Uint16 x); //读取按键所在列void GetKey(void); //读取按键值void Motor(); //电机void show(); //蜂鸣器//void stop1();void MotionControl1(void); //单四拍正转void MotionControl2(void); //单四拍反转void MotionControl3(void); //八拍拍正转void MotionControl4(void); //八拍拍反转void PhaseOff(Uint16 i);void PhaseOn(Uint16 i);void Init_LedGpio(void);void Buzz_Gpio_Init(void); //蜂鸣器响interrupt void cpu_timer0_isr(void);/*****************3列全部输出低电平****************************/ void ResetAllKY(void){RST_KY3 ;RST_KY2 ;RST_KY1 ;}/********************读取3行IO电平状态***********************/ void KX_AllStatus(void){KX_Status[1] = KX1_STATUS;KX_Status[2] = KX2_STATUS;KX_Status[3] = KX3_STATUS;}/*************************读取按键行位置****************/void Read_KX(Uint16 x){KX_AllStatus();if(KX_Status[x] == 0){KX_Tim[x]++;if(KX_Tim[x] >= 6000){KX_On = x;KX_Tim[1]=0;KX_Tim[2]=0;KX_Tim[3]=0;}}}/*******************************指定列输出高电平*******************/ void Set_KY(Uint16 x){if(x==1){SET_KY1;}if(x==2){SET_KY2;}if(x==3){SET_KY3;}}/*******************************指定列输出低电平******************/ void Rst_KY(Uint16 x){if(x==1){RST_KY1;}if(x==2){RST_KY2;}if(x==3){RST_KY3;}}/****************************读取按键列位置***********************/ void Read_KY(Uint16 x){if(!KX_Status[KX_On] && KX_On){Set_KY(x);delay2(200);KX_AllStatus();if(KX_Status[KX_On]){KY_On = x;Key = Keys[KX_On-1][KY_On-1];KY_On = 0;KX_On = 0;}Rst_KY(x);}}void GetKey(void){Read_KX(1);Read_KX(2);Read_KX(3);Read_KY(1);Read_KY(2);Read_KY(3);}/*****************按键IO初始化************************************/void Init_KeyGpio(void){EALLOW;//////////////////////////////以下3个IO口设置为输出,作为列扫描//////////////////////////////KY3: 对应PCB端子KEY_MATRIX:IO24GpioCtrlRegs.GPBPUD.bit.GPIO48 = 0; // Enable pullup on GPIO11GpioDataRegs.GPBSET.bit.GPIO48 = 1; // Load output latchGpioCtrlRegs.GPBMUX2.bit.GPIO48 = 0; // GPIO11 = GPIOGpioCtrlRegs.GPBDIR.bit.GPIO48 = 1; // GPIO11 = output//KY2: 对应PCB端子KEY_MATRIX:IO25GpioCtrlRegs.GPBPUD.bit.GPIO49 = 0; // Enable pullup on GPIO11GpioDataRegs.GPBSET.bit.GPIO49 = 1; // Load output latchGpioCtrlRegs.GPBMUX2.bit.GPIO49 = 0; // GPIO11 = GPIOGpioCtrlRegs.GPBDIR.bit.GPIO49 = 1; // GPIO11 = output//KY1: 对应PCB端子KEY_MATRIX:IO26GpioCtrlRegs.GPBPUD.bit.GPIO50 = 0; // Enable pullup on GPIO11GpioDataRegs.GPBSET.bit.GPIO50 = 1; // Load output latchGpioCtrlRegs.GPBMUX2.bit.GPIO50 = 0; // GPIO11 = GPIOGpioCtrlRegs.GPBDIR.bit.GPIO50 = 1; // GPIO11 = output//////////////////////////////以下3个IO口设置为输入,作为行扫描//////////////////////////////KX3: 对应PCB端子KEY_MATRIX:IO28GpioCtrlRegs.GPBPUD.bit.GPIO51 = 0; // Enable pullup on GPIO11 GpioCtrlRegs.GPBMUX2.bit.GPIO51 = 0; // 设置为一般IO口GpioCtrlRegs.GPBDIR.bit.GPIO51 = 0; // IO口方向为输入//KX2: 对应PCB端子KEY_MATRIX:IO29GpioCtrlRegs.GPBPUD.bit.GPIO52 = 0; // Enable pullup on GPIO11GpioCtrlRegs.GPBMUX2.bit.GPIO52 = 0; // 设置为一般IO口GpioCtrlRegs.GPBDIR.bit.GPIO52 = 0; // IO口方向为输入//KX1: 对应PCB端子KEY_MATRIX:IO30GpioCtrlRegs.GPBPUD.bit.GPIO53 = 0; // Enable pullup on GPIO11 GpioCtrlRegs.GPBMUX2.bit.GPIO53 = 0; // 设置为一般IO口GpioCtrlRegs.GPBDIR.bit.GPIO53 = 0; // IO口方向为输入EDIS;ResetAllKY();}/******************电机控制IO初始化*****************/void Init_StepMotorGpio(void){EALLOW;//Phase AGpioCtrlRegs.GPAPUD.bit.GPIO8 = 0; // Enable pullup on GPIO11GpioDataRegs.GPASET.bit.GPIO8 = 1; // Load output latchGpioCtrlRegs.GPAMUX1.bit.GPIO8 = 0; // GPIO11 = GPIOGpioCtrlRegs.GPADIR.bit.GPIO8 = 1; // GPIO11 = output//Phase BGpioCtrlRegs.GPAPUD.bit.GPIO13 = 0; // Enable pullup on GPIO11GpioDataRegs.GPASET.bit.GPIO13 = 1; // Load output latchGpioCtrlRegs.GPAMUX1.bit.GPIO13 = 0; // GPIO11 = GPIOGpioCtrlRegs.GPADIR.bit.GPIO13 = 1; // GPIO11 = output//Phase CGpioCtrlRegs.GPAPUD.bit.GPIO10 = 0; // Enable pullup on GPIO11GpioDataRegs.GPASET.bit.GPIO10 = 1; // Load output latchGpioCtrlRegs.GPAMUX1.bit.GPIO10 = 0; // GPIO11 = GPIOGpioCtrlRegs.GPADIR.bit.GPIO10 = 1; // GPIO11 = output//Phase DGpioCtrlRegs.GPAPUD.bit.GPIO14 = 0; // Enable pullup on GPIO11 GpioDataRegs.GPASET.bit.GPIO14 = 1; // Load output latchGpioCtrlRegs.GPAMUX1.bit.GPIO14 = 0; // GPIO11 = GPIOGpioCtrlRegs.GPADIR.bit.GPIO14 = 1; // GPIO11 = outputEDIS;PHA_OFF;PHB_OFF;PHC_OFF;PHD_OFF;}/***************电机控制IO高电平输出***********/void PhaseOn(Uint16 i){switch(i){case 0xA:PHA_ON;break;case 0xB:PHB_ON;break;case 0xC:PHC_ON;break;case 0xD:PHD_ON;break;case 0x0:break;default:break;}}/*******************************电机控制IO低电平输出******/void PhaseOff(Uint16 i){switch(i){case 0xA:PHA_OFF;break;case 0xB:PHB_OFF;break;case 0xC:PHC_OFF;break;case 0xD:PHD_OFF;break;case 0x0:break;default:break;}}/************************单四拍控制时序zheng转函数**********/void MotionControl1(void){Uint16 loop = 0;for(loop = 0;loop<=7;loop++){PhaseOn (StepMode1[loop] & 0x000F); //第一位:控制信号高电平判断PhaseOn ((StepMode1[loop] & 0x00F0)>>4); //第二位:控制信号高电平判断PhaseOff((StepMode1[loop] & 0x0F00)>>8); //第三位:控制信号低电平判断PhaseOff((StepMode1[loop] & 0xF000)>>12); //第四位:控制信号低电平判断delay2(STEP_TIME);}}/************************单四拍控制时序fan转函数**************/void MotionControl2(void){Uint16 loop = 0;for(loop = 0;loop<=7;loop++){PhaseOn (StepMode1_N[loop] & 0x000F); //第一位:控制信号高电平判断 PhaseOn ((StepMode1_N[loop] & 0x00F0)>>4); //第二位:控制信号高电平判断 PhaseOff((StepMode1_N[loop] & 0x0F00)>>8); //第三位:控制信号低电平判断 PhaseOff((StepMode1_N[loop] & 0xF000)>>12); //第四位:控制信号低电平判断 delay2(STEP_TIME);}}/******************************************八拍控制时序正转********/ void MotionControl3(void){Uint16 loop = 0;for(loop = 0;loop<=7;loop++){PhaseOn (StepMode3[loop] & 0x000F); //第一位:控制信号高电平判断 PhaseOn ((StepMode3[loop] & 0x00F0)>>4); //第二位:控制信号高电平判断 PhaseOff((StepMode3[loop] & 0x0F00)>>8); //第三位:控制信号低电平判断 PhaseOff((StepMode3[loop] & 0xF000)>>12); //第四位:控制信号低电平判断 delay2(STEP_TIME);}}/************************八拍控制时序反转函数********************/void MotionControl4(){Uint16 loop = 0;for(loop = 0;loop<=7;loop++){PhaseOn (StepMode3_N[loop] & 0x000F); //第一位:控制信号高电平判断 PhaseOn ((StepMode3_N[loop] & 0x00F0)>>4); //第二位:控制信号高电平判断 PhaseOff((StepMode3_N[loop] & 0x0F00)>>8); //第三位:控制信号低电平判断 PhaseOff((StepMode3_N[loop] & 0xF000)>>12); //第四位:控制信号低电平判断 delay2(STEP_TIME);}}/****************************初始化IO端口**************************/void Buzz_Gpio_Init(void){EALLOW;GpioCtrlRegs.GPBPUD.bit.GPIO35 = 0; // Enable pullup on GPIO35GpioDataRegs.GPBSET.bit.GPIO35 = 1; // Load output latchGpioCtrlRegs.GPBMUX1.bit.GPIO35 = 0; // GPIO35 = GPIOGpioCtrlRegs.GPBDIR.bit.GPIO35 = 1; // GPIO35 = outputEDIS;}/*******************数码管位选IO 接口初始化***************************/// 设置SEG1~4为I/O输出,并初始化为Lvoid Init_LEDS_Gpio(void){EALLOW;//GpioCtrlRegs.GPBPUD.bit.GPIO16= 0; // Enable pullup on GPIO16 GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 0; // GPIO16 = GPIOGpioCtrlRegs.GPADIR.bit.GPIO16 = 1; // GPIO16 = outputGpioDataRegs.GPASET.bit.GPIO16 = 1; // Load output latch//GpioCtrlRegs.GPBPUD.bit.GPIO59= 0; // Enable pullup on GPIO17 GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 0; // GPIO17 = GPIOGpioCtrlRegs.GPADIR.bit.GPIO17 = 1; // GPIO17 = outputGpioDataRegs.GPASET.bit.GPIO17 = 1; // Load output latch//GpioCtrlRegs.GPBPUD.bit.GPIO62 = 0; // Enable pullup on GPIO62 GpioCtrlRegs.GPBMUX2.bit.GPIO62 = 0; // GPIO62 = GPIOGpioCtrlRegs.GPBDIR.bit.GPIO62 = 1; // GPIO62 = outputGpioDataRegs.GPBSET.bit.GPIO62 = 1; // Load output latch//GpioCtrlRegs.GPBPUD.bit.GPIO63 = 0; // Enable pullup on GPIO63 GpioCtrlRegs.GPBMUX2.bit.GPIO63 = 0; // GPIO63 = GPIOGpioCtrlRegs.GPBDIR.bit.GPIO63 = 1; // GPIO63 = outputGpioDataRegs.GPBSET.bit.GPIO63 = 1; // Load output latchEDIS;RST_BIT1;RST_BIT2;RST_BIT3;RST_BIT4;}/*************数码管位选函数(从低位到高位扫描)*************/// 数码管位选函数void Sellect_Bit(Uint16 i){switch(i){case 0:SET_BIT1; //选通数码管第一位RST_BIT2; //关断数码管第四位RST_BIT3;RST_BIT4;break;case 1:RST_BIT1;SET_BIT2; //选通数码管第二位RST_BIT3;RST_BIT4;break;case 2:RST_BIT1;RST_BIT2; //关断数码管第二位SET_BIT3; //选通数码管第三位RST_BIT4;break;case 3:RST_BIT1;RST_BIT2;RST_BIT3; //关断数码管第三位SET_BIT4; //选通数码管第四位break;default:break;}}/****************** 拆分要显示的四位数保存到数组DisData_Trans【】**********/ // 4位数拆分为4个数,保存到数组DisData_Trans[4],DisData_Trans[0]为个位void DisData_Trans(Uint16 data){if(data>=100){DisData_Bit[2] = data % 1000 / 100 ; //百位数DisData_Bit[1] = data % 100 / 10; //十位数DisData_Bit[0] = data % 10; //个位数if(k%2!=0){DisData_Bit[3]=10;}else DisData_Bit[3]=11;}if(data<100 &&data>=10){DisData_Bit[3] = 11;//DisData_Bit[2] = 11;DisData_Bit[1] = data % 100 / 10;DisData_Bit[0] = data % 10;if(k%2!=0){DisData_Bit[2]=10;}else DisData_Bit[2]=11;}if(data<10 &&data>0){DisData_Bit[3] = 11;DisData_Bit[2] = 11;//DisData_Bit[1] = 11;DisData_Bit[0] = data % 10;if(k%2!=0){DisData_Bit[1]=10;}else DisData_Bit[1]=11;}}/*******************************延时函数*****************/void delay2(Uint32 t){Uint32 i = 0;for (i = 0; i < t; i++);}/*************************************Spi初始化**********************/ void spi_init(){SpiaRegs.SPICCR.all =0x004F; // Reset on, Falling Edge out, 16-bit char bits//0x000F对应Rising Edge,0x004F对应Falling Edge SpiaRegs.SPICTL.all =0x0006; // Enable master mode, normal phase,// enable talk, and SPI int disabled.SpiaRegs.SPIBRR =0x007F; // 波特率寄存器:波特率=LSPCLK/(SPIBRR+1),// 最大为LSPCLK/4,最小为LSPCLK/128(0x7F)SpiaRegs.SPICCR.all =0x00DF; // Relinquish SPI from Reset(环路模式)SpiaRegs.SPIPRI.bit.FREE = 1; // Set so breakpoints don't disturb xmission(自由运行)}/**********************Spi模块FIFO设置*************************/// 使能FIFO发送功能,接收功能未开启void spi_fifo_init(){// Initialize SPI FIFO registersSpiaRegs.SPIFFTX.all=0xE040;SpiaRegs.SPIFFRX.all=0x204f;SpiaRegs.SPIFFCT.all=0x0;}/********Spi发送************************************************/// 将数据a发送到SPITXBUFvoid spi_xmit(Uint16 a){SpiaRegs.SPITXBUF=a;}/********************** **********/// 在四个数码管上显示4位数DisData,DisData=0000~9999;void Disp4Nums(unsigned int DisData){unsigned int Loop=0;DisData_Trans(DisData); //拆分四位数for(Loop=0;Loop<4;Loop++) //分别显示四位{Sellect_Bit(Loop); //选择要扫描的数码管位spi_xmit(msg[DisData_Bit[Loop]]); //串行输出要显示的数字delay2(25000); //延时配合人眼反应时间}}void show() //蜂鸣器响应函数{static Uint16 step = 0,cnt=0;if(alarm_flag ==1){ alarm_flag=0;for(step=0;step<3;step++){for(cnt=0;cnt<100;cnt++){BUZZ_CLK_GENER;delay2(10000);}BUZZ_OFF;delay2(1000000);}}}void Motor1() //电机函数{static Uint16 buf;buf = (int)(DisData/2.8); //电机步数if(k%2==0) //正转{while(buf){MotionControl2();buf--;}if(buf ==0){alarm_flag =1;}}else if(k%2 !=0) //反转{while(buf){MotionControl1();buf--;}if(buf ==0){alarm_flag =1;}}}void keyscan(){while(Key != 9){GetKey();switch(Key){case0:Key=0;DisData_Bit[2]=11;DisData_Bit[1]=11;DisData_Bit[0]=DisData%10;break;case 1:Key = 0; DisData++; if(DisData_Bit[0]>9){DisData = 0;}break; //+1 case 2:Key = 0; DisData+=10; if(DisData_Bit[1]>9){DisData%=100;}break; //+10 case 3:Key = 0; DisData+=100; if(DisData_Bit[2]==3){DisData/=100;}break; //+100 case 4:Key = 0; DisData--; if(DisData_Bit[0] ==0){DisData = 9;}break; //-1case 5:Key = 0; DisData-=10; if(DisData_Bit[1] ==0){DisData+=90;}break; //-10 case 6:Key = 0; DisData-=100; if(DisData_Bit[2] ==0){DisData %=100;}break; //-100 case7:Key = 0; DisData = DisData/10; break; //退格键case 8:Key = 0; k++;break; //负号键case 9:Key = 0; Motor1();break; //确定键,电机转相应角度default:break;}if(DisData >360) DisData = 0; //数值大于360,清零}}void main(void){ InitSysCtrl();EALLOW;GpioCtrlRegs.GPBMUX2.all = 0x0; // GPIO pinGpioCtrlRegs.GPBDIR.all = 0xFF; // Output pinGpioDataRegs.GPBDAT.all =0xFF; // Close LEDsEDIS;InitSpiaGpio(); //28335 SPIa引脚Init_LEDS_Gpio(); // 初始化3个数码管的片选引脚Init_KeyGpio(); //初始化按键IOInit_StepMotorGpio(); //电机初始化DINT;InitPieCtrl();IER = 0x0000;IFR = 0x0000;InitPieVectTable();spi_fifo_init(); // Initialize the Spi FIFOspi_init(); // init SPIEALLOW; // This is needed to write to EALLOW protected registers PieVectTable.TINT0 = &cpu_timer0_isr;Count = 0; //初始化变量Flag=0;EDIS; // This is needed to disable write to EALLOW protected registers InitCpuTimers(); // For this example, only initialize the Cpu Timers#if (CPU_FRQ_150MHZ)// Configure CPU-Timer 0 to interrupt every 500 milliseconds:// 150MHz CPU Freq, 50 millisecond Period (in uSeconds)ConfigCpuTimer(&CpuTimer0, 150, 1000);#endif#if (CPU_FRQ_100MHZ)// Configure CPU-Timer 0 to interrupt every 500 milliseconds:// 100MHz CPU Freq, 50 millisecond Period (in uSeconds)ConfigCpuTimer(&CpuTimer0, 100, 500000);#endifCpuTimer0Regs.TCR.all = 0x4001;IER |= M_INT1;PieCtrlRegs.PIEIER1.bit.INTx7 = 1;EINT; // Enable Global interrupt INTMERTM; // Enable Global realtime interrupt DBGM while(1){keyscan(); //按键显示函数Motor1(); //电机转动函数}}interrupt void cpu_timer0_isr(void){ static char T0IntCnt;CpuTimer0.InterruptCount++;T0IntCnt=(T0IntCnt+1)%7;if(T0IntCnt<4){Disp4Nums(DisData);}else if(T0IntCnt==6){RST_BIT1;RST_BIT2;RST_BIT3;RST_BIT4;}show(); //蜂鸣器函数PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;}五系统调试及结果分析程序中步进电机的角度计算:电机里面有两个圈,为1:16,也就是内圈转16步,外圈转1步,外圈转一圈为八拍。