cancel
Showing results for 
Search instead for 
Did you mean: 

Dear Community members, I am writing code from scratch to glow LED present in PC13 of STM32F103C(Blue pill) but the LED is not getting turned ON. Kindly help me with this. I am attaching the code below.

SVemp.2
Associate II

Code:

//LED

//Pin:C

//Pin Num:13

#define PERIPH_BASE (0x40000000UL)

#define APB2_OFFSET (0x00010000UL)

#define APB2BASEADD (PERIPH_BASE + APB2_OFFSET)

#define GPIOC_OFFSET (0x1000UL)

#define GPIOC_BASE (APB2BASEADD+GPIOC_OFFSET)

#define AHB_OFFSET (0x18000UL)

#define RCC_OFFSET (0x3000UL)

#define AHB_BASE (PERIPH_BASE+AHB_OFFSET)

#define RCC_BASE (AHB_BASE+RCC_OFFSET)

// Page 109 RCC EN Register.

#define APB2RCCENOFFSET (0x18UL)

#define RCC_APB2EN_R (*(volatile unsigned int *)(RCC_BASE+APB2RCCENOFFSET))

#define GPIOCEN (1U<<4) //Binary: 0000 0000 0000 0000 0000 0000 0001 0000

#define MODE_R_LOW_R (0x00UL)

#define MODE_R_HIGH_R (0x04UL)

#define GPIOC_MODER_R (*(volatile unsigned int *)(GPIOC_BASE+MODE_R_HIGH_R))

//9.2 has Port related information.

#define OD_R_OFFSET (0x0CUL) //Output data Register

#define GPIOC_OD_R (*(volatile unsigned int *)(GPIOC_BASE+OD_R_OFFSET))

#define PIN13 (1u<<13)

#define LED_PIN PIN13

int main(void)

{

/*1.Enable clock access to GPIOC*/

RCC_APB2EN_R |= (15u << 0);

/*2. Set PC13 as output pin*/

GPIOC_MODER_R |= (1u<<20);//Set bit 20 to 1 to make port work as output

GPIOC_MODER_R |= (1u<<21);//Set bit 21 to 1 to make port work as output

GPIOC_MODER_R &=~(1u<<22);//Set bit 22 to 0 to set output port to push-pull configuration

while(1)

{

/*3.Set PC13 high*/

GPIOC_OD_R |= LED_PIN;

}

}

6 REPLIES 6

If the LED cathode is connected to PC13 and anode through resistor to VCC, you need to set ODR to 0 (or just leave it at its reset value).

Generally, if you use debugger (which I'd recommend you to do), read out and check content of the registers as the first debugging step. In debugger, you can also manipulate the registers directly, to see its effect.

JW

ssipa.1
Associate II

try another pin of the LED connected or read this:

"STM32F103C8T6" specifies the microcontroller - there is no "the LED". Any LED will be specific to your board; in which case you need to specify the board you are using or indicate how the LED is connected to the pin (a schematic image perhaps). However, the obvious thing to try is to set it low rather than high - the "on" state is dependent on how the LED is connected.

TDK
Guru

Using the register definitions within the CMSIS headers rather than defining things will make it so much easier to develop and read.

If you feel a post has answered your question, please click "Accept as Solution".
gbm
Lead III

This is the first program I wrote for checking my first BluePill. 🙂

/*
	STM32F10x led blink for F103MDB
	gbm, 01'2016
*/
#include "stm32f10x.h"
 
#define SYSCLK_FREQ	72000000u
#define SYSTICK_FREQ	100
 
#define LED_BIT	13	// PC13, active low
//========================================================================
 
int main(void)
{
	// enable peripherals
	RCC->APB2ENR = RCC_APB2ENR_IOPCEN;
	// port setup
	GPIOC->CRH = 1u << (5*4); // set as output
	SysTick_Config(SYSCLK_FREQ / SYSTICK_FREQ);
	SCB->SCR = SCB_SCR_SLEEPONEXIT_Msk;	// sleep while not in handler
	__WFI();	// go to sleep
}
 
void SysTick_Handler(void)
{
	static uint8_t tdiv;
	
	if (++tdiv == SYSTICK_FREQ)
	{
		tdiv = 0;
		GPIOC->ODR ^= 1 << LED_BIT;	// incorrect but works in simple cases
	}
}

SVemp.2
Associate II

Thank u all for the response. I have edited my code like this and this worked:

#include "stm32f103x6.h"

int main(void)

{

RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;

GPIOC->CRH |= 0x44344444;

while(1)

{

      GPIOC->BSRR = GPIO_BSRR_BS13;

      for(int i = 0;i<100000;i++){}

      GPIOC->BSRR = GPIO_BSRR_BR13;

      for(int i = 0;i<100000;i++){}

}

}

From this code how do i calculate the actual delay time provided by the for loop?

> From this code how do i calculate the actual delay time provided by the for loop?

This depends on too many factors to be almost impossible to determine; in any case it's impractical to depend on it for anything but basic tests like this one. And then, simply measure e.g. with oscilloscope; unless you push it to the limits (try to make it too short), it will depend on the exact top value (here 100000) almost linearly.

Note, that if optimization in compiler is turned on, the for loop will be optimized out entirely, unless you tag i as volatile.

For precise timing, use timers.

JW