This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

LED not blinking (mysteriously) ?

Hi,

I've been evaluating Keil MDK-ARM for a while have an STM3210C-EVAL board in my hands. It's similar to Keil's MCBSTM32C eval board.

As usual, I tried to understand how to blink a LED. I manipulated an example project and tried to blink LED4 which is blue and connected to PD4. No luck. It was not blinking. I spend couple of hours to find what's wrong, but couldn't find any clue. Debug was running well but LED was not blinking. Then today, I just tried to blink other LED's after running out of other ideas. And voila, just the orange LED (LED2, PD13) started to blink.

So what can cause this?

They are 4 simple LED's connected to ports with 4 simple resistors. But I just can blink only one. And I'm sure they are working physically, since they are blinking with the demo firmware.

Am I missing something mysterious?

Here is the code I'm using. (Manipulated version of $K/ARM/Boards/Keil/MCBSTM32C/Blinky project)

/******************************************************************************/
/* BLINKY.C: LED Flasher                                                      */
/******************************************************************************/
/* This file is part of the uVision/ARM development tools.                    */
/* Copyright (c) 2005-2009 Keil Software. All rights reserved.                */
/* This software may only be used under the terms of a valid, current,        */
/* end user licence from KEIL for a compatible version of KEIL software       */
/* development tools. Nothing else gives you the right to use this software.  */
/******************************************************************************/

#include <stm32f10x_cl.h>

#define LED_NUM     8                   /* Number of user LEDs                */

const long led_mask[] = { 1<<7, 1<<13, 1<<3, 1<<4};


int main (void) {
  int AD_val, i;
  int num = -1;
  int dir =  1;

  SystemInit();

  /* Setup GPIO for LEDs                                                      */
  RCC->APB2ENR |=  1 <<  5;             /* Enable GPIOD clock                 */
  GPIOD->CRH    = 0x33333333;           /* Configure the GPIO for LEDs        */

  /* Setup and initialize ADC converter                                       */
  RCC->APB2ENR |=  1 <<  9;             /* Enable ADC1 clock                  */
  GPIOC->CRL   &= 0xFFF0FFFF;           /* Configure PC4 as ADC.14 input      */
  ADC1->SQR1    = 0x00000000;           /* Regular channel 1 conversion       */
  ADC1->SQR2    = 0x00000000;           /* Clear register                     */
  ADC1->SQR3    = 14 <<  0;             /* SQ1 = channel 14                   */
  ADC1->SMPR1   =  5 << 12;             /* Channel 14 sample time is 55.5 cyc */
  ADC1->SMPR2   = 0x00000000;           /* Clear register                     */
  ADC1->CR1     =  1 <<  8;             /* Scan mode on                       */
  ADC1->CR2     = (1 << 20) |           /* Enable external trigger            */
                  (7 << 17) |           /* EXTSEL = SWSTART                   */
                  (1 <<  1) |           /* Continuous conversion              */
                  (1 <<  0) ;           /* ADC enable                         */
  ADC1->CR2    |=  1 <<  3;             /* Initialize calibration registers   */
  while (ADC1->CR2 & (1 << 3));         /* Wait for initialization to finish  */
  ADC1->CR2    |=  1 <<  2;             /* Start calibration                  */
  while (ADC1->CR2 & (1 << 2));         /* Wait for calibration to finish     */
  ADC1->CR2    |=  1 << 22;             /* Start first conversion             */

  for (;;)
  {                            /* Loop forever                       */
    if (ADC1->SR & (1 << 1))
        {          /* If conversion has finished         */
      AD_val = ADC1->DR & 0x0FFF;       /* Read AD converted value            */
      ADC1->CR2 |= 1 << 22;             /* Start new conversion               */
    }

    /* Calculate 'num': 0, 1, ... , LED_NUM-1, LED_NUM-1, ... , 1, 0, 0, ...  */
    num += dir;
    if (num >= LED_NUM) { dir = -1; num = LED_NUM-1; }
    else if   (num < 0) { dir =  1; num = 0;         }

    GPIOD->BSRR = 1 << 13;        /* Please change 13 with the numbers 7,3 and 4 to try other LED's */
    for (i = 0; i < ((AD_val << 8) + 100000); i++);
    GPIOD->BSRR = 1 << (13+16);  /* Please change 13 with the numbers 7,3 and 4 to try other LED's */
        for (i = 0; i < ((AD_val << 8) + 100000); i++);
  }
}

Parents
  • Thanks Robert and Andy,

    I meant "3.5 drivers are not provided by Keil and if you want to use it, you have to change things, like using stm32f10x.h rather than stm32f10x_lib.h" etc.

    As Robert said, the GPIOD->CRL register did the trick. Now I can blink all of the LED's.

    ***

    I want to ask some more questions about your ARM and Keil Architecture experience.

    ***

    What I want to do is, build some vendor independent libraries about my area of expertise. Therefore CMSIS looks like a good way to start. But I also can use some basic #defined keywords to achieve my goal, because most of the libraries will work with simple hardware interfaces.

    So according to this idea and your opinion about the maturity level of CMSIS peripheral libraries, what would you choose? Use CMSIS libraries or use some vendor specific startup codes and define some general interface for library modules?

    ***

    Another question related to this topic:

    To test both ideas I tried ST's new 3.5 library first. (Because it supports all of the CMSIS peripheral interfaces, unlike the 2.0 library.)

    To blink a LED, I used SystemInit() and GPIO_Init() with it's struct parameter (Which is taken from the library example as you suggested Andy).

    But it didn't blink the LED properly. Then I checked the GPIO_Init() function implemented in stm32f10x_gpio.c and saw that there is no APB2ENR register command. Shouldn't be there a APB2ENR command to enable GPIOD clock signal? Or do I have to use RCC_APB2PeriphClockCmd() function to enable it? Is it a standard CMSIS function or ST specific? (I used NXP LPC1343 and LPC Xpresso in my previous project, and used GPIO_Init() successfuly without having to use any RCC functions)

    ***

    And a last question. After installing ST 3.5 peripheral library I wanted to test it with a simple project. If I add stm32f10x.h for CMSIS core and peripheral libraries it starts to give linking errors for the peripheral library (undefined symbols). This is because armcc compiler does not compile the related files (for example stm32f10x_gpio.c) into object files. To pass this problem I have to add peripheral files to my project. This is also the way the MDK ARM project template shows, which is provided with the Library.

    Is this the right way? Or there is a more elegant way to compile all of the project without adding all of the peripheral files? (My basic C Language knowledge says, if you add a header file to your main source file, all of the related h and c files would be compiled. But this isn't happening if I use "Build Target (F7)")

    ***

    Thanks for your patience about my long and never ending questions :) I hope I'm not asking FAQ.

Reply
  • Thanks Robert and Andy,

    I meant "3.5 drivers are not provided by Keil and if you want to use it, you have to change things, like using stm32f10x.h rather than stm32f10x_lib.h" etc.

    As Robert said, the GPIOD->CRL register did the trick. Now I can blink all of the LED's.

    ***

    I want to ask some more questions about your ARM and Keil Architecture experience.

    ***

    What I want to do is, build some vendor independent libraries about my area of expertise. Therefore CMSIS looks like a good way to start. But I also can use some basic #defined keywords to achieve my goal, because most of the libraries will work with simple hardware interfaces.

    So according to this idea and your opinion about the maturity level of CMSIS peripheral libraries, what would you choose? Use CMSIS libraries or use some vendor specific startup codes and define some general interface for library modules?

    ***

    Another question related to this topic:

    To test both ideas I tried ST's new 3.5 library first. (Because it supports all of the CMSIS peripheral interfaces, unlike the 2.0 library.)

    To blink a LED, I used SystemInit() and GPIO_Init() with it's struct parameter (Which is taken from the library example as you suggested Andy).

    But it didn't blink the LED properly. Then I checked the GPIO_Init() function implemented in stm32f10x_gpio.c and saw that there is no APB2ENR register command. Shouldn't be there a APB2ENR command to enable GPIOD clock signal? Or do I have to use RCC_APB2PeriphClockCmd() function to enable it? Is it a standard CMSIS function or ST specific? (I used NXP LPC1343 and LPC Xpresso in my previous project, and used GPIO_Init() successfuly without having to use any RCC functions)

    ***

    And a last question. After installing ST 3.5 peripheral library I wanted to test it with a simple project. If I add stm32f10x.h for CMSIS core and peripheral libraries it starts to give linking errors for the peripheral library (undefined symbols). This is because armcc compiler does not compile the related files (for example stm32f10x_gpio.c) into object files. To pass this problem I have to add peripheral files to my project. This is also the way the MDK ARM project template shows, which is provided with the Library.

    Is this the right way? Or there is a more elegant way to compile all of the project without adding all of the peripheral files? (My basic C Language knowledge says, if you add a header file to your main source file, all of the related h and c files would be compiled. But this isn't happening if I use "Build Target (F7)")

    ***

    Thanks for your patience about my long and never ending questions :) I hope I'm not asking FAQ.

Children
No data