STM32G0开发笔记:FreeRTOS和FreeModbus库使用

发布时间:2023-06-27  

使用Platformio平台的libopencm3开发框架来开发STM32G0,以下为FreeRTOS和FreeModbus库使用。


1 新建项目

建立freertos_modbus项目

在PIO的Home页面新建项目,项目名称freertos_modbus,选择开发板为 MonkeyPi_STM32_G070RB,开发框架选择libopencm3;


项目建立完成后在src目录下新建main.c主程序文件;

修改下载和调试方式,这里开发板使用的是DAPLink仿真器,因此修改platformio.ini文件如下:

1upload_protocol = cmsis-dap

2debug_tool = cmsis-dap

2 编写程序

直接在之前的FreeRTOS工程上进行添加;


2.1 添加 freeModbus 库

从git仓库下载源码: https://github.com/cwalter-at/freemodbus


将下载的源码中的mobus文件夹放置到工程的lib目录下,然后在modbus目录新建library.json文件,内容如下:


1{

 2    "name": "FreeModbus",

 3    "version": "master",

 4    "repository":{

 5        "type":"git",

 6        "url":"https://github.com/cwalter-at/freemodbus"

 7    },

 8    "build": {

 9        "flags": [

10            "-Iascii",

11            "-Ifunctions",

12            "-Iinclude",

13            "-Irtu",

14            "-Itcp"

15        ],

16        "srcFilter": [

17            "+"

18        ]

19    }

20}

然后从FreeModbus源码中的 demoBAREport中复制文件到工程的srcmodbus_port文件夹下,最后的文件夹结构如下:

30273d60cfbcc0ab4b6922ec41567cfb_poYBAGPE8HKAOQsRAACNC8rHm2s539.png

2.2 移植

portevent:

1/* ----------------------- Modbus includes ----------------------------------*/

 2#include "mb.h"

 3#include "mbport.h"

 4#include "FreeRTOS.h"

 5#include "task.h"

 6

 7/* ----------------------- Variables ----------------------------------------*/

 8static eMBEventType eQueuedEvent;

 9static BOOL     xEventInQueue;

10static uint32_t modbus_last_active_time = 0;

11

12uint32_t get_modbus_last_active_time(void)

13{

14    return modbus_last_active_time;

15}

16

17/* ----------------------- Start implementation -----------------------------*/

18BOOL

19xMBPortEventInit( void )

20{

21    xEventInQueue = FALSE;

22    return TRUE;

23}

24

25BOOL

26xMBPortEventPost( eMBEventType eEvent )

27{

28    xEventInQueue = TRUE;

29    eQueuedEvent = eEvent;

30

31    if (eEvent == EV_EXECUTE) {

32        modbus_last_active_time = xTaskGetTickCount();

33    }

34    return TRUE;

35}

36

37BOOL

38xMBPortEventGet( eMBEventType * eEvent )

39{

40    BOOL            xEventHappened = FALSE;

41

42    if( xEventInQueue )

43    {

44        *eEvent = eQueuedEvent;

45        xEventInQueue = FALSE;

46        xEventHappened = TRUE;

47    }

48    return xEventHappened;

49}

portserial

这里使用RS485,因此需要对RS485使能端口进行配置,其他为串口的配置,然后在发送和接收中断时候调用modbus相关接口进行处理:


1#include "port.h"

  2

  3#include "FreeRTOS.h"

  4#include "queue.h"

  5

  6#include 3/cm3/nvic.h>

  7#include 3/stm32/usart.h>

  8#include 3/stm32/rcc.h>

  9#include 3/stm32/gpio.h>

 10

 11/* ----------------------- Modbus includes ----------------------------------*/

 12#include "mb.h"

 13#include "mbport.h"

 14

 15/* ----------------------- static functions ---------------------------------*/

 16

 17xQueueHandle uart_queue;

 18

 19#define RS485_1_CLOCK        RCC_GPIOB

 20#define RS485_1_EN_PORT        GPIOB

 21#define RS485_1_EN_PIN        GPIO8

 22

 23static void rs485_delay(int n)

 24{

 25    while (--n) {

 26        __asm__ volatile ("nop");

 27    }

 28}

 29

 30static inline void rs485_1_rx_mode(void)

 31{

 32    gpio_clear(RS485_1_EN_PORT, RS485_1_EN_PIN);

 33}

 34

 35static inline void rs485_1_tx_mode(void)

 36{

 37    gpio_set(RS485_1_EN_PORT, RS485_1_EN_PIN);

 38}

 39

 40static inline void rs485_gpio_init(void)

 41{

 42    rcc_periph_clock_enable(RS485_1_CLOCK);

 43    gpio_mode_setup(RS485_1_EN_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, RS485_1_EN_PIN);

 44

 45    rs485_1_rx_mode();

 46}

 47

 48/* ----------------------- Start implementation -----------------------------*/

 49void

 50vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable )

 51{

 52    /* If xRXEnable enable serial receive interrupts. If xTxENable enable

 53     * transmitter empty interrupts.

 54     */

 55    if (xRxEnable) {

 56        rs485_delay(10000);

 57        rs485_1_rx_mode();

 58        rs485_delay(10000);

 59        usart_enable_rx_interrupt(USART1);

 60    }

 61    else {

 62        usart_disable_rx_interrupt(USART1);

 63    }

 64

 65    if (xTxEnable) {

 66        rs485_delay(10000);

 67        rs485_1_tx_mode();

 68        rs485_delay(10000);

 69        usart_enable_tx_interrupt(USART1);

 70    }

 71    else {

 72        usart_disable_tx_interrupt(USART1);

 73

 74    }

 75}

 76

 77BOOL

 78xMBPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity )

 79{

 80    nvic_enable_irq(NVIC_USART1_IRQ);

 81

 82    rcc_periph_clock_enable(RCC_GPIOB);

 83    gpio_mode_setup(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO6 | GPIO7);

 84    gpio_set_af(GPIOB, GPIO_AF0, GPIO6 | GPIO7);

 85

 86    rcc_periph_clock_enable(RCC_USART1);

 87

 88    /* Set up USART/UART parameters using the libopencm3 helper functions */

 89    usart_set_baudrate(USART1, ulBaudRate);

 90    usart_set_databits(USART1, ucDataBits);

 91    usart_set_stopbits(USART1, USART_STOPBITS_1);

 92    usart_set_mode(USART1, USART_MODE_TX_RX);

 93

 94    switch (eParity) {

 95        case MB_PAR_ODD:

 96            usart_set_parity(USART1, USART_PARITY_ODD);

 97            break;

 98        case MB_PAR_EVEN:

 99            usart_set_parity(USART1, USART_PARITY_EVEN);

100            break;

101        default:

102            usart_set_parity(USART1, USART_PARITY_NONE);

103            break;

104    }

105

106    usart_set_flow_control(USART1, USART_FLOWCONTROL_NONE);

107

108    usart_enable(USART1);

109

110    rs485_gpio_init();

111

112    return TRUE;

113}

114

115BOOL

116xMBPortSerialPutByte( CHAR ucByte )

117{

118

119    usart_send_blocking(USART1, (uint16_t) ucByte);    

120

121    return TRUE;

122}

123

124BOOL

125xMBPortSerialGetByte( CHAR * pucByte )

126{

127    *pucByte = usart_recv(USART1);

128

129    return TRUE;

130}

131

132

133uint32_t uart1_isr, uart1_icr;

134

135void usart1_isr(void)

136{

137

138    /* Check if we were called because of RXNE. */

139    if (((USART_CR1(USART1) & USART_CR1_RXNEIE) != 0) &&

140        ((USART_ISR(USART1) & USART_ISR_RXNE) != 0)) {

141

142        /* Retrieve the data from the peripheral. */

143        // usart_recv(USART1);

144

145        pxMBFrameCBByteReceived();

146

147    }

148

149

150    /* Check if we were called because of TXE. */

151    if (((USART_CR1(USART1) & USART_CR1_TXEIE) != 0) &&

152        ((USART_ISR(USART1) & USART_ISR_TXE) != 0)) {

153

154        /* Put data into the transmit register. */

155        //usart_send(USART1, data);

156

157        pxMBFrameCBTransmitterEmpty();

158

159    }

160

161}

porttimer

1#include "port.h"

 2

 3#include 

 4#include 

 5#include 

 6

 7/* ----------------------- Modbus includes ----------------------------------*/

 8#include "mb.h"

 9#include "mbport.h"

10

11/* ----------------------- static functions ---------------------------------*/

12static void prvvTIMERExpiredISR( void );

13

14/* ----------------------- Start implementation -----------------------------*/

15BOOL

16xMBPortTimersInit( USHORT usTim1Timerout50us )

17{

18    rcc_periph_clock_enable(RCC_TIM2);

19    nvic_enable_irq(NVIC_TIM2_IRQ);

20    rcc_periph_reset_pulse(RST_TIM2);

21

22    timer_set_mode(TIM2, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);

23

24    timer_set_prescaler(TIM2, (rcc_apb1_frequency/ 20000));

25

26    timer_disable_preload(TIM2);

27    timer_continuous_mode(TIM2);

28

29    timer_set_period(TIM2, usTim1Timerout50us);

30    timer_enable_counter(TIM2);

31

32    timer_enable_irq(TIM2, TIM_DIER_UIE);

33

34    return TRUE;

35}

36

37

38inline void

39vMBPortTimersEnable(  )

40{

41    timer_set_counter(TIM2, 0);

42    timer_enable_counter(TIM2);

43}

44

45inline void

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>