Как я могу изменить свои входы функции с массивом chracter

Привет всем, я пишу встроенный код C на микропроцессорах STM32Fxx с Keil MicroVision IDE. В своем проекте я использую 8 штук реле. Я объявил каждое из моих реле следующим примером кода.

 #define DO9_Pin GPIO_PIN_14
 #define DO9_GPIO_Port GPIOC
 #define DO8_Pin GPIO_PIN_15
 #define DO8_GPIO_Port GPIOC
 #define DO7_Pin GPIO_PIN_1
 #define DO7_GPIO_Port GPIOA
 #define DO6_Pin GPIO_PIN_0
 #define DO6_GPIO_Port GPIOA
 #define DO5_Pin GPIO_PIN_7
 #define DO5_GPIO_Port GPIOB
 #define DO4_Pin GPIO_PIN_6
 #define DO4_GPIO_Port GPIOB
 #define DO3_Pin GPIO_PIN_5
 #define DO3_GPIO_Port GPIOB
 #define DO2_Pin GPIO_PIN_1
 #define DO2_GPIO_Port GPIOB
 #define DO1_Pin GPIO_PIN_4
 #define DO1_GPIO_Port GPIOA
 #define DO0_Pin GPIO_PIN_3
 #define DO0_GPIO_Port GPIOA`

После этого я отрегулировал статус реле ("GPIO PIN STATUS") с помощью хорошо известных функций HAL. Например, в каждом цилиндре я устанавливаю состояние моих 9 реле с выводами микроконтроллеров, для этого я использую этот кодовый блок `

  void prsSetResetRelays(unsigned char coilNo,char status){

    if(coilNo==0){
        if(status=='s' || status=='S'){
            HAL_GPIO_WritePin(DO0_GPIO_Port,DO0_Pin,GPIO_PIN_SET);
       }else{
            HAL_GPIO_WritePin(DO0_GPIO_Port,DO0_Pin,GPIO_PIN_RESET);
        }
    }
    else if(coilNo==1){
        if(status=='s' || status=='S'){
            HAL_GPIO_WritePin(DO1_GPIO_Port,DO1_Pin,GPIO_PIN_SET);
        }else{
            HAL_GPIO_WritePin(DO1_GPIO_Port,DO1_Pin,GPIO_PIN_RESET);
        }
    }
    else if(coilNo==2){
        if(status=='s' || status=='S'){
            HAL_GPIO_WritePin(DO2_GPIO_Port,DO2_Pin,GPIO_PIN_SET);
        }else{
            HAL_GPIO_WritePin(DO2_GPIO_Port,DO2_Pin,GPIO_PIN_RESET);
        }
    }
    else if(coilNo==3){
        if(status=='s' || status=='S'){
            HAL_GPIO_WritePin(DO3_GPIO_Port,DO3_Pin,GPIO_PIN_SET);
        }else{
            HAL_GPIO_WritePin(DO3_GPIO_Port,DO3_Pin,GPIO_PIN_RESET);
        }
    }else if(coilNo==4){
        if(status=='s' || status=='S'){
            HAL_GPIO_WritePin(DO4_GPIO_Port,DO4_Pin,GPIO_PIN_SET);
        }else{
            HAL_GPIO_WritePin(DO4_GPIO_Port,DO4_Pin,GPIO_PIN_RESET);
        }
    }else if(coilNo==5){
        if(status=='s' || status=='S'){
            HAL_GPIO_WritePin(DO5_GPIO_Port,DO5_Pin,GPIO_PIN_SET);
        }else{
            HAL_GPIO_WritePin(DO5_GPIO_Port,DO5_Pin,GPIO_PIN_RESET);
        }
    }
    else if(coilNo==6){
        if(status=='s' || status=='S'){
            HAL_GPIO_WritePin(DO6_GPIO_Port,DO6_Pin,GPIO_PIN_SET);
        }else{
            HAL_GPIO_WritePin(DO6_GPIO_Port,DO6_Pin,GPIO_PIN_RESET);
        }
    }
    else if(coilNo==7){
        if(status=='s' || status=='S'){
            HAL_GPIO_WritePin(DO7_GPIO_Port,DO7_Pin,GPIO_PIN_SET);
        }else{
            HAL_GPIO_WritePin(DO7_GPIO_Port,DO7_Pin,GPIO_PIN_RESET);
        }
    }
    else if(coilNo==8){
        if(status=='s' || status=='S'){
            HAL_GPIO_WritePin(DO8_GPIO_Port,DO8_Pin,GPIO_PIN_SET);
        }else{
            HAL_GPIO_WritePin(DO8_GPIO_Port,DO8_Pin,GPIO_PIN_RESET);
        }
    }
      else if(coilNo==9){
          if(status=='s' || status=='S'){
              HAL_GPIO_WritePin(DO9_GPIO_Port,DO9_Pin,GPIO_PIN_SET);
          }else{
                HAL_GPIO_WritePin(DO9_GPIO_Port,DO9_Pin,GPIO_PIN_RESET);
         }
      }

    }

У меня вопрос такой. Есть ли способ сделать это, чтобы сократить этот код в более короткой форме. Могу ли я использовать для цикла, а не все заявления. Например, я хотел бы написать код вроде:

      for(int i=0;i<10;i++){
           if(status=='s' || status=='S'){
                  HAL_GPIO_WritePin(DO[i]_GPIO_Port,DO[i]_Pin,GPIO_PIN_SET);
           }else{
                HAL_GPIO_WritePin(DO[i]_GPIO_Port,DO[i]_Pin,GPIO_PIN_RESET);
         }
       }

Есть ли способ для меня, чтобы сделать такой вид записи на языке программирования c. Заранее спасибо.

1 ответ

Решение

Вы не можете индексировать имена препроцессоров, нет. Они не являются переменными времени выполнения, они строго используются для замены текста до того, как компилятор даже увидит код.

Правильное решение состоит в том, чтобы смоделировать ваш массив реле в виде массива:

static const struct {
  GPIO_TypeDef *port;
  uint16_t     pin;
} relays[] = {
 { GPIOC, GPIO_PIN_14 },
 { GPIOC, GPIO_PIN_15 },
 ... more here ...
};

Затем вы можете использовать индекс в массиве, чтобы получить данные о порте / выводе и ткнуть в него:

void prsSetResetRelays(unsigned char coilNo, char status)
{
  if(coilNo >= sizeof relays / sizeof *relays)
    return;
  HAL_GPIO_WritePin(relays[coilNo].port, relays[coilNo].pin,
    (status == 's' || status == 'S') ? GPIO_PIN_SET : GPIO_PIN_RESET);
}
Другие вопросы по тегам