// 4A - USART1 jednoduché vysílání #include "stm32f0xx.h" #include "stm32f0xx_ll_bus.h" #include "stm32f0xx_ll_gpio.h" #include "stm32f0xx_ll_rcc.h" #include "stm32f0xx_ll_usart.h" #include "stm32f0xx_ll_utils.h" // kvůli konfiguraci clocku #include "stdio.h" // kvůli fci snprintf() void init_clock(void); void init_usart1(void); void usart1_putchar(uint8_t data); void usart1_puts(char *Buffer); LL_RCC_ClocksTypeDef clocks; volatile uint8_t posli=0; volatile uint16_t pocet_stisku=0; char text[31]; int main(void){ init_clock(); // 48MHz z HSE init_usart1(); SysTick_Config(480000); // přerušení 100x za vteřinu while (1){ if(posli){ // jakmile máme co odesílat posli=0; // už jsme to poslali snprintf(text,30,"Stisknuto %u krat\n\r",pocet_stisku); // připraví řetězec usart1_puts(text);// odešle řetězec } } } // Rutina přerušení Systick - pravidelná kontrola stavu tlačítka void SysTick_Handler(void){ static uint8_t button_status=1; if(!LL_GPIO_IsInputPinSet(GPIOA,LL_GPIO_PIN_0) && button_status==0){ button_status=1; // tlačítko stisknuto pocet_stisku++; // inkrementuj počítadlo stisků posli=1; // dej vědět hlavní smyčce ať pošle zprávu } if(LL_GPIO_IsInputPinSet(GPIOA,LL_GPIO_PIN_0)){ button_status=0; // tlačítko uvolněno } } void usart1_puts(char *Buffer){ while(*Buffer){ // než narazíš na konec řetězce (znak /0) while(!LL_USART_IsActiveFlag_TXE(USART1)){}; // čekej než bude volno v Tx Bufferu LL_USART_TransmitData8(USART1,*Buffer++); // předej znak k odeslání } } void init_usart1(void){ LL_USART_InitTypeDef usart; LL_GPIO_InitTypeDef gp; // konfigurace pinů - PA9 jako TX LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA); // clock pro GPIOA LL_GPIO_StructInit(&gp); gp.Pin = LL_GPIO_PIN_9; gp.Mode = LL_GPIO_MODE_ALTERNATE; gp.Speed = LL_GPIO_SPEED_HIGH; gp.Alternate = LL_GPIO_AF_1; gp.Pull = LL_GPIO_PULL_NO; LL_GPIO_Init(GPIOA,&gp); // konfigurace USART LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_USART1); // clock pro USART1 z APB1 // USART1 si může vybírat z vícero zdrojů clocku (aby mohl běžet v režimu spánku) LL_RCC_SetUSARTClockSource(LL_RCC_USART1_CLKSOURCE_PCLK1); // clock z APB1 // konfigurace USARTu usart.BaudRate = 9600; // 9600 b/s usart.DataWidth = LL_USART_DATAWIDTH_8B; usart.HardwareFlowControl = LL_USART_HWCONTROL_NONE; usart.OverSampling = LL_USART_OVERSAMPLING_16; // pokud není nouze o rychlost raději 16x usart.Parity = LL_USART_PARITY_NONE; usart.StopBits = LL_USART_STOPBITS_1; usart.TransferDirection = LL_USART_DIRECTION_TX; // pouze vysíláme LL_USART_Init(USART1,&usart); // můžete hlídat návratovou hodnotu ... LL_USART_Enable(USART1); } // 48MHz z externího 8MHz signálu void init_clock(void){ LL_UTILS_PLLInitTypeDef pll; LL_UTILS_ClkInitTypeDef clk; pll.Prediv = LL_RCC_PREDIV_DIV_2; // 8MHz / 2 = 4MHz pll.PLLMul = LL_RCC_PLL_MUL_12; // 4MHz * 12 = 48MHz clk.AHBCLKDivider = LL_RCC_SYSCLK_DIV_1; // APB i AHB bez předděličky clk.APB1CLKDivider = LL_RCC_APB1_DIV_1; // voláme konfiguraci clocku LL_PLL_ConfigSystemClock_HSE(8000000,LL_UTILS_HSEBYPASS_ON,&pll,&clk); // aktualizuj proměnnou SystemCoreClock SystemCoreClockUpdate(); }