?? steper.c
字號:
/*----------------------------------------------------------------------------------------------------
名稱: 步進電機四相八拍驅動程序
文件名:steper.c
作者: eastboy
E-mail: eastboy_007@163.com
日期: 2008年7月16日
版本: 1.0
申明: 按鍵部分程序參考了raosibin的4×4按鍵狀態機思想程序
說明:
1.可通過按鍵選擇正轉或反轉,碰到限位開關后自動微調上一次微調值后停止;
2.可通過按鍵微調,即低速轉動,以便精確調整位置;
3.仿真時通過兩個按鈕模擬前后限位開關,以模擬實際生活當中步進電機帶軸運動時部件的前后電限位,
程序并可自動記住以前后限位開關為基點的微調步數;
4.本程序只是通過了軟件功能仿真,未做實物實驗,不保證實際使用時可用,實際使用時應做相應參數調整;
5.本程序未加入電機過流保護部分,有興趣可以自行加入。
-----------------------------------------------------------------------------------------------------*/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
#include <stdint.h>
#define ShortPush 0x40
#define LongPush 0x80
volatile uint8_t Direction=0,Limit=0; //Direction旋轉方向,0為順時針,1為逆時針;Limit限位,0為前限位,1為后限位
volatile uint8_t Pflag=0,TuneFlag=0; //Pflag限位開關標志,1為開關動作;TuneFlag微調標志,0為不微調,1為微調加,2為微調減,3為微調連加,4為微調連減
volatile SlowSpeed=0;//低速標志,1為低速,0為高速,用于微調時選低速
static uint8_t stepper[8]={0x80,0xC0,0x40,0x60,0x20,0x30,0x10,0x90}; //驅動狀態碼表
volatile uint16_t Position[2]={0x00,0x00};//限位開關動作后的微調步數記錄
volatile uint8_t keycode=0x00;
volatile uint8_t LastKey=0xFF,CurKey=0x00;
volatile uint8_t keytimes=0x00;
volatile uint8_t key_limit=0x00;
volatile uint8_t stepcnt=0;
volatile uint16_t Pcnt=0;
#define StepperStop() { TCCR1B=0x00; PORTD&=~(1<<PD3); PORTC&=~(1<<PC2|1<<PC3); }//Disable driver
#define StepperStart() { PORTD|=(1<<PD3); TCCR1B=(1<<CS02|1<<CS00); TIMSK|=1<<TOIE1;}//Enable driver
ISR(SIG_OVERFLOW1)
{
TCCR1B=0x00;//停止定時器
if(SlowSpeed==1) //60ms
{
TCNT1H=0xC5;
TCNT1L=0x69;
}
else if(SlowSpeed==0) //15ms
{
TCNT1H=0xF1;
TCNT1L=0x5B;
}
if(Direction==0)
{
PORTC&=~(1<<PC2|1<<PC3);
PORTD=((1<<PD3)|stepper[stepcnt]);
stepcnt++;
if(stepcnt>7) stepcnt=0;
PORTC|=1<<PC2;
}
else if(Direction==1)
{
PORTC&=~(1<<PC3|1<<PC2);
PORTD=((1<<PD3)|stepper[stepcnt]);
stepcnt--;
if(stepcnt==0xFF) stepcnt=7;
PORTC|=1<<PC3;
}
if(TuneFlag!=0)
{
switch(TuneFlag)
{
case 0x01:
case 0x03:
if(Limit==0x00)
if(Pcnt>0) Pcnt--;
else
Pcnt++;
break;
case 0x02:
case 0x04:
if(Limit==0x00)
Pcnt++;
else
{
if(Pcnt>0) Pcnt--;
}
break;
default:
break;
}
Position[Limit]=Pcnt;
eeprom_is_ready();
eeprom_write_word((Limit==0x00 ? 0x01 : 0x03),Position[Limit]);
if(TuneFlag==1 || TuneFlag==2)
{
StepperStop();
goto T0End;
}
else
StepperStart();
goto T0End;
}
if(Pflag==1)
{
Pcnt++;
if(Pcnt>=Position[Limit])
{
StepperStop();
goto T0End;
}
else
TCCR1B=(1<<CS11|1<<CS10);//啟動定時器
}
else
TCCR1B=(1<<CS11|1<<CS10);//啟動定時器
T0End:
;
}
ISR(SIG_INTERRUPT0)
{
cli();
StepperStop();
key_limit=(PINB & 0X30);
if(key_limit==0x20) //前限位
{
Direction=1;
Limit=0;
}
else if(key_limit==0x10) //后限位
{
Direction=0;
Limit=1;
}
Pflag=1;
Pcnt=0;
StepperStart();
sei();
}
ISR(SIG_OVERFLOW0)
{
TCNT0=0x64;
CurKey=(PINB & 0X0F);
if(CurKey==LastKey)
{
keytimes++;
if(keytimes%5==0)//短按
{
keycode=(ShortPush|CurKey);
}
else if(keytimes>100) //長按
{
keytimes=101;
keycode=(LongPush|CurKey);
}
}
else if(CurKey!=LastKey)
{
LastKey=CurKey;
keytimes=0x00;
}
else //無鍵按下或已釋放
{
keytimes=0x00;
}
}
void Timer0_init()
{
TCCR0=0x00;
TCNT0=0x64; //10mS
TCCR0=(1<<CS02|1<<CS00); //1024預分頻
TIMSK|=1<<TOIE0;
}
void Timer1_init()
{
TCCR1B=0x00;//停止定時器
TCNT1H=0xF1;
TCNT1L=0x5B;//初始值
TCCR1A=0x00;
//TCCR1B=(1<<CS11|1<<CS10);//啟動定時器
TIMSK|=1<<TOIE1;
}
void avr_init()
{
//初始化端口
DDRB=0X00; //配置為輸入,內部上拉
PORTB=0XFF;
DDRC=(1<<PC2|1<<PC3); //PC2,PC3 LED Out
PORTC=0x00;
DDRD=(1<<PD3|1<<PD4|1<<PD5|1<<PD6|1<<PD7);
PORTD=0X00;
MCUCR=(1<<ISC01);
GICR=1<<INT0;
//初始化變量
Direction=0;
eeprom_is_ready();
if(eeprom_read_byte(0x00)==0xFF)
{
eeprom_is_ready();
eeprom_write_byte(0x00,0x00);
eeprom_is_ready();
eeprom_write_word(0x01,0x0000);
eeprom_is_ready();
eeprom_write_word(0x03,0x0000);
Position[0]=0;
Position[1]=0;
}
else
{
Position[0]=eeprom_read_word(0x01);
Position[1]=eeprom_read_word(0x03);
}
Timer0_init();
Timer1_init();
}
int main()
{
cli();
avr_init();
sei();
while(1)
{
switch(keycode)
{
case 0x4E: //正轉
Direction=0; //旋轉方向,0為順時針,1為逆時針
SlowSpeed=0; //速度標志,為1時慢速
Pflag=0; //限位標志,為1時限位開關作用
TuneFlag=0; //微調標志,0為正常運轉,1為位置微調
StepperStart();
break;
case 0x4D: //反轉
Direction=1;
SlowSpeed=0;
Pflag=0;
TuneFlag=0;
StepperStart();
break;
case 0x4B: //微調+
Direction=0;
SlowSpeed=1;
TuneFlag=1;
Pflag=0;
StepperStart();
break;
case 0x47: //微調-
Direction=1;
SlowSpeed=1;
TuneFlag=2;
Pflag=0;
StepperStart();
break;
case 0x8E:
break;
case 0x8D:
break;
case 0x8B: //連續微調+
TuneFlag=3;
Pflag=0;
break;
case 0x87: //連續微調-
TuneFlag=4;
Pflag=0;
break;
default:
break;
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -