#include #include "stm32f3xx.h" // The current clock frequency uint32_t SystemCoreClock=8000000; // Counts milliseconds volatile uint32_t systick_count=0; // Interrupt handler void SysTick_Handler() { systick_count++; } // Delay some milliseconds. // Note that effective time may be up to 1ms shorter than requested. void delay_ms(int ms) { uint32_t start=systick_count; while (systick_count-startISR & USART_ISR_TXE)); USART2->TDR = *ptr++; } return len; } // Change system clock to 72 MHz using 8 MHz crystal void init_clock() { // Because the debugger switches PLL on, we may need to switch // back to the HSI oscillator before we can configure the PLL // Enable HSI oscillator SET_BIT(RCC->CR, RCC_CR_HSION); // Wait until HSI oscillator is ready while(!READ_BIT(RCC->CR, RCC_CR_HSIRDY)) {} // Switch to HSI oscillator MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_HSI); // Wait until the switch is done while ((RCC->CFGR & RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_HSI) {} // Disable the PLL CLEAR_BIT(RCC->CR, RCC_CR_PLLON); // Wait until PLL is fully stopped while(READ_BIT(RCC->CR, RCC_CR_PLLRDY)) {} // Flash latency 2 wait states MODIFY_REG(FLASH->ACR, FLASH_ACR_LATENCY, FLASH_ACR_LATENCY_1); // Enable HSE oscillator SET_BIT(RCC->CR, RCC_CR_HSEON); // Wait until HSE oscillator is ready while(!READ_BIT(RCC->CR, RCC_CR_HSERDY)) {} // 72 MHz using the 8 MHz HSE oscillator with 9x PLL, lowspeed I/O runs at 36 MHz WRITE_REG(RCC->CFGR, RCC_CFGR_SWS_HSE + RCC_CFGR_PLLSRC_HSE_PREDIV + RCC_CFGR_PLLMUL9 + RCC_CFGR_PPRE1_DIV2); // Enable PLL SET_BIT(RCC->CR, RCC_CR_PLLON); // Wait until PLL is ready while(!READ_BIT(RCC->CR, RCC_CR_PLLRDY)) {} // Select PLL as clock source MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_PLL); // Update variable SystemCoreClock=72000000; // Disable the HSI oscillator CLEAR_BIT(RCC->CR, RCC_CR_HSION); } void init_io() { // Enable clock for Port A SET_BIT(RCC->AHBENR, RCC_AHBENR_GPIOAEN); // PA5 = Output for the LED MODIFY_REG(GPIOA->MODER, GPIO_MODER_MODER5, GPIO_MODER_MODER5_0); // Use system clock for USART2 SET_BIT(RCC->APB1ENR, RCC_APB1ENR_USART2EN); MODIFY_REG(RCC->CFGR3, RCC_CFGR3_USART2SW, RCC_CFGR3_USART2SW_0); // PA2 (TxD) shall use the alternate function 7 (see data sheet) MODIFY_REG(GPIOA->AFR[0], GPIO_AFRL_AFRL2, 7UL<MODER, GPIO_MODER_MODER2, GPIO_MODER_MODER2_1); // PA3 (RxD) shall use the alternate function 7 (see data sheet) MODIFY_REG(GPIOA->AFR[0], GPIO_AFRL_AFRL3, 7UL<MODER, GPIO_MODER_MODER3, GPIO_MODER_MODER3_1); // Set baudrate, assuming that USART2 is clocked with // the same frequency as the CPU core (no prescalers) USART2->BRR = (SystemCoreClock / 115200); // Enable transmitter of USART2 USART2->CR1 = USART_CR1_UE + USART_CR1_TE; } void SystemInit() { // Switch the FPU on SCB->CPACR = 0x00F00000; } int main() { init_clock(); init_io(); // Initialize the timer for 1 ms intervals SysTick_Config(SystemCoreClock/1000); printf("Start\n"); delay_ms(100); while (1) { // LED an WRITE_REG(GPIOA->BSRR, GPIO_BSRR_BS_5); uint32_t start=systick_count; float f=1.0; for (int i=0; i<10000; i++) { f=f*1.001; if (f>100000.0) { f=1.0; } } // LED aus WRITE_REG(GPIOA->BSRR, GPIO_BSRR_BR_5); printf("f=%f, duration=%ld ms\n",f, systick_count-start); delay_ms(500); } }