使用按钮开关移动代码
Moving through code using a Push Button switch
我正在尝试合并一个按钮开关来控制我的步进电机软件。
我为电机设置了三个功能,它会按顺序旋转三个不同的角度(从 0-180 度向前,90 度反向和 90 度反向再次回到 0),一个接一个。
我想使用一个按钮开关按顺序逐步执行这些功能。
有人对如何执行此操作有任何建议吗?我想我必须创建一个案例陈述,但一直在兜圈子,没有任何进展。
下面是我当前的代码,此时按下开关将 运行 第一个 "if" 功能将电机顺时针旋转 180 度:
#define F_CPU 1000000
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define A PINB0
#define C PINB1
#define B PINB4
#define D PINB3
int16_t i=0; // Auxiliary variable ()
void HalfStep(uint8_t step);
void Forward_180(void);
void Reverse_90(void);
void Reverse_90_2(void);
/********************************* MAIN ********************************/
int main(void)
{
DDRB |= (1<<A) | (1<<B) | (1<<C) | (1<<D); // Set output pins
DDRB &= ~(1<<PINB5); // Set input pin for switch
while(1)
{
if(bit_is_clear(PINB, 5))
{
Forward_180(); // Clockwise 180 degrees
}
if(bit_is_clear(PINB, 5)) // Anti-clockwise 90 degrees
{
Reverse_90();
}
if(bit_is_clear(PINB, 5)) // Anti-clockwise 90 degrees again
{
Reverse_90_2();
}
}
return 0;
}
/***************** HALF STEPPING & DIRECITON FUNCTIONS *****************/
void HalfStep(uint8_t step)
{
switch (step)
{
case 0: // whole number after i%8
PORTB |= (1<<A) | (1<<D);
PORTB &= ~((1<<B) | (1<<C));
break;
case 1: // 0.125
PORTB |= (1<<A);
PORTB &= ~((1<<B)|(1<<C)|(1<<D));
break;
case 2: // 0.25
PORTB |= (1<<A)|(1<<C);
PORTB &= ~((1<<B)|(1<<D));
break;
case 3: // 0.375
PORTB |= (1<<C);
PORTB &= ~((1<<A)|(1<<B)|(1<<D));
break;
case 4: // 0.5
PORTB |= (1<<B)|(1<<C);
PORTB &= ~((1<<A)|(1<<D));
break;
case 5: // 0.625
PORTB |= (1<<C);
PORTB &= ~((1<<A)|(1<<B)|(1<<D));
break;
case 6: // 0.75
PORTB |= (1<<D)|(1<<C);
PORTB &= ~((1<<A)|(1<<B));
break;
case 7: // 0.875
PORTB |= (1<<D);
PORTB &= ~((1<<A)|(1<<B)|(1<<C));
break;
}
}
void Forward_180(void)
{
while (i<=48)
{
HalfStep(i%8);
i++;
_delay_ms(5);
};
}
void Reverse_90(void)
{
while (i>=24)
{
HalfStep(i%8);
i--;
_delay_ms(10);
};
}
void Reverse_90_2(void)
{
while (i>=0)
{
HalfStep(i%8);
i--;
_delay_ms(10);
};
}
我建议使用状态机。
类似这样的事情(我假设你需要编写一些代码来做一个演示):
/* States */
typedef enum EnumStates
{
ST_IDLE,
ST_FORWARD_180,
ST_WAIT_FOR_STEP_2,
ST_REVERSE_90,
ST_WAIT_FOR_STEP_3,
ST_REVERSE_90_2,
}
EState;
/* to know if the switch was pressed */
char _keypressed = 0;
/* state variable */
EState _state = ST_IDLE;
/* very simple keyboard process */
void SwitchTask(void)
{
/* The keypressed flag will be valid for one cycle of the while loop */
_keypressed = 0;
if (bit_is_clear(PINB, 5))
{
_keypressed = 1;
/* this is a simple way to implement debouncing */
/* I assume you do not have timing requirements */
_delay_ms(100);
}
}
/* demo task */
/* This task implements a simple state machine */
void DemoTask(void)
{
switch(_state)
{
case ST_FORWARD_180:
Forward_180();
_state = ST_WAIT_FOR_STEP_2;
break;
case ST_REVERSE_90:
Reverse_90();
_state = ST_WAIT_FOR_STEP_3;
break;
case ST_REVERSE_90_2:
Reverse_90_2();
_state = ST_IDLE;
break;
case ST_IDLE:
case ST_WAIT_FOR_STEP_2:
case ST_WAIT_FOR_STEP_3:
if (_keypressed > 0)
{
_state++;
}
break;
default:
break;
}
}
int main(void)
{
/* initialization */
DDRB |= (1<<A) | (1<<B) | (1<<C) | (1<<D); // Set output pins
DDRB &= ~(1<<PINB5); // Set input pin for switch
_keypressed = 0;
while(1)
{
SwitchTask();
DemoTask();
}
return 0;
}
我正在尝试合并一个按钮开关来控制我的步进电机软件。
我为电机设置了三个功能,它会按顺序旋转三个不同的角度(从 0-180 度向前,90 度反向和 90 度反向再次回到 0),一个接一个。
我想使用一个按钮开关按顺序逐步执行这些功能。
有人对如何执行此操作有任何建议吗?我想我必须创建一个案例陈述,但一直在兜圈子,没有任何进展。
下面是我当前的代码,此时按下开关将 运行 第一个 "if" 功能将电机顺时针旋转 180 度:
#define F_CPU 1000000
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define A PINB0
#define C PINB1
#define B PINB4
#define D PINB3
int16_t i=0; // Auxiliary variable ()
void HalfStep(uint8_t step);
void Forward_180(void);
void Reverse_90(void);
void Reverse_90_2(void);
/********************************* MAIN ********************************/
int main(void)
{
DDRB |= (1<<A) | (1<<B) | (1<<C) | (1<<D); // Set output pins
DDRB &= ~(1<<PINB5); // Set input pin for switch
while(1)
{
if(bit_is_clear(PINB, 5))
{
Forward_180(); // Clockwise 180 degrees
}
if(bit_is_clear(PINB, 5)) // Anti-clockwise 90 degrees
{
Reverse_90();
}
if(bit_is_clear(PINB, 5)) // Anti-clockwise 90 degrees again
{
Reverse_90_2();
}
}
return 0;
}
/***************** HALF STEPPING & DIRECITON FUNCTIONS *****************/
void HalfStep(uint8_t step)
{
switch (step)
{
case 0: // whole number after i%8
PORTB |= (1<<A) | (1<<D);
PORTB &= ~((1<<B) | (1<<C));
break;
case 1: // 0.125
PORTB |= (1<<A);
PORTB &= ~((1<<B)|(1<<C)|(1<<D));
break;
case 2: // 0.25
PORTB |= (1<<A)|(1<<C);
PORTB &= ~((1<<B)|(1<<D));
break;
case 3: // 0.375
PORTB |= (1<<C);
PORTB &= ~((1<<A)|(1<<B)|(1<<D));
break;
case 4: // 0.5
PORTB |= (1<<B)|(1<<C);
PORTB &= ~((1<<A)|(1<<D));
break;
case 5: // 0.625
PORTB |= (1<<C);
PORTB &= ~((1<<A)|(1<<B)|(1<<D));
break;
case 6: // 0.75
PORTB |= (1<<D)|(1<<C);
PORTB &= ~((1<<A)|(1<<B));
break;
case 7: // 0.875
PORTB |= (1<<D);
PORTB &= ~((1<<A)|(1<<B)|(1<<C));
break;
}
}
void Forward_180(void)
{
while (i<=48)
{
HalfStep(i%8);
i++;
_delay_ms(5);
};
}
void Reverse_90(void)
{
while (i>=24)
{
HalfStep(i%8);
i--;
_delay_ms(10);
};
}
void Reverse_90_2(void)
{
while (i>=0)
{
HalfStep(i%8);
i--;
_delay_ms(10);
};
}
我建议使用状态机。
类似这样的事情(我假设你需要编写一些代码来做一个演示):
/* States */
typedef enum EnumStates
{
ST_IDLE,
ST_FORWARD_180,
ST_WAIT_FOR_STEP_2,
ST_REVERSE_90,
ST_WAIT_FOR_STEP_3,
ST_REVERSE_90_2,
}
EState;
/* to know if the switch was pressed */
char _keypressed = 0;
/* state variable */
EState _state = ST_IDLE;
/* very simple keyboard process */
void SwitchTask(void)
{
/* The keypressed flag will be valid for one cycle of the while loop */
_keypressed = 0;
if (bit_is_clear(PINB, 5))
{
_keypressed = 1;
/* this is a simple way to implement debouncing */
/* I assume you do not have timing requirements */
_delay_ms(100);
}
}
/* demo task */
/* This task implements a simple state machine */
void DemoTask(void)
{
switch(_state)
{
case ST_FORWARD_180:
Forward_180();
_state = ST_WAIT_FOR_STEP_2;
break;
case ST_REVERSE_90:
Reverse_90();
_state = ST_WAIT_FOR_STEP_3;
break;
case ST_REVERSE_90_2:
Reverse_90_2();
_state = ST_IDLE;
break;
case ST_IDLE:
case ST_WAIT_FOR_STEP_2:
case ST_WAIT_FOR_STEP_3:
if (_keypressed > 0)
{
_state++;
}
break;
default:
break;
}
}
int main(void)
{
/* initialization */
DDRB |= (1<<A) | (1<<B) | (1<<C) | (1<<D); // Set output pins
DDRB &= ~(1<<PINB5); // Set input pin for switch
_keypressed = 0;
while(1)
{
SwitchTask();
DemoTask();
}
return 0;
}