搜索
您的当前位置:首页正文

步进电机

来源:爱go旅游网
中山大学移动信息工程学院本科生实验报告

(2015学年春季学期)

课程名称:数字信号处理与控制 年级&班级 学号 一、实验题目:

步进电机控制实验:

基础:控制步进电机转动一个固定的角度,如90°,180°, 270°...(需要根据步距角进行推算)

附加:结合步进电机和蜂鸣器,使得步进电机对应蜂鸣器不同音高转动不同速度。

13级6班 13354329

任课教师:杨然 姓名 助教: 黄焕

王梅燕 专业(方向) 软件工程(移动信息工程) 二、实验内容

1. 实验原理

步进电机是将电脉冲信号转变为角位移或线位移的开环控制元步进电机件。当步进驱动器接收到一个脉冲信号,它就驱动步进电机按设定的方向转动一个固定的角度,称为“步距角”,它的旋转是以固定的角度一步一步运行的。可以通过控制脉冲个数来控制角位移量,从而达到准确定位的目的;同时可以通过控制脉冲频率来控制电机转动的速度和加速度,从而达到调速的目的。

1)相数:产生不同对极N、S磁场的激磁线圈对数。常用m表示。

2)拍数:完成一个磁场周期性变化所需脉冲数或导电状态用n表示,或指电机转过一个齿距角所需脉冲数。

3)步距角:对应一个脉冲信号,电机转子转过的角位移用θ表示。θ=360度/(转子齿数*运行拍数),以常规二、四相,转子齿为50齿电机为例。四拍运行时步距角为θ=360度/(50*4)=1.8度(俗称整步),八拍运行时步距角为θ=360度/(50*8)=0.9度(俗称半步)。

4)正确数据提示:正确的步距角是《手册》的步距角的1/(2^k),那么如何来计算这个k值呢?

5.625°*(2^k)*nCount = 步距角/(2^k)(90°,180°, 270°...)

我们先给nCount预设置一些数值,然后看电机转了多少角度,然后反推回来转90°nCount等于多少。我们知道转90°,nCount=1024,所以计算k值:90°= 5.625°*(2^k)*1024,得到k = 6.

步进电机是由寄存器 PWMR 控制。这个寄存器映射在DSP 的空CTRLR 上,当DSP向该地址写数据(8 位有效值)时,高两位为‘10’时数据的低4 位将写入PWMR 寄存器(PWM4、PWM3、PWM2、PWM1)。

顺序输入以下控制信号,电机正传,逆序电机反转。

控制的方法是:首先设置全局控制寄存器中的PWME 位为‘1’,再使DSP 以一定的频率改变PWM4-1 各位状态,输出正向或反向的PWM 波。

- 1 -

2. 实验步骤

向左转、向右转

将每一步PWM值写入CTRLR寄存器中

三、实验结果

#include \"ICETEK-C6713-A.h\" #include \"clk.h\"

int nAddStep,nStep,nCount; int timercount; main() {

int nMusicCount; int nWork;

unsigned char dbScanCode; char cKey; timercount=0;

nCount=nStep=0; nAddStep=1; init_pll();

init_emif(); // 初始化emif

- 2 -

InitCTR(); // 初始化ICETEK-CTR InitInterrupt();

// 设置DX0管脚为通用输出管脚以驱动蜂鸣器 SPCR0&=0x0fffeffff; // /XRST=0 PCR0|=0x2000; // RIOEN=1

*((unsigned short int *)0x0901f000e)= 0x0c2;

CTRGR=8; // BUZZE=1 打开蜂鸣器, 见ICETEK-CTR的全局控制寄存器描述 nMusicCount=0;

// 设置合适的音长和音高

for ( nWork=0;nWorkmusic[nWork][0]*=40; music[nWork][1]*=3; music[nWork][1]/=4; }

while ( 1 ) {

if(nCount>16){ 这是用来控制步进机转动的角度的代码 nCount=0; 90°-> nCount = 1024 // if(nCount>1023) break;//90 180°-> nCount = 2048 // if(nCount>2047) break;//180 270°-> nCount = 3072 // if(nCount>3071) break;//270 ... Delay(music[nMusicCount][1]); nMusicCount++;

nMusicCount%=nMusicNumber;

TIMER1PRD=music[nMusicCount][0]; // 切换音符 TIMER1CTL=0x3c0; dbScanCode=GetKey();

if ( dbScanCode!=0 && dbScanCode!=0x0ff ) {

if ( dbScanCode==SCANCODE_9) break; else {

cKey=ConvertScanToChar(dbScanCode); if ( cKey==SCANCODE_4 ) nAddStep=1;

else if ( cKey==SCANCODE_6 ) nAddStep=-1; } } }

}

CSR&=0xfffffffe; // 关中断 GIE=0

TIMER1CTL&=0x0ffffff3f; // GO=0 /HLD=0 =>计数器暂停 *((unsigned short int *)0x0901f000e)= 0x0c0; CloseCTR(); exit(0); }

- 3 -

void interrupt Timer() //中断响应函数 {

if(timercount>5){ CTRLR=pwm[nStep]; nStep+=nAddStep;

if ( nStep<0 ) nStep=7; else if ( nStep>7 ) nStep=0; nCount++; timercount=0; }

timercount++; PCR0^=0x20; }

void InitInterrupt(void) {

// 设置中断控制寄存器

CSR&=0xfffffffe; // 关中断 GIE=0

ISTP=0x00000c00; // 重置中断向量表到0C00h IMH=0x08000000; // 指定Timer1产生int15中断 IML=0;

ICR=0xff; // 清除等待的中断 IER=0x8003; // 使能int15中断 // 设置定时器产生中断信号的频率

TIMER1PRD=0x7A12; // 定时器1的周期 TIMER1CTL=0x3c0; // 开始计数 CSR=CSR|1; // 开中断 }

四、问题与感想

我们起先不明白究竟要通过控制哪一个变量来控制步进电机转动的角度,刚开始认为是改变PWM寄存器的拍数,让它只从pwm[1]循环到pwm[4],不做pwm[5]~pwm[7],结果电机照常转动,但是不停下来。后来想了很久,发现加入if(nCount>3000) break;指令,电机会自行停止下来。经过思考后我们才弄懂了中断处理的实验原理,原来之前做的实验还是懵懵懂懂的。当while循环进行了一个中断周期时就会触发中断,然后处理中断后回到while循环来。中断处理完成了控制电机正转和反转的工作。当我们设定if(nCount>3000) break,就是为了让nCount计数计到3001时退出整个while循环停止转动。于是,我们计算出k的值之后,得到了精准的角度对应的准确的nCount值。

- 4 -

因篇幅问题不能全部显示,请点此查看更多更全内容

Top