2018-04-03 06:22 AM
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.2018-04-04 03:15 AM
What else is running there ?
I always want to heave up when I see Hal_Delay() in posted code ...
2018-04-04 04:10 AM
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 sterowaniaHAL_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 */2018-04-04 04:42 AM
it might be it. do you know how can i change/remove optimalization in keil uvision?
2018-04-04 04:52 AM
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 ...
2018-04-04 05:02 AM
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.
2018-04-04 05:15 AM
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 ... ?
2018-04-04 05:22 AM
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 anunsigned char
->int
conversion involved in your code.2018-04-04 05:24 AM
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.
2018-04-04 05:29 AM
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 ?
2018-04-04 06:06 AM
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.