/***************************************************************************//**
* \file main.c
*
* \details Blinking Onboard LED with 1 second delay_ms using Timer
* - STM32 Timer Tutorial
*
* \author EmbeTronicX
*
* \This code is verified with STM32F103 Board
*
*******************************************************************************/
/***************************************************************************//**
\details Providing milli seconds Delay_ms by running Timer
\return void
\retval none
*******************************************************************************/
#define TIM3_base 0x40000400
#define TIM_SR_UIF 1
#define RCC_base 0x40021000
#define RCC_CR_HSIRDY 2
#define RCC_CFGR_SW 3
#define RCC_CR_HSEON (1 << 16)
#define GPIOC_base 0x40011000
/*******************************************************************/
void delay1(volatile uint16_t time){
volatile uint16_t x, y;
for(x=0; x<time; x++)
for(y=0; y<235; y++);
}
/********************************************************************/
static void delay_ms( uint32_t ms )
{
volatile uint32_t *TIM3_CNT = (uint32_t*) (TIM3_base + 0x24);
volatile uint32_t *TIM3_SR = (uint32_t*) (TIM3_base + 0x10);
volatile uint32_t i;
for( i = 0; i <= ms; i++ )
{
/* Clear the count */
*TIM3_CNT = 0;
/* Wait UIF to be set */
while((*TIM3_SR & TIM_SR_UIF) == 0); /* This will generate 1ms delay_ms */
/* Reset UIF */
*TIM3_SR &= ~TIM_SR_UIF;
}
}
/***************************************************************************//**
\details This function enables the HSI clock as a system clock and generate
the 8MHz. The Internal HSI Clock is 8MHz. So, we are not using PLL
and not dividing, Multiplying. So, we will get the 16MHz as it is.
\return void
\retval none
*******************************************************************************/
static void SetSystemClockTo8Mhz(void)
{
volatile uint32_t *RCC_CR = (uint32_t*) (RCC_base + 0x00);
volatile uint32_t *RCC_CFGR = (uint32_t*) (RCC_base + 0x04);
/* Enabling the HSI clock - If not enabled and ready */
if( (*RCC_CR & RCC_CR_HSIRDY) == 0)
{
*RCC_CR |= RCC_CR_HSION; /* HSION=1 */
/* Waiting until HSI clock is ready */
while( (*RCC_CR & RCC_CR_HSIRDY) == 0);
}
/* Select AHB prescaler to 1 */
*RCC_CFGR |= ~(1 << 7);
/* APB1 prescaler to 1 */
*RCC_CFGR |= ~(1 << 10);
/* APB2 prescaler to 1 */
*RCC_CFGR |= ~(1 << 13);
/* Select the HSI as system clock source */
*RCC_CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
//RCC->CFGR |= RCC_CFGR_SW_HSI;
//FLASH->ACR |= FLASH_ACR_LATENCY_2;
/* Disabling HSE Clock */
*RCC_CR &= ~RCC_CR_HSEON;
}
/***************************************************************************//**
\details This function configures the timer 3 to generate the 1ms delay_ms.
\return void
\retval none
*******************************************************************************/
static void ConfigureTimer3(void)
{
volatile uint32_t *RCC_APB1ENR = (uint32_t*) (RCC_base + 0x1C);
volatile uint32_t *TIM3_PSC = (uint32_t*) (TIM3_base + 0x28);
volatile uint32_t *TIM3_ARR = (uint32_t*) (TIM3_base + 0x2C);
volatile uint32_t *TIM3_CR1 = (uint32_t*) (TIM3_base + 0x00);
/* Enable the APB clock FOR TIM3 */
*RCC_APB1ENR |= 2;
/* fCK_PSC / (PSC[15:0] + 1)
(8 MHz / (7+1)) = 1 MHz timer clock speed */
*TIM3_PSC = 7;
/* (1 MHz / 1000) = 1KHz = 1ms */
/* So, this will generate the 1ms delay_ms */
*TIM3_ARR = 999;
/* Finally enable TIM3 module */
*TIM3_CR1 = (1 << 0);
}
/***************************************************************************//**
\details The main function. It should not return.
\return void
\retval none
*******************************************************************************/
int main(void)
{
volatile uint32_t *RCC_APB2ENR = (uint32_t*) (RCC_base + 0x18);
volatile uint32_t *GPIOC_CRH = (uint32_t*) (GPIOC_base + 0x04);
volatile uint32_t *GPIOC_ODR = (uint32_t*) (GPIOC_base + 0x0C);
/* Set System clock to 8MHz using HSI*/
// SetSystemClockTo8Mhz();
/* Configure the Timer 3 */
ConfigureTimer3();
/* Enable the APB clock all GPIO port C */
*RCC_APB2ENR |= 1 << 4;
/* PC13 as output */
*GPIOC_CRH &= ~(15 << 20); /* Clear MODE13 and CNF13 fields */
*GPIOC_CRH |= 2 << 20; /* Set MODE13 to 3 (Output) */
/* Endless loop */
while(1)
{
/* Turn ON the LED of PC13 */
*GPIOC_ODR |= 1 << 13;
delay_ms(1000);
/* Turn OFF the LED of PC13 */
*GPIOC_ODR &= ~(1 << 13);
delay_ms(1000);
}
}