• 沒有找到結果。

基于 AVR 单片机的两相混合式步进电动机控制实例

3.7.1 控制系统硬件

基于 ATmega48 单片机的两相混合式步进电动机角度细分控制电路原理图如图 3­45 所示。

单片机的 T1 定时器产生一个恒频脉冲信号 CLK,作为 D 触发器 74ALS74 和 8 位串行 D/A 转

换器 Max522 的时钟; 单片机实现脉冲分配, 并由 PB3、 PB4 口输出两相绕组的导通控制信号;

同时, 单片机根据指令要求输出各相绕组的给定电流, 并由 Max522 转换为模拟信号 Ig1、 Ig2,

通过恒频斩波实现步进电动机的角度细分控制。

电流采样信号 FB1 和 FB2 首先经阻容滤波后,与由 R17 和 R18(或 R22 和 R23)分压得 到的给定电压进行比较,实现硬件电流保护;然后利用运算放大器 LM324 对每相绕组的电流 采样值进行放大,放大后的电流信号与  Max522  输出的电流给定信号  Ig1(或  Ig2)一起送入  LM339 比较器进行比较,实现斩波控制。

显示电路由 SN74HC595 和 LG2641 组成。SN74HC595 为 8 位移位寄存器,QA­QH 为并 行数据输出,SER 为串行数据输入,RCLK 为输出寄存器时钟,SRCLK 为串行数据时钟。在  SRCLK 上升沿,SER 的数据被锁存到 SN74HC595 寄存器中,随着 SRCLK 时钟的推进,8 位 数据依次被送到 SN74HC595 中,由于 SN74HC595 是带输出锁存的,只有在 RCLK 上升时,

新的 8 位数据才会更新到 QA­QH 中。

(a)单片机与 D 触发器和 D/A 转换器

图 3­45  基于 ATmega48 单片机的两相混合式步进电动机控制系统原理图

(b)显示电路

(c)A 相驱动和保护电路

图 3­45  基于 ATmega48 单片机的两相混合式步进电动机控制系统原理图(续图)

(d)B 相驱动和保护电路

图 3­45  基于 ATmega48 单片机的两相混合式步进电动机控制系统原理图(续图) 

LG3641AH 为 4 位 8 段共阳极数码管,COM1~COM4 引脚电平为高时,对应的数码管才 亮。为了简化电路,此处采用动态显示。在每一瞬间,SN74HC595  并行输出口输出相应的  8  位数码管段码,而位选则控制 I/O 口输出该显示位的选通电平,保证该位显示相应字符。

四位数码管从左到右依次显示:模式(1、2) 、正反转(0、1) 、角度细分等级(1、2、3) 、 速度等级(0~8) ,其中模式 1 为角度细分控制,模式 2 是速度控制。

按键的功能分配如下: 

S1­开始/停止;S4­正转/反转;S5­复位;S3­模式 1 选择,在模式 1 下,S2 键­角度细分加, 

S3­角度细分减;S4­模式 2 选择,在模式 2 下,S2­速度加,S3­速度减。

3.7.2 控制软件例程 

/**************************************************************/ 

/*功能:基于 ATmega48 单片机的两相混合式步进电动机角度细分控制*/ 

/*文件名:step_motor.c;开发环境:ICCAVR  */ 

/*编制:大连理工大学电气工程学院大学生创新实践小组  */ 

/*完成日期:2008 年 9 月  */ 

/**************************************************************/ 

#include <iom48v.h> 

#include <macros.h> 

#define uchar unsigned char 

#define uint unsigned int  uint t[4]={17,16,15,14};

uint Table[]= 

temp>>=1; //第 7 位控制位  temp&=0x40; 

PORTD&=0xbf; 

control=0x1a;  //送 B 寄存器(0­1)  given=temp1; 

temp1+=0xff/n; 

DAconver(control,given); 

control=0x00;  //两通道打开  given=0xff; 

DAconver(control,given); 

PORTB|=0x18;  //PB3、PB4 输入高电平,传递到 D 口中  PORTD&=0xdf; 

PORTD|=0x20;  //产生一个时钟 CLK 的上升沿  } 

} break; 

case 1: { 

temp1=0xff; 

for(i=1;i<=n;i++) {  //产生 AQ(1­0) BQ(1)  2

control=0x19;  //送 A 寄存器(1­0)  given=temp1; 

temp1­=0xff/n; 

DAconver(control,given); 

control=0x1a;  //送 B 寄存器(1)  given=0xff; 

DAconver(control,given); 

control=0x00;  //两通道打开  given=0xff; 

DAconver(control,given); 

PORTB|=0x18;  //PB3、PB4 输入高电平,传递到 D 口中  PORTD&=0xdf; 

PORTD|=0x20;  //产生一个时钟 CLK 的上升沿  } 

}break; 

case 2:{ 

temp1=0; 

for(i=1;i<=n;i++) { 

control=0x19;  //产生/AQ(0­1) BQ(1)  3  given=temp1; 

PORTB&=0xf7;  //PB3 输入低电平,传递到 A D 口中  PORTB|=0x10;  //PB4 输入高电平,传递到 B D 口中  PORTD&=0xdf; 

PORTD|=0x20;  //产生一个时钟 CLK 的上升沿  } 

}break; 

case 3: {  temp1=0xff; 

for(i=1;i<=n;i++){ 

control=0x19;  //产生  /AQ(1) BQ(1­0)  4  given=0xff; 

DAconver(control,given); 

PORTB&=0xf7;      //PB3 输入低电平,传递到 A D 口中  PORTB|=0x10;  //PB4 输入高电平,传递到 B D 口中  PORTD&=0xdf; 

PORTD|=0x20;  //产生一个时钟 CLK 的上升沿  } 

}break; 

case 4: {  temp1=0; 

for(i=1;i<=n;i++){ 

control=0x19;  //产生  /AQ(1) /BQ(0­1)    5  given=0xff; 

PORTD|=0x20;  //产生一个时钟 CLK 的上升沿  } 

}break; 

case 5: {  temp1=0xff; 

for(i=1;i<=n;i++) { 

control=0x19;//产生  /AQ(1­0) /BQ(1)  6  given=temp1; 

PORTD|=0x20;  //产生一个时钟 CLK 的上升沿  } 

}break;

case 6:{ 

temp1=0; 

for(i=1;i<=n;i++){ 

control=0x19;  //产生  AQ(0­1) /BQ(1)  7  given=temp1; 

PORTD|=0x20;  //产生一个时钟 CLK 的上升沿  } 

}break; 

case 7:{ 

temp1=0xff; 

for(i=1;i<=n;i++){ 

control=0x19;  //产生  AQ(1) /BQ(1­0)    8  given=0xff; 

PORTD|=0x20;  //产生一个时钟 CLK 的上升沿  } 

if(j==0) PORTB|=0x01;    //4 位数码管的最低位 COM1  if(j==1) PORTB|=0x02;    //4 位数码管的第二位 COM2

if(j==2) PORTC|=0x10;  //4 位数码管的第三位 COM3  if(j==3) PORTC|=0x20;  //4 位数码管的第四位 COM4  } 

/************************显示子程序****************************/ 

void Display(uint *t)  { 

uint i,j,sel; 

for(j=0;j<4;j++) { 

for(i=1;i<=8;i++){  //输入八位数据,即八位段码  sel=Table[t[j]]; 

sel>>=(i­1); 

sel&=0x01;  //保留最低位  PORTD&=0xfe;  //最低位 PD0 清零  PORTD|=sel;  //给 PD0 输入值  PORTC&=0xfe;  //使 PC0 为低电平 

PORTC|=0x01;  //使 PC0 为高电平,由此产生一个上升沿  } 

PORTC&=0xfd; 

PORTC|=0x02;  //PC1 产生一个上升沿,输出数据  ledbit(j);  //位选通 

DelayMs (3);  //延时  PORTC&=0xcf; 

PORTB&=0xfc;  //清除位选通信号  } 

TCCR1B = 0x00;  //stop T1 显示中断  TCNT1H=0xff; 

TCNT1L=0x1f; 

TCCR1B=0x03; 

TIMSK1=0x01; 

SREG=0x80; 

while(1) { 

if((PIND&0x04)==0) {t[3]=1;t[2]=0;t[1]=1;t[0]=3;break;}  //S3 键:模式 1  角度细分  if((PIND&0x08)==0)    {t[3]=2;t[2]=0;t[1]=1;t[0]=0;break;}  //S4 键:模式 2  速度控制  } 

TCCR0B = 0x00;  //stop T0 加速中断  TCNT0 = 0xff;

TCCR0B=0x06; 

TIMSK0=0x01; 

MCUCR = 0x00;  //INT0  减速中断  EICRA = 0x0A; //extended ext ints  //下降沿  EIMSK = 0x03; 

while(1) { 

subdividing(R,t[1]); 

if(t[2]==0) R++; 

else R­­; 

if(t[1]!=3)  t[1]++; 

}  else { 

if(t[0]!=8)  t[0]++; 

if(t[1]!=1)  t[1]­­; 

} else { 

if(t[0]!=0)  t[0]­­; 

}  }

#pragma interrupt_handler int1_isr:3 

相關文件