基本介紹
- 中文名:步進電機的M16驅動
- 驅動晶片:ULN2803
- 作 者:銅河
- 版 本:V1.0
此程式可驅動五引線步進電機,通過按鍵可控制步進電機的轉速、方向、三種驅動方式,三種驅動方式分別為:單四拍驅動、雙四拍驅動、單雙八拍驅動,其中以單雙八拍驅動轉速最慢。具體聯接方式在程式中有說明。
/************************************
* 步進電機的M16驅動程式 *
* 功 能:用M16驅動步進電機 *
* 實現三種驅動方式 *
* 單四拍驅動、雙四拍驅動 *
* 單雙八拍驅動 *
* 聯接方式:PC0-3分別通過2803接A-D *
* 步進電機公共端接+5V電源 *
* 建立日期:2008年04月05日 *
* 修改日期:2008年04月06日 *
* 主控晶片:M16 *
* 時鐘頻率:外部晶體 7.3728MHZ *
* 編 譯 器:ICCAVR 6.31A *
************************************/
#include
#include
#include "delay.h"
/************************************
* 步進電機的M16驅動程式 *
* 功 能:用M16驅動步進電機 *
* 實現三種驅動方式 *
* 單四拍驅動、雙四拍驅動 *
* 單雙八拍驅動 *
* 聯接方式:PC0-3分別通過2803接A-D *
* 步進電機公共端接+5V電源 *
* 建立日期:2008年04月05日 *
* 修改日期:2008年04月06日 *
* 主控晶片:M16 *
* 時鐘頻率:外部晶體 7.3728MHZ *
* 編 譯 器:ICCAVR 6.31A *
************************************/
#include
#include
#include "delay.h"
#define RD_KEY() ((~(PINC|0x0F))>>4)//四按鍵接於PC4-PC7
unsigned char i=0; //轉動計數
unsigned char m=1; //驅動方式參數
unsigned char n=0; //轉動方向參數
unsigned int zhuansu=61500; //轉速數據
unsigned char m=1; //驅動方式參數
unsigned char n=0; //轉動方向參數
unsigned int zhuansu=61500; //轉速數據
/****************************
* 連線埠配置函式 *
****************************/
void port_init(void)
{
PORTA = 0x40;
DDRA = 0x40;
PORTB = 0x00;
DDRB = 0x00;
PORTC = 0xF0;
DDRC = 0x0F;
PORTD = 0x00;
DDRD = 0x00;
}
* 連線埠配置函式 *
****************************/
void port_init(void)
{
PORTA = 0x40;
DDRA = 0x40;
PORTB = 0x00;
DDRB = 0x00;
PORTC = 0xF0;
DDRC = 0x0F;
PORTD = 0x00;
DDRD = 0x00;
}
/****************************
* 正轉操作函式 *
* 入 口:a 三種工作方式 *
****************************/
void bj_fs(unsigned char a)
{
switch(a)
{
case 1: //單四拍方式驅動
PORTC |= 1<<i; //A、B、C、D驅動
i++;
if(i>=4)i=0;
break;
case 2: //雙四拍方式驅動
if(i!=4) //AB、BC、CD、DA驅動
PORTC |= (1<<i)|(1<<(i-1));
else
PORTC |= (1<<(i-1))|1;
i++;
if(i>=5)i=1;
break;
case 3: //單雙八拍方式驅動
if(i%2) //A、AB、B、BC、C、CD、D、DA驅動
{
if(i!=7)
PORTC |= (1<<(i/2))|(1<<(i/2+1));
else
PORTC |= (1<<(i/2))|1;
}
else
{
PORTC |= 1<<(i/2);
}
i++;
if(i>=8)i=0;
break;
default:break;
}
}
* 正轉操作函式 *
* 入 口:a 三種工作方式 *
****************************/
void bj_fs(unsigned char a)
{
switch(a)
{
case 1: //單四拍方式驅動
PORTC |= 1<<i; //A、B、C、D驅動
i++;
if(i>=4)i=0;
break;
case 2: //雙四拍方式驅動
if(i!=4) //AB、BC、CD、DA驅動
PORTC |= (1<<i)|(1<<(i-1));
else
PORTC |= (1<<(i-1))|1;
i++;
if(i>=5)i=1;
break;
case 3: //單雙八拍方式驅動
if(i%2) //A、AB、B、BC、C、CD、D、DA驅動
{
if(i!=7)
PORTC |= (1<<(i/2))|(1<<(i/2+1));
else
PORTC |= (1<<(i/2))|1;
}
else
{
PORTC |= 1<<(i/2);
}
i++;
if(i>=8)i=0;
break;
default:break;
}
}
/****************************
* 反轉操作函式 *
* 入 口:a 三種工作方式 *
****************************/
void bj_fsf(unsigned char a)
{
switch(a)
{
case 1: //單四拍方式驅動
PORTC |= 1<<(3-i); //D、C、B、A驅動
i++;
if(i>=4)i=0;
break;
case 2: //雙四拍方式驅動
if(i!=4) //AD、CD、BC、AB驅動
PORTC |= (1<<(3-i))|(1<<(4-i));
else
PORTC |= (1<<(i-1))|1;
i++;
if(i>=5)i=1;
break;
case 3: //單雙八拍方式驅動
if(i%2) //DA、D、CD、C、BC、B、AB、A驅動
{
PORTC |= 1<<(3-i/2);
}
else
{
if(i)
PORTC |= (1<<(3-i/2))|(1<<(4-i/2));
else
PORTC |= (1<<(3-i/2))|1;
}
i++;
if(i>=8)i=0;
break;
case 4:
default:break;
}
}
* 反轉操作函式 *
* 入 口:a 三種工作方式 *
****************************/
void bj_fsf(unsigned char a)
{
switch(a)
{
case 1: //單四拍方式驅動
PORTC |= 1<<(3-i); //D、C、B、A驅動
i++;
if(i>=4)i=0;
break;
case 2: //雙四拍方式驅動
if(i!=4) //AD、CD、BC、AB驅動
PORTC |= (1<<(3-i))|(1<<(4-i));
else
PORTC |= (1<<(i-1))|1;
i++;
if(i>=5)i=1;
break;
case 3: //單雙八拍方式驅動
if(i%2) //DA、D、CD、C、BC、B、AB、A驅動
{
PORTC |= 1<<(3-i/2);
}
else
{
if(i)
PORTC |= (1<<(3-i/2))|(1<<(4-i/2));
else
PORTC |= (1<<(3-i/2))|1;
}
i++;
if(i>=8)i=0;
break;
case 4:
default:break;
}
}
/****************************
* 定時器1配置函式 *
* 工作模式:普通模式 *
* 工作方式:溢出中斷 *
* 預 分 頻:64 *
* 時鐘頻率:外部7.3728MHZ *
****************************/
void timer1_init(void)
{
TCCR1B = 0x00;
TCNT1H = zhuansu>>8;
TCNT1L = zhuansu&0xFF;
TCCR1A = 0x00;
TCCR1B = 0x02;
}
/****************************
* 定時器1中斷函式 *
****************************/
#pragma interrupt_handler timer1_ovf_isr:9
void timer1_ovf_isr(void)
{
TCNT1H = zhuansu>>8;
TCNT1L = zhuansu&0xFF;
PORTC &= 0xF0;
if(n)
bj_fsf(m); //反轉
else
bj_fs(m); //正轉
}
* 定時器1配置函式 *
* 工作模式:普通模式 *
* 工作方式:溢出中斷 *
* 預 分 頻:64 *
* 時鐘頻率:外部7.3728MHZ *
****************************/
void timer1_init(void)
{
TCCR1B = 0x00;
TCNT1H = zhuansu>>8;
TCNT1L = zhuansu&0xFF;
TCCR1A = 0x00;
TCCR1B = 0x02;
}
/****************************
* 定時器1中斷函式 *
****************************/
#pragma interrupt_handler timer1_ovf_isr:9
void timer1_ovf_isr(void)
{
TCNT1H = zhuansu>>8;
TCNT1L = zhuansu&0xFF;
PORTC &= 0xF0;
if(n)
bj_fsf(m); //反轉
else
bj_fs(m); //正轉
}
/****************************
* 器件初始化函式 *
****************************/
void init_devices(void)
{
CLI();
port_init();
timer1_init();
* 器件初始化函式 *
****************************/
void init_devices(void)
{
CLI();
port_init();
timer1_init();
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x04;
SEI();
}
GICR = 0x00;
TIMSK = 0x04;
SEI();
}
/****************************
* 主函式 *
****************************/
void main(void)
{
unsigned char key,key1;
init_devices();
while(1)
{
key=RD_KEY(); //按鍵掃描
if(key)
{
delay_ms(20);
key1=RD_KEY();
if(key==key1)
{
switch(key) //按鍵有效,相應處理
{
case 0x01: //S1鍵處理:轉速增加
zhuansu += 100;
if(zhuansu>62000)zhuansu=62000;
break;
case 0x02: //S2鍵處理:轉速降低
zhuansu -= 100;
if(zhuansu<5000)zhuansu=5000;
break;
case 0x04: //S3鍵處理:轉換驅動方式
m++;
if(m>=4)m=1;
break;
case 0x08: //S4鍵處理:正反轉控制
if(n)
n=0;
else
n=1;
break;
default:break;
}
}
while(key) //等待按鍵釋放
{
delay_ms(10);
key=RD_KEY();
}
}
}
}
完整的工程項目檔案如下,此工程已通過驗證。
* 主函式 *
****************************/
void main(void)
{
unsigned char key,key1;
init_devices();
while(1)
{
key=RD_KEY(); //按鍵掃描
if(key)
{
delay_ms(20);
key1=RD_KEY();
if(key==key1)
{
switch(key) //按鍵有效,相應處理
{
case 0x01: //S1鍵處理:轉速增加
zhuansu += 100;
if(zhuansu>62000)zhuansu=62000;
break;
case 0x02: //S2鍵處理:轉速降低
zhuansu -= 100;
if(zhuansu<5000)zhuansu=5000;
break;
case 0x04: //S3鍵處理:轉換驅動方式
m++;
if(m>=4)m=1;
break;
case 0x08: //S4鍵處理:正反轉控制
if(n)
n=0;
else
n=1;
break;
default:break;
}
}
while(key) //等待按鍵釋放
{
delay_ms(10);
key=RD_KEY();
}
}
}
}
完整的工程項目檔案如下,此工程已通過驗證。