1

I try to program an STM32F103C8 circuit. I use an ST-LINK V2 programmer. After running a sample of code that used special libraries, I was able to see the built-in LED ON, but now I want to program the board without using those libraries, and I don't know why I cannot see anything, the LED is OFF the whole time. Here is the code:

#include "stm32f10x.h"                  // Device header

int main(){
    RCC->APB2ENR |= 1<<4;
    GPIOC->CRH &= ~0xFF0FFFF;
    GPIOC->CRH |= 0x00300000;
    GPIOC->ODR |= 1<<13;//turn PC_13 ON
    while(1){
        
    }
}
8
  • Try replacing one library function at a time, and testing after each change. When your code breaks, you will know exactly which line was wrong. Commented Apr 16, 2021 at 13:08
  • How do these magic hex numbers make sense? F00F0000 is not 00300000 is not 00002000. Commented Apr 16, 2021 at 13:21
  • What do you mean by magic hex numbers? Commented Apr 16, 2021 at 13:49
  • I do this in order to be sure that those bits are cleared. That's why there may occur a glitch or sth like this. But this is not the problem Commented Apr 16, 2021 at 13:53
  • @old_timer I will disassemble the code. I use Keil IDE, could you give me more details about accessing the ARM assembly code? Commented Apr 16, 2021 at 13:54

2 Answers 2

2

Based on the info that you have the LED on PC13, I assume you're using the famous Blue Pill board. In that board, LED connection is inverted because of the special limitations of PC13 - that pin should only sink current, not source. So, in order to turn it on, you need to write 0 to corresponding bit of ODR.

Normally, I'm against the usage of magic numbers. But for STM32F103, using hex literals for GPIO configuration is practical, because one single hex digit uniquely defines the pin mode. One can memorize the meaning of hex literals for GPIO settings, and use them in a compact assignment which defines the 8 pins of a GPIO port at once. If you make GPIO configurations only once, you don't need &= or |= operators.

Also, prefer using BSRR instead of ODR, because it allows atomic modification of output pins.

Here is a LED blink example for Blue Pill board:

//========================================================================
// Includes
//========================================================================
#include "stm32f1xx.h"
#include <stdbool.h>
#include <stdint.h>

//========================================================================
// Local Variables
//========================================================================
volatile uint32_t sysTick = 0;

//========================================================================
// Local Function Prototypes
//========================================================================
void initialize(void);
void delayMs(uint32_t ms);

//========================================================================
// Initialization
//========================================================================
void initialize(void) {

    SystemCoreClock = 8000000U;

    RCC->APB2ENR |= RCC_APB2ENR_IOPCEN // Enable PortC
            | RCC_APB2ENR_AFIOEN; // Enable A.F.Z

    // Pin Remaps
    AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_JTAGDISABLE; // JTAG is disabled

    // GPIO Settings
    GPIOC->CRH = 0x44244444; // LED connected to PC13
    GPIOC->BSRR = (1 << 13); // LED is inverted, turn it off.

    // SysTick Settings
    SysTick_Config(SystemCoreClock / 1000);

    // Initialization Done Signal
    GPIOC->BSRR = (1 << (13 + 16));
    delayMs(200);
    GPIOC->BSRR = (1 << 13);
}

//========================================================================
// Main
//========================================================================
int main(void) {

    initialize();

    while (true) {
        delayMs(500);
        GPIOC->BSRR = (1 << (13 + 16));
        delayMs(500);
        GPIOC->BSRR = (1 << 13);
    }
}

//========================================================================
// Interrupt Handlers
//========================================================================

void SysTick_Handler(void)
{
    ++sysTick;
}

//========================================================================
// Local Functions
//========================================================================

void delayMs(uint32_t ms) {
    uint32_t start = sysTick;
    while (sysTick - start < ms);
}
Sign up to request clarification or add additional context in comments.

Comments

1
#include "stm32f10x.h"                  // Device header

int main(void){
    RCC->APB2ENR |= 1<<4;
    GPIOC->CRH &= 0xFF0FFFF;//clear the necessary bit 
    GPIOC->CRH |= 0x00300000;//set the necessary bit
    GPIOC->ODR &= ~(1<<13);//turn PC_13 ON
        while(1){
        
    }
}

This code works. The problem was that PC13 controls the cathode, not the anode of the built-in LED. That's why I should write: GPIO->ODR &= ~(1 << 13); in order to turn ON the LED.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.