{"id":355127,"date":"2024-05-20T23:02:18","date_gmt":"2024-05-20T23:02:18","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=355127"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=355127","title":{"rendered":"<span>\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 libopencm3: \u0411\u044b\u0441\u0442\u0440\u044b\u0439 \u0441\u0442\u0430\u0440\u0442 (\u0427\u0430\u0441\u0442\u044c 3). \u0420\u0430\u0431\u043e\u0442\u0430 \u0441 USART, \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f\u043c\u0438, I2C \u0438 \u0442\u0430\u0439\u043c\u0435\u0440\u0430\u043c\u0438<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p><a href=\"https:\/\/habr.com\/ru\/companies\/auriga\/articles\/728270\/\">\u0427\u0430\u0441\u0442\u044c 1. \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 libopencm3<\/a><\/p>\n<p><a href=\"https:\/\/habr.com\/ru\/companies\/auriga\/articles\/729418\/\">\u0427\u0430\u0441\u0442\u044c 2. \u0420\u0430\u0431\u043e\u0442\u0430 \u0441 GPIO, SPI, \u043e\u0442\u043b\u0430\u0434\u043a\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 GDB<\/a><\/p>\n<p>\u0427\u0430\u0441\u0442\u044c 3. \u0420\u0430\u0431\u043e\u0442\u0430 \u0441 USART, \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f\u043c\u0438, I2C \u0438 \u0442\u0430\u0439\u043c\u0435\u0440\u0430\u043c\u0438<\/p>\n<p>\u0414\u0430\u043d\u043d\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u0430\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0432 \u0446\u0438\u043a\u043b\u0435, \u043f\u043e\u0441\u0432\u044f\u0449\u0435\u043d\u043d\u043e\u043c \u0431\u044b\u0441\u0442\u0440\u043e\u043c\u0443 \u0441\u0442\u0430\u0440\u0442\u0443 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u043e\u0434 STM32 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 libopencm3. \u0411\u0435\u0437 \u043b\u0438\u0448\u043d\u0438\u0445 \u0441\u043b\u043e\u0432 \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0438\u044e \u043e\u0441\u0442\u0430\u0432\u0448\u0435\u0439\u0441\u044f \u043f\u0435\u0440\u0438\u0444\u0435\u0440\u0438\u0438, \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0447\u0430\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u0439 \u0432 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430\u0445.<\/p>\n<h4>\u0422\u0440\u0435\u0442\u0438\u0439 \u043f\u0440\u043e\u0435\u043a\u0442: \u041f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0447\u0435\u0440\u0435\u0437 USART &amp; \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439<\/h4>\n<p>\u041f\u043e\u0440\u0430 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 \u0441 \u043e\u043a\u0440\u0443\u0436\u0430\u044e\u0449\u0438\u043c \u043c\u0438\u0440\u043e\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e USART \u2013 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0435\u0433\u043e \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u043e\u043c \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0442\u0435\u043a\u0441\u0442\u0430.   <\/p>\n<p><strong>\u0426\u0435\u043b\u044c: \u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0432 USART \u0441\u0442\u0440\u043e\u0447\u043a\u0443 \u00abHello from LibOpenCM3!\u00bb \u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c: \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c 9600, 8 \u0431\u0438\u0442 \u0434\u0430\u043d\u043d\u044b\u0445, \u043e\u0434\u0438\u043d \u0441\u0442\u043e\u043f-\u0431\u0438\u0442, \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0447\u0435\u0442\u043d\u043e\u0441\u0442\u0438 \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u0430.<\/strong><\/p>\n<p>\u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043d\u0430\u0448 \u043f\u0440\u043e\u0435\u043a\u0442:<\/p>\n<pre><code>.\/make_project.sh ex3_1_usart<\/code><\/pre>\n<p>\u041d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0435 \u0448\u0430\u0433\u0438 \u043d\u0435 \u043e\u0442\u043b\u0438\u0447\u0430\u044e\u0442\u0441\u044f \u043e\u0442 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u0435\u0432: \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u0447\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432, \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u0437\u0430 \u043f\u0435\u0440\u0438\u0444\u0435\u0440\u0438\u044e, \u0438 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0442\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u043e\u0440\u0442\u0430 \u0438 \u043f\u0435\u0440\u0438\u0444\u0435\u0440\u0438\u0438.<\/p>\n<details class=\"spoiler\">\n<summary>STM32F1<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#include &lt;libopencm3\/stm32\/rcc.h> #include &lt;libopencm3\/stm32\/gpio.h> #include &lt;libopencm3\/stm32\/usart.h> #include \"ex3_1_usart.h\" static void clock_setup(void) { rcc_clock_setup_pll(&amp;rcc_hse_configs[RCC_CLOCK_HSE8_72MHZ]); rcc_periph_clock_enable(RCC_GPIOA); rcc_periph_clock_enable(RCC_AFIO); rcc_periph_clock_enable(RCC_USART2); } int main(void) { clock_setup(); while(1); }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>STM32F4<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#include &lt;libopencm3\/stm32\/rcc.h> #include &lt;libopencm3\/stm32\/gpio.h> #include &lt;libopencm3\/stm32\/usart.h> #include \"ex3_1_usart.h\" static void clock_setup(void) { rcc_clock_setup_pll(&amp;rcc_hse_25mhz_3v3[RCC_CLOCK_3V3_96MHZ]); rcc_periph_clock_enable(RCC_GPIOA); rcc_periph_clock_enable(RCC_USART2); } int main(void) { clock_setup(); while(1); }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041e\u0442\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u0443\u0435\u043c USART \u0441 \u0442\u0440\u0435\u0431\u0443\u0435\u043c\u044b\u043c\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438. \u0424\u0443\u043d\u043a\u0446\u0438\u0438 libopencm3 \u0438\u043d\u0442\u0443\u0438\u0442\u0438\u0432\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u043d\u044b. \u0422\u0430\u043a \u0436\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043c \u043d\u043e\u0436\u043a\u0438 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0439 RX \u0438 TX, \u0430\u043a\u0442\u0438\u0432\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0432 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438.  <\/p>\n<details class=\"spoiler\">\n<summary>STM32F1<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#include &lt;libopencm3\/stm32\/rcc.h> #include &lt;libopencm3\/stm32\/gpio.h> #include &lt;libopencm3\/stm32\/usart.h> #include \"ex3_1_usart.h\"   static void clock_setup(void) {         rcc_clock_setup_pll(&amp;rcc_hse_configs[RCC_CLOCK_HSE8_72MHZ]);         rcc_periph_clock_enable(RCC_GPIOA);         rcc_periph_clock_enable(RCC_AFIO);         rcc_periph_clock_enable(RCC_USART2); }   int main(void) {         clock_setup();           gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO2 | GPIO3 );           usart_set_baudrate(USART2, 9600);         usart_set_databits(USART2, 8);         usart_set_stopbits(USART2, USART_STOPBITS_1);         usart_set_parity(USART2, USART_PARITY_NONE);         usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE);         usart_set_mode(USART2, USART_MODE_TX_RX);         usart_enable(USART2);           while(1); }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>STM32F4<\/summary>\n<div class=\"spoiler__content\">\n<\/div>\n<\/details>\n<p>USART \u0433\u043e\u0442\u043e\u0432 \u043a \u043f\u0440\u0438\u0435\u043c\u0443 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0435 \u0434\u0430\u043d\u043d\u044b\u0445. \u0422\u0430\u043a \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043c \u0447\u0442\u043e-\u043d\u0438\u0431\u0443\u0434\u044c \u0432 \u0441\u0442\u043e\u0440\u043e\u043d\u0443 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0430. \u041d\u0430\u043f\u0438\u0448\u0435\u043c \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0449\u0443\u044e \u043f\u043e\u0441\u0438\u043c\u0432\u043e\u043b\u044c\u043d\u043e \u0432 USART \u0441\u0442\u0440\u043e\u043a\u0443:<\/p>\n<pre><code class=\"cpp\">static void usart_transmit(const char *str) { while (*str != '\\000') { usart_send_blocking(USART2, *str); str++; } }<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0438 \u043c\u0435\u0436\u0434\u0443 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430\u043c\u0438 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f \u043f\u043e\u0434\u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439 DWT, \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0439 \u0440\u0430\u043d\u0435\u0435:<\/p>\n<details class=\"spoiler\">\n<summary>STM32F1<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#include &lt;libopencm3\/stm32\/rcc.h> #include &lt;libopencm3\/stm32\/gpio.h> #include &lt;libopencm3\/stm32\/usart.h> #include &lt;libopencm3\/cm3\/dwt.h> #include \"ex3_1_usart.h\"   static void clock_setup(void) {         rcc_clock_setup_pll(&amp;rcc_hse_configs[RCC_CLOCK_HSE8_72MHZ]);         rcc_periph_clock_enable(RCC_GPIOA);         rcc_periph_clock_enable(RCC_AFIO);         rcc_periph_clock_enable(RCC_USART2); }   static uint32_t dwt_setup(void) {         dwt_enable_cycle_counter();         __asm volatile (\"nop\");         __asm volatile (\"nop\");         __asm volatile (\"nop\");        if(dwt_read_cycle_counter())      {        return 0;      }      else   {     return 1;   } }   static void dwt_delay_ms(uint32_t milliseconds) {         uint32_t initial_ticks = dwt_read_cycle_counter();         uint32_t ms_count_tics = milliseconds * (rcc_ahb_frequency \/ 1000);         while ((dwt_read_cycle_counter() - initial_ticks) &lt; ms_count_tics); }   static void usart_transmit(const char *str) {         while (*str != '\\000') {                 usart_send_blocking(USART2, *str);                 str++;         } }   int main(void) {         clock_setup();         dwt_setup();           gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO2 | GPIO3 );           usart_set_baudrate(USART2, 9600);         usart_set_databits(USART2, 8);         usart_set_stopbits(USART2, USART_STOPBITS_1);         usart_set_parity(USART2, USART_PARITY_NONE);         usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE);         usart_set_mode(USART2, USART_MODE_TX_RX);         usart_enable(USART2);           while(1){                 dwt_delay_ms(1000);                 usart_transmit(\"Hello from LibOpenCM3!\\r\\n\");         } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>STM32F4<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#include &lt;libopencm3\/stm32\/rcc.h> #include &lt;libopencm3\/stm32\/gpio.h> #include &lt;libopencm3\/stm32\/usart.h> #include &lt;libopencm3\/cm3\/dwt.h> #include \"ex3_1_usart.h\"   static void clock_setup(void) {         rcc_clock_setup_pll(&amp;rcc_hse_25mhz_3v3[RCC_CLOCK_3V3_96MHZ]);         rcc_periph_clock_enable(RCC_GPIOA);         rcc_periph_clock_enable(RCC_USART2); }   static uint32_t dwt_setup(void) {         dwt_enable_cycle_counter();         __asm volatile (\"nop\");         __asm volatile (\"nop\");         __asm volatile (\"nop\");        if(dwt_read_cycle_counter())      {        return 0;      }      else   {     return 1;   } }   static void dwt_delay_ms(uint32_t milliseconds) {         uint32_t initial_ticks = dwt_read_cycle_counter();         uint32_t ms_count_tics = milliseconds * (rcc_ahb_frequency \/ 1000);         while ((dwt_read_cycle_counter() - initial_ticks) &lt; ms_count_tics); }   static void usart_transmit(const char *str) {         while (*str != '\\000') {                 usart_send_blocking(USART2, *str);                 str++;         } }   int main(void) {         clock_setup();         dwt_setup();         gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO2 | GPIO3);         gpio_set_af(GPIOA, GPIO_AF7, GPIO2 | GPIO3);           usart_set_baudrate(USART2, 9600);         usart_set_databits(USART2, 8);         usart_set_stopbits(USART2, USART_STOPBITS_1);         usart_set_parity(USART2, USART_PARITY_NONE);         usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE);         usart_set_mode(USART2, USART_MODE_TX_RX);           usart_enable(USART2);         while(1){                 dwt_delay_ms(1000);                 usart_transmit(\"Hello from LibOpenCM3!\\r\\n\");         } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u0441\u0431\u043e\u0440\u043a\u0443 \u0438 \u043f\u0440\u043e\u0448\u0438\u0432\u043a\u0443, \u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043d\u0438\u043a Serial2Usb \u043a \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0443: PA3 \u043a TX, PA2 \u043a RX.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/25c\/fc1\/885\/25cfc18855a28c3bfaef234f3d16187e.png\" alt=\"\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043d\u0438\u043a\u0430 USB-2-Serial  \u043a \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0443 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 BluePill\" title=\"\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043d\u0438\u043a\u0430 USB-2-Serial  \u043a \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0443 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 BluePill\" width=\"579\" height=\"516\" data-src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/25c\/fc1\/885\/25cfc18855a28c3bfaef234f3d16187e.png\"\/><\/p>\n<div><figcaption>\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043d\u0438\u043a\u0430 USB-2-Serial \u043a \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0443 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 BluePill<\/figcaption><\/div>\n<\/figure>\n<p>\u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u044c\u043d\u0443\u044e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443, \u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c\u0441\u044f \u043a \u0441\u0438\u043c\u0432\u043e\u043b\u044c\u043d\u043e\u043c\u0443 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0443 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043d\u0438\u043a\u0430.<\/p>\n<pre><code>$ cu -l \/dev\/ttyUSB0 -s 9600 Connected. Hello from LibOpenCM3! Hello from LibOpenCM3! Hello from LibOpenCM3! Hello from LibOpenCM3! Hello from LibOpenCM3! Hello from LibOpenCM3!<\/code><\/pre>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043d\u0430\u0448 \u0448\u0430\u0433 \u2013 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0432 \u0441\u0442\u043e\u0440\u043e\u043d\u0443 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u043e\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0438\u0444\u0435\u0440\u0438\u044e \u043d\u0430 \u043f\u0440\u0435\u0434\u043c\u0435\u0442 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u2013 \u0434\u0443\u0440\u043d\u043e\u0439 \u0442\u043e\u043d, \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u043d\u0430\u0448\u0430 \u0446\u0435\u043b\u044c \u0431\u0443\u0434\u0435\u0442 \u0432\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f\u043c\u0438 STM32.<\/p>\n<p><strong>\u0426\u0435\u043b\u044c: \u043f\u0440\u0438 \u0441\u0442\u0430\u0440\u0442\u0435 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u044b\u0434\u0430\u0442\u044c \u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b \u00abHello\u00bb, \u043e\u0436\u0438\u0434\u0430\u0442\u044c \u0432\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043a\u043e\u043c\u0430\u043d\u0434. \u041f\u0440\u0438 \u0432\u0432\u0435\u0434\u0435\u043d\u0438\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u00abtoggle_led\u00bb<\/strong> <strong>\u2013<\/strong> <strong>\u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434\u0430 \u043d\u0430 \u043d\u043e\u0436\u043a\u0435 PC13, \u0430 \u043f\u0440\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u0435 \u00absay_hello\u00bb \u2013 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0443 \u00abHello from LibOpenCM3!\u00bb.<\/strong><\/p>\n<p>\u0420\u0430\u0431\u043e\u0442\u0430 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439 \u0432 STM32 \u043e\u043f\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 NVIC (Nested Vector Interrupt Controller) \u0438 \u043d\u0438\u0447\u0435\u043c \u043e\u0441\u043e\u0431\u043e \u043d\u0435 \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u0434\u0440\u0443\u0433\u0438\u0445 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u043e\u0432 (\u043a \u043f\u0440\u0438\u043c\u0435\u0440\u0443, Atmega). \u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435, \u0443 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439 \u0432 STM32 \u0438\u043c\u0435\u044e\u0442\u0441\u044f \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u044b.<\/p>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 USART \u0441 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439.<\/p>\n<p>\u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0448\u0430\u0431\u043b\u043e\u043d \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430:<\/p>\n<pre><code>$ .\/make_project.sh ex3_2_usart_irq<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0432\u044b\u043c \u0434\u0435\u043b\u043e\u043c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043c \u0438 \u0430\u043a\u0442\u0438\u0432\u0438\u0437\u0438\u0440\u0443\u0435\u043c NVIC:<\/p>\n<details class=\"spoiler\">\n<summary>STM32F1<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#include &lt;libopencm3\/stm32\/rcc.h> #include &lt;libopencm3\/cm3\/nvic.h> #include \"ex3_2_usart_irq.h\"   static void clock_setup(void) {         rcc_clock_setup_pll(&amp;rcc_hse_configs[RCC_CLOCK_HSE8_72MHZ]);         rcc_periph_clock_enable(RCC_GPIOA); }   int main(void) {         clock_setup();         nvic_enable_irq(NVIC_USART2_IRQ); \/\/\u0412\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439 \u0434\u043b\u044f USART2         nvic_set_priority(NVIC_USART2_IRQ, 1); \/\/\u041e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e, \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0435\u043c \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f.         while(1); }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>STM32F4<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#include &lt;libopencm3\/stm32\/rcc.h> #include &lt;libopencm3\/cm3\/nvic.h> #include \"ex3_2_usart_irq.h\"   static void clock_setup(void) {         rcc_clock_setup_pll(&amp;rcc_hse_25mhz_3v3[RCC_CLOCK_3V3_96MHZ]);         rcc_periph_clock_enable(RCC_GPIOA);         rcc_periph_clock_enable(RCC_USART2); }   int main(void) {         clock_setup();         nvic_enable_irq(NVIC_USART2_IRQ); \/\/\u0412\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439 \u0434\u043b\u044f USART         nvic_set_priority(NVIC_USART2_IRQ, 1); \/\/\u041e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e, \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0435\u043c \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f.         while(1); }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043c\u044b \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u0443\u0435\u043c USART \u043f\u043e\u0447\u0442\u0438 \u0442\u0430\u043a \u0436\u0435, \u043a\u0430\u043a \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435. \u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435, \u0447\u0442\u043e \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u2013 \u0430\u043a\u0442\u0438\u0432\u0438\u0437\u0430\u0446\u0438\u044e \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439 \u043f\u043e \u043f\u0440\u0438\u0435\u043c\u0443 \u0434\u0430\u043d\u043d\u044b\u0445. \u0412\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e usart_enable_rx_interrupt() \u0438 \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0438\u0440\u0443\u0435\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439 usart2_isr(). \u041f\u043e\u043b\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u0438\u043c\u0435\u043d \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 (<a href=\"http:\/\/libopencm3.org\/docs\/latest\/stm32f1\/html\/group__CM3__nvic__isrprototypes__STM32F1.html#ga4ef5b9c30c57ea631c43778171dd0908\">F1 series<\/a>,\u00a0<a href=\"http:\/\/libopencm3.org\/docs\/latest\/stm32f4\/html\/group__CM3__nvic__isrprototypes__STM32F4.html#ga4ef5b9c30c57ea631c43778171dd0908\">F4 series<\/a>).<\/p>\n<p>\u0415\u0449\u0435 \u043d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0435\u043c \u0441\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u043e\u0436\u043a\u0443 PC13, \u043f\u043e\u0434\u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u043d\u0443\u044e \u043a \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434\u0443.<\/p>\n<details class=\"spoiler\">\n<summary>STM32F1<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#include &lt;libopencm3\/stm32\/rcc.h> #include &lt;libopencm3\/cm3\/nvic.h> #include &lt;libopencm3\/stm32\/usart.h> #include &lt;libopencm3\/stm32\/gpio.h>   #include \"ex3_2_usart_irq.h\"   static void clock_setup(void) {         rcc_clock_setup_pll(&amp;rcc_hse_configs[RCC_CLOCK_HSE8_72MHZ]);         rcc_periph_clock_enable(RCC_GPIOA);         rcc_periph_clock_enable(RCC_GPIOC);         rcc_periph_clock_enable(RCC_AFIO);         rcc_periph_clock_enable(RCC_USART2); }   int main(void) {         clock_setup();         nvic_enable_irq(NVIC_USART2_IRQ); \/\/\u0412\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439 \u0434\u043b\u044f USART2         nvic_set_priority(NVIC_USART2_IRQ, 1); \/\/\u041e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e, \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0435\u043c \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f.         gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO2);         gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, GPIO3);           gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_10_MHZ,  GPIO_CNF_OUTPUT_PUSHPULL, GPIO13);         gpio_set(GPIOC, GPIO13);             usart_set_baudrate(USART2, 9600);         usart_set_databits(USART2, 8);         usart_set_stopbits(USART2, USART_STOPBITS_1);         usart_set_parity(USART2, USART_PARITY_NONE);         usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE);         usart_set_mode(USART2, USART_MODE_TX_RX);         usart_enable_rx_interrupt(USART2);         usart_enable(USART2);           while(1); }   void usart2_isr(void){ }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>STM32F4<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#include &lt;libopencm3\/stm32\/rcc.h> #include &lt;libopencm3\/cm3\/nvic.h> #include &lt;libopencm3\/stm32\/usart.h> #include &lt;libopencm3\/stm32\/gpio.h> #include \"ex3_2_usart_irq.h\"   static void clock_setup(void) {         rcc_clock_setup_pll(&amp;rcc_hse_25mhz_3v3[RCC_CLOCK_3V3_96MHZ]);         rcc_periph_clock_enable(RCC_GPIOA);         rcc_periph_clock_enable(RCC_GPIOC);         rcc_periph_clock_enable(RCC_USART2); }   int main(void) {         clock_setup();         nvic_enable_irq(NVIC_USART2_IRQ); \/\/\u0412\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439 \u0434\u043b\u044f USART         nvic_set_priority(NVIC_USART2_IRQ, 1); \/\/\u041e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e, \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0435\u043c \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f.         gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO2 | GPIO3);         gpio_set_af(GPIOA, GPIO_AF7, GPIO2 | GPIO3);           gpio_mode_setup(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO13);         gpio_set(GPIOC, GPIO13);           usart_set_baudrate(USART2, 9600);         usart_set_databits(USART2, 8);         usart_set_stopbits(USART2, USART_STOPBITS_1);         usart_set_parity(USART2, USART_PARITY_NONE);         usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE);         usart_set_mode(USART2, USART_MODE_TX_RX);         usart_enable_rx_interrupt(USART2);         usart_enable(USART2);         while(1); }   void usart2_isr(void){ }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u0433\u043e\u0442\u043e\u0432 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043f\u043e\u0441\u0442\u0443\u043f\u0430\u044e\u0449\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f \u043d\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0434\u043b\u044f \u043f\u0440\u0438\u0435\u043c\u0430\/\u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438. \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0434\u0432\u0430 \u043a\u043e\u043b\u044c\u0446\u0435\u0432\u044b\u0445 \u0431\u0443\u0444\u0435\u0440\u0430 \u043d\u0430 \u043f\u0440\u0438\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u043d\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0443, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u043d\u0438\u043c\u0438.<\/p>\n<details class=\"spoiler\">\n<summary>\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u043a\u043e\u043b\u044c\u0446\u0435\u0432\u044b\u043c\u0438 \u0431\u0443\u0444\u0435\u0440\u0430\u043c\u0438<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#define BUF_SIZE 128   uint8_t tx_buffer[BUF_SIZE] = {}; uint8_t rx_buffer[BUF_SIZE] = {};   typedef struct {   uint8_t *data;   uint32_t size;   uint32_t head;   uint32_t tail;   uint32_t length; } rb;   typedef struct {         uint8_t cmd_code;         uint8_t assembling; } cmd;   volatile rb tx_rb = {   .data = tx_buffer,   .size = sizeof(tx_buffer),   .head = 0,   .tail = 0,   .length = 0 };   volatile rb rx_rb = {   .data = rx_buffer,   .size = sizeof(rx_buffer),   .head = 0,   .tail = 0,   .length = 0 };   cmd cli_cmd = {   .cmd_code = 0,   .assembling =0 };     static uint8_t rb_push(volatile rb *ring, const uint8_t data) {   if (((ring->tail + 1) % ring->size) != ring->head)   {     ring->data[ring->tail++] = data;     ring->tail %= ring->size;     ring->length++;     return 1;   }   return 0; }   static uint8_t rb_pop(volatile b *ring, uint8_t *data) {   if (ring->head != ring->tail)   {     *data = ring->data[ring->head++];     ring->head %= ring->size;     ring->length--;     return 1;   }   return 0; }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u0430\u0440\u0441\u0438\u043d\u0433 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u043a\u043e\u043c\u0430\u043d\u0434 \u043c\u044b \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c: \u043f\u043e\u0431\u0430\u0439\u0442\u043d\u043e \u0431\u0443\u0434\u0435\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e XOR \u043d\u0430\u0434 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u043c \u0431\u0430\u0439\u0442\u043e\u043c \u0438 \u043a\u043e\u0434\u043e\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u044b. \u041f\u0440\u0438 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u0438 \u0441\u0438\u043c\u0432\u043e\u043b\u0430 \u043a\u043e\u043d\u0446\u0430 \u0441\u0442\u0440\u043e\u043a\u0438 \u043c\u044b \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u0443\u0435\u043c \u044d\u0442\u043e \u043a\u0430\u043a \u043a\u043e\u043d\u0435\u0446 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0438 \u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0432\u0448\u0438\u0439\u0441\u044f \u043a\u043e\u0434 \u043a\u043e\u043c\u0430\u043d\u0434\u044b. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u043d\u0430\u0431\u043e\u0440\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u043a\u043e\u043c\u0430\u043d\u0434 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043f\u043e\u0441\u0438\u043c\u0432\u043e\u043b\u044c\u043d\u044b\u0445 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0439.<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u0430\u0440\u0441\u0438\u043d\u0433 \u043a\u043e\u043c\u0430\u043d\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">static void parse_cmd(volatile rb *ring, cmd *cli){         uint8_t data = 0;         while(rb_pop(ring, &amp;data)){                 if(data == 0x0D){ \/\/ \\r char                         cli->assembling = 0;                         break;                 } else {                                 cli->assembling = 1;                                 cli->cmd_code ^= data;                 }         }         if (!cli->assembling){                 switch(cli->cmd_code){                         case 0x20: \/\/ \"toggle_led\" cmd                                 gpio_toggle(GPIOC, GPIO13);                                 break;                         case 0x56: \/\/ \"say_hello\" cmd                                 usart_transmit(&amp;tx_rb, \"Hello from LibOpenCm3!\\n\");                                 break;                         default:                                 break;                 }                 cli->cmd_code = 0;                 cli->assembling = 1;         } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u043e\u043c\u0435\u0441\u0442\u0438\u043c \u0441\u0442\u0440\u043e\u043a\u0443 \u0432 \u043a\u043e\u043b\u044c\u0446\u0435\u0432\u043e\u0439 \u0431\u0443\u0444\u0435\u0440, \u0430 \u0437\u0430\u0442\u0435\u043c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c \u0444\u043b\u0430\u0433 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0435.<\/p>\n<details class=\"spoiler\">\n<summary>\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">static void usart_transmit(volatile rb *ring, const char *str){         while (*str != '\\000') {                 rb_push(ring, (uint8_t)*str);                 str++;         }         usart_enable_tx_interrupt(USART2); }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043f\u043e\u043b\u043d\u0438\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439. \u0412 \u043d\u0435\u043c \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c, \u043f\u043e \u043a\u0430\u043a\u043e\u0439 \u043f\u0440\u0438\u0447\u0438\u043d\u0435 \u0431\u044b\u043b\u043e \u0432\u044b\u0437\u0432\u0430\u043d\u043e \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0435: \u043f\u043e \u043f\u0440\u0438\u0435\u043c\u0443 \u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0435. \u0422\u0430\u043a\u0436\u0435 \u043f\u0440\u0438 \u043f\u0440\u0438\u0435\u043c\u0435 \u0431\u0430\u0439\u0442\u0430 \u043d\u0435\u043c\u0435\u0434\u043b\u0435\u043d\u043d\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043c \u0435\u0433\u043e \u043e\u0431\u0440\u0430\u0442\u043d\u043e, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044f \u0440\u0435\u0436\u0438\u043c \u044d\u0445\u043e. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u0440\u0438\u0435\u043c\u0430 \u0441\u0438\u043c\u0432\u043e\u043b\u0430 \\r, \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c\u043e\u0433\u043e \u043c\u043e\u0435\u0439 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043e\u0439, \u0432 \u043e\u0442\u0432\u0435\u0442 \u043e\u0442\u0434\u0430\u0434\u0438\u043c \u0441\u0438\u043c\u0432\u043e\u043b \u043d\u043e\u0432\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438.<\/p>\n<details class=\"spoiler\">\n<summary>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">void usart2_isr(void) {         uint8_t data = 0;         if (usart_get_flag(USART2, USART_SR_TXE)) {                 if(rb_pop(&amp;tx_rb, &amp;data)){                         usart_send(USART2, data);                 } else {                         usart_disable_tx_interrupt(USART2);                 }         }           if (usart_get_flag(USART2, USART_SR_RXNE)) {                 data = (uint8_t)usart_recv(USART2);                 rb_push(&amp;rx_rb, data);                 if (data == 0x0D){                         usart_send(USART2, 0x0A);                 } else {                         usart_send(USART2, data);                 }         }  }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 main \u0432 \u0446\u0438\u043a\u043b\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043a\u0430\u0436\u0434\u0443\u044e \u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434\u0443 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c, \u0438\u043c\u0435\u044e\u0442\u0441\u044f \u043b\u0438 \u0443 \u043d\u0430\u0441 \u043a\u0430\u043a\u0438\u0435-\u043d\u0438\u0431\u0443\u0434\u044c \u043d\u043e\u0432\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u043f\u0440\u0438\u0435\u043c\u043d\u043e\u043c \u043a\u043e\u043b\u044c\u0446\u0435\u0432\u043e\u043c \u0431\u0443\u0444\u0435\u0440\u0435. \u0414\u043b\u044f \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434\u043d\u043e\u0439 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0438 \u0432\u043d\u043e\u0432\u044c \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f DWT.<\/p>\n<p>\u041e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u043c \u0432\u0441\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0432\u043c\u0435\u0441\u0442\u0435, \u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u043c \u043a\u043e\u0434 \u0432 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440.  <\/p>\n<details class=\"spoiler\">\n<summary>STM32F1<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#include &lt;libopencm3\/stm32\/rcc.h> #include &lt;libopencm3\/cm3\/nvic.h> #include &lt;libopencm3\/stm32\/usart.h> #include &lt;libopencm3\/stm32\/gpio.h> #include &lt;libopencm3\/cm3\/dwt.h>   #include \"ex3_2_usart_irq.h\" #define BUF_SIZE 128   static void clock_setup(void) {         rcc_clock_setup_pll(&amp;rcc_hse_configs[RCC_CLOCK_HSE8_72MHZ]);         rcc_periph_clock_enable(RCC_GPIOA);         rcc_periph_clock_enable(RCC_GPIOC);         rcc_periph_clock_enable(RCC_AFIO);         rcc_periph_clock_enable(RCC_USART2); }     uint8_t tx_buffer[BUF_SIZE] = {}; uint8_t rx_buffer[BUF_SIZE] = {};   typedef struct {   uint8_t *data;   uint32_t size;   uint32_t head;   uint32_t tail;   uint32_t length; } rb;   typedef struct {         uint8_t cmd_code;         uint8_t assembling; } cmd;   volatile rb tx_rb = {   .data = tx_buffer,   .size = sizeof(tx_buffer),   .head = 0,   .tail = 0,   .length = 0 };   volatile rb rx_rb = {   .data = rx_buffer,   .size = sizeof(rx_buffer),   .head = 0,   .tail = 0,   .length = 0 };   cmd cli_cmd = {   .cmd_code = 0,   .assembling =0 }; static uint8_t rb_push(volatile rb *ring, const uint8_t data) {   if (((ring->tail + 1) % ring->size) != ring->head)   {     ring->data[ring->tail++] = data;     ring->tail %= ring->size;     ring->length++;     return 1;   }   return 0; }   static uint8_t rb_pop(volatile rb *ring, uint8_t *data) {   if (ring->head != ring->tail)   {     *data = ring->data[ring->head++];     ring->head %= ring->size;     ring->length--;     return 1;   }   return 0; }   static void usart_transmit(volatile rb *ring, const char *str){         while (*str != '\\000') {                 rb_push(ring, (uint8_t)*str);                 str++;         }         usart_enable_tx_interrupt(USART2); }     static void parse_cmd(volatile rb *ring, cmd *cli){         uint8_t data = 0;         while(rb_pop(ring, &amp;data)){                 if(data == 0x0D){ \/\/ \\r char                         cli->assembling = 0;                         break;                 } else {                                 cli->assembling = 1;                                 cli->cmd_code ^= data;                 }         }         if (!cli->assembling){                 switch(cli->cmd_code){                         case 0x20: \/\/ \"toggle_led\" cmd                                 gpio_toggle(GPIOC, GPIO13);                                 break;                         case 0x56: \/\/ \"say_hello\" cmd                                 usart_transmit(&amp;tx_rb, \"Hello from LibOpenCm3!\\n\");                                 break;                         default:                                 break;                 }                 cli->cmd_code = 0;                 cli->assembling = 1;         } }   static uint32_t  dwt_setup(void) {         dwt_enable_cycle_counter();         __asm volatile (\"nop\");         __asm volatile (\"nop\");         __asm volatile (\"nop\");        if(dwt_read_cycle_counter())      {        return 0;      }      else   {     return 1;   } }   static void dwt_delay_us(uint32_t microseconds) {         uint32_t initial_ticks = dwt_read_cycle_counter();         uint32_t us_count_tics = microseconds * (rcc_ahb_frequency \/ 1000000);         while ((dwt_read_cycle_counter() - initial_ticks) &lt; us_count_tics); }     int main(void) {         clock_setup();         dwt_setup();         nvic_enable_irq(NVIC_USART2_IRQ); \/\/\u0412\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439 \u0434\u043b\u044f USART2         nvic_set_priority(NVIC_USART2_IRQ, 1); \/\/\u041e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e, \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0435\u043c \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f.         gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO2);         gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, GPIO3);           gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_10_MHZ,  GPIO_CNF_OUTPUT_PUSHPULL, GPIO13);         gpio_set(GPIOC, GPIO13);             usart_set_baudrate(USART2, 9600);         usart_set_databits(USART2, 8);         usart_set_stopbits(USART2, USART_STOPBITS_1);         usart_set_parity(USART2, USART_PARITY_NONE);         usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE);         usart_set_mode(USART2, USART_MODE_TX_RX);         usart_enable_rx_interrupt(USART2);         usart_enable(USART2);           usart_transmit(&amp;tx_rb, \"Startup\\r\\n\");           while(1){                 dwt_delay_us(1000);                 if(rx_rb.length > 0){                         parse_cmd(&amp;rx_rb, &amp;cli_cmd);                 }         } } void usart2_isr(void){                 uint8_t data = 0;         if (usart_get_flag(USART2, USART_SR_TXE)) {                 if(rb_pop(&amp;tx_rb, &amp;data)){                         usart_send(USART2, data);                 } else {                         usart_disable_tx_interrupt(USART2);                 }         }           if (usart_get_flag(USART2, USART_SR_RXNE)) {                 data = (uint8_t)usart_recv(USART2);                 rb_push(&amp;rx_rb, data);                 if (data == 0x0D){                         usart_send(USART2, 0x0A);                 } else {                         usart_send(USART2, data);                 }         } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>STM32F4<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#include &lt;libopencm3\/stm32\/rcc.h> #include &lt;libopencm3\/cm3\/nvic.h> #include &lt;libopencm3\/stm32\/usart.h> #include &lt;libopencm3\/stm32\/gpio.h> #include &lt;libopencm3\/cm3\/dwt.h> #include \"ex3_2_usart_irq.h\" #define BUF_SIZE 128   static void clock_setup(void) {         rcc_clock_setup_pll(&amp;rcc_hse_25mhz_3v3[RCC_CLOCK_3V3_96MHZ]);         rcc_periph_clock_enable(RCC_GPIOA);         rcc_periph_clock_enable(RCC_GPIOC);         rcc_periph_clock_enable(RCC_USART2); }   uint8_t tx_buffer[BUF_SIZE] = {}; uint8_t rx_buffer[BUF_SIZE] = {};   typedef struct {   uint8_t *data;   uint32_t size;   uint32_t head;   uint32_t tail;   uint32_t length; } rb;   typedef struct {         uint8_t cmd_code;         uint8_t assembling; } cmd;   volatile rb tx_rb = {   .data = tx_buffer,   .size = sizeof(tx_buffer),   .head = 0,   .tail = 0,   .length = 0 };   volatile rb rx_rb = {   .data = rx_buffer,   .size = sizeof(rx_buffer),   .head = 0,   .tail = 0,   .length = 0 };   cmd cli_cmd = {   .cmd_code = 0,   .assembling =0 };   static uint8_t rb_push(volatile rb *ring, const uint8_t data) {   if (((ring->tail + 1) % ring->size) != ring->head)   {     ring->data[ring->tail++] = data;     ring->tail %= ring->size;     ring->length++;     return 1;   }   return 0; } static uint8_t rb_pop(volatile rb *ring, uint8_t *data) {   if (ring->head != ring->tail)   {     *data = ring->data[ring->head++];     ring->head %= ring->size;     ring->length--;     return 1;   }   return 0; }   static void usart_transmit(volatile rb *ring, const char *str){         while (*str != '\\000') {                 rb_push(ring, (uint8_t)*str);                 str++;         }         usart_enable_tx_interrupt(USART2); }     static void parse_cmd(volatile rb *ring, cmd *cli){         uint8_t data = 0;         while(rb_pop(ring, &amp;data)){                 if(data == 0x0D){ \/\/ \\r char                         cli->assembling = 0;                         break;                 } else {                                 cli->assembling = 1;                                 cli->cmd_code ^= data;                 }         }         if (!cli->assembling){                 switch(cli->cmd_code){                         case 0x20: \/\/ \"toggle_led\" cmd                                 gpio_toggle(GPIOC, GPIO13);                                 break;                         case 0x56: \/\/ \"say_hello\" cmd                                 usart_transmit(&amp;tx_rb, \"Hello from LibOpenCm3!\\n\");                                 break;                         default:                                 break;                 }                 cli->cmd_code = 0;                 cli->assembling = 1;         } }   static uint32_t  dwt_setup(void) {         dwt_enable_cycle_counter();         __asm volatile (\"nop\");         __asm volatile (\"nop\");         __asm volatile (\"nop\");        if(dwt_read_cycle_counter())      {        return 0;      }      else   {     return 1;   } } static void dwt_delay_us(uint32_t microseconds) {         uint32_t initial_ticks = dwt_read_cycle_counter();         uint32_t us_count_tics = microseconds * (rcc_ahb_frequency \/ 1000000);         while ((dwt_read_cycle_counter() - initial_ticks) &lt; us_count_tics); }   int main(void) {         clock_setup();         dwt_setup();         nvic_enable_irq(NVIC_USART2_IRQ); \/\/\u0412\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439 \u0434\u043b\u044f USART         nvic_set_priority(NVIC_USART2_IRQ, 1); \/\/\u041e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e, \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0435\u043c \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f.         gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO2 | GPIO3);         gpio_set_af(GPIOA, GPIO_AF7, GPIO2 | GPIO3);           gpio_mode_setup(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO13);         gpio_set(GPIOC, GPIO13);           usart_set_baudrate(USART2, 9600);         usart_set_databits(USART2, 8);         usart_set_stopbits(USART2, USART_STOPBITS_1);         usart_set_parity(USART2, USART_PARITY_NONE);         usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE);         usart_set_mode(USART2, USART_MODE_TX_RX);         usart_enable_rx_interrupt(USART2);         usart_enable(USART2);           usart_transmit(&amp;tx_rb, \"Startup\\r\\n\");           while(1){                 dwt_delay_us(1000);                 if(rx_rb.length > 0){                         parse_cmd(&amp;rx_rb, &amp;cli_cmd);                 }         } }   void usart2_isr(void){         uint8_t data = 0;         if (usart_get_flag(USART2, USART_SR_TXE)) {                 if(rb_pop(&amp;tx_rb, &amp;data)){                         usart_send(USART2, data);                 } else {                         usart_disable_tx_interrupt(USART2);                 }         }           if (usart_get_flag(USART2, USART_SR_RXNE)) {                 data = (uint8_t)usart_recv(USART2);                 rb_push(&amp;rx_rb, data);                 if (data == 0x0D){                         usart_send(USART2, 0x0A);                 } else {                         usart_send(USART2, data);                 }         } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c<\/p>\n<pre><code>$ cu -l \/dev\/ttyUSB0 -s 9600 Connected. Startup say_hello Hello from LibOpenCm3! toggle_led<\/code><\/pre>\n<h3>\u0427\u0435\u0442\u0432\u0451\u0440\u0442\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442: \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 I2C<\/h3>\n<p>\u0418\u0434\u0435\u043c \u0434\u0430\u043b\u0435\u0435, \u0438 \u0443 \u043d\u0430\u0441 \u043d\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u0434\u043b\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u043e\u0431\u043e\u0440\u0443\u0434\u043e\u0432\u0430\u043d\u0438\u0435\u043c: I2C.<\/p>\n<p><strong>\u0426\u0435\u043b\u044c: \u0412\u044b\u0432\u0435\u0441\u0442\u0438 \u043d\u0430 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0439 LCD \u044d\u043a\u0440\u0430\u043d 1602, \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044b\u043c \u0447\u0435\u0440\u0435\u0437 \u043c\u043e\u0434\u0443\u043b\u044c \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u0435\u043b\u044c GPIO \u043f\u043e\u0440\u0442\u043e\u0432 PCF8574.<\/strong><\/p>\n<p>\u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442:<\/p>\n<pre><code>.\/make_project.sh ex4_i2c<\/code><\/pre>\n<ul>\n<li>\n<p>\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u0447\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u043e\u0442\u043d\u043e\u0441\u044f\u0449\u0438\u0435\u0441\u044f \u0432 I2C<\/p>\n<\/li>\n<li>\n<p>\u0412\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0442\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u0440\u0442\u0430, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u044b \u043f\u0438\u043d\u044b, \u0442\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0431\u043b\u043e\u043a\u0430 AFIO \u0438 \u0431\u043b\u043e\u043a\u0430 I2C<\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>STM32F1<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#include &lt;libopencm3\/stm32\/rcc.h> #include &lt;libopencm3\/stm32\/gpio.h> #include &lt;libopencm3\/stm32\/i2c.h> #include \"ex4_i2c.h\"   static void clock_setup(void) {         rcc_clock_setup_pll(&amp;rcc_hse_configs[RCC_CLOCK_HSE8_72MHZ]);         rcc_periph_clock_enable(RCC_GPIOB);         rcc_periph_clock_enable(RCC_AFIO);         rcc_periph_clock_enable(RCC_I2C1); }   int main(void) {         clock_setup();         gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ , GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN , GPIO8 | GPIO9);         gpio_primary_remap(AFIO_MAPR_SWJ_CFG_FULL_SWJ, AFIO_MAPR_I2C1_REMAP);           i2c_peripheral_disable(I2C1);         i2c_set_own_7bit_slave_address(I2C1, 0x00);         i2c_set_speed(I2C1, i2c_speed_sm_100k, rcc_apb1_frequency\/1000000);         i2c_peripheral_enable(I2C1);         while(1){           } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>STM32F4<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#include &lt;libopencm3\/stm32\/rcc.h> #include &lt;libopencm3\/stm32\/gpio.h> #include &lt;libopencm3\/stm32\/i2c.h> #include \"ex4_i2c.h\"   static void clock_setup(void) {         rcc_clock_setup_pll(&amp;rcc_hse_25mhz_3v3[RCC_CLOCK_3V3_96MHZ]);         rcc_periph_clock_enable(RCC_GPIOB);         rcc_periph_clock_enable(RCC_I2C1); } int main(void) {         clock_setup();         gpio_mode_setup(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO8 | GPIO9);         gpio_set_output_options(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, GPIO8 | GPIO9);         gpio_set_af(GPIOB, GPIO_AF4, GPIO8 | GPIO9);           i2c_peripheral_disable(I2C1);         i2c_set_own_7bit_slave_address(I2C1, 0x00);         i2c_set_speed(I2C1, i2c_speed_sm_100k, rcc_apb1_frequency\/1000000);         i2c_peripheral_enable(I2C1);         while(1){           } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041d\u0430\u0448 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u0433\u043e\u0442\u043e\u0432 \u043a \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0447\u0435\u0440\u0435\u0445 I2C. \u0414\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u0447\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 i2c_transfer7(). \u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0441\u043b\u0443\u0436\u0435\u0431\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0434\u0438\u0441\u043f\u043b\u0435\u0435\u043c 1602, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0435\u0451.<\/p>\n<pre><code class=\"cpp\">#define LCD1602_ADDR 0x3F #define LCD1602_BACKLIGHT 0x08 #define LCD1602_ENABLE 0x04 #define LCD1602_WIDTH 20   \/\/ Maximum characters per line #define LCD1602_CHR  1 \/\/ Mode - Sending data #define LCD1602_CMD  0 \/\/ Mode - Sending command #define LCD1602_LINE_1  0x80 \/\/ LCD RAM address for the 1st line #define LCD1602_LINE_2  0xC0 \/\/ LCD RAM address for the 2nd lin   static void lcd1602_write_byte(uint32_t i2c, uint8_t byte, uint8_t flag){         uint8_t transaction[6] = {0};         transaction[0] = (flag | (byte &amp; 0xF0) | LCD1602_BACKLIGHT);         transaction[1] = ((flag | (byte &amp; 0xF0) | LCD1602_BACKLIGHT) | LCD1602_ENABLE);         transaction[2] = ((flag | (byte &amp; 0xF0) | LCD1602_BACKLIGHT) &amp; ~LCD1602_ENABLE);           transaction[3] = (flag | ((byte&lt;&lt;4) &amp; 0xF0) | LCD1602_BACKLIGHT);         transaction[4] = ((flag | ((byte&lt;&lt;4) &amp; 0xF0) | LCD1602_BACKLIGHT) | LCD1602_ENABLE );         transaction[5] = ((flag | ((byte&lt;&lt;4) &amp; 0xF0) | LCD1602_BACKLIGHT) &amp; ~LCD1602_ENABLE);           for(uint8_t i = 0; i &lt; 6; i++){                 i2c_transfer7(i2c, LCD1602_ADDR, &amp;transaction[i], 1, NULL, 0);         } }   static void lcd1602_init(uint32_t i2c){         lcd1602_write_byte(i2c, 0x33, LCD1602_CMD); \/\/ 110011 Initialise         lcd1602_write_byte(i2c, 0x32, LCD1602_CMD); \/\/ 110010 Initialise         lcd1602_write_byte(i2c, 0x06, LCD1602_CMD); \/\/ 000110 Cursor move direction         lcd1602_write_byte(i2c, 0x0C, LCD1602_CMD); \/\/ 001100 Display On,Cursor Off, Blink Off         lcd1602_write_byte(i2c, 0x28, LCD1602_CMD); \/\/ 101000 Data length, number of lines, font size         lcd1602_write_byte(i2c, 0x01, LCD1602_CMD); \/\/ 000001 Clear display }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u0443\u0435\u043c \u0432\u0441\u0435 \u0447\u0430\u0441\u0442\u0438 \u0432 \u0435\u0434\u0438\u043d\u043e\u0435 \u0446\u0435\u043b\u043e\u0435.  <\/p>\n<details class=\"spoiler\">\n<summary>STM32F1<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#include &lt;libopencm3\/stm32\/rcc.h> #include &lt;libopencm3\/stm32\/gpio.h> #include &lt;libopencm3\/stm32\/i2c.h> #include \"ex4_i2c.h\"   #define LCD1602_ADDR 0x3F #define LCD1602_BACKLIGHT 0x08 #define LCD1602_ENABLE 0x04 #define LCD1602_WIDTH 20   \/\/ 20 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u043d\u0430 \u043b\u0438\u043d\u0438\u044e #define LCD1602_CHR  1 \/\/ \u0420\u0435\u0436\u0438\u043c \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 #define LCD1602_CMD  0 \/\/ \u0420\u0435\u0436\u0438\u043c \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043a\u043e\u043c\u0430\u043d\u0434 #define LCD1602_LINE_1  0x80 \/\/ LCD RAM \u0430\u0434\u0440\u0435\u0441 \u043f\u0435\u0440\u0432\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 #define LCD1602_LINE_2  0xC0 \/\/ LCD RAM \u0430\u0434\u0440\u0435\u0441 \u0432\u0442\u043e\u0440\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438   static void clock_setup(void) {         rcc_clock_setup_pll(&amp;rcc_hse_configs[RCC_CLOCK_HSE8_72MHZ]);         rcc_periph_clock_enable(RCC_GPIOB);         rcc_periph_clock_enable(RCC_AFIO);         rcc_periph_clock_enable(RCC_I2C1); }   static void lcd1602_write_byte(uint32_t i2c, uint8_t byte, uint8_t flag){         uint8_t transaction[6] = {0};         transaction[0] = (flag | (byte &amp; 0xF0) | LCD1602_BACKLIGHT);         transaction[1] = ((flag | (byte &amp; 0xF0) | LCD1602_BACKLIGHT) | LCD1602_ENABLE);         transaction[2] = ((flag | (byte &amp; 0xF0) | LCD1602_BACKLIGHT) &amp; ~LCD1602_ENABLE);           transaction[3] = (flag | ((byte&lt;&lt;4) &amp; 0xF0) | LCD1602_BACKLIGHT);         transaction[4] = ((flag | ((byte&lt;&lt;4) &amp; 0xF0) | LCD1602_BACKLIGHT) | LCD1602_ENABLE );         transaction[5] = ((flag | ((byte&lt;&lt;4) &amp; 0xF0) | LCD1602_BACKLIGHT) &amp; ~LCD1602_ENABLE);           for(uint8_t i = 0; i &lt; 6; i++){                 i2c_transfer7(i2c, LCD1602_ADDR, &amp;transaction[i], 1, NULL, 0);         } }   static void lcd1602_init(uint32_t i2c){         lcd1602_write_byte(i2c, 0x33, LCD1602_CMD); \/\/ 110011 Initialise         lcd1602_write_byte(i2c, 0x32, LCD1602_CMD); \/\/ 110010 Initialise         lcd1602_write_byte(i2c, 0x06, LCD1602_CMD); \/\/ 000110 Cursor move direction         lcd1602_write_byte(i2c, 0x0C, LCD1602_CMD); \/\/ 001100 Display On,Cursor Off, Blink Off         lcd1602_write_byte(i2c, 0x28, LCD1602_CMD); \/\/ 101000 Data length, number of lines, font size         lcd1602_write_byte(i2c, 0x01, LCD1602_CMD); \/\/ 000001 Clear display }   int main(void) {         clock_setup();         gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ , GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN , GPIO8 | GPIO9);         gpio_primary_remap(AFIO_MAPR_SWJ_CFG_FULL_SWJ, AFIO_MAPR_I2C1_REMAP);           i2c_peripheral_disable(I2C1);         i2c_set_own_7bit_slave_address(I2C1, 0x00);         i2c_set_speed(I2C1, i2c_speed_sm_100k, rcc_apb1_frequency\/1000000);         i2c_peripheral_enable(I2C1);           lcd1602_init(I2C1);         lcd1602_write_byte(I2C1, ((LCD1602_LINE_1) | ((0x00) &amp; 0x0f)), LCD1602_CMD);           const char msg[15] = \"Hi!\";         lcd1602_write_byte(I2C1, (uint8_t)msg[0], LCD1602_CHR);         lcd1602_write_byte(I2C1, (uint8_t)msg[1], LCD1602_CHR);         lcd1602_write_byte(I2C1, (uint8_t)msg[2], LCD1602_CHR);         while(1){           } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>STM32F4<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#include &lt;libopencm3\/stm32\/rcc.h> #include &lt;libopencm3\/stm32\/gpio.h> #include &lt;libopencm3\/stm32\/i2c.h> #include \"ex4_i2c.h\"   #define LCD1602_ADDR 0x3F #define LCD1602_BACKLIGHT 0x08 #define LCD1602_ENABLE 0x04 #define LCD1602_WIDTH 20   \/\/ 20 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u043d\u0430 \u043b\u0438\u043d\u0438\u044e #define LCD1602_CHR  1 \/\/ \u0420\u0435\u0436\u0438\u043c \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 #define LCD1602_CMD  0 \/\/ \u0420\u0435\u0436\u0438\u043c \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043a\u043e\u043c\u0430\u043d\u0434 #define LCD1602_LINE_1  0x80 \/\/ LCD RAM \u0430\u0434\u0440\u0435\u0441 \u043f\u0435\u0440\u0432\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 #define LCD1602_LINE_2  0xC0 \/\/ LCD RAM \u0430\u0434\u0440\u0435\u0441 \u0432\u0442\u043e\u0440\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438     static void clock_setup(void) {         rcc_clock_setup_pll(&amp;rcc_hse_25mhz_3v3[RCC_CLOCK_3V3_96MHZ]);         rcc_periph_clock_enable(RCC_GPIOB);         rcc_periph_clock_enable(RCC_I2C1); }   static void lcd1602_write_byte(uint32_t i2c, uint8_t byte, uint8_t flag){         uint8_t transaction[6] = {0};         transaction[0] = (flag | (byte &amp; 0xF0) | LCD1602_BACKLIGHT);         transaction[1] = ((flag | (byte &amp; 0xF0) | LCD1602_BACKLIGHT) | LCD1602_ENABLE);         transaction[2] = ((flag | (byte &amp; 0xF0) | LCD1602_BACKLIGHT) &amp; ~LCD1602_ENABLE);           transaction[3] = (flag | ((byte&lt;&lt;4) &amp; 0xF0) | LCD1602_BACKLIGHT);         transaction[4] = ((flag | ((byte&lt;&lt;4) &amp; 0xF0) | LCD1602_BACKLIGHT) | LCD1602_ENABLE );         transaction[5] = ((flag | ((byte&lt;&lt;4) &amp; 0xF0) | LCD1602_BACKLIGHT) &amp; ~LCD1602_ENABLE);           for(uint8_t i = 0; i &lt; 6; i++){                 i2c_transfer7(i2c, LCD1602_ADDR, &amp;transaction[i], 1, NULL, 0);         } }   static void lcd1602_init(uint32_t i2c){         lcd1602_write_byte(i2c, 0x33, LCD1602_CMD); \/\/ 110011 Initialise         lcd1602_write_byte(i2c, 0x32, LCD1602_CMD); \/\/ 110010 Initialise         lcd1602_write_byte(i2c, 0x06, LCD1602_CMD); \/\/ 000110 Cursor move direction         lcd1602_write_byte(i2c, 0x0C, LCD1602_CMD); \/\/ 001100 Display On,Cursor Off, Blink Off         lcd1602_write_byte(i2c, 0x28, LCD1602_CMD); \/\/ 101000 Data length, number of lines, font size         lcd1602_write_byte(i2c, 0x01, LCD1602_CMD); \/\/ 000001 Clear display }   int main(void) {         clock_setup();         gpio_mode_setup(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO8 | GPIO9);         gpio_set_output_options(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, GPIO8 | GPIO9);         gpio_set_af(GPIOB, GPIO_AF4, GPIO8 | GPIO9);           i2c_peripheral_disable(I2C1);         i2c_set_own_7bit_slave_address(I2C1, 0x00);         i2c_set_speed(I2C1, i2c_speed_sm_100k, rcc_apb1_frequency\/1000000);         i2c_peripheral_enable(I2C1);           lcd1602_init(I2C1);         lcd1602_write_byte(I2C1, ((LCD1602_LINE_1) | ((0x00) &amp; 0x0f)), LCD1602_CMD);           const char msg[15] = \"Hi!\";         lcd1602_write_byte(I2C1, (uint8_t)msg[0], LCD1602_CHR);         lcd1602_write_byte(I2C1, (uint8_t)msg[1], LCD1602_CHR);         lcd1602_write_byte(I2C1, (uint8_t)msg[2], LCD1602_CHR);         while(1){           } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u0440\u043e\u0448\u0438\u0432\u0430\u0435\u043c \u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u044d\u043a\u0440\u0430\u043d\u0447\u0438\u043a.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/06e\/e35\/ab2\/06ee35ab216d66b345fffd56633cccee.png\" alt=\"\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u0435\u043b\u044f GPIO PCF8574 \u043a \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0443 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 BluePill. \u041e\u0431\u0432\u044f\u0437\u043a\u0430 PCF8574 \u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044b\u0439 \u043a \u043d\u0435\u0439 \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u043e\u043f\u0443\u0449\u0435\u043d\u0430\" title=\"\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u0435\u043b\u044f GPIO PCF8574 \u043a \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0443 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 BluePill. \u041e\u0431\u0432\u044f\u0437\u043a\u0430 PCF8574 \u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044b\u0439 \u043a \u043d\u0435\u0439 \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u043e\u043f\u0443\u0449\u0435\u043d\u0430\" width=\"456\" height=\"552\" data-src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/06e\/e35\/ab2\/06ee35ab216d66b345fffd56633cccee.png\"\/><\/p>\n<div><figcaption>\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u0435\u043b\u044f GPIO PCF8574 \u043a \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0443 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 BluePill. \u041e\u0431\u0432\u044f\u0437\u043a\u0430 PCF8574 \u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044b\u0439 \u043a \u043d\u0435\u0439 \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u043e\u043f\u0443\u0449\u0435\u043d\u0430<\/figcaption><\/div>\n<\/figure>\n<p>\u041d\u0430 \u043d\u0435\u043c \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u0443\u0434\u0435\u043c \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u00abHi!\u00bb.<\/p>\n<h3>\u041f\u044f\u0442\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442: \u0422\u0430\u0439\u043c\u0435\u0440\u044b<\/h3>\n<p>\u041b\u044e\u0431\u043e\u043c\u0443, \u043a\u0442\u043e \u0438\u043c\u0435\u043b \u0434\u0435\u043b\u043e \u0441 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u043e\u0432, \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e, \u0447\u0442\u043e \u0442\u0430\u0439\u043c\u0435\u0440\u044b \u2013 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0447\u0430\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u0435 \u043e\u0431\u043e\u0440\u0443\u0434\u043e\u0432\u0430\u043d\u0438\u0435. \u0418\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0437\u0430\u0434\u0435\u0440\u0436\u0435\u043a, \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 PWM \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432, \u0432\u044b\u0437\u043e\u0432\u0430 \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440, \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u044d\u043d\u043a\u043e\u0434\u0435\u0440\u0430\u043c\u0438 \u0438 \u043c\u043d\u043e\u0433\u043e\u0433\u043e \u0434\u0440\u0443\u0433\u043e\u0433\u043e.<\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0442\u0440\u0438 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u0430\u0439\u043c\u0435\u0440\u0430:<\/p>\n<ul>\n<li>\n<p>\u0422\u0430\u0439\u043c\u0435\u0440 \u0434\u043b\u044f \u0432\u044b\u0437\u043e\u0432\u0430 \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440<\/p>\n<\/li>\n<li>\n<p>\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f PWM \u0441\u0438\u0433\u043d\u0430\u043b\u0430<\/p>\n<\/li>\n<li>\n<p>\u0421\u0447\u0438\u0442\u044b\u0432\u0430\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u044d\u043d\u043a\u043e\u0434\u0435\u0440\u0430<\/p>\n<\/li>\n<\/ul>\n<p><u>\u0422\u0430\u0439\u043c\u0435\u0440 \u0434\u043b\u044f \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u043e\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0439<\/u><\/p>\n<p><strong>\u0426\u0435\u043b\u044c: \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0442\u0430\u0439\u043c\u0435\u0440 \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f \u043c\u043e\u0440\u0433\u0430\u043b \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434\u043e\u043c \u043d\u0430 \u043f\u043b\u0430\u0442\u0435 \u0441 \u0447\u0430\u0441\u0442\u043e\u0442\u043e\u0439 100 \u0413\u0435\u0440\u0446.<\/strong><\/p>\n<ul>\n<li>\n<p>\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u0447\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0442\u0430\u0439\u043c\u0435\u0440\u043e\u043c, GPIO, \u0438 NVIC \u0434\u043b\u044f \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439;<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c \u043d\u043e\u0436\u043a\u0443 PC13 \u043d\u0430 \u0432\u044b\u0445\u043e\u0434;<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c \u0434\u0435\u043b\u0438\u0442\u0435\u043b\u044c \u0442\u0430\u043a\u0442\u043e\u0432\u043e\u0433\u043e \u0441\u0438\u0433\u043d\u0430\u043b\u0430 (\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0440\u0430\u0432\u0435\u043d 72 \u041c\u0433\u0446 \u0434\u043b\u044f STM32F1 \u0438 96 \u041c\u0413\u0446 \u0434\u043b\u044f STM32F4) \u0434\u043b\u044f \u0442\u0430\u0439\u043c\u0435\u0440\u0430 TIM3, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0447\u0430\u0441\u0442\u043e\u0442\u0443 \u0441\u0447\u0435\u0442\u0430 2 \u041c\u0433\u0446;<\/p>\n<\/li>\n<li>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0437\u0430\u0434\u0430\u0435\u043c \u043f\u0435\u0440\u0438\u043e\u0434 \u0432 10000, \u0447\u0442\u043e \u0432\u044b\u0437\u043e\u0432\u0435\u0442 \u043f\u0435\u0440\u0435\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0442\u0430\u0439\u043c\u0435\u0440\u0430 \u0441 \u0447\u0430\u0441\u0442\u043e\u0442\u043e\u0439 200 \u0413\u0435\u0440\u0446;<\/p>\n<\/li>\n<li>\n<p>\u0410\u043a\u0442\u0438\u0432\u0438\u0440\u0443\u0435\u043c \u0432\u044b\u0437\u043e\u0432 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f \u043f\u043e \u043f\u0435\u0440\u0435\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044e;<\/p>\n<\/li>\n<li>\n<p>\u0412 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0435 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0438\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u0438\u043d\u0430 PC13, \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u043a \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434\u0443.<\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>STM32F1<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#include &lt;libopencm3\/stm32\/rcc.h> #include &lt;libopencm3\/stm32\/gpio.h> #include &lt;libopencm3\/stm32\/timer.h> #include &lt;libopencm3\/cm3\/nvic.h> #include \"ex5_1_timer.h\"   static void clock_setup(void) {         rcc_clock_setup_pll(&amp;rcc_hse_configs[RCC_CLOCK_HSE8_72MHZ]);         rcc_periph_clock_enable(RCC_GPIOC);         rcc_periph_clock_enable(RCC_TIM3); }   int main(void) {         clock_setup();           gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO13);           rcc_periph_reset_pulse(RST_TIM3);         timer_set_mode(TIM3, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);         timer_continuous_mode(TIM3);         timer_set_prescaler(TIM3, 36-1); \/\/72 Mhz \/ 36 = 2 Mhz         timer_set_period(TIM3, 10000-1); \/\/ 2 Mhz \/ 10000 = 200 Hz         timer_disable_preload(TIM3);         timer_enable_irq(TIM3, TIM_DIER_UIE);         timer_enable_counter(TIM3);         nvic_enable_irq(NVIC_TIM3_IRQ);           while(1){         } }   void tim3_isr(){         if (timer_interrupt_source(TIM3, TIM_SR_UIF)) {                 timer_clear_flag(TIM3, TIM_SR_UIF);                 gpio_toggle(GPIOC, GPIO13);         } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>STM32F4<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#include &lt;libopencm3\/stm32\/rcc.h> #include &lt;libopencm3\/stm32\/gpio.h> #include &lt;libopencm3\/stm32\/timer.h> #include &lt;libopencm3\/cm3\/nvic.h> #include \"ex5_1_timer.h\"  static void clock_setup(void) {         rcc_clock_setup_pll(&amp;rcc_hse_25mhz_3v3[RCC_CLOCK_3V3_96MHZ]);         rcc_periph_clock_enable(RCC_GPIOC);         rcc_periph_clock_enable(RCC_TIM3); }  int main(void) {         clock_setup();          gpio_mode_setup(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO13);          rcc_periph_reset_pulse(RST_TIM3);         timer_set_mode(TIM3, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);         timer_continuous_mode(TIM3);         timer_set_prescaler(TIM3, 48-1); \/\/96 Mhz \/ 48 = 2 Mhz         timer_set_period(TIM3, 10000-1); \/\/ 2 Mhz \/ 10000 = 200 Hz         timer_disable_preload(TIM3);         timer_enable_irq(TIM3, TIM_DIER_UIE);         timer_enable_counter(TIM3);         nvic_enable_irq(NVIC_TIM3_IRQ);          while(1){         } }  void tim3_isr(){         if (timer_interrupt_source(TIM3, TIM_SR_UIF)) {                 timer_clear_flag(TIM3, TIM_SR_UIF);                 gpio_toggle(GPIOC, GPIO13);         } }<\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a33\/8e9\/aae\/a338e9aae3434a518ca40324719c720e.png\" alt=\"\u041b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044b\u0439 \u043a \u043d\u043e\u0436\u043a\u0435 PC13\" title=\"\u041b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044b\u0439 \u043a \u043d\u043e\u0436\u043a\u0435 PC13\" width=\"802\" height=\"447\" data-src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a33\/8e9\/aae\/a338e9aae3434a518ca40324719c720e.png\"\/><\/p>\n<div><figcaption>\u041b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044b\u0439 \u043a \u043d\u043e\u0436\u043a\u0435 PC13<\/figcaption><\/div>\n<\/figure>\n<\/div>\n<\/details>\n<p><u>\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f PWM \u0441\u0438\u0433\u043d\u0430\u043b\u0430<\/u><\/p>\n<p><strong>\u0426\u0435\u043b\u044c: \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0442\u0430\u0439\u043c\u0435\u0440 \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u043b \u0432\u044b\u0432\u043e\u0434 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 \u0441 \u0447\u0430\u0441\u0442\u043e\u0442\u043e\u0439 100 \u0413\u0435\u0440\u0446 \u0438 \u0441\u043a\u0432\u0430\u0436\u043d\u043e\u0441\u0442\u044c\u044e 0.25.<\/strong><\/p>\n<p>\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u044f:<\/p>\n<ul>\n<li>\n<p>\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u0447\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0442\u0430\u0439\u043c\u0435\u0440\u043e\u043c, GPIO;<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c \u043d\u043e\u0436\u043a\u0443 PA6 \u043a\u0430\u043a \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e;<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c \u0434\u0435\u043b\u0438\u0442\u0435\u043b\u044c \u0442\u0430\u043a\u0442\u043e\u0432\u043e\u0433\u043e \u0441\u0438\u0433\u043d\u0430\u043b\u0430 (\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0440\u0430\u0432\u0435\u043d 72 \u041c\u0433\u0446 \u0434\u043b\u044f STM32F1 \u0438 96 \u041c\u0413\u0446 \u0434\u043b\u044f STM32F4) \u0434\u043b\u044f \u0442\u0430\u0439\u043c\u0435\u0440\u0430 TIM3, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0447\u0430\u0441\u0442\u043e\u0442\u0443 \u0441\u0447\u0435\u0442\u0430 2 \u041c\u0433\u0446;<\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u0434\u0430\u0435\u043c \u043f\u0435\u0440\u0438\u043e\u0434 \u0432 20000, \u0447\u0442\u043e \u0432\u044b\u0437\u043e\u0432\u0435\u0442 \u043f\u0435\u0440\u0435\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0442\u0430\u0439\u043c\u0435\u0440\u0430 \u0441 \u0447\u0430\u0441\u0442\u043e\u0442\u043e\u0439 100 \u0413\u0435\u0440\u0446;<\/p>\n<\/li>\n<li>\n<p>\u0410\u043a\u0442\u0438\u0432\u0438\u0440\u0443\u0435\u043c \u0440\u0435\u0436\u0438\u043c PWM1;<\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u0434\u0430\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043f\u0440\u0438 \u0434\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0435\u0442 \u0441\u043e\u0431\u044b\u0442\u0438\u0435. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 5000;<\/p>\n<\/li>\n<li>\n<p>\u0412\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u043e\u043c OC1;<\/p>\n<\/li>\n<li>\n<p>\u0412\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0441\u0430\u043c \u0441\u0447\u0435\u0442\u0447\u0438\u043a.<\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>STM32F1<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#include &lt;libopencm3\/stm32\/rcc.h> #include &lt;libopencm3\/stm32\/gpio.h> #include &lt;libopencm3\/stm32\/timer.h> #include \"ex5_2_timer.h\"   static void clock_setup(void) {         rcc_clock_setup_pll(&amp;rcc_hse_configs[RCC_CLOCK_HSE8_72MHZ]);         rcc_periph_clock_enable(RCC_GPIOA);         rcc_periph_clock_enable(RCC_TIM3); }   int main(void) {         clock_setup();           gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO6);           rcc_periph_reset_pulse(RST_TIM3);         timer_set_mode(TIM3, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);         timer_continuous_mode(TIM3);         timer_set_prescaler(TIM3, 36-1); \/\/72 Mhz \/ 36 = 2 Mhz         timer_set_period(TIM3, 20000-1); \/\/ 2 Mhz \/ 20000 = 100 Hz           timer_set_oc_mode(TIM3, TIM_OC1, TIM_OCM_PWM1);         timer_set_oc_value(TIM3, TIM_OC1, 5000-1);         timer_enable_oc_output(TIM3, TIM_OC1);           timer_set_counter(TIM3, 0);         timer_enable_preload(TIM3);         timer_enable_counter(TIM3);           while(1){         } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>STM32F4<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#include &lt;libopencm3\/stm32\/rcc.h> #include &lt;libopencm3\/stm32\/gpio.h> #include &lt;libopencm3\/stm32\/timer.h> #include \"ex5_2_timer.h\"  static void clock_setup(void) {         rcc_clock_setup_pll(&amp;rcc_hse_25mhz_3v3[RCC_CLOCK_3V3_96MHZ]);         rcc_periph_clock_enable(RCC_GPIOA);         rcc_periph_clock_enable(RCC_TIM3); }  int main(void) {         clock_setup();          gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO6);         gpio_set_output_options(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO6);         gpio_set_af(GPIOA, GPIO_AF2, GPIO6);          rcc_periph_reset_pulse(RST_TIM3);         timer_set_mode(TIM3, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);         timer_continuous_mode(TIM3);         timer_set_prescaler(TIM3, 48-1); \/\/96 Mhz \/ 48 = 2 Mhz         timer_set_period(TIM3, 20000-1); \/\/ 2 Mhz \/ 20000 = 100 Hz          timer_set_oc_mode(TIM3, TIM_OC1, TIM_OCM_PWM1);         timer_set_oc_value(TIM3, TIM_OC1, 5000-1);         timer_enable_oc_output(TIM3, TIM_OC1);          timer_set_counter(TIM3, 0);         timer_enable_preload(TIM3);         timer_enable_counter(TIM3);         while(1); }<\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/839\/1a1\/231\/8391a123157f54894006cc240e8b57de.png\" alt=\"\u041b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044b\u0439 \u043a \u043f\u0438\u043d\u0443 PA6\" title=\"\u041b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044b\u0439 \u043a \u043f\u0438\u043d\u0443 PA6\" width=\"802\" height=\"447\" data-src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/839\/1a1\/231\/8391a123157f54894006cc240e8b57de.png\"\/><\/p>\n<div><figcaption>\u041b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044b\u0439 \u043a \u043f\u0438\u043d\u0443 PA6<\/figcaption><\/div>\n<\/figure>\n<\/div>\n<\/details>\n<p><u>\u0421\u0447\u0438\u0442\u044b\u0432\u0430\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u044d\u043d\u043a\u043e\u0434\u0435\u0440\u0430<\/u><\/p>\n<p><strong>\u0426\u0435\u043b\u044c: \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u044d\u043d\u043a\u043e\u0434\u0435\u0440 \u043a \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0443. \u042d\u043d\u043a\u043e\u0434\u0435\u0440 \u0434\u043e\u043b\u0436\u0435\u043d \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u0441\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043e\u0442 0 \u0434\u043e 2000, \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0441\u0432\u043e\u0435\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043e\u043d \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u0441\u0432\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0432 USART.<\/strong><\/p>\n<p>\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u044f:<\/p>\n<ul>\n<li>\n<p>\u041d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043f\u043e\u0440\u0442\u044b \u043d\u0430 \u043d\u0443\u0436\u043d\u044b\u0435 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438;<\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u0434\u0430\u0442\u044c \u0442\u0430\u0439\u043c\u0435\u0440\u0443 \u043f\u0435\u0440\u0438\u043e\u0434 \u0440\u0430\u0432\u043d\u044b\u0439 &#171;\u0447\u0438\u0441\u043b\u043e \u0448\u0430\u0433\u043e\u0432 * 4&#187;. \u042d\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0443 \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u043d\u044b\u0445 \u0430\u0440\u0434\u0443\u0438\u043d\u043e-\u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u043d\u043e\u0433\u043e \u044d\u043d\u043a\u043e\u0434\u0435\u0440\u0430 \u043e\u0434\u0438\u043d \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438\u0439 &#171;\u043a\u043b\u0438\u043a&#187; \u043f\u0440\u0438 \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u0435 \u043f\u043e\u0440\u043e\u0436\u0434\u0430\u0435\u0442 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043d\u0430 4. \u042d\u0442\u043e \u0436\u0435 \u043c\u044b \u0443\u0447\u0442\u0435\u043c \u043f\u0440\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043e\u0442 \u0442\u0430\u0439\u043c\u0435\u0440\u0430, \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u044f \u0441\u0434\u0432\u0438\u0433 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u043d\u0430 2 \u0431\u0438\u0442\u0430 \u0432\u043f\u0440\u0430\u0432\u043e \u0434\u043b\u044f \u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043d\u0430 4;<\/p>\n<\/li>\n<li>\n<p>\u041f\u0435\u0440\u0435\u0432\u0435\u0441\u0442\u0438 \u0442\u0430\u0439\u043c\u0435\u0440 \u0432 &#171;slave mode&#187;, \u0440\u0435\u0436\u0438\u043c \u044d\u043d\u043a\u043e\u0434\u0435\u0440\u0430;<\/p>\n<\/li>\n<li>\n<p>\u0414\u043b\u044f \u0431\u043e\u0440\u044c\u0431\u044b \u0441 \u0434\u0440\u0435\u0431\u0435\u0437\u0433\u043e\u043c \u043a\u043e\u043d\u0442\u0430\u043a\u0442\u043e\u0432 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u044e \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u0432 \u043e\u0442 \u044d\u043d\u043a\u043e\u0434\u0435\u0440\u0430 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 timer_ic_set_filter();<\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u0442\u0435\u043c \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0432\u0445\u043e\u0434\u044b TIM_IC1 \u0438 TIM_IC2.<\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>STM32F1<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#include &lt;libopencm3\/stm32\/rcc.h> #include &lt;libopencm3\/stm32\/gpio.h> #include &lt;libopencm3\/stm32\/timer.h> #include &lt;libopencm3\/stm32\/usart.h>   #include \"ex5_3_timer.h\"   uint32_t current_value = 0;   static void clock_setup(void) {         rcc_clock_setup_pll(&amp;rcc_hse_configs[RCC_CLOCK_HSE8_72MHZ]);         rcc_periph_clock_enable(RCC_GPIOA);         rcc_periph_clock_enable(RCC_AFIO);         rcc_periph_clock_enable(RCC_USART2);         rcc_periph_clock_enable(RCC_TIM1); }     static uint32_t rotary_encoder_tim1_get_value(void){     return (timer_get_counter(TIM1) >> 2); }   static void usart_transmit(uint32_t number){         uint16_t div = 1000;         while (div > 0) {                 usart_send_blocking(USART2, ((uint8_t)(number \/ div) + 0x30));                 number = number % div;                 div \/= 10;         }           usart_send_blocking(USART2, 0x0D);         usart_send_blocking(USART2, 0x0A); }   int main(void) {         uint32_t max_value = 2000;         clock_setup();         gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO8 | GPIO9);         gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO2);           timer_set_period(TIM1, max_value*4 );         timer_slave_set_mode(TIM1, TIM_SMCR_SMS_EM3);         timer_ic_set_filter(TIM1, TIM_IC1,  TIM_IC_DTF_DIV_32_N_8 );         timer_ic_set_filter(TIM1, TIM_IC2,  TIM_IC_DTF_DIV_32_N_8 );         timer_ic_set_input(TIM1, TIM_IC1, TIM_IC_IN_TI1);         timer_ic_set_input(TIM1, TIM_IC2, TIM_IC_IN_TI2);         timer_set_counter(TIM1, 0);         timer_enable_update_event(TIM1);         timer_enable_counter(TIM1);           usart_set_baudrate(USART2, 9600);         usart_set_databits(USART2, 8);         usart_set_stopbits(USART2, USART_STOPBITS_1);         usart_set_parity(USART2, USART_PARITY_NONE);         usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE);         usart_set_mode(USART2, USART_MODE_TX);         usart_enable(USART2);           while(1){                 if(rotary_encoder_tim1_get_value() != current_value){                         current_value =  rotary_encoder_tim1_get_value();                         usart_transmit(current_value);                 }         }   }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>STM32F4<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#include &lt;libopencm3\/stm32\/rcc.h> #include &lt;libopencm3\/stm32\/gpio.h> #include &lt;libopencm3\/stm32\/timer.h> #include &lt;libopencm3\/stm32\/usart.h> #include \"ex5_3_timer.h\"  uint32_t current_value = 0;  static void clock_setup(void) {         rcc_clock_setup_pll(&amp;rcc_hse_25mhz_3v3[RCC_CLOCK_3V3_96MHZ]);         rcc_periph_clock_enable(RCC_GPIOA);         rcc_periph_clock_enable(RCC_USART2);         rcc_periph_clock_enable(RCC_TIM1); }  static uint32_t rotary_encoder_tim1_get_value(void){     return (timer_get_counter(TIM1) >> 2); }  static void usart_transmit(uint32_t number){         uint16_t div = 1000;         while (div > 0) {                 usart_send_blocking(USART2, ((uint8_t)(number \/ div) + 0x30));                 number = number % div;                 div \/= 10;         }          usart_send_blocking(USART2, 0x0D);         usart_send_blocking(USART2, 0x0A); }    int main(void) {         uint32_t max_value = 2000;          clock_setup();          gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO8 | GPIO9);         gpio_set_af(GPIOA, GPIO_AF1, GPIO8 | GPIO9);          gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO2);         gpio_set_af(GPIOA, GPIO_AF7, GPIO2);          timer_set_period(TIM1, max_value*4 );         timer_slave_set_mode(TIM1, TIM_SMCR_SMS_EM3);         timer_ic_set_filter(TIM1, TIM_IC1,  TIM_IC_DTF_DIV_32_N_8 );         timer_ic_set_filter(TIM1, TIM_IC2,  TIM_IC_DTF_DIV_32_N_8 );         timer_ic_set_input(TIM1, TIM_IC1, TIM_IC_IN_TI1);         timer_ic_set_input(TIM1, TIM_IC2, TIM_IC_IN_TI2);         timer_set_counter(TIM1, 0);         timer_enable_update_event(TIM1);         timer_enable_counter(TIM1);          usart_set_baudrate(USART2, 9600);         usart_set_databits(USART2, 8);         usart_set_stopbits(USART2, USART_STOPBITS_1);         usart_set_parity(USART2, USART_PARITY_NONE);         usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE);         usart_set_mode(USART2, USART_MODE_TX);         usart_enable(USART2);          while(1){                 if(rotary_encoder_tim1_get_value() != current_value){                         current_value =  rotary_encoder_tim1_get_value();                         usart_transmit(current_value);                 }         } }<\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/2eb\/aa8\/58c\/2ebaa858c3b1d75fdb1b8508740634ec.png\" alt=\"\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 BluePill \u043f\u043b\u0430\u0442\u044b \u043a \u044d\u043d\u043a\u043e\u0434\u0435\u0440\u0443 \u0441 \u0432\u044b\u0432\u043e\u0434\u043e\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0432 USART. \u041f\u043e\u0434\u0442\u044f\u0433\u0438\u0432\u0430\u044e\u0449\u0438\u0435 \u0440\u0435\u0437\u0438\u0441\u0442\u043e\u0440\u044b \u043e\u0431\u044b\u0447\u043d\u043e \u0443\u0436\u0435 \u0443\u0441\u0442\u0430\u043d\u0432\u043b\u0435\u043d\u044b \u043d\u0430 \u043c\u043e\u0434\u0443\u043b\u044f\u0445 \u044d\u043d\u043a\u043e\u0434\u0435\u0440\u0430.\" title=\"\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 BluePill \u043f\u043b\u0430\u0442\u044b \u043a \u044d\u043d\u043a\u043e\u0434\u0435\u0440\u0443 \u0441 \u0432\u044b\u0432\u043e\u0434\u043e\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0432 USART. \u041f\u043e\u0434\u0442\u044f\u0433\u0438\u0432\u0430\u044e\u0449\u0438\u0435 \u0440\u0435\u0437\u0438\u0441\u0442\u043e\u0440\u044b \u043e\u0431\u044b\u0447\u043d\u043e \u0443\u0436\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u044b \u043d\u0430 \u043c\u043e\u0434\u0443\u043b\u044f\u0445 \u044d\u043d\u043a\u043e\u0434\u0435\u0440\u0430.\" width=\"786\" height=\"507\" data-src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/2eb\/aa8\/58c\/2ebaa858c3b1d75fdb1b8508740634ec.png\"\/><\/p>\n<div><figcaption>\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 BluePill \u043f\u043b\u0430\u0442\u044b \u043a \u044d\u043d\u043a\u043e\u0434\u0435\u0440\u0443 \u0441 \u0432\u044b\u0432\u043e\u0434\u043e\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0432 USART. \u041f\u043e\u0434\u0442\u044f\u0433\u0438\u0432\u0430\u044e\u0449\u0438\u0435 \u0440\u0435\u0437\u0438\u0441\u0442\u043e\u0440\u044b \u043e\u0431\u044b\u0447\u043d\u043e \u0443\u0436\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u044b \u043d\u0430 \u043c\u043e\u0434\u0443\u043b\u044f\u0445 \u044d\u043d\u043a\u043e\u0434\u0435\u0440\u0430.<\/figcaption><\/div>\n<\/figure>\n<\/div>\n<\/details>\n<pre><code>$ cu -l \/dev\/ttyUSB0 -s 9600 Connected. 2000 1999 1998 1999 2000 0000 0001 0002 <\/code><\/pre>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u043c\u044b \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043c \u043d\u0430\u0448 \u0432\u0432\u043e\u0434\u043d\u044b\u0439 \u043a\u0443\u0440\u0441 \u0432 libopencm3. \u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u043c\u043e\u0438 \u0441\u0442\u0430\u0440\u0430\u043d\u0438\u044f \u0432\u043d\u0435\u0441\u043b\u0438 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0432\u043a\u043b\u0430\u0434 \u0432 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u0438\u0437\u0430\u0446\u0438\u044e \u0434\u0430\u043d\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438. \u042f \u0431\u0443\u0434\u0443 \u0440\u0430\u0434, \u0435\u0441\u043b\u0438 \u043d\u0430 GitHub \u0441\u0442\u0430\u043d\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u0435 \u0440\u0430\u0437\u043d\u043e\u043e\u0431\u0440\u0430\u0437\u043d\u044b\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c libopencm3.<\/p>\n<p>\u0415\u0449\u0435 \u0440\u0430\u0437 \u043d\u0430\u043f\u043e\u043c\u043d\u044e, \u0447\u0442\u043e \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u0432\u0441\u0435\u0445 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u043d\u0430 Github \u0432\u00a0<a href=\"https:\/\/github.com\/bsdmry\/stm_dev\">\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<\/a>.<\/p>\n<p>\u0421\u043f\u0430\u0441\u0438\u0431\u043e \u0437\u0430 \u0443\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f! \u0416\u0435\u043b\u0430\u044e \u0432\u0441\u0435\u043c \u043e\u0441\u0438\u043b\u0438\u0432\u0448\u0438\u043c \u044d\u0442\u0443 \u0441\u0435\u0440\u0438\u044e \u0441\u0442\u0430\u0442\u0435\u0439 \u043f\u043e\u0431\u043e\u043b\u044c\u0448\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432. \u041a\u0430\u043a \u0445\u043e\u0431\u0431\u0438\u0439\u043d\u044b\u0445, \u0442\u0430\u043a \u0438 \u043a\u043e\u043c\u043c\u0435\u0440\u0447\u0435\u0441\u043a\u0438\u0445.<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/761612\/\"> https:\/\/habr.com\/ru\/articles\/761612\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p><a href=\"https:\/\/habr.com\/ru\/companies\/auriga\/articles\/728270\/\">\u0427\u0430\u0441\u0442\u044c 1. \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 libopencm3<\/a><\/p>\n<p><a href=\"https:\/\/habr.com\/ru\/companies\/auriga\/articles\/729418\/\">\u0427\u0430\u0441\u0442\u044c 2. \u0420\u0430\u0431\u043e\u0442\u0430 \u0441 GPIO, SPI, \u043e\u0442\u043b\u0430\u0434\u043a\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 GDB<\/a><\/p>\n<p>\u0427\u0430\u0441\u0442\u044c 3. \u0420\u0430\u0431\u043e\u0442\u0430 \u0441 USART, \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f\u043c\u0438, I2C \u0438 \u0442\u0430\u0439\u043c\u0435\u0440\u0430\u043c\u0438<\/p>\n<p>\u0414\u0430\u043d\u043d\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u0430\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0432 \u0446\u0438\u043a\u043b\u0435, \u043f\u043e\u0441\u0432\u044f\u0449\u0435\u043d\u043d\u043e\u043c \u0431\u044b\u0441\u0442\u0440\u043e\u043c\u0443 \u0441\u0442\u0430\u0440\u0442\u0443 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u043e\u0434 STM32 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 libopencm3. \u0411\u0435\u0437 \u043b\u0438\u0448\u043d\u0438\u0445 \u0441\u043b\u043e\u0432 \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0438\u044e \u043e\u0441\u0442\u0430\u0432\u0448\u0435\u0439\u0441\u044f \u043f\u0435\u0440\u0438\u0444\u0435\u0440\u0438\u0438, \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0447\u0430\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u0439 \u0432 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430\u0445.<\/p>\n<h4>\u0422\u0440\u0435\u0442\u0438\u0439 \u043f\u0440\u043e\u0435\u043a\u0442: \u041f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0447\u0435\u0440\u0435\u0437 USART &amp; \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439<\/h4>\n<p>\u041f\u043e\u0440\u0430 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 \u0441 \u043e\u043a\u0440\u0443\u0436\u0430\u044e\u0449\u0438\u043c \u043c\u0438\u0440\u043e\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e USART \u2013 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0435\u0433\u043e \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u043e\u043c \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0442\u0435\u043a\u0441\u0442\u0430.   <\/p>\n<p><strong>\u0426\u0435\u043b\u044c: \u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0432 USART \u0441\u0442\u0440\u043e\u0447\u043a\u0443 \u00abHello from LibOpenCM3!\u00bb \u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c: \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c 9600, 8 \u0431\u0438\u0442 \u0434\u0430\u043d\u043d\u044b\u0445, \u043e\u0434\u0438\u043d \u0441\u0442\u043e\u043f-\u0431\u0438\u0442, \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0447\u0435\u0442\u043d\u043e\u0441\u0442\u0438 \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u0430.<\/strong><\/p>\n<p>\u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043d\u0430\u0448 \u043f\u0440\u043e\u0435\u043a\u0442:<\/p>\n<pre><code>.\/make_project.sh ex3_1_usart<\/code><\/pre>\n<p>\u041d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0435 \u0448\u0430\u0433\u0438 \u043d\u0435 \u043e\u0442\u043b\u0438\u0447\u0430\u044e\u0442\u0441\u044f \u043e\u0442 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u0435\u0432: \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u0447\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432, \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u0437\u0430 \u043f\u0435\u0440\u0438\u0444\u0435\u0440\u0438\u044e, \u0438 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0442\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u043e\u0440\u0442\u0430 \u0438 \u043f\u0435\u0440\u0438\u0444\u0435\u0440\u0438\u0438.<\/p>\n<details class=\"spoiler\">\n<summary>STM32F1<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#include &lt;libopencm3\/stm32\/rcc.h> #include &lt;libopencm3\/stm32\/gpio.h> #include &lt;libopencm3\/stm32\/usart.h> #include \"ex3_1_usart.h\" static void clock_setup(void) { rcc_clock_setup_pll(&amp;rcc_hse_configs[RCC_CLOCK_HSE8_72MHZ]); rcc_periph_clock_enable(RCC_GPIOA); rcc_periph_clock_enable(RCC_AFIO); rcc_periph_clock_enable(RCC_USART2); } int main(void) { clock_setup(); while(1); }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>STM32F4<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#include &lt;libopencm3\/stm32\/rcc.h> #include &lt;libopencm3\/stm32\/gpio.h> #include &lt;libopencm3\/stm32\/usart.h> #include \"ex3_1_usart.h\" static void clock_setup(void) { rcc_clock_setup_pll(&amp;rcc_hse_25mhz_3v3[RCC_CLOCK_3V3_96MHZ]); rcc_periph_clock_enable(RCC_GPIOA); rcc_periph_clock_enable(RCC_USART2); } int main(void) { clock_setup(); while(1); }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041e\u0442\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u0443\u0435\u043c USART \u0441 \u0442\u0440\u0435\u0431\u0443\u0435\u043c\u044b\u043c\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438. \u0424\u0443\u043d\u043a\u0446\u0438\u0438 libopencm3 \u0438\u043d\u0442\u0443\u0438\u0442\u0438\u0432\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u043d\u044b. \u0422\u0430\u043a \u0436\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043c \u043d\u043e\u0436\u043a\u0438 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0439 RX \u0438 TX, \u0430\u043a\u0442\u0438\u0432\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0432 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438.  <\/p>\n<details class=\"spoiler\">\n<summary>STM32F1<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#include &lt;libopencm3\/stm32\/rcc.h> #include &lt;libopencm3\/stm32\/gpio.h> #include &lt;libopencm3\/stm32\/usart.h> #include \"ex3_1_usart.h\"   static void clock_setup(void) {         rcc_clock_setup_pll(&amp;rcc_hse_configs[RCC_CLOCK_HSE8_72MHZ]);         rcc_periph_clock_enable(RCC_GPIOA);         rcc_periph_clock_enable(RCC_AFIO);         rcc_periph_clock_enable(RCC_USART2); }   int main(void) {         clock_setup();           gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO2 | GPIO3 );           usart_set_baudrate(USART2, 9600);         usart_set_databits(USART2, 8);         usart_set_stopbits(USART2, USART_STOPBITS_1);         usart_set_parity(USART2, USART_PARITY_NONE);         usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE);         usart_set_mode(USART2, USART_MODE_TX_RX);         usart_enable(USART2);           while(1); }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>STM32F4<\/summary>\n<div class=\"spoiler__content\">\n<\/div>\n<\/details>\n<p>USART \u0433\u043e\u0442\u043e\u0432 \u043a \u043f\u0440\u0438\u0435\u043c\u0443 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0435 \u0434\u0430\u043d\u043d\u044b\u0445. \u0422\u0430\u043a \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043c \u0447\u0442\u043e-\u043d\u0438\u0431\u0443\u0434\u044c \u0432 \u0441\u0442\u043e\u0440\u043e\u043d\u0443 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0430. \u041d\u0430\u043f\u0438\u0448\u0435\u043c \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0449\u0443\u044e \u043f\u043e\u0441\u0438\u043c\u0432\u043e\u043b\u044c\u043d\u043e \u0432 USART \u0441\u0442\u0440\u043e\u043a\u0443:<\/p>\n<pre><code class=\"cpp\">static void usart_transmit(const char *str) { while (*str != '\\000') { usart_send_blocking(USART2, *str); str++; } }<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0438 \u043c\u0435\u0436\u0434\u0443 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430\u043c\u0438 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f \u043f\u043e\u0434\u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439 DWT, \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0439 \u0440\u0430\u043d\u0435\u0435:<\/p>\n<details class=\"spoiler\">\n<summary>STM32F1<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#include &lt;libopencm3\/stm32\/rcc.h> #include &lt;libopencm3\/stm32\/gpio.h> #include &lt;libopencm3\/stm32\/usart.h> #include &lt;libopencm3\/cm3\/dwt.h> #include \"ex3_1_usart.h\"   static void clock_setup(void) {         rcc_clock_setup_pll(&amp;rcc_hse_configs[RCC_CLOCK_HSE8_72MHZ]);         rcc_periph_clock_enable(RCC_GPIOA);         rcc_periph_clock_enable(RCC_AFIO);         rcc_periph_clock_enable(RCC_USART2); }   static uint32_t dwt_setup(void) {         dwt_enable_cycle_counter();         __asm volatile (\"nop\");         __asm volatile (\"nop\");         __asm volatile (\"nop\");        if(dwt_read_cycle_counter())      {        return 0;      }      else   {     return 1;   } }   static void dwt_delay_ms(uint32_t milliseconds) {         uint32_t initial_ticks = dwt_read_cycle_counter();         uint32_t ms_count_tics = milliseconds * (rcc_ahb_frequency \/ 1000);         while ((dwt_read_cycle_counter() - initial_ticks) &lt; ms_count_tics); }   static void usart_transmit(const char *str) {         while (*str != '\\000') {                 usart_send_blocking(USART2, *str);                 str++;         } }   int main(void) {         clock_setup();         dwt_setup();           gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO2 | GPIO3 );           usart_set_baudrate(USART2, 9600);         usart_set_databits(USART2, 8);         usart_set_stopbits(USART2, USART_STOPBITS_1);         usart_set_parity(USART2, USART_PARITY_NONE);         usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE);         usart_set_mode(USART2, USART_MODE_TX_RX);         usart_enable(USART2);           while(1){                 dwt_delay_ms(1000);                 usart_transmit(\"Hello from LibOpenCM3!\\r\\n\");         } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>STM32F4<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#include &lt;libopencm3\/stm32\/rcc.h> #include &lt;libopencm3\/stm32\/gpio.h> #include &lt;libopencm3\/stm32\/usart.h> #include &lt;libopencm3\/cm3\/dwt.h> #include \"ex3_1_usart.h\"   static void clock_setup(void) {         rcc_clock_setup_pll(&amp;rcc_hse_25mhz_3v3[RCC_CLOCK_3V3_96MHZ]);         rcc_periph_clock_enable(RCC_GPIOA);         rcc_periph_clock_enable(RCC_USART2); }   static uint32_t dwt_setup(void) {         dwt_enable_cycle_counter();         __asm volatile (\"nop\");         __asm volatile (\"nop\");         __asm volatile (\"nop\");        if(dwt_read_cycle_counter())      {        return 0;      }      else   {     return 1;   } }   static void dwt_delay_ms(uint32_t milliseconds) {         uint32_t initial_ticks = dwt_read_cycle_counter();         uint32_t ms_count_tics = milliseconds * (rcc_ahb_frequency \/ 1000);         while ((dwt_read_cycle_counter() - initial_ticks) &lt; ms_count_tics); }   static void usart_transmit(const char *str) {         while (*str != '\\000') {                 usart_send_blocking(USART2, *str);                 str++;         } }   int main(void) {         clock_setup();         dwt_setup();         gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO2 | GPIO3);         gpio_set_af(GPIOA, GPIO_AF7, GPIO2 | GPIO3);           usart_set_baudrate(USART2, 9600);         usart_set_databits(USART2, 8);         usart_set_stopbits(USART2, USART_STOPBITS_1);         usart_set_parity(USART2, USART_PARITY_NONE);         usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE);         usart_set_mode(USART2, USART_MODE_TX_RX);           usart_enable(USART2);         while(1){                 dwt_delay_ms(1000);                 usart_transmit(\"Hello from LibOpenCM3!\\r\\n\");         } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u0441\u0431\u043e\u0440\u043a\u0443 \u0438 \u043f\u0440\u043e\u0448\u0438\u0432\u043a\u0443, \u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043d\u0438\u043a Serial2Usb \u043a \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0443: PA3 \u043a TX, PA2 \u043a RX.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043d\u0438\u043a\u0430 USB-2-Serial \u043a \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0443 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 BluePill<\/figcaption><\/div>\n<\/figure>\n<p>\u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u044c\u043d\u0443\u044e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443, \u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c\u0441\u044f \u043a \u0441\u0438\u043c\u0432\u043e\u043b\u044c\u043d\u043e\u043c\u0443 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0443 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043d\u0438\u043a\u0430.<\/p>\n<pre><code>$ cu -l \/dev\/ttyUSB0 -s 9600 Connected. Hello from LibOpenCM3! Hello from LibOpenCM3! Hello from LibOpenCM3! Hello from LibOpenCM3! Hello from LibOpenCM3! Hello from LibOpenCM3!<\/code><\/pre>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043d\u0430\u0448 \u0448\u0430\u0433 \u2013 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0432 \u0441\u0442\u043e\u0440\u043e\u043d\u0443 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u043e\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0438\u0444\u0435\u0440\u0438\u044e \u043d\u0430 \u043f\u0440\u0435\u0434\u043c\u0435\u0442 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u2013 \u0434\u0443\u0440\u043d\u043e\u0439 \u0442\u043e\u043d, \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u043d\u0430\u0448\u0430 \u0446\u0435\u043b\u044c \u0431\u0443\u0434\u0435\u0442 \u0432\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f\u043c\u0438 STM32.<\/p>\n<p><strong>\u0426\u0435\u043b\u044c: \u043f\u0440\u0438 \u0441\u0442\u0430\u0440\u0442\u0435 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u044b\u0434\u0430\u0442\u044c \u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b \u00abHello\u00bb, \u043e\u0436\u0438\u0434\u0430\u0442\u044c \u0432\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043a\u043e\u043c\u0430\u043d\u0434. \u041f\u0440\u0438 \u0432\u0432\u0435\u0434\u0435\u043d\u0438\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u00abtoggle_led\u00bb<\/strong> <strong>\u2013<\/strong> <strong>\u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434\u0430 \u043d\u0430 \u043d\u043e\u0436\u043a\u0435 PC13, \u0430 \u043f\u0440\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u0435 \u00absay_hello\u00bb \u2013 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0443 \u00abHello from LibOpenCM3!\u00bb.<\/strong><\/p>\n<p>\u0420\u0430\u0431\u043e\u0442\u0430 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439 \u0432 STM32 \u043e\u043f\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 NVIC (Nested Vector Interrupt Controller) \u0438 \u043d\u0438\u0447\u0435\u043c \u043e\u0441\u043e\u0431\u043e \u043d\u0435 \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u0434\u0440\u0443\u0433\u0438\u0445 \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u043e\u0432 (\u043a \u043f\u0440\u0438\u043c\u0435\u0440\u0443, Atmega). \u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435, \u0443 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439 \u0432 STM32 \u0438\u043c\u0435\u044e\u0442\u0441\u044f \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u044b.<\/p>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 USART \u0441 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439.<\/p>\n<p>\u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0448\u0430\u0431\u043b\u043e\u043d \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430:<\/p>\n<pre><code>$ .\/make_project.sh ex3_2_usart_irq<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0432\u044b\u043c \u0434\u0435\u043b\u043e\u043c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043c \u0438 \u0430\u043a\u0442\u0438\u0432\u0438\u0437\u0438\u0440\u0443\u0435\u043c NVIC:<\/p>\n<details class=\"spoiler\">\n<summary>STM32F1<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#include &lt;libopencm3\/stm32\/rcc.h> #include &lt;libopencm3\/cm3\/nvic.h> #include \"ex3_2_usart_irq.h\"   static void clock_setup(void) {         rcc_clock_setup_pll(&amp;rcc_hse_configs[RCC_CLOCK_HSE8_72MHZ]);         rcc_periph_clock_enable(RCC_GPIOA); }   int main(void) {         clock_setup();         nvic_enable_irq(NVIC_USART2_IRQ); \/\/\u0412\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439 \u0434\u043b\u044f USART2         nvic_set_priority(NVIC_USART2_IRQ, 1); \/\/\u041e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e, \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0435\u043c \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f.         while(1); }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>STM32F4<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#include &lt;libopencm3\/stm32\/rcc.h> #include &lt;libopencm3\/cm3\/nvic.h> #include \"ex3_2_usart_irq.h\"   static void clock_setup(void) {         rcc_clock_setup_pll(&amp;rcc_hse_25mhz_3v3[RCC_CLOCK_3V3_96MHZ]);         rcc_periph_clock_enable(RCC_GPIOA);         rcc_periph_clock_enable(RCC_USART2); }   int main(void) {         clock_setup();         nvic_enable_irq(NVIC_USART2_IRQ); \/\/\u0412\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439 \u0434\u043b\u044f USART         nvic_set_priority(NVIC_USART2_IRQ, 1); \/\/\u041e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e, \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0435\u043c \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f.         while(1); }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043c\u044b \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u0443\u0435\u043c USART \u043f\u043e\u0447\u0442\u0438 \u0442\u0430\u043a \u0436\u0435, \u043a\u0430\u043a \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435. \u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435, \u0447\u0442\u043e \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u2013 \u0430\u043a\u0442\u0438\u0432\u0438\u0437\u0430\u0446\u0438\u044e \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439 \u043f\u043e \u043f\u0440\u0438\u0435\u043c\u0443 \u0434\u0430\u043d\u043d\u044b\u0445. \u0412\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e usart_enable_rx_interrupt() \u0438 \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0438\u0440\u0443\u0435\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439 usart2_isr(). \u041f\u043e\u043b\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u0438\u043c\u0435\u043d \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 (<a href=\"http:\/\/libopencm3.org\/docs\/latest\/stm32f1\/html\/group__CM3__nvic__isrprototypes__STM32F1.html#ga4ef5b9c30c57ea631c43778171dd0908\">F1 series<\/a>,\u00a0<a href=\"http:\/\/libopencm3.org\/docs\/latest\/stm32f4\/html\/group__CM3__nvic__isrprototypes__STM32F4.html#ga4ef5b9c30c57ea631c43778171dd0908\">F4 series<\/a>).<\/p>\n<p>\u0415\u0449\u0435 \u043d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0435\u043c \u0441\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u043e\u0436\u043a\u0443 PC13, \u043f\u043e\u0434\u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u043d\u0443\u044e \u043a \u0441\u0432\u0435\u0442\u043e\u0434\u0438\u043e\u0434\u0443.<\/p>\n<details class=\"spoiler\">\n<summary>STM32F1<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">#include &lt;libopencm3\/stm32\/rcc.h> #include &lt;libopencm3\/cm3\/nvic.h> #include &lt;libopencm3\/stm32\/usart.h> #include &lt;libopencm3\/stm32\/gpio.h>   #include \"ex3_2_usart_irq.h\"   static void clock_setup(void) {         rcc_clock_setup_pll(&amp;rcc_hse_configs[RCC_CLOCK_HSE8_72MHZ]);         rcc_periph_clock_enable(RCC_GPIOA);         rcc_periph_clock_enable(RCC_GPIOC);         rcc_periph_clock_enable(RCC_AFIO);         rcc_periph_clock_enable(RCC_USART2); }   int main(void) {         clock_setup();         nvic_enable_irq(NVIC_USART2_IRQ); \/\/\u0412\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439 \u0434\u043b\u044f<\/code><\/pre>\n<\/div>\n<\/details>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-355127","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/355127","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=355127"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/355127\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=355127"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=355127"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=355127"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}