Как написать инструкцию switch с помощью IAR IDE и контроллера STM32

#embedded #stm32 #iar

Вопрос:

Я новичок во встроенном программировании на C и работе с драйверами HAL устройств STM32F10x. Я использую IDE IAR и компилятор C. Следующий переключатель, похоже, не работает и выдает мне ошибки:

 Error[Pe053]: expected a ":"  
 

и

 Error[Pe065]: expected a ";" 
 

в нескольких местах инструкций switch.

     // header file
    #define OUTPUT_GEN_PURPOSE              (uint32_t) 0x00)
    #define OUTPUT_OD                       (uint32_t) 0x01)
    #define OUTPUT_ALT_FUNCTION             (uint32_t) 0x02)
    #define OUTPUT_ALT_FUNCTION_OD          (uint32_t) 0x03)
    #define INPUT_ANALOG                    (uint32_t) 0x00)
    #define INPUT_FLOATING                  (uint32_t) 0x01)
    #define INPUT_PU_PD                     (uint32_t) 0x02)
    #define CNF_POS_BIT1                    (PINPOS[pinNumber]   2)
    #define CNF_POS_BIT2                    (PINPOS[pinNumber]   3)
 
     // C file
        switch(mode_type)
        {
          // Output Modes
        
        case OUTPUT_GEN_PURPOSE | INPUT_ANALOG:
          port->CRH amp;= ~((1<<CNF_POS_BIT1) | (1<<CNF_POS_BIT2));
          break;
    
        case OUTPUT_OD | INPUT_FLOATING:
          port->CRH amp;= ~(1<<CNF_POS_BIT2);
          port->CRH |= (1<<CNF_POS_BIT1);
          break;
    
        case OUTPUT_ALT_FUNCTION | INPUT_PU_PD:
          port->CRH |= OUTPUT_ALT_FUNCTION<<(CNF_POS_BIT1);
          break;
          
        case OUTPUT_ALT_FUNCTION_OD:
          port->CRH |= OUTPUT_ALT_FUNCTION_OD<<(CNF_POS_BIT1);
          break;      
        }
 

Пожалуйста, дайте мне знать, если возникнут какие-либо проблемы с синтаксисом инструкций switch и т. Д.

Комментарии:

1. тот факт, что вы используете IDE IAR или контроллер STM32 или что он встроен, не имеет отношения к синтаксису. Вы должны пометить это [C]. Диагностика компилятора полезна. Не описывайте и не исключайте их, скопируйте и вставьте их дословно и полностью. Они указывают, например, строку кода, о которой они сообщают, которую вы опустили.

2. Если вы получаете ошибку, связанную с макросами, вы должны рассмотреть эту ошибку в контексте расширения макросов, потому что именно это «видит» компилятор и сообщает об этом. Вы можете рассмотреть более простой 0x00lu вариант или просто 0x00u ((uint32_t) 0x00) — скобки не требуются. Или используйте C и, скажем static const std::uint32_t OUTPUT_GEN_PURPOSE = 0x00u ; , для лучшей безопасности типов и более четкого синтаксиса и семантики.

3. Не говорите нам, что вы сделали «несколько модификаций», а затем не показываете эти модификации и их результат. Заявление не содержит никакого полезного содержания. Банальность удалена.

Ответ №1:

Например:

 case OUTPUT_OD | INPUT_FLOATING:
 

расширяется до:

 case (uint32_t) 0x01) | (uint32_t) 0x01):
 

Круглые скобки несбалансированы из-за ошибки в определениях макросов:

 #define OUTPUT_GEN_PURPOSE              ((uint32_t) 0x00)
//                                      ^
//                                      Parenthesis
 

Семантика ваших case констант кажется маловероятной (и необычной). Вы на самом деле намеревались:

     case OUTPUT_OD :
    case INPUT_FLOATING:
          port->CRH amp;= ~(1<<CNF_POS_BIT2);
          port->CRH |= (1<<CNF_POS_BIT1);
          break;    
 

значение mode_type является одним из или OUTPUT_OD INPUT_FLOATING , а не битовым ИЛИ макрозначением?

При таких значениях макросов это на самом деле не вызывает сбоя, но семантически код не имеет того значения, которое вы, скорее всего, предполагаете, и это приведет к путанице или путанице будущих сопровождающих, а в других случаях может произойти сбой.