cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with switch/case

Jakub B
Associate III
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.
34 REPLIES 34
Posted on April 04, 2018 at 10:15

What else is running there ?

I always want to heave up when I see Hal_Delay() in posted code ...

Jakub B
Associate III
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 */
Posted on April 04, 2018 at 11:42

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

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 ...

Posted on April 04, 2018 at 12:02

Like i said before:

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.

yes i check pins and its all works exactly like in debugger.

I changed level of optimalization and rebuilded project. Nothing changed.

i send order with number (case) and if i send normal proper orders i have ok response.

If i send order with number not included (which in case should go to default and do nothing) i get response from output on case 0. If i remove case 0 i get response on case 1 (first available from top).

what shocked me is that when i changed switch to if ... i got exactly the same problem.

Posted on April 04, 2018 at 12:15

OK. It wasn't clear what you meant - that's why I asked if you were just stepping in the debugger, or if this was the actual observed behaviour on the pins.

Are you sure that the problem is in the switch itself ? Could it not be that whatever 'feeds' the switch - ie, whatever calls the 

rozkaz3() function - is actually passing spurious stuff ... ?

Posted on April 04, 2018 at 12:22

If i send order with number not included (which in case should go to default and do nothing) i get response from output on case 0. If i remove case 0 i get response on case 1 (first available from top).

In your place, I would check on instruction level (assembler) what happens in those cases.

The

switch

statement implies an integer argument, so there seems an

unsigned char

->

int

conversion involved in your code.
Posted on April 04, 2018 at 12:24

I posted (almost) full code a little earlier. At the moment im stuck.

I tried changing it, compiling with different program (recent attolic true studio)...

whole purpose is that board gets by uart package with information about adress of board (so its knows it for this board), then checks what kind of order it is (rozkaz3, config, stany) and then do what it was asked for.

config changes configuration that is doing nothing for now and is on different bufor[♯].

stany sends package with info on inputs and is on different bufor[♯]

only rozkaz3 uses bufor[3] and while function is working its not changed (checked in debugger)

It might be somethng relatively stupid for you and something unimaginable for me.

Posted on April 04, 2018 at 12:29

package recieved in uint8_t, copied then to bufor that is uint8_t.

should i convert it to something else?

edit:how can i do assembler check in keil/attolic ?

Posted on April 04, 2018 at 13:06

should i convert it to something else?

Not necessarily, a conversion is implied in such cases.

An added type cast would make clear what you mean - in this and other cases (self-documenting source !).

package recieved in uint8_t, copied then to bufor that is uint8_t.

Can you really rule out an asynchronous mechanism (interrupt/DMA) changing the buffer in the background ?

edit:how can i do assembler check in keil/attolic ?

Dunno with Keil.

Atollic is basically Eclipse, switch to 'Instruction step mode' during debugging, the Eclipse way.