我开发了一个系统,它读取来自3:8解码器的三条线。该解码器将7线机械继电器减少到3线。所以总结一下就是这样:
m2 m1 m0 (decoder output)
exti3 exti2 exti1
RL01 on 0 0 1
RL02 on 0 1 0
RL03 on 0 1 1
RL04 on 1 0 0
RL05 on 1 0 1
RL06 on 1 1 0
RL07 on 1 1 1
同时只激活一个继电器。
我试图找出一种方法来读取中断,并根据其值来做不同的事情。
我正在使用STM32F4 micro,据我所知,它的调度程序以这种方式工作:
考虑到这个概念,我不知道如何做我想做的事。
将全局变量设置为ISR中的标志并在主程序中读取它们对我没有帮助,因为我想要的是在按下机械继电器时停止步进电机,并根据前两个概念,如果我设置标志,首先我的程序将完成移动步进电机然后它将停止它,但我希望它直接停止。
这是我用来移动步进电机的功能,如果有帮助的话:
void moveMotorDegrees (uint8_t player, uint16_t degrees)
{
double steps = 0;
uint16_t cycles = 0;
uint16_t i = 0;
double oneLapSteps = 200;
double oneLapDegrees = 360;
steps = degrees * (oneLapSteps/oneLapDegrees);
cycles = round(2 * steps);
switch (player)
{
case 1:
HAL_GPIO_WritePin(RESET_M1_GPIO_Port, RESET_M1_Pin, GPIO_PIN_SET);
break;
case 2:
HAL_GPIO_WritePin(RESET_M2_GPIO_Port, RESET_M2_Pin, GPIO_PIN_SET);
break;
case 3:
HAL_GPIO_WritePin(RESET_M3_GPIO_Port, RESET_M3_Pin, GPIO_PIN_SET);
break;
case 4:
HAL_GPIO_WritePin(RESET_M4_GPIO_Port, RESET_M4_Pin, GPIO_PIN_SET);
break;
}
for (i = 0; i < cycles; i++)
{
HAL_Delay(5);
switch (player)
{
case 1:
HAL_GPIO_TogglePin(STEP_M1_GPIO_Port, STEP_M1_Pin);
break;
case 2:
HAL_GPIO_TogglePin(STEP_M2_GPIO_Port, STEP_M2_Pin);
break;
case 3:
HAL_GPIO_TogglePin(STEP_M3_GPIO_Port, STEP_M3_Pin);
break;
case 4:
HAL_GPIO_TogglePin(STEP_M4_GPIO_Port, STEP_M4_Pin);
break;
}
}
HAL_Delay(200);
switch (player)
{
case 1:
HAL_GPIO_WritePin(RESET_M1_GPIO_Port, RESET_M1_Pin, GPIO_PIN_RESET);
break;
case 2:
HAL_GPIO_WritePin(RESET_M2_GPIO_Port, RESET_M2_Pin, GPIO_PIN_RESET);
break;
case 3:
HAL_GPIO_WritePin(RESET_M3_GPIO_Port, RESET_M3_Pin, GPIO_PIN_RESET);
break;
case 4:
HAL_GPIO_WritePin(RESET_M4_GPIO_Port, RESET_M4_Pin, GPIO_PIN_RESET);
break;
}
}
提前致谢。
答案 0 :(得分:0)
根据之前与@serge和@MartinNyolt的对话,我认为这可行:
void moveMotorDegrees (uint8_t player, uint16_t degrees)
{
double steps = 0;
uint16_t cycles = 0;
uint16_t i = 0;
double oneLapSteps = 200;
double oneLapDegrees = 360;
steps = degrees * (oneLapSteps/oneLapDegrees);
cycles = round(2 * steps);
switch (player)
{
case 1:
HAL_GPIO_WritePin(RESET_M1_GPIO_Port, RESET_M1_Pin, GPIO_PIN_SET);
break;
case 2:
HAL_GPIO_WritePin(RESET_M2_GPIO_Port, RESET_M2_Pin, GPIO_PIN_SET);
break;
case 3:
HAL_GPIO_WritePin(RESET_M3_GPIO_Port, RESET_M3_Pin, GPIO_PIN_SET);
break;
case 4:
HAL_GPIO_WritePin(RESET_M4_GPIO_Port, RESET_M4_Pin, GPIO_PIN_SET);
break;
}
for (i = 0; i < cycles; i++)
{
HAL_Delay(5);
switch (player)
{
case 1:
if ((MA2_Flag != 1 && MA1_Flag != 1 && MA0_Flag != 1) || (MA2_Flag != 1 && MA1_Flag != 1 && MA0_Flag != 0))
{
HAL_GPIO_TogglePin(STEP_M1_GPIO_Port, STEP_M1_Pin);
}
break;
case 2:
if ((MA2_Flag != 1 && MA1_Flag != 0 && MA0_Flag != 0) || (MA2_Flag != 1 && MA1_Flag != 0 && MA0_Flag != 1))
{
HAL_GPIO_TogglePin(STEP_M2_GPIO_Port, STEP_M2_Pin);
}
break;
case 3:
if ((MA2_Flag != 0 && MA1_Flag != 1 && MA0_Flag != 0) || (MA2_Flag != 0 && MA1_Flag != 1 && MA0_Flag != 1))
{
HAL_GPIO_TogglePin(STEP_M3_GPIO_Port, STEP_M3_Pin);
}
break;
case 4:
if ((MA2_Flag != 0 && MA1_Flag != 0 && MA0_Flag != 1) || (MAAux_Flag != 1))
{
HAL_GPIO_TogglePin(STEP_M4_GPIO_Port, STEP_M4_Pin);
}
break;
}
}
MAAux_Flag = 0;
MA2_Flag = 0;
MA1_Flag = 0;
MA0_Flag = 0;
HAL_Delay(200);
switch (player)
{
case 1:
HAL_GPIO_WritePin(RESET_M1_GPIO_Port, RESET_M1_Pin, GPIO_PIN_RESET);
break;
case 2:
HAL_GPIO_WritePin(RESET_M2_GPIO_Port, RESET_M2_Pin, GPIO_PIN_RESET);
break;
case 3:
HAL_GPIO_WritePin(RESET_M3_GPIO_Port, RESET_M3_Pin, GPIO_PIN_RESET);
break;
case 4:
HAL_GPIO_WritePin(RESET_M4_GPIO_Port, RESET_M4_Pin, GPIO_PIN_RESET);
break;
}
}
在每个case语句中,我有两个if条件。每个人根据一个不同的继电器(见下图)。在ISR内部,我设置了标志。
可能执行了多个步骤但是每个步骤都是1.8度,这不会成为问题。
我想在主程序中执行一个函数来根据标志停止一个或另一个电机,但是直接在moveMotorsDistance函数内部管理标志它是最好的解决方案,因为实际上它会停止移动步进电机。