Skip to main content
Jakub B
Associate II
April 3, 2018
Question

Problem with switch/case

  • April 3, 2018
  • 34 replies
  • 7073 views
Posted on April 03, 2018 at 15:22

Hi

I got a problem with a switch in my MCU. I use custom board with STM32F030C8T6.

This here is part of my program:

void rozkaz3(void) {

switch(bufor[3]){

case 0:

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET);

HAL_Delay(1000);

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);

break;

case 1: HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET);

HAL_Delay(1000);

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET);

break;

case 2:

HAL_GPIO_WritePin(GPIOF, GPIO_PIN_7, GPIO_PIN_RESET);

HAL_Delay(1000);

HAL_GPIO_WritePin(GPIOF, GPIO_PIN_7, GPIO_PIN_SET);

break;

case 3:

HAL_GPIO_WritePin(GPIOF, GPIO_PIN_6, GPIO_PIN_RESET);

HAL_Delay(1000);

HAL_GPIO_WritePin(GPIOF, GPIO_PIN_6, GPIO_PIN_SET);

break;

case 5:

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, GPIO_PIN_RESET);

HAL_Delay(1000);

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, GPIO_PIN_SET);

break;

case 6:

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);

HAL_Delay(1000);

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);

break;

case 7:

case 4:

default:

break;

case 12:

NVIC_SystemReset();

break;

it switches on and off outputs i chose based on number. My board has 6 outputs. Case 4 and case 7 are not configured and not connected.

If i order case 0,1,2,3,5,6,11,12 all works well.

If i order case 4 or 7 my program works on case 0 then case 4/7. If i delete case 0 it will work on case 1 and then case 4/7 and so on.

It works first available case in switch then case i ordered.

Now if i change only this:

case 7:

case 4:

default:

HAL_Delay(1000);

break;

I works ok.

And with HAL_Delay(1) its not working again.

Whats happening and how to make it work right without HAL_Delay ?

Note: this post was migrated and contained many threaded conversations, some content may be missing.
    This topic has been closed for replies.

    34 replies

    waclawek.jan
    Super User
    April 3, 2018
    Posted on April 03, 2018 at 16:25

    I say the problem is in that part of code we don't see.

    JW

    T J
    Senior III
    April 3, 2018
    Posted on April 04, 2018 at 01:17

    case 4 is out of order,

    you must either leave it out,

    or put it in order.

    Case 12 is also out of order.

    do you like Dials or Knobs ?

    Jakub B
    Jakub BAuthor
    Associate II
    April 4, 2018
    Posted on April 04, 2018 at 09:22

    case 4 works fine like that. Ive put it in order for test now and nothing changed.

    i checked order of cases and i can switch hovewer i want it and it doesnt matter.

    I did put for fun cases in order 1253067 and i worked with no changes.

    edit: im a knob man

    T J
    Senior III
    April 4, 2018
    Posted on April 04, 2018 at 09:50

    artistically , knob is the better word,  but its just a bit too colourful these days..

    Jakub B
    Jakub BAuthor
    Associate II
    April 4, 2018
    Posted on April 04, 2018 at 11:22

    The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6ut&d=%2Fa%2F0X0000000bxw%2FnTxLuPjtz4KBL_xSDI7r3_vg6VpNEiy58KfZmlY31Xo&asPdf=false
    Andrew Neil
    Super User
    April 4, 2018
    Posted on April 04, 2018 at 11:34

    If i order case 4 or 7 my program works on

    case 0 then case 4/7

    .

    Are you describing what happens when you step the code in the debugger?

    If so, this could be just down to optimisation

    https://www.avrfreaks.net/forum/shortcuts-taken-optimized-code-may-occasionally-sic-be-surprising

     

    Do you actually see the correct pins being toggled ?

    A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
    Jakub B
    Jakub BAuthor
    Associate II
    April 4, 2018
    Posted on April 04, 2018 at 11:42

    it might be it. do you know how can i change/remove optimalization in keil uvision?

    Andrew Neil
    Super User
    April 4, 2018
    Posted on April 04, 2018 at 11:52

    The main question is:

    Do you actually see the correct pins being toggled ?

    If yes, then the code is working properly - and there is nothing to worry about!

    :)

    The optimisation settings are in the Project Properties - see the Keil documentation for details ...

    A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
    Jakub B
    Jakub BAuthor
    Associate II
    April 4, 2018
    Posted on April 04, 2018 at 13:10

    update:

    with delay before all if's it works fine BUT it have to be more than 500ms (?).

    void rozkaz3(void) {

         //sprawdzenie numeru wyjscia do sterowania

    HAL_Delay(600);    

    if(bufor[3]==0x00){

                                HAL_Delay(1000);}

    if(bufor[3]==0x01){

                                 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET);        

                                HAL_Delay(1000);

                                HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);

         }

    if(bufor[3]==0x02){

                                 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET);        

                                HAL_Delay(1000);

                                HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET);

         }

    if(bufor[3]==0x03){

                                 HAL_GPIO_WritePin(GPIOF, GPIO_PIN_7, GPIO_PIN_RESET);        

                                HAL_Delay(1000);

                                HAL_GPIO_WritePin(GPIOF, GPIO_PIN_7, GPIO_PIN_SET);

         }

    if(bufor[3]==0x04){

                                 HAL_GPIO_WritePin(GPIOF, GPIO_PIN_6, GPIO_PIN_RESET);        

                                HAL_Delay(1000);

                                HAL_GPIO_WritePin(GPIOF, GPIO_PIN_6, GPIO_PIN_SET);

         }

    if(bufor[3]==0x06){

                                 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, GPIO_PIN_RESET);        

                                HAL_Delay(1000);

                                HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, GPIO_PIN_SET);

         }

    if(bufor[3]==0x07){

                                 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);        

                                HAL_Delay(1000);

                                HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);

         }

    if(bufor[3]==0x0C){uint8_t odpowiedz[15]; // ramka bez crc do wyslania

                                sprintf(odpowiedz,'%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c', adres, 0x04, 0x06, konfiguracja, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00); //wpisanie danych do odpowiedzi

                                wy_crc=CRC2(14,odpowiedz); //ramka do obliczenia crc

                                wy_crc1=wy_crc; //crc1 do ramki wysylane

                                wy_crc=wy_crc>>8; //przesuwamy bity

                                wy_crc2=wy_crc; // crc2 do ramki wysylanej

                                sprintf(Config,'%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c', adres, 0x04, 0x06, konfiguracja, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,wy_crc1,wy_crc2); // drukowanie stanow wejscia do wiadomosci wysylanej

                                // Rozpoczecie nadawania danych z wykorzystaniem przerwan

                                HAL_UART_Transmit_DMA(&huart1, Config, 17);

            }

    if(bufor[3]==0x0D){

                                NVIC_SystemReset();

            }

    it looks like function is working faster then checking requirements. Delay lets it  work properly but 600ms is a lot of time to just wait.any ideas?

    i had a same problem that was solved by adding 1ms delay. i was recieving only packages that was sent in longer periods of time in between. if i added 1ms it worked with packages that was sent almost with no period of time.

      /* USER CODE BEGIN WHILE */

      while (1)

      {

            HAL_UART_Receive_DMA(&huart1, Received, 8); //rozpoczecie nasluchiwania

            HAL_Delay(1);

            if (ramka==1){

                //przekierowanie rozkazu do funkcji

                switch(bufor[1]){

                    case 1:{

                    config(); break;

                    }

                    case 4:{

                    stany(); break;

                    }

                    case 5:{

                    rozkaz3(); break;

                    }

                    default: break;

            }

        }

        ramka=0;

        memset(bufor, 0xFF, 8);

      /* USER CODE END WHILE */
    Andrew Neil
    Super User
    April 4, 2018
    Posted on April 04, 2018 at 13:19

    So I think that takes us right back to the very first reply - from

    Waclawek.Jan

    :

    https://community.st.com/0D70X000006SlY6SAK

    And from

    meyer.frank

    :

    https://community.st.com/0D70X000006SlY6SAK

    Something else is 'corrupting'

    bufor[3] ...

    A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
    AvaTar
    Senior III
    April 4, 2018
    Posted on April 04, 2018 at 13:29

    My experience tells me:

    • NEVER use a synchronous wait;
    • Always work on a snapshot copy of asynchronous data (keyword PLC ...)
    waclawek.jan
    Super User
    April 4, 2018
    Posted on April 04, 2018 at 19:43

    Now follow Laurent's guidelines, but next time, you should present a consistent set of code and problem description; don't just make random changes and then post.

    JW

    Jakub B
    Jakub BAuthor
    Associate II
    April 6, 2018
    Posted on April 06, 2018 at 15:55

    You all focused on race condition and cant understand one thing so ill try to show you something:

    0690X0000060AS9QAM.png

    Those in color are only possible packages for now

    1st yellow one is stany - it goes every 2 seconds and works properly

    those from rozkaz part in yellow works properly

    red ones when sent work as if i sent green one

    green one works properly.

    If i had race condition on bufor[3] i would have all orders on yellow switched to green too.

    But only those two red dont work. Why would race condition be triggered only on those 2 and not all of them?

    Jakub B
    Jakub BAuthor
    Associate II
    April 6, 2018
    Posted on April 06, 2018 at 15:56

    btw: ill do pictures of debug later when im in lab. probably on monday

    AvaTar
    Senior III
    April 6, 2018
    Posted on April 06, 2018 at 17:58

    I would suggest to set a data breakpoint on the 'incorrect' case, conditionally triggering on those erraneous conditions.

    Perhaps toggle a free GPIO before, and trigger a scope showing the serial communication.