I have developed a system which reads three lines coming from a 3:8 decoder. This decoder reduces 7 lines mechanical relays to 3 lines. So to sum up it is this way:
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
Only one relay will be activated at the same time.
I was trying to figure out a way to read the interrupts and in depending of its values do different things.
I am using a STM32F4 micro and as far as I know, its scheduler works this way:
- When an interrupt occurs, the program jumps to its ISR, it does what it is inside, and it returns to where it was before.
- If an interrupt occurs when the program is in another one, it can happens two things. If the priority of the current interrupt is greater than the incoming one, then first it will finish the execution of the current interrupt and then it will jump to the incoming one. If the priority of the incoming one is greater than the actual one, then it will jump to the incoming one and then it will return to the first one.
Taking into account this concepts, I dont know how to do what I want.
Setting global variables as flags in the ISR's and reading them in the main program would not help me, because what I want is to stop a stepper motor when the mechanical relay is pressed, and acording to the two previous concepts, if I set flags, first of all my program will finish to move the stepper motor and then it will stop it, but I want it to be stopped directly.
- What I want is to handle every single relay on its own, however I have only 3 interrupts and I am not sure I will be able to do it.
- The decoder was used to save some pins for other stuff to be able to handle 7 relays with just 3 pins. At the beginning I thought it would work, but now I am not very sure. I cant change the hardware at this point.
This is the function I use to move my stepper motors, if it helps:
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;
}
}
Thanks in advance.