Hi everyone,
I want to turn on a LED on my STM32F4-discovery board
Here is the code :
int main() {
// Enable the GPIO Clock
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
// GPIO Configuration
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_14; // Led 6 Blue selected
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; // Mod out !
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; // 50 MHZ clock frequency
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; // Push pull mod
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; // Pull up
GPIO_Init(GPIOD, &GPIO_InitStruct);
// Turn on the LED
GPIO_SetBits(GPIOD, GPIO_Pin_14);
return 0; }
I'm using uvision 5.13.0.0
It compiles and flash succesfully but nothing happen after. I don't know what is wrong with this. I also tried with this :
STM_EVAL_LEDInit(LED6); STM_EVAL_LEDOn(LED6);
but there is no worked.
Can you help me ? Many thanks :)
First thing is that you're falling out of main.
Put in something like:
void main (void) { // do stuff while (1) ; }
Thanks for your help.
I change line "return 0;" by "while(1);" but it had change nothing. Any other idea ?
Try Troubleshooting using the System Viewer. I would look at RCC and GPIOD to see if the Registers appear to be properly set up.
Or heaven forbid, use the debugger, and have the while loop alternately drive the led high and low, and step through the code to confirm it's actually being run.
The code looks Ok.
Hi guys,
I launched a debug session for this code :
int main() { // Enable the GPIOD Clock RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); // GPIOD Configuration GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_15; // Led 6 Blue selected GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; // Mod out ! GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; // 50 MHZ clock frequency GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; // Push pull mod GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; // Pull up GPIO_Init(GPIOD, &GPIO_InitStruct); // GPIOD-PIN 15 ON while(1) { GPIO_SetBits(GPIOD, GPIO_Pin_15) ; } }
Here is the result of debug session :
12: // GPIOD Configuration 13: GPIO_InitTypeDef GPIO_InitStruct; 0x080004E2 2101 MOVS r1,#0x01 0x080004E4 2008 MOVS r0,#0x08 0x080004E6 F7FFFF3D BL.W RCC_AHB1PeriphClockCmd (0x08000364) 14: GPIO_InitStruct.GPIO_Pin = GPIO_Pin_15; // Led 6 Blue selected 0x080004EA F44F4080 MOV r0,#0x4000 0x080004EE 9000 STR r0,[sp,#0x00] 15: GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; // Mod out ! 0x080004F0 2002 MOVS r0,#0x02 0x080004F2 F88D0004 STRB r0,[sp,#0x04] 16: GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; // 50 MHZ clock frequency 0x080004F6 F88D0005 STRB r0,[sp,#0x05] 17: GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; // Push pull mod 0x080004FA 2000 MOVS r0,#0x00 0x080004FC F88D0006 STRB r0,[sp,#0x06] 18: GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; // Pull up 19: 0x08000500 2001 MOVS r0,#0x01 0x08000502 F88D0007 STRB r0,[sp,#0x07] 20: GPIO_Init(GPIOD, &GPIO_InitStruct); 21: 22: // GPIOD-PIN 15 ON 0x08000506 4669 MOV r1,sp 0x08000508 4804 LDR r0,[pc,#16] ; @0x0800051C 0x0800050A F7FFFEDB BL.W GPIO_Init (0x080002C4) 23: while(1) 24: { 0x0800050E E004 B 0x0800051A 25: GPIO_SetBits(GPIOD, GPIO_Pin_15) ; 0x08000510 F44F4180 MOV r1,#0x4000 0x08000514 4801 LDR r0,[pc,#4] ; @0x0800051C 0x08000516 F7FFFF1D BL.W GPIO_SetBits (0x08000354) 0x0800051A E7F9 B 0x08000510 0x0800051C 0C00 DCW 0x0C00 0x0800051E 4002 DCW 0x4002 0x08000520 F04F7040 MOV r0,#0x3000000 0x08000524 EEE10A10 VMSR FPSCR, r0 0x08000528 4770 BX lr 0x0800052A 0000 MOVS r0,r0 0x0800052C 053C DCW 0x053C 0x0800052E 0800 DCW 0x0800 0x08000530 0000 DCW 0x0000 0x08000532 2000 DCW 0x2000 0x08000534 0660 DCW 0x0660 0x08000536 0000 DCW 0x0000 0x08000538 01C4 DCW 0x01C4 0x0800053A 0800 DCW 0x0800 0x0800053C FFFFFFFF DCD 0xFFFFFFFF 0x08000540 FFFFFFFF DCD 0xFFFFFFFF
I wonder if my homemade base project is well configured. Maybe the uC isn't well init.
I think there is also some code before main in the start up file that will be performed to set up the clocks. That is why I suggested that you use system viewer to look at the RCC.
Can you right click on the project so you can get to project options and the debug tab. and the Unclick the run to main checkbox. then run debug. choose to single step into the code.
What function does the debugger go to. Does it go into a function probably called system_init. This is where it would initialize the clock stuff. this code is before the main function in another file that is assembly code.
also can you find a function to clear the led.
Hope this helps
I launched a debug session with your advises and it runs until System init function like you said.
175: LDR R0, =SystemInit 0x0800020C 4809 LDR r0,[pc,#36] ; @0x08000234
.
Then there is this code but i can't find a function to clear the LED :
LDR R0, =SystemInit BLX R0 LDR R0, =__main BX R0 ENDP
Then with the system viewer i checked some registers. In RCC, i checked AHB1ENR and nothing is activated. In GPIOD, i checked BSRR register and nothing is activated too. It seems that clocks are not well initialized. Do you know what i must change to correct it ?
Many thanks !
One more thing that came to mind. Make sure you have the debug selected and not simulation. I think simulation might be the default mode. You should find the check box in the same place you unchecked run to main.
do some more single stepping and verify that the clock registers are really being written to.
Refer to this appnote http://www.keil.com/appnotes/docs/apnt_268.asp
Even when it says Middleware, it is actually a good step-by-step introduction that is generic enough.
This might help to: www2.keil.com/.../
Use something like this in your loop
while(1) { GPIO_SetBits(GPIOD, GPIO_Pin_15); // Toggle the LED, so you can see it change as you step each function GPIO_ResetBits(GPIOD, GPIO_Pin_15); // this isn't magic just requires some thought }
Ok, we're getting really off in the weeds. When you use the debugger, does it get you to the first instruction of main(), OR NOT??
If you hit STOP, where does it stop?
If you uncheck "run to main", can you step over SystemInit, or does it crash?
The code in __main sets up the C runtime environment and eventually calls your main() function.
If SystemInit() is failing, you need to look at the source code in system_stm32f4xx.c and determine if it's doing something stupid, like setting the clocks wrong, or the PLL too high. The Discovery board uses an 8 MHz source clock, make sure your code is consistent with that, and the HSE_VALUE for the project is 8000000.
Hi,
Fisrt i appologize, I'm a newbie and this is the fisrt time I use Keil and STM32. I checked with all your instructions and when i check "Run to main" option it crashes and i'm on this loop :
void HardFault_Handler(void) { /* Go to infinite loop when Hard Fault exception occurs */ while (1) { } }
So i can't go in main. Then I unchecked "Run to main" option. SystemInit is ok and doesn't crash. In my project i have these options in preprocessor symbols definition:
USE_STDPERIPH_DRIVER,STM32F4XX,KEIL_IDE,PLL_M=8,PLL_N=336,PLL_P=2,PLL_Q=7,HSE_VALUE=8000000
Then it starts __main instruction and it seems to crash here. What can i do after that to check the error ?
Many thanks,
When you call __main, lots of things will happen before you reach your normal main() function.
You might get a stack overflow.
Or maybe your memory layout doesn't match your chip, so the startup code tries to initialize non-existing memory.
Maybe your project specifies external memory, and you haven't initialized the memory controller that interfaces with the external memory.
Or it could be that the stack pointer is initialized assuming that the stack resides in memory that is only available once __main is executed. With the execution of __main being a call, that execution occurs, only to fail when it attempts to return to the caller.