2016-08-30 3 views
1

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 마이크로를 사용하고 그리고 내가 아는 한, 그 스케줄러가 이런 방식으로 작동합니다 인터럽트가 발생하면

  • 프로그램이 ISR에 점프를, 그것이 내부에 무엇을 수행하고, 이전 위치로 돌아갑니다.
  • 프로그램이 다른 프로그램에있을 때 인터럽트가 발생하면 두 가지 일이 발생할 수 있습니다. 현재 인터럽트의 우선 순위가 들어오는 인터럽트보다 큰 경우 먼저 현재 인터럽트의 실행을 완료 한 다음 들어오는 인터럽트로 점프합니다. 들어오는 우선 순위가 실제 우선 순위보다 높으면 들어오는 우선 순위로 건너 뛰고 첫 번째로 돌아갑니다.

이 개념을 고려할 때, 나는 내가 원하는 것을 어떻게하는지 모른다.

전역 변수를 ISR의 플래그로 설정하고 주 프로그램에서 읽는 것이 도움이되지 않습니다. 원하는 것은 기계식 릴레이를 눌렀을 때 스테퍼 모터를 멈추고 두 가지 이전 개념에 따르면 if 플래그를 세우면, 우선 내 프로그램이 스테퍼 모터를 움직이기 위해 끝내고 멈출 것입니다.하지만 멈추게 할 것입니다.

  1. 내가 원하는 것은 모든 단일 릴레이를 자체적으로 처리하는 것이지만 단 3 개의 인터럽트 만 가지고 있으며이를 수행 할 수 있을지 확신하지 못합니다.
  2. 디코더는 다른 부품이 3 개의 핀으로 7 개의 릴레이를 처리 할 수 ​​있도록 일부 핀을 저장하는 데 사용되었습니다. 처음에 나는 그것이 효과가있을 것이라고 생각했지만, 지금은 확신이 없습니다. 나는이 시점에서 하드웨어를 바꿀 수 없다.

    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

exti1 exti2 및 exti3이 MCPU의 인터럽트 라인입니까? – Serge

+0

나는 1) 달성하고자하는 것이 무엇인지, 2) 당신이 가지고있는 어려움, 3) 3 : 8 디코더가이 질문에서 어떤 역할을 하는가? 모터를 멈추기 위해 인터럽트를 받으면 글로벌 플래그를 설정하기 만하면됩니다. 다음 번에 모터를 한 단계 앞으로 전진 시키려면 해당 플래그가 설정되어 있는지 확인하십시오. –

+0

예, 맞습니다. @serge –

답변

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; 
    } 
} 

나는 두 가지 조건이되는 경우가 있습니다. 각각 다른 하나의 릴레이에 따라 (아래 이미지 참조). ISR 안에서 나는 깃발을 세웠다.

Truth Table of encoder 8:3

는 아마도 하나 이상의 단계는 실행되지만 1.8도 늘 문제 하나 하나에.

플래그에 따라 하나의 모터 또는 다른 모터를 정지시키는 기능을 원했지만 실제로 moveMotorsDistance 기능 내에서 플래그를 관리하는 것은 실제로 스테퍼 모터의 이동을 멈추기 때문에 최상의 솔루션입니다.

관련 문제