AVR stdio写的ATMEGA16控制步进电机正反转和速度,供大家免费参阅和批评
适合初学者,总共七个按键 三个按键控制三个速度正转,三个按键控制三个速度反转,一个按键控制停止。
本程序控制步进电机是和步进电机驱动器相连接的,所以脉冲只有一路,如果想直接连步进电机只需要稍加改动即可。
主程序预览:
#define F_CPU 800000UL
#include
#include
#define INT8U unsigned int
#define INT16U unsigned int
const INT8U FFW[]={0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00};//一拍p0口输出8个脉冲
//按键定义
#define K1_DOWN()((PIND &_BV(PD0)) == 0x00)//K1:正转速度1
#define K2_DOWN()((PIND &_BV(PD1)) == 0x00)//K2:正转速度2
#define K3_DOWN()((PIND &_BV(PD2)) == 0x00)//K3:正转速度3
#define K4_DOWN()((PIND &_BV(PD3)) == 0x00)//K4:停止
#define K5_DOWN()((PIND &_BV(PD4)) == 0x00)//K5:反转速度1
#define K6_DOWN()((PIND &_BV(PD5)) == 0x00)//K6:反转速度2
#define K7_DOWN()((PIND &_BV(PD6)) == 0x00)//K7:反转速度3
void STEP_MOTOR_FWRUN_1(INT8U n)
{
INT8U i,j;
for(i=0;i
{
for(j=0;j<16;j++)//循环输出16*8拍
{
//if (K1_DOWN())break;
if (K2_DOWN())break;
if (K3_DOWN())break;
if (K4_DOWN())return;//中途按下K4时电机停止转动
if (K5_DOWN())break;
if (K6_DOWN())break;
if (K7_DOWN())break;
PORTB=FFW[j];
_delay_us(50);
}
PORTB=0x01;//最后一圈之后输出0x01这一拍电机回到起点
}
}
void STEP_MOTOR_FWRUN_2(INT8U n)
{
INT8U i,j;
for(i=0;i
{
for(j=0;j<16;j++)
{
if (K1_DOWN())break;
// if (K2_DOWN())break;
if (K3_DOWN())break;
if (K4_DOWN())return;//中途按下K4时电机停止转动
if (K5_DOWN())break;
if (K6_DOWN())break;
if (K7_DOWN())break;
PORTB=FFW[j];
_delay_us(150);
}
PORTB=0x01;//最后一圈之后输出0x01这一拍电机回到起点
}
}
void STEP_MOTOR_FWRUN_3(INT8U n)
{
INT8U i,j;
for(i=0;i
{
for(j=0;j<16;j++)
{
if (K1_DOWN())break;
if (K2_DOWN())break;
// if (K3_DOWN())break;
if (K4_DOWN())return;//中途按下K4时电机停止转动
if (K5_DOWN())break;
if (K6_DOWN())break;
if (K7_DOWN())break;
PORTB=FFW[j];
_delay_us(300);
}
PORTB=0x01;//最后一圈之后输出0x01这一拍电机回到起点
}
}
void STEP_MOTOR_CWRUN_5(INT8U n)
{
INT8U i,j;
for(i=0;i
{
for(j=0;j<16;j++)
{
if (K1_DOWN())break;
if (K2_DOWN())break;
if (K3_DOWN())break;
if (K4_DOWN())return;//中途按下K4时电机停止转动
// if (K5_DOWN())break;
if (K6_DOWN())break;
if (K7_DOWN())break;
PORTB=FFW[j];
_delay_us(300);
}
PORTB=0x01;//最后一圈之后输出0x01这一拍电机回到起点
}
}
void STEP_MOTOR_CWRUN_6(INT8U n)
{
INT8U i,j;
for(i=0;i
{
for(j=0;j<16;j++)
{
if (K1_DOWN())break;
if (K2_DOWN())break;
if (K3_DOWN())break;
if (K4_DOWN())return;//中途按下K4时电机停止转动
if (K5_DOWN())break;
//if (K6_DOWN())break;
if (K7_DOWN())break;
PORTB=FFW[j];//方向为0时正转
_delay_us(150);
}
PORTB=0x01;//最后一圈之后输出0x01这一拍电机回到起点
}
}
void STEP_MOTOR_CWRUN_7(INT8U n)
{
INT8U i,j;
for(i=0;i
{
for(j=0;j<16;j++)
{ if (K1_DOWN())break;
if (K2_DOWN())break;
if (K3_DOWN())break;
if (K4_DOWN())return;//中途按下K4时电机停止转动
if (K5_DOWN())break;
if (K6_DOWN())break;
// if (K7_DOWN())break;
PORTB=FFW[j];
_delay_us(50);
}
PORTB=0x01;//最后一圈之后输出0x01这一拍电机回到起点
}
}
void beep()
{
PORTC=0x40;
_delay_ms(120);
PORTC=0X00;
}
void initonbeep()
{
PORTC=0x40;
_delay_ms(120);
PORTC=0X00;
_delay_ms(120);
PORTC=0x40;
_delay_ms(120);
PORTC=0X00;
_delay_ms(120);
PORTC=0x40;
_delay_ms(120);
PORTC=0X00;
_delay_ms(120);
PORTC=0x40;
_delay_ms(120);
PORTC=0X00;
}
int main()
{
INT8U r=65535;
DDRB=0xFF;PORTB=FFW[0]; //控 制输出
DDRD=0X00;PORTD=0xFF; //按键输入
DDRA=0X00;PORTA=0xFF; //方向信号
DDRC=0XFF;PORTC=0x00; //蜂鸣器
initonbeep ();
while(1)
{
if(K1_DOWN())
{
_delay_us(200);
if(K1_DOWN())
{
beep();
//while(K1_DOWN()); //等待 K1 释放
PORTA=0x00; //方向信号为0
STEP_MOTOR_FWRUN_1(r);//点击正转r圈
}
}
if(K2_DOWN())
{
_delay_us(200);
if(K2_DOWN())
{
beep();
//while(K1_DOWN()); //等待 K1 释放
PORTA=0x00; //方向信号为0
STEP_MOTOR_FWRUN_2(r);//点击正转r圈
}
}
if(K3_DOWN())
{
_delay_us(200);
if(K3_DOWN())
{
beep();
//while(K1_DOWN()); //等待 K1 释放
PORTA=0x00; //方向信号为0
STEP_MOTOR_FWRUN_3(r);//点击正转r圈
}
}
if(K5_DOWN())
{
_delay_us(200);
if(K5_DOWN())
{
beep();
//while(K2_DOWN()); //等待K2释放
PORTA=0x01;
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』