{"id":276577,"date":"2016-03-21T10:55:02","date_gmt":"2016-03-21T07:55:02","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=276577"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=276577","title":{"rendered":"\u041f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 FreeModbus 1.5 \u043f\u043e\u0434 STM32 HAL rs485 \u0431\u0435\u0437 RTOS"},"content":{"rendered":"<p>       \u0421 \u043d\u0435\u0434\u0430\u0432\u043d\u0438\u0445 \u043f\u043e\u0440 \u044f \u043d\u0430\u0447\u0430\u043b \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c\u0441\u044f \u0432\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c\u044b\u043c\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u043c\u0438 \u0438 \u0434\u043e\u043a\u0430\u0442\u0438\u043b\u0441\u044f \u0434\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u043e\u0432, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e STM32F373. \u041e\u0434\u043d\u043e\u0439 \u0438\u0437 \u0437\u0430\u0434\u0430\u0447 \u0431\u044b\u043b\u043e \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u044c Modbus Slave RTU \u043f\u043e\u0432\u0435\u0440\u0445 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 rs485.<\/p>\n<p>  \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0441\u0440\u043e\u043a\u0438 \u043f\u043e\u0434\u0436\u0438\u043c\u0430\u043b\u0438 \u0431\u044b\u043b\u043e \u043f\u0440\u0438\u043d\u044f\u0442\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0432\u0437\u044f\u0442\u044c \u0447\u0442\u043e-\u043d\u0438\u0431\u0443\u0434\u044c \u0433\u043e\u0442\u043e\u0432\u043e\u0435, \u0447\u0435\u043c \u044f \u0438 \u0437\u0430\u043d\u044f\u043b\u0441\u044f. \u041d\u0435\u0434\u043e\u043b\u0433\u043e\u0435 \u0433\u0443\u0433\u043b\u0435\u043d\u0438\u0435 \u043d\u0430\u0432\u0435\u043b\u043e \u043c\u0435\u043d\u044f \u043d\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 <a href=\"http:\/\/www.freemodbus.org\/\">FreeModbus<\/a>, \u0430 \u0432\u043e\u0442 \u0442\u0443\u0442 \u043d\u0430\u0447\u0430\u043b\u0430\u0441\u044c \u0431\u043e\u043b\u044c \u0441 \u043a\u043e\u0442\u043e\u0440\u043e\u0439, \u044f \u043d\u0430\u0434\u0435\u044e\u0441\u044c, \u0432\u044b \u043d\u0435 \u0441\u0442\u043e\u043b\u043a\u043d\u0435\u0442\u0435\u0441\u044c.<br \/>  <a name=\"habracut\"><\/a>  <\/p>\n<h4>0. \u0413\u043e\u0442\u043e\u0432\u0438\u043c \u043f\u0440\u043e\u0435\u043a\u0442<\/h4>\n<p>  \u0414\u043b\u044f \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0441\u0442\u0430\u0440\u0442\u0430 \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e <a href=\"http:\/\/www.st.com\/web\/catalog\/tools\/FM147\/CL1794\/SC961\/SS1743\/PF259242?icmp=stm32cubemx_pron_pr-stm32cubef2_apr2014&amp;sc=stm32cube-pr2\">STM32CubeMX<\/a>, \u043e\u043d \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0431\u044b\u0441\u0442\u0440\u043e \u0433\u0435\u043d\u0435\u0440\u0438\u0442\u044c \u043a\u043e\u0434 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 \u0431\u0435\u0437 \u0431\u043e\u043b\u0438. \u0412 \u043c\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e STM32F373VCTx LQFP100.<\/p>\n<p>  \u041f\u0435\u0440\u0435\u0444\u0435\u0440\u0438\u044f:<\/p>\n<ul>\n<li> TIM6 <\/li>\n<li> USART1 <\/li>\n<\/ul>\n<p>  \u0414\u0435\u043b\u0430\u044e \u044d\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 <code>HAL_TIM_Base_MspInit()<\/code> \u0438 <code>HAL_UART_MspInit()<\/code>, \u044d\u0442\u043e \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442 \u0432\u0430\u043c \u0436\u0438\u0437\u043d\u044c, \u0435\u0441\u043b\u0438 \u0431\u0443\u0434\u0435\u0442\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u0438\u0435 \u0442\u0430\u0439\u043c\u0435\u0440\u044b \u0438 usart&#8217;\u044b.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/004\/ab7\/9a5\/004ab79a50dd40d495c8cf16a5953ab4.PNG\" alt=\"peripheral\"\/><\/p>\n<p>  \u0422\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435:<\/p>\n<p>  \u041d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e, \u0447\u0442\u043e\u0431\u044b \u0442\u0430\u0439\u043c\u0435\u0440 TIM6 \u0438\u043b\u0438 \u0442\u043e\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b \u0432\u044b\u0431\u0440\u0430\u043b\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u043b \u043d\u0430 \u0447\u0430\u0441\u0442\u043e\u0442\u0435 \u043d\u0435 \u043d\u0438\u0436\u0435 20\u043a\u0413\u0446. \u041f\u043e\u0448\u0443\u0440\u0448\u0430\u0432 \u043f\u043e \u043a\u043e\u0434\u0443 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u044f \u043f\u043e\u043d\u044f\u043b, \u0447\u0442\u043e TIM6 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0430 PCLK1 (Peripheral CLocK). \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u043e\u043d (\u0442\u0430\u0439\u043c\u0435\u0440) \u0442\u0430\u043a\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043e\u0442 HSI (High Speed Internal resonator), \u0442\u0430\u043a \u0436\u0435 \u043a\u0430\u043a \u0438 \u0432\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435, \u043d\u043e \u043c\u043d\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u044d\u0442\u043e \u043c\u0430\u043b\u043e\u0432\u0430\u0442\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u043f\u043e\u0433\u043d\u0430\u043b \u0432\u0441\u0435 \u044d\u0442\u043e \u0434\u0435\u043b\u043e \u0447\u0435\u0440\u0435\u0437 PLL (Phase-Locked Loop) \u0438 \u0432\u044b\u0441\u0442\u0430\u0432\u0438\u043b \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043c\u043d\u043e\u0436\u0438\u0442\u0435\u043b\u044f \u043d\u0430 x8, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0434\u043d\u044f\u0442\u044c \u0434\u043e 32\u041c\u0413\u0446, \u0442\u0430\u043a \u041c\u041a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043f\u043b\u0430\u0432\u043d\u0435\u0435 \u0438 \u043f\u0440\u0438\u044f\u0442\u043d\u0435\u0435.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/b6c\/30a\/b89\/b6c30ab89e2b4423bae4e40d3872a44a.PNG\" alt=\"clock config\"\/><\/p>\n<p>  \u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f:<\/p>\n<p>  \u041d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0442\u0430\u0439\u043c\u0435\u0440\u043e\u043c \u043f\u043e \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u043a\u043b\u044e\u0447\u0438\u043c \u0435\u0433\u043e \u043d\u0430 \u0432\u043a\u043b\u0430\u0434\u043a\u0435 Configuration \u0440\u0430\u0437\u0434\u0435\u043b System NVIC \u00abTIM6 global interrupt and DAC1 underrun error interrupts\u00bb. \u0422\u0430\u043a\u0436\u0435 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u044b \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f \u043e\u0442 USART1 \u00abUSART1 global interrupt \/ USART1 wake-up interrupt through EXTI line 25\u00bb.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/9fd\/80e\/725\/9fd80e7253d441efa808d3445c7d42cb.PNG\" alt=\"image\"\/><\/p>\n<p>  \u042f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u043c\u043d\u043e\u0433\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439 \u0434\u043b\u044f \u0438\u043d\u0434\u0438\u043a\u0430\u0446\u0438\u0438 \u043e\u0448\u0438\u0431\u043e\u043a, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0435 \u043e\u0431\u0440\u0430\u0449\u0430\u0439\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043a\u0443\u0447\u0443 \u0433\u0430\u043b\u043e\u0447\u0435\u043a.<\/p>\n<p>  \u041d\u0430 \u044d\u0442\u043e\u043c \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u043c, \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442, \u0433\u0435\u043d\u0435\u0440\u0438\u043c \u043a\u043e\u0434.<\/p>\n<p>  \u042f \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u044e \u043a\u043e\u0434 \u0434\u043b\u044f <a href=\"http:\/\/www.openstm32.org\/Downloading+the+System+Workbench+for+STM32+installer?structure=Documentation\">SW4STM32<\/a> (System Workbench for STM32, \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f). \u041f\u0440\u0435\u0434\u043f\u043e\u0447\u0438\u0442\u0430\u044e \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 .h\/.c \u0444\u0430\u0439\u043b\u044b \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0444\u0435\u0440\u0438\u0438, \u0432\u043a\u043b\u044e\u0447\u0430\u0442\u044c full_assert \u0438 \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u0432\u044b\u0437\u043e\u0432\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0435\u0440\u0435\u0444\u0435\u0440\u0438\u0438.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/ae9\/0c6\/e53\/ae90c6e538844ec2850413fd69557031.PNG\" alt=\"image\"\/><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/6d6\/eb6\/f8d\/6d6eb6f8db3e4d52b7e5a4678bf29b5c.PNG\" alt=\"image\"\/><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/87d\/873\/0b4\/87d8730b491343268c98aa2e54127142.PNG\" alt=\"image\"\/><\/p>\n<h4>1. Download &#038; install<\/h4>\n<p>  \u0422\u0443\u0442 \u0432\u0441\u0435 \u043f\u0440\u043e\u0441\u0442\u043e: \u043a\u0430\u0447\u0430\u0435\u043c <a href=\"https:\/\/sourceforge.net\/projects\/freemodbus.berlios\/files\/freemodbus-v1.5.0.zip\/download\">\u0430\u0440\u0445\u0438\u0432<\/a>, \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u044b\u0432\u0430\u0435\u043c, \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0441\u043e\u0440\u0446\u044b \u0438\u0437 <i>\u0430\u0440\u0445\u0438\u0432\/modbus\/<\/i> \u0432 \u043f\u0440\u043e\u0435\u043a\u0442, \u043d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0435\u043c \u043f\u0440\u043e <i>\u0430\u0440\u0445\u0438\u0432\/modbus\/include<\/i>, \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 include&#8217;\u044b.<br \/>  \u0422\u0430\u043a\u0436\u0435 \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f port layer, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043c\u044b \u0438 \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c, \u0431\u0435\u0440\u0435\u043c \u0435\u0433\u043e \u0438\u0437 <i>\u0430\u0440\u0445\u0438\u0432\/demo\/BARE<\/i>, \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c, \u0433\u043e\u0442\u043e\u0432\u043e.<\/p>\n<h4>2. \u041f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c<\/h4>\n<p>  \u0412\u0441\u0435 \u0434\u0435\u043b\u0430\u0435\u043c \u043e\u043f\u0438\u0440\u0430\u044f\u0441\u044c \u043d\u0430 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u0443\u044e <a href=\"http:\/\/www.freemodbus.org\/api\/sec_porting_serial.html\">\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e<\/a>.<\/p>\n<h5>port.h<\/h5>\n<p>  \u041d\u0430\u0447\u043d\u0435\u043c \u0441 include&#8217;\u043e\u0432: \u044f \u0443\u0431\u0438\u0440\u0430\u044e <i>assert.h<\/i>, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u043a\u0438\u0434\u044b\u0432\u0430\u044e <code>assert()<\/code> \u043d\u0430 <code>assert_param()<\/code>, \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044e <i>stm32f3xx_hal.h<\/i>, \u0435\u0441\u043b\u0438 \u0432\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0435\u0440\u0438\u0438, \u0442\u043e \u0432\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443.<\/p>\n<p>  \u0414\u0430\u043b\u0435\u0435 \u043d\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u044e\u0442 \u043c\u0430\u043a\u0440\u043e\u0441\u044b <code>ENTER_CRITICAL_SECTION( )<\/code> \u0438 <code>EXIT_CRITICAL_SECTION( )<\/code>. \u0417\u0430\u043c\u0435\u043d\u044f\u0435\u043c \u0438\u0445 \u043d\u0430 <code>__disable_irq()<\/code> \u0438 <code>__enable_irq()<\/code> \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e.<\/p>\n<p>  \u0422\u0430\u043a\u0436\u0435 \u044f \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044e \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f <code>UART_IRQ_Handler()<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043a\u043e\u0441\u0442\u044b\u043b\u044c\u043d\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0440\u0435\u0430\u043a\u0446\u0438\u0438 \u043d\u0430 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f.<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">port.h<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">\/*  * FreeModbus Libary: BARE Port  * Copyright (C) 2006 Christian Walter &lt;wolti@sil.at&gt;  *  * This library is free software; you can redistribute it and\/or  * modify it under the terms of the GNU Lesser General Public  * License as published by the Free Software Foundation; either  * version 2.1 of the License, or (at your option) any later version.  *  * This library is distributed in the hope that it will be useful,  * but WITHOUT ANY WARRANTY; without even the implied warranty of  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU  * Lesser General Public License for more details.  *  * You should have received a copy of the GNU Lesser General Public  * License along with this library; if not, write to the Free Software  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA  *  * File: $Id: port.h,v 1.1 2006\/08\/22 21:35:13 wolti Exp $  *\/  #ifndef _PORT_H #define _PORT_H  #include &quot;stm32f3xx_hal.h&quot; #include &lt;inttypes.h&gt;  #define\tINLINE                      inline #define PR_BEGIN_EXTERN_C           extern &quot;C&quot; { #define\tPR_END_EXTERN_C             }  \/\/ \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f\u043c\u0438 #define ENTER_CRITICAL_SECTION( )\t__disable_irq() #define EXIT_CRITICAL_SECTION( )\t__enable_irq()  \/\/ \u043f\u043e\u0434\u043c\u0435\u043d\u0438\u043c \u0432\u044b\u0437\u043e\u0432\u044b \u043f\u043e \u0432\u0441\u0435\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 #define assert(val) assert_param(val)  typedef uint8_t BOOL;  typedef unsigned char UCHAR; typedef char CHAR;  typedef uint16_t USHORT; typedef int16_t SHORT;  typedef uint32_t ULONG; typedef int32_t LONG;  #ifndef TRUE #define TRUE            1 #endif  #ifndef FALSE #define FALSE           0 #endif  \/\/ callback \u0434\u043b\u044f uart BOOL UART_IRQ_Handler(USART_TypeDef * usart);  #endif <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<h5>porttimer.c<\/h5>\n<p>  \u041e\u043f\u044f\u0442\u044c \u043d\u0430\u0447\u043d\u0435\u043c \u0441 include&#8217;\u043e\u0432: \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 platform includes \u0434\u043e\u0431\u0430\u0432\u0438\u043c <code>stm32f3xx_hal_tim.h<\/code>, \u0438\u0437 \u043d\u0435\u0433\u043e \u043d\u0443\u0436\u043d\u0430 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430 <code>TIM_COUNTERMODE_UP<\/code>.<\/p>\n<p>  \u0412 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 static functions \u044f \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044e handler \u0434\u043b\u044f \u0442\u0430\u0439\u043c\u0435\u0440\u0430 \u0438 2 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u0430, \u0438 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430.<br \/>  \u0424\u0443\u043d\u043a\u0446\u0438\u044e <code>xMBPortTimersInit()<\/code> \u043d\u0430\u043f\u043e\u043b\u043d\u0438\u043c \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u0442\u0430\u0439\u043c\u0435\u0440\u0430. \u0420\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0442\u0438\u043a\u0430\u0442\u044c \u043a\u0430\u0436\u0434\u044b\u0435 50 \u043c\u043a\u0441.<\/p>\n<p>  htim \u2014 \u043d\u0430\u0448 handler, \u0442\u0438\u043f \u2014 <code>static TIM_HandleTypeDef<\/code>, \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0439<br \/>  timeout \u2014 <code>static uint16_t<\/code>, \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0439<br \/>  downcounter \u2014 <code>static uint16_t<\/code>, \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0439<\/p>\n<pre><code class=\"cpp\">    htim.Instance = TIM6; \/\/ \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c, \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 6 \u0442\u0430\u0439\u043c\u0435\u0440\u043e\u043c     htim.Init.CounterMode = TIM_COUNTERMODE_UP; \/\/ \u0442\u0438\u043f \u0440\u0430\u0431\u043e\u0442\u044b \u0442\u0430\u0439\u043c\u0435\u0440\u0430 (\u043e\u0442 0 \u0438 \u0432\u0432\u0435\u0440\u0445)     \/* \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0434\u0435\u043b\u0438\u0442\u0435\u043b\u044c \u0447\u0430\u0441\u0442\u043e\u0442\u044b \u0442\u0430\u0439\u043c\u0435\u0440\u0430, \u043d\u0430\u043c \u0436\u0435 \u043d\u0435 \u043d\u0443\u0436\u0435\u043d \u0442\u0430\u0439\u043c\u0435\u0440 \u043d\u0430 32\u041c\u0413\u0446        HAL_RCC_GetPCLK1Freq() - \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0447\u0430\u0441\u0442\u043e\u0442\u0443 PCLK1, \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0431\u0443\u0434\u0435\u0442 32000000        \u0434\u0435\u043b\u0438\u043c \u043d\u0430 1000000, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u0435\u043b\u0438\u0442\u0435\u043b\u044c \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0442\u0430\u0439\u043c\u0435\u0440\u0430 \u0441 \u0447\u0430\u0441\u0442\u043e\u0442\u043e\u0439 1\u041c\u0413\u0446        \u0430 -1 - \u044d\u0442\u043e \u0441\u0430\u043c\u044b\u0439 \u0441\u043e\u043a: \u0434\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e 0 - \u044d\u0442\u043e \u0434\u0435\u043b\u0438\u0442\u0435\u043b\u044c \u043d\u0430 1, 1 - \u0434\u0435\u043b\u0438\u0442\u0435\u043b\u044c \u043d\u0430 2 \u0438 \u0442.\u0434.*\/     htim.Init.Prescaler = (HAL_RCC_GetPCLK1Freq() \/ 1000000) - 1;     \/\/ \u043f\u0435\u0440\u0438\u043e\u0434 50 \u043c\u043a\u0441, \u0441 -1, \u0434\u0443\u043c\u0430\u044e, \u0432\u0441\u0435 \u043f\u043e\u043d\u044f\u0442\u043d\u043e     htim.Init.Period = 50 - 1;      \/\/ \u0437\u0430\u043f\u0438\u0448\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u0430, \u043e\u043d\u043e \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0442\u0430\u0439\u043c\u0435\u0440\u0430     timeout = usTim1Timerout50us;      \/\/ \u0432\u0441\u0435, \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0442\u0430\u0439\u043c\u0435\u0440\u0430, \u0432\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u0434\u0435\u043b\u0430\u0435\u0442 HAL     return HAL_OK == HAL_TIM_Base_Init(&htim) ? TRUE : FALSE; <\/code><\/pre>\n<p>  \u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>vMBPortTimersEnable()<\/code>. \u0422\u0443\u0442 2 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f:<\/p>\n<ol>\n<li> \u0421\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u0442\u0430\u0439\u043c\u0435\u0440.<\/li>\n<li> \u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0442\u0430\u0439\u043c\u0435\u0440 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e \u0441 \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0439 \u0441\u0432\u044f\u0437\u044c\u044e \u043f\u043e \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044e.<\/li>\n<\/ol>\n<p>  <\/p>\n<pre><code class=\"cpp\">    downcounter = timeout;     HAL_TIM_Base_Start_IT(&htim); <\/code><\/pre>\n<p>  \u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>vMBPortTimersDisable()<\/code>. \u0422\u0443\u0442 \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0442\u043a\u043b\u044e\u0447\u0438\u043c \u0442\u0430\u0439\u043c\u0435\u0440.<\/p>\n<pre><code class=\"cpp\">    HAL_TIM_Base_Stop_IT(&htim); <\/code><\/pre>\n<p>  \u0422\u0430\u043a\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0434\u043b\u044f \u0440\u0435\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0430 \u0442\u0430\u0439\u043c\u0435\u0440 <code>HAL_TIM_Base_Stop_IT()<\/code>:<\/p>\n<pre><code class=\"cpp\">    \/\/ \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0435 \u0442\u043e\u0433\u043e \u0442\u0438\u043f\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0443\u0436\u0435\u043d \u0438 \u043e\u043d \u043d\u0430\u0448\u0435\u0433\u043e \u0442\u0430\u0439\u043c\u0435\u0440\u0430     if(__HAL_TIM_GET_FLAG(&htim, TIM_FLAG_UPDATE) != RESET && __HAL_TIM_GET_IT_SOURCE(&htim, TIM_IT_UPDATE) !=RESET) {         __HAL_TIM_CLEAR_IT(&htim, TIM_IT_UPDATE); \/\/ \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c \u0444\u043b\u0430\u0433 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f         if (!--downcounter) \/\/ \u0434\u0435\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0438\u0440\u0443\u0435\u043c \u0441\u0447\u0435\u0442\u0447\u0438\u043a, \u043f\u043e\u043a\u0430 \u043e\u043d \u043d\u0435 \u0434\u043e\u0441\u0442\u0438\u0433\u043d\u0435\u0442 \u043d\u0443\u043b\u044f             prvvTIMERExpiredISR(); \/\/ \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c callback \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438     } <\/code><\/pre>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">porttimer.c<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">\/*  * FreeModbus Libary: BARE Port  * Copyright (C) 2006 Christian Walter &lt;wolti@sil.at&gt;  *  * This library is free software; you can redistribute it and\/or  * modify it under the terms of the GNU Lesser General Public  * License as published by the Free Software Foundation; either  * version 2.1 of the License, or (at your option) any later version.  *  * This library is distributed in the hope that it will be useful,  * but WITHOUT ANY WARRANTY; without even the implied warranty of  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU  * Lesser General Public License for more details.  *  * You should have received a copy of the GNU Lesser General Public  * License along with this library; if not, write to the Free Software  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA  *  * File: $Id: porttimer.c,v 1.1 2006\/08\/22 21:35:13 wolti Exp $  *\/  \/* ----------------------- Platform includes --------------------------------*\/ #include &quot;port.h&quot; #include &quot;stm32f3xx_hal_tim.h&quot;  \/* ----------------------- Modbus includes ----------------------------------*\/ #include &quot;mb.h&quot; #include &quot;mbport.h&quot;  \/* ----------------------- static functions ---------------------------------*\/ static void prvvTIMERExpiredISR( void ); static TIM_HandleTypeDef htim;  static uint16_t timeout = 0; static uint16_t downcounter = 0;  \/* ----------------------- Start implementation -----------------------------*\/ BOOL xMBPortTimersInit( USHORT usTim1Timerout50us ) { \thtim.Instance = TIM6; \thtim.Init.CounterMode = TIM_COUNTERMODE_UP; \thtim.Init.Prescaler = (HAL_RCC_GetPCLK1Freq() \/ 1000000) - 1; \thtim.Init.Period = 50 - 1;  \ttimeout = usTim1Timerout50us;      return HAL_OK == HAL_TIM_Base_Init(&htim) ? TRUE : FALSE; }  inline void vMBPortTimersEnable(  ) {     \/* Enable the timer with the timeout passed to xMBPortTimersInit( ) *\/ \tdowncounter = timeout; \tHAL_TIM_Base_Start_IT(&htim); }  inline void vMBPortTimersDisable(  ) {     \/* Disable any pending timers. *\/ \tHAL_TIM_Base_Stop_IT(&htim); }  \/* Create an ISR which is called whenever the timer has expired. This function  * must then call pxMBPortCBTimerExpired( ) to notify the protocol stack that  * the timer has expired.  *\/ static void prvvTIMERExpiredISR( void ) {     ( void )pxMBPortCBTimerExpired(  ); }  void TIM6_DAC1_IRQHandler(void) { \t\/* TIM Update event *\/ \tif(__HAL_TIM_GET_FLAG(&htim, TIM_FLAG_UPDATE) != RESET && __HAL_TIM_GET_IT_SOURCE(&htim, TIM_IT_UPDATE) !=RESET) { \t\t__HAL_TIM_CLEAR_IT(&htim, TIM_IT_UPDATE); \t\tif (!--downcounter) \t\t\tprvvTIMERExpiredISR(); \t} }  <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<h5>portserial.c<\/h5>\n<p>  \u0412 \u043e\u0431\u0449\u0435\u043c \u0442\u043e \u0432\u0441\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u0431\u044b\u043b\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0430 \u0438\u043c\u0435\u043d\u043d\u043e \u0438\u0437-\u0437\u0430 \u044d\u0442\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c UART-layer \u043d\u0430 STM32 \u043f\u043e\u0434 \u00ab\u0447\u0438\u0441\u0442\u044b\u043c\u00bb HAL \u043c\u043d\u0435 \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0438 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u043b\u0435\u0437\u0442\u044c \u0433\u043b\u0443\u0431\u0436\u0435. \u0412 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u044b \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f, \u0441\u0438\u0433\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u044e\u0449\u0438\u0435 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0431\u0443\u0444\u0444\u0435\u0440 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043f\u0443\u0441\u0442 \u0438 \u0447\u0442\u043e \u0431\u0443\u0444\u0444\u0435\u0440 \u043f\u0440\u0438\u0435\u043c\u0430 \u043d\u0435 \u043f\u0443\u0441\u0442. \u0410 HAL \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0442\u0430\u043a\u0438\u0435 callback&#8217;\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0431\u0443\u0434\u0435\u043c \u0432\u044b\u043f\u0435\u043d\u0434\u0440\u0438\u0432\u0430\u0442\u044c\u0441\u044f.<\/p>\n<p>  \u0422\u0435\u0437\u0430\u0443\u0440\u0443\u0441:<\/p>\n<p>  huart \u2014 handler \u0434\u043b\u044f UART, <code>static UART_HandleTypeDef<\/code><br \/>  DE_Port \u2014 \u043f\u043e\u0440\u0442 \u043d\u043e\u0436\u043a\u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u043a\u0430\u043d\u0430\u043b\u0430, <code>static GPIO_TypeDef *<\/code><br \/>  DE_Pin \u2014 \u043f\u0438\u043d \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u043a\u0430\u043d\u0430\u043b\u0430, <code>static uint16_t<\/code><\/p>\n<p>  \u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>vMBPortSerialEnable()<\/code>. \u0422\u0443\u0442 \u043c\u044b \u043e\u0431\u0440\u0430\u0442\u0438\u043c\u0441\u044f \u043a \u00ab\u0441\u043a\u0440\u044b\u0442\u044b\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044f\u043c\u00bb HAL.<\/p>\n<pre><code class=\"cpp\">    if (xRxEnable) { \/\/ \u0435\u0441\u043b\u0438 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u0435\u043c\u0441\u044f \u0432 \u0440\u0435\u0436\u0438\u043c \u043f\u0440\u0438\u0435\u043c\u0430         \/\/ \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0434\u0440\u0430\u0439\u0432\u0435\u0440 \u0432 \u0440\u0435\u0436\u0438\u043c \u043f\u0440\u0438\u0435\u043c\u0430 (\u0441\u043c. \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u044b \u0440\u0430\u0431\u043e\u0442\u044b rs485)         HAL_GPIO_WritePin(DE_Port, DE_Pin, GPIO_PIN_RESET);         __HAL_UART_ENABLE_IT(&huart, UART_IT_RXNE); \/\/ \u0440\u0430\u0437\u0440\u0435\u0448\u0430\u0435\u043c \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0435, \u0440\u0435\u0430\u0433\u0438\u0440\u0443\u0435\u0442 \u0435\u0441\u043b\u0438 \u0431\u0443\u0444\u0435\u0440 \u043f\u0440\u0438\u0435\u043c\u0430 \u043d\u0435 \u043f\u0443\u0441\u0442     } else {         __HAL_UART_DISABLE_IT(&huart, UART_IT_RXNE); \/\/ \u0437\u0430\u043f\u0440\u0435\u0449\u0430\u0435\u043c \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0435     }     if (xTxEnable) { \/\/ \u0435\u0441\u043b\u0438 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u0435\u043c\u0441\u044f \u0432 \u0440\u0435\u0436\u0438\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438         \/\/ \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0434\u0440\u0430\u0439\u0432\u0435\u0440 \u0432 \u0440\u0435\u0436\u0438\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 (\u0441\u043c. \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u044b \u0440\u0430\u0431\u043e\u0442\u044b rs485)         HAL_GPIO_WritePin(DE_Port, DE_Pin, GPIO_PIN_SET);         __HAL_UART_ENABLE_IT(&huart, UART_IT_TXE); \/\/ \u0440\u0430\u0437\u0440\u0435\u0448\u0430\u0435\u043c \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0435, \u0440\u0435\u0430\u0433\u0438\u0440\u0443\u0435\u0442 \u0435\u0441\u043b\u0438 \u0431\u0443\u0444\u0435\u0440 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043f\u0443\u0441\u0442     } else {         __HAL_UART_DISABLE_IT(&huart, UART_IT_TXE); \/\/ \u0437\u0430\u043f\u0440\u0435\u0449\u0430\u0435\u043c \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0435     } <\/code><\/pre>\n<p>  \u0414\u0430\u043b\u0435\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u043e\u0440\u0442\u0430 <code>xMBPortSerialInit()<\/code>. \u0421\u0434\u0435\u043b\u0430\u043b \u0435\u0435 \u0431\u043e\u043b\u0435\u0435-\u043c\u0435\u043d\u0435\u0435 \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u043e\u0439, \u043e\u043d\u0430 \u0441\u0430\u043c\u0430 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u0439 UART, \u043d\u043e \u043d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0435\u043c, \u0447\u0442\u043e \u0447\u0430\u0441\u0442\u044c \u0441 MSP-\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0430: \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0438\u043d\u043e\u0432, \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f \u0438 \u043f\u0440.<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">xMBPortSerialInit()<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">    huart.Init.Mode = UART_MODE_TX_RX; \/\/ \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u043d\u0430 \u043f\u0440\u0438\u0435\u043c \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0443     huart.Init.HwFlowCtl = UART_HWCONTROL_NONE; \/\/ \u0431\u0435\u0437 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044f \u043f\u043e\u0442\u043e\u043a\u0430 (\u0443 \u043d\u0430\u0441 \u0436\u0435 rs485)     \/\/ \u0441\u044d\u043c\u043f\u043b\u0438\u043d\u0433, \u043d\u0435 \u043c\u043e\u0433\u0443 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e \u043e\u0431\u044a\u044f\u0441\u043d\u0438\u0442\u044c, \u043d\u043e \u044d\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0434\u043b\u044f \u0437\u0430\u0449\u0438\u0442\u044b \u043e\u0442 \u0448\u0443\u043c\u043e\u0432     huart.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;     huart.Init.OverSampling = UART_OVERSAMPLING_16;     \/\/ \u043e\u0434\u0438\u043d \u0441\u0442\u043e\u043f-\u0431\u0438\u0442     huart.Init.StopBits = UART_STOPBITS_1;     \/\/ \u0431\u0435\u0437 \u0434\u043e\u043f-\u0444\u0438\u0447     huart.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;      \/\/ \u043f\u043e\u0440\u0442\u043e\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u0430\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f: UART, \u043d\u043e\u0436\u043a\u0430 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044f \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u0435\u043c\u043e\u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438     switch (ucPORT) {     case 0:         huart.Instance = USART1;         DE_Port = GPIOA;         DE_Pin = GPIO_PIN_12;             break;     case 1:         huart.Instance = USART2;         DE_Port = GPIOA;         DE_Pin = GPIO_PIN_1;             break;     case 2:         huart.Instance = USART3;         DE_Port = GPIOB;         DE_Pin = GPIO_PIN_14;             break;     default:         \/\/ \u0432\u044b\u0437\u043e\u0432\u0435\u043c \u043e\u0448\u0438\u0431\u043a\u0443, \u0435\u0441\u043b\u0438 \u0432\u044b\u0431\u0440\u0430\u043b\u0438 \u043d\u0435 \u0442\u043e\u0442 \u043d\u043e\u043c\u0435\u0440 \u043f\u043e\u0440\u0442\u0430, \u0445\u043e\u0442\u044f \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u043e\u0439 \u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043d\u043e \u0445\u043e\u0442\u044c \u0447\u0442\u043e-\u0442\u043e         return FALSE;     }      \/\/ \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c     huart.Init.BaudRate = ulBaudRate;      \/\/ \u0440\u0430\u0437\u043c\u0435\u0440 \u0441\u043b\u043e\u0432\u0430     switch (ucDataBits) {     case 8:         huart.Init.WordLength = UART_WORDLENGTH_8B;         break;     case 9:         huart.Init.WordLength = UART_WORDLENGTH_9B;         break;     default:         \/\/ \u0432\u044b\u0437\u043e\u0432\u0435\u043c \u043e\u0448\u0438\u0431\u043a\u0443, \u0435\u0441\u043b\u0438 \u0432\u044b\u0431\u0440\u0430\u043b\u0438 \u043d\u0435 \u0442\u043e\u0442 \u043d\u043e\u043c\u0435\u0440 \u043f\u043e\u0440\u0442\u0430, \u0445\u043e\u0442\u044f \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u043e\u0439 \u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043d\u043e \u0445\u043e\u0442\u044c \u0447\u0442\u043e-\u0442\u043e         return FALSE;     }      \/\/ \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c \u0431\u0438\u0442 \u0447\u0435\u0442\u043d\u043e\u0441\u0442\u0438     switch (eParity) {     case MB_PAR_NONE:         huart.Init.Parity = UART_PARITY_NONE;         break;     case MB_PAR_EVEN:         huart.Init.Parity = UART_PARITY_EVEN;         break;     case MB_PAR_ODD:         huart.Init.Parity = UART_PARITY_ODD;         break;     default:         \/\/ \u0432\u044b\u0437\u043e\u0432\u0435\u043c \u043e\u0448\u0438\u0431\u043a\u0443, \u0435\u0441\u043b\u0438 \u0432\u044b\u0431\u0440\u0430\u043b\u0438 \u043d\u0435 \u0442\u043e\u0442 \u043d\u043e\u043c\u0435\u0440 \u043f\u043e\u0440\u0442\u0430, \u0445\u043e\u0442\u044f \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u043e\u0439 \u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043d\u043e \u0445\u043e\u0442\u044c \u0447\u0442\u043e-\u0442\u043e         return FALSE;     }      \/\/ \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u043f\u043e\u0440\u0442, \u043a\u0430\u043a rs485     return HAL_OK == HAL_RS485Ex_Init(&huart, UART_DE_POLARITY_HIGH, 0, 0) ? TRUE : FALSE; <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432\u0432\u043e\u0434\u0430\/\u0432\u044b\u0432\u043e\u0434\u0430 <code>xMBPortSerialPutByte()<\/code> \u0438 <code>xMBPortSerialGetByte()<\/code>. \u0422\u0443\u0442 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0434\u0435\u043b\u0430\u0442\u044c \u0445\u0430\u0440\u0434\u043a\u043e\u0440\u043d\u044b\u0439 \u043d\u0438\u0437\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u044b\u0439 (\u0434\u043b\u044f HAL) IO, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u044b UART&#8217;\u0430.<\/p>\n<p>  \u0414\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u0431\u0430\u0439\u0442\u0430 \u0438\u0437 \u043f\u043e\u0440\u0442\u0430: <code>*pucByte = huart.Instance-&gt;RDR<\/code><br \/>  \u0414\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0438 \u0431\u0430\u0439\u0442\u0430 \u0432 \u043f\u043e\u0440\u0442: <code>huart.Instance-&gt;TDR = ucByte<\/code><\/p>\n<p>  \u0418, \u043d\u0430\u043f\u043e\u0441\u043b\u0435\u0434\u043e\u043a, \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>UART_IRQ_Handler()<\/code>, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u044b \u043e\u043f\u0438\u0441\u0430\u043b\u0438 \u0432 <i>port.h<\/i>. \u041e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u0437\u0430 \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0439 \u0432\u0432\u043e\u0434\u0430\/\u0432\u044b\u0432\u043e\u0434\u0430. \u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0438\u0434\u0435\u044f: \u0435\u0441\u043b\u0438 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0435 \u00ab\u043d\u0430\u0448\u0435\u00bb, \u0442.\u0435. \u043e\u0442 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u043e\u0440\u0442\u0430, \u0438 \u0442\u043e, \u0447\u0442\u043e \u043c\u044b \u0436\u0434\u0435\u043c, \u0442\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c <code>TRUE<\/code> \u2014 \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442, \u0447\u0442\u043e \u043c\u044b \u0435\u0433\u043e \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u0438\u043b\u0438.<\/p>\n<pre><code class=\"cpp\">    if (usart == huart.Instance) { \/\/ \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c, \u0447\u0442\u043e \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0435\u043e\u0442 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u043e\u0440\u0442\u0430         if((__HAL_UART_GET_IT(&huart, UART_IT_RXNE) != RESET) && (__HAL_UART_GET_IT_SOURCE(&huart, UART_IT_RXNE) != RESET)) { \/\/ \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c, \u0447\u0442\u043e \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e             pxMBFrameCBByteReceived(); \/\/ \u0441\u043e\u043e\u0431\u0449\u0438\u043c \u043e\u0431 \u044d\u0442\u043e\u043c \u0431\u0438\u0431\u043b\u043c\u043e\u0442\u0435\u043a\u0435             __HAL_UART_SEND_REQ(&huart, UART_RXDATA_FLUSH_REQUEST); \/\/ \u043d\u0430\u0434\u043e \u0441\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0435             return TRUE; \/\/ \u0433\u043e\u0432\u043e\u0440\u0438\u043c, \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u0438\u043b\u0438         }         if((__HAL_UART_GET_IT(&huart, UART_IT_TXE) != RESET) &&(__HAL_UART_GET_IT_SOURCE(&huart, UART_IT_TXE) != RESET)) { \/\/ \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c, \u0447\u0442\u043e \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e             pxMBFrameCBTransmitterEmpty(); \/\/ \u0441\u043e\u043e\u0431\u0449\u0438\u043c \u043e\u0431 \u044d\u0442\u043e\u043c \u0431\u0438\u0431\u043b\u043c\u043e\u0442\u0435\u043a\u0435             return TRUE; \/\/ \u0433\u043e\u0432\u043e\u0440\u0438\u043c, \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u0438\u043b\u0438         }     }     return FALSE; \/\/ \u0433\u043e\u0432\u043e\u0440\u0438\u043c, \u0447\u0442\u043e \u044d\u0442\u043e \u043d\u0435 \u043d\u0430\u0448\u0435, \u043f\u0443\u0441\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0442 \u0434\u0430\u043b\u044c\u0448\u0435 <\/code><\/pre>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">portserial.c<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">\/*  * FreeModbus Libary: BARE Port  * Copyright (C) 2006 Christian Walter &lt;wolti@sil.at&gt;  *  * This library is free software; you can redistribute it and\/or  * modify it under the terms of the GNU Lesser General Public  * License as published by the Free Software Foundation; either  * version 2.1 of the License, or (at your option) any later version.  *  * This library is distributed in the hope that it will be useful,  * but WITHOUT ANY WARRANTY; without even the implied warranty of  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU  * Lesser General Public License for more details.  *  * You should have received a copy of the GNU Lesser General Public  * License along with this library; if not, write to the Free Software  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA  *  * File: $Id: portserial.c,v 1.1 2006\/08\/22 21:35:13 wolti Exp $  *\/  #include &quot;port.h&quot;  \/* ----------------------- Modbus includes ----------------------------------*\/ #include &quot;mb.h&quot; #include &quot;mbport.h&quot;  \/* ----------------------- static functions ---------------------------------*\/ static UART_HandleTypeDef huart; static GPIO_TypeDef * DE_Port; static uint16_t DE_Pin; \/* ----------------------- Start implementation -----------------------------*\/ void vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable ) {     \/* If xRXEnable enable serial receive interrupts. If xTxENable enable      * transmitter empty interrupts.      *\/ \tif (xRxEnable) { \t\tHAL_GPIO_WritePin(DE_Port, DE_Pin, GPIO_PIN_RESET); \t\t__HAL_UART_ENABLE_IT(&huart, UART_IT_RXNE); \t} else { \t\t__HAL_UART_DISABLE_IT(&huart, UART_IT_RXNE); \t}  \tif (xTxEnable) { \t\tHAL_GPIO_WritePin(DE_Port, DE_Pin, GPIO_PIN_SET); \t\t__HAL_UART_ENABLE_IT(&huart, UART_IT_TXE); \t} else { \t\t__HAL_UART_DISABLE_IT(&huart, UART_IT_TXE); \t} }  BOOL xMBPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity ) { \thuart.Init.Mode = UART_MODE_TX_RX; \thuart.Init.HwFlowCtl = UART_HWCONTROL_NONE; \thuart.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED; \thuart.Init.OverSampling = UART_OVERSAMPLING_16; \thuart.Init.StopBits = UART_STOPBITS_1; \thuart.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;  \tswitch (ucPORT) { \tcase 0: \t\thuart.Instance = USART1; \t\tDE_Port = GPIOA; \t\tDE_Pin = GPIO_PIN_4; \t\tbreak; \tcase 1: \t\thuart.Instance = USART2; \t\tDE_Port = GPIOA; \t\tDE_Pin = GPIO_PIN_1; \t\tbreak; \tcase 2: \t\thuart.Instance = USART3; \t\tDE_Port = GPIOB; \t\tDE_Pin = GPIO_PIN_14; \t\tbreak; \tdefault: \t\treturn FALSE; \t}  \thuart.Init.BaudRate = ulBaudRate;  \tswitch (ucDataBits) { \t\tcase 8: \t\t\thuart.Init.WordLength = UART_WORDLENGTH_8B; \t\t\tbreak; \t\tcase 9: \t\t\thuart.Init.WordLength = UART_WORDLENGTH_9B; \t\t\tbreak; \t\tdefault: \t\t\treturn FALSE; \t}  \tswitch (eParity) { \tcase MB_PAR_NONE: \t\thuart.Init.Parity = UART_PARITY_NONE; \t\tbreak; \tcase MB_PAR_EVEN: \t\thuart.Init.Parity = UART_PARITY_EVEN; \t\tbreak; \tcase MB_PAR_ODD: \t\thuart.Init.Parity = UART_PARITY_ODD; \t\tbreak; \tdefault: \t\treturn FALSE; \t}      return HAL_OK == HAL_RS485Ex_Init(&huart, UART_DE_POLARITY_HIGH, 0, 0); }  BOOL xMBPortSerialPutByte( CHAR ucByte ) {     \/* Put a byte in the UARTs transmit buffer. This function is called      * by the protocol stack if pxMBFrameCBTransmitterEmpty( ) has been      * called. *\/ \thuart.Instance-&gt;TDR = ucByte;     return TRUE; }  BOOL xMBPortSerialGetByte( CHAR * pucByte ) {     \/* Return the byte in the UARTs receive buffer. This function is called      * by the protocol stack after pxMBFrameCBByteReceived( ) has been called.      *\/ \t*pucByte = huart.Instance-&gt;RDR;     return TRUE; }  BOOL UART_IRQ_Handler(USART_TypeDef * usart) { \tif (usart == huart.Instance) { \t\tif((__HAL_UART_GET_IT(&huart, UART_IT_RXNE) != RESET) && (__HAL_UART_GET_IT_SOURCE(&huart, UART_IT_RXNE) != RESET)) { \t\t\tpxMBFrameCBByteReceived(); \t\t\t__HAL_UART_SEND_REQ(&huart, UART_RXDATA_FLUSH_REQUEST); \t\t\treturn TRUE; \t\t} \t\tif((__HAL_UART_GET_IT(&huart, UART_IT_TXE) != RESET) &&(__HAL_UART_GET_IT_SOURCE(&huart, UART_IT_TXE) != RESET)) { \t\t\tpxMBFrameCBTransmitterEmpty(); \t\t\treturn TRUE; \t\t} \t} \treturn FALSE; } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u041a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0431\u044b \u043d\u0430 \u044d\u0442\u043e\u043c \u0432\u0441\u0435, \u043d\u043e \u0435\u0441\u0442\u044c \u0435\u0449\u0435 \u043f\u0430\u0440\u0430 \u043c\u043e\u043c\u0435\u043d\u0442\u043e\u0432:<\/p>\n<p>  \u041a\u0430\u043a \u0432\u044b \u043c\u043e\u0433\u043b\u0438 \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>UART_IRQ_Handler()<\/code> \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442. \u0427\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c, \u043d\u0430\u0434\u043e \u043f\u043e\u0441\u0435\u0442\u0438\u0442\u044c \u0444\u0430\u0439\u043b <i>stm32f3xx_it.c<\/i>. \u0422\u0430\u043c \u0434\u043e\u0431\u0430\u0432\u0438\u043c include \u0434\u043b\u044f <i>port.h<\/i>. \u0412\u043e \u0432\u0441\u0435 USARTx_IRQ_Handler&#8217;\u044b \u043d\u0430\u0434\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 (\u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 <code>USART1_IRQ_Handle()<\/code>).<\/p>\n<pre><code class=\"cpp\">    \/\/ \u0435\u0441\u043b\u0438 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0447\u0435\u043d\u043e, \u0442\u043e \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u0435\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0434\u0430\u043b\u044c\u0448\u0435     if (FALSE != UART_IRQ_Handler(USART1))         return; <\/code><\/pre>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">stm32f3xx_it.h<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">\/**   ******************************************************************************   * @file    stm32f3xx_it.c   * @brief   Interrupt Service Routines.   ******************************************************************************   *   * COPYRIGHT(c) 2016 STMicroelectronics   *   * Redistribution and use in source and binary forms, with or without modification,   * are permitted provided that the following conditions are met:   *   1. Redistributions of source code must retain the above copyright notice,   *      this list of conditions and the following disclaimer.   *   2. Redistributions in binary form must reproduce the above copyright notice,   *      this list of conditions and the following disclaimer in the documentation   *      and\/or other materials provided with the distribution.   *   3. Neither the name of STMicroelectronics nor the names of its contributors   *      may be used to endorse or promote products derived from this software   *      without specific prior written permission.   *   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &quot;AS IS&quot;   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.   *   ******************************************************************************   *\/ \/* Includes ------------------------------------------------------------------*\/ #include &quot;stm32f3xx_hal.h&quot; #include &quot;stm32f3xx.h&quot; #include &quot;stm32f3xx_it.h&quot;  \/* USER CODE BEGIN 0 *\/ #include &quot;port.h&quot; \/* USER CODE END 0 *\/  \/* External variables --------------------------------------------------------*\/ extern UART_HandleTypeDef huart1;  \/******************************************************************************\/ \/*            Cortex-M4 Processor Interruption and Exception Handlers         *\/  \/******************************************************************************\/  \/** * @brief This function handles System tick timer. *\/ void SysTick_Handler(void) {   \/* USER CODE BEGIN SysTick_IRQn 0 *\/    \/* USER CODE END SysTick_IRQn 0 *\/   HAL_IncTick();   HAL_SYSTICK_IRQHandler();   \/* USER CODE BEGIN SysTick_IRQn 1 *\/    \/* USER CODE END SysTick_IRQn 1 *\/ }  \/******************************************************************************\/ \/* STM32F3xx Peripheral Interrupt Handlers                                    *\/ \/* Add here the Interrupt Handlers for the used peripherals.                  *\/ \/* For the available peripheral interrupt handler names,                      *\/ \/* please refer to the startup file (startup_stm32f3xx.s).                    *\/ \/******************************************************************************\/  \/** * @brief This function handles USART1 global interrupt \/ USART1 wake-up interrupt through EXTI line 25. *\/ void USART1_IRQHandler(void) {   \/* USER CODE BEGIN USART1_IRQn 0 *\/ \tif (FALSE != UART_IRQ_Handler(USART1)) \t\treturn;   \/* USER CODE END USART1_IRQn 0 *\/   HAL_UART_IRQHandler(&huart1);   \/* USER CODE BEGIN USART1_IRQn 1 *\/    \/* USER CODE END USART1_IRQn 1 *\/ }  \/* USER CODE BEGIN 1 *\/  \/* USER CODE END 1 *\/ \/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****\/ <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0418 \u0441\u0430\u043c\u043e\u0435 \u0441\u0442\u0440\u0430\u043d\u043d\u043e\u0435, \u0447\u0442\u043e \u044f \u043f\u043e\u043a\u0430 \u0442\u0430\u043a \u0438 \u043d\u0435 \u0441\u043c\u043e\u0433 \u0440\u0435\u0448\u0438\u0442\u044c: \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430, \u043f\u0440\u0438 \u043e\u0442\u0432\u0435\u0442\u0435, \u043e\u0442\u0434\u0430\u0432\u0430\u043b\u0430 \u0432\u0441\u0435 \u0431\u0430\u0439\u0442\u044b \u043a\u0440\u043e\u043c\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e. \u041c\u0435\u043d\u044f \u044d\u0442\u043e \u0443\u0431\u0438\u0432\u0430\u043b\u043e, \u043f\u0440\u0438\u0447\u0435\u043c \u043f\u0440\u0438 \u043f\u043e\u0434\u0441\u0447\u0435\u0442\u0435 \u0432\u0441\u0435 \u0431\u044b\u043b\u043e \u041e\u041a, \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e \u044d\u0442\u043e \u0432\u043e\u043f\u0440\u043e\u0441 UART&#8217;\u0430 \u0438\u043b\u0438 \u043a\u0440\u0438\u0432\u044b\u0445 \u0440\u0443\u043a, \u043d\u043e \u0441\u043f\u0430\u0441\u043b\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435: \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432 \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0431\u0430\u0439\u0442 \u043d\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0443 \u0435\u0449\u0435 \u0435\u0434\u0438\u043d\u0438\u0446\u0443 (\u0444\u0430\u0439\u043b <i>modbus\/rtu\/mbrtu.c<\/i> \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>eMBRTUSend()<\/code>).<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">modbus\/rtu\/mbrtu.c \u0444\u0443\u043d\u043a\u0446\u0438\u044f eMBRTUSend()<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">eMBErrorCode eMBRTUSend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLength ) {     eMBErrorCode    eStatus = MB_ENOERR;     USHORT          usCRC16;      ENTER_CRITICAL_SECTION(  );      \/* Check if the receiver is still in idle state. If not we where to      * slow with processing the received frame and the master sent another      * frame on the network. We have to abort sending the frame.      *\/     if( eRcvState == STATE_RX_IDLE )     {         \/* First byte before the Modbus-PDU is the slave address. *\/         pucSndBufferCur = ( UCHAR * ) pucFrame - 1;         usSndBufferCount = 1;          \/* Now copy the Modbus-PDU into the Modbus-Serial-Line-PDU. *\/         pucSndBufferCur[MB_SER_PDU_ADDR_OFF] = ucSlaveAddress;         usSndBufferCount += usLength;          \/* Calculate CRC16 checksum for Modbus-Serial-Line-PDU. *\/         usCRC16 = usMBCRC16( ( UCHAR * ) pucSndBufferCur, usSndBufferCount );         ucRTUBuf[usSndBufferCount++] = ( UCHAR )( usCRC16 & 0xFF );         ucRTUBuf[usSndBufferCount++] = ( UCHAR )( usCRC16 &gt;&gt; 8 );           usSndBufferCount++; \/\/ \u0432\u043e\u0442 \u0442\u0443\u0442 \u044d\u0442\u043e\u0442 \u043a\u043e\u0441\u0442\u044b\u043b\u044c \u043e\u0431\u0438\u0442\u0430\u0435\u0442           \/* Activate the transmitter. *\/         eSndState = STATE_TX_XMIT;         vMBPortSerialEnable( FALSE, TRUE );     }     else     {         eStatus = MB_EIO;     }     EXIT_CRITICAL_SECTION(  );     return eStatus; } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<h4>3. Usage<\/h4>\n<p>  \u0423\u0436\u0435 \u043f\u043e\u0447\u0442\u0438 \u0433\u043e\u0442\u043e\u0432\u043e.<\/p>\n<h5>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430<\/h5>\n<p>  \u041f\u043e\u0441\u0435\u0442\u0438\u043c <i>mbconfig.h<\/i>. \u0418\u0449\u0438\u0442\u0435 \u0435\u0433\u043e \u0432 include&#8217;\u0430\u0445. \u0423 \u043c\u0435\u043d\u044f SW4STM32, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u0435\u043d\u044f \u0441\u043f\u0430\u0441\u0430\u0435\u0442 Ctrl + Click. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u0443\u0435\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u0441 ModbusRTU:<\/p>\n<pre><code class=\"cpp\">\/*! \\brief If Modbus ASCII support is enabled. *\/ #define MB_ASCII_ENABLED                        (  0 )  \/*! \\brief If Modbus RTU support is enabled. *\/ #define MB_RTU_ENABLED                          (  1 )  \/*! \\brief If Modbus TCP support is enabled. *\/ #define MB_TCP_ENABLED                          (  0 ) <\/code><\/pre>\n<p>  \u0415\u0449\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u043e\u0442\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435, \u044d\u0442\u043e \u043e\u0431\u043b\u0435\u0433\u0447\u0438\u0442 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043d\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c callback&#8217;\u0438.<\/p>\n<h5>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435<\/h5>\n<p>  <\/p>\n<ol>\n<li> #include \u00abmb.h<\/li>\n<li> eMBInit()<\/li>\n<li> eMBEnable()<\/li>\n<li> eMBPoll()<\/li>\n<\/ol>\n<p>  \u0418 \u043d\u0435 \u0437\u0430\u0431\u0443\u0434\u044c\u0442\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c callback&#8217;\u0438.<\/p>\n<p>  \u041d\u0430 \u044d\u0442\u043e\u043c \u0441\u0447\u0438\u0442\u0430\u044e, \u0447\u0442\u043e \u0441\u0432\u043e\u044e \u043c\u0438\u0441\u0441\u0438\u044e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043b, \u0437\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u043c\u0438 \u0438 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0435\u0439 \u0438\u0434\u0438\u0442\u0435 \u043d\u0430 <a href=\"http:\/\/www.freemodbus.org\/api\/index.html\">\u043e\u0444\u0444-\u0441\u0430\u0439\u0442<\/a>.<\/p>\n<p>  Usage: <a href=\"http:\/\/www.freemodbus.org\/api\/group__modbus.html\">Modules\/Modbus<\/a><br \/>  Callbacks: <a href=\"http:\/\/www.freemodbus.org\/api\/group__modbus__registers.html\">Modules\/Modbus Registers<\/a>       <\/p>\n<div class=\"clear\"><\/div>\n<p> \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:\/\/habrahabr.ru\/post\/279747\/\"> https:\/\/habrahabr.ru\/post\/279747\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>       \u0421 \u043d\u0435\u0434\u0430\u0432\u043d\u0438\u0445 \u043f\u043e\u0440 \u044f \u043d\u0430\u0447\u0430\u043b \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c\u0441\u044f \u0432\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c\u044b\u043c\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u043c\u0438 \u0438 \u0434\u043e\u043a\u0430\u0442\u0438\u043b\u0441\u044f \u0434\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u0438\u043a\u0440\u043e\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u043e\u0432, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e STM32F373. \u041e\u0434\u043d\u043e\u0439 \u0438\u0437 \u0437\u0430\u0434\u0430\u0447 \u0431\u044b\u043b\u043e \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u044c Modbus Slave RTU \u043f\u043e\u0432\u0435\u0440\u0445 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 rs485.<\/p>\n<p>  \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0441\u0440\u043e\u043a\u0438 \u043f\u043e\u0434\u0436\u0438\u043c\u0430\u043b\u0438 \u0431\u044b\u043b\u043e \u043f\u0440\u0438\u043d\u044f\u0442\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0432\u0437\u044f\u0442\u044c \u0447\u0442\u043e-\u043d\u0438\u0431\u0443\u0434\u044c \u0433\u043e\u0442\u043e\u0432\u043e\u0435, \u0447\u0435\u043c \u044f \u0438 \u0437\u0430\u043d\u044f\u043b\u0441\u044f. \u041d\u0435\u0434\u043e\u043b\u0433\u043e\u0435 \u0433\u0443\u0433\u043b\u0435\u043d\u0438\u0435 \u043d\u0430\u0432\u0435\u043b\u043e \u043c\u0435\u043d\u044f \u043d\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 <a href=\"http:\/\/www.freemodbus.org\/\">FreeModbus<\/a>, \u0430 \u0432\u043e\u0442 \u0442\u0443\u0442 \u043d\u0430\u0447\u0430\u043b\u0430\u0441\u044c \u0431\u043e\u043b\u044c \u0441 \u043a\u043e\u0442\u043e\u0440\u043e\u0439, \u044f \u043d\u0430\u0434\u0435\u044e\u0441\u044c, \u0432\u044b \u043d\u0435 \u0441\u0442\u043e\u043b\u043a\u043d\u0435\u0442\u0435\u0441\u044c.  <\/p>\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-276577","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/276577","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=276577"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/276577\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=276577"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=276577"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=276577"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}