打印
[活动专区]

【N32G430开发板试用】RTX+MODBUS测试

[复制链接]
467|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 aple0807 于 2022-7-2 19:57 编辑

首先感谢论坛提供的开发板进行学习,N32G430是接触国民技术的第二款芯片,拿到板子先添加RTX操作系统及基本的外设测试。整体用法和STM32基本一致,但N32G430提供了更灵活的外设管脚映射,同一外设提供了更多的管脚选择方案。

RTX作为arm官方RTOS,直接从KEIL安装目录复制出来添加到工程即可,配置也比较简单,本次测试os tick配置为500Hz。对于高速MCU来说,使用RTOS可以显著提高MCU的运转效率,能有效解决一些外设对系统的阻塞。

分享一个IO配置模板程序,个人感觉这样更直观一些
typedef const struct
{
        GPIO_Module *port;
        uint32_t mode;
        uint32_t pull;
        uint32_t rate;
        uint32_t current;
        uint32_t alt;
        uint32_t val_init;
        uint32_t pin;

} gpio_init_cfg_type;

static gpio_init_cfg_type gpio_cfg[] = {
        {GPIOA, GPIO_MODE_AF_PP, GPIO_NO_PULL, GPIO_SLEW_RATE_FAST, GPIO_DS_8MA, GPIO_AF5_USART1, 1, GPIO_PIN_9},
        {GPIOA, GPIO_MODE_AF_PP, GPIO_PULL_UP, GPIO_SLEW_RATE_FAST, GPIO_DS_8MA, GPIO_AF5_USART1, 1, GPIO_PIN_10},
        
        {GPIOB, GPIO_MODE_AF_PP, GPIO_NO_PULL, GPIO_SLEW_RATE_FAST, GPIO_DS_8MA, GPIO_AF10_UART3, 1, GPIO_PIN_10},
        {GPIOB, GPIO_MODE_AF_PP, GPIO_PULL_UP, GPIO_SLEW_RATE_FAST, GPIO_DS_8MA, GPIO_AF10_UART3, 1, GPIO_PIN_11},
        
        {GPIOB, GPIO_MODE_AF_PP, GPIO_NO_PULL, GPIO_SLEW_RATE_FAST, GPIO_DS_8MA, GPIO_AF7_UART4, 1, GPIO_PIN_0},
        {GPIOB, GPIO_MODE_AF_PP, GPIO_PULL_UP, GPIO_SLEW_RATE_FAST, GPIO_DS_8MA, GPIO_AF7_UART4, 1, GPIO_PIN_1},
        
        {GPIOA, GPIO_MODE_OUT_PP, GPIO_NO_PULL, GPIO_SLEW_RATE_FAST, GPIO_DS_8MA, 0, 1, GPIO_PIN_15},
        {GPIOB, GPIO_MODE_OUT_PP, GPIO_NO_PULL, GPIO_SLEW_RATE_FAST, GPIO_DS_8MA, 0, 1, GPIO_PIN_3},
        {GPIOB, GPIO_MODE_OUT_PP, GPIO_NO_PULL, GPIO_SLEW_RATE_FAST, GPIO_DS_8MA, 0, 1, GPIO_PIN_4},
};

void bsp_gpio_init(void)
{
        int index;

        // clock enable
        RCC_APB2_Peripheral_Clock_Enable(RCC_APB2_PERIPH_AFIO);
        
        RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOA);
        RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOB);
        RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOC);
        RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOD);
        
        
        for(int index = 0;index < sizeof(gpio_cfg)/sizeof(gpio_cfg[0]);index++)
        {
                GPIO_InitType GPIO_InitStructure;

                GPIO_Structure_Initialize(&GPIO_InitStructure);
               
                GPIO_InitStructure.Pin          = gpio_cfg[index].pin;

                GPIO_InitStructure.GPIO_Mode    = gpio_cfg[index].mode;

                GPIO_InitStructure.GPIO_Current = gpio_cfg[index].current;
               
                GPIO_InitStructure.GPIO_Alternate = gpio_cfg[index].alt;
               
                GPIO_InitStructure.GPIO_Slew_Rate = gpio_cfg[index].rate;
               
                GPIO_InitStructure.GPIO_Pull = gpio_cfg[index].pull;

                GPIO_Peripheral_Initialize(gpio_cfg[index].port, &GPIO_InitStructure);
               
                if(GPIO_InitStructure.GPIO_Mode == GPIO_MODE_OUT_PP || GPIO_InitStructure.GPIO_Mode == GPIO_MODE_OUT_OD)
                {
                        if(gpio_cfg[index].val_init)
                                GPIO_Pins_Set(gpio_cfg[index].port, gpio_cfg[index].pin);
                        else
                                GPIO_Pins_Reset(gpio_cfg[index].port, gpio_cfg[index].pin);
                }
        }
}
本示例配置UART1,UART3,UART4的管脚,UART1作为调试打印端口,UART和UART4分别做MODBUS主机和从机。
modbus用现成的协议栈,只需要修改端口及定时器管理即可。端口部分主要是初始化和中断处理,定时器在1ms系统定时器中计数处理。

modbus串口初始化
static void mb_port_Init(mb_mode_type mbMode, uint32_t ulBaudRate, mb_parity_type eParity)
{
        USART_InitType cfg;

        mb_port_hal_cfg();

        mbObjInit(mbMode);

        mb_byte_send = mb_rtu_byte_send;

        cfg.Mode = USART_MODE_RX | USART_MODE_TX;
        cfg.HardwareFlowControl = USART_HFCTRL_NONE;
        cfg.BaudRate = ulBaudRate;

        if (mbMode == MB_RTU_MASTER || mbMode == MB_RTU_SLAVE)
        {
                // rtu mode
                if (MB_PAR_NONE == eParity)
                {
                        cfg.WordLength = USART_WL_8B;
                        cfg.StopBits = USART_STPB_2;
                        cfg.Parity = USART_PE_NO;
                }
                else if (MB_PAR_NONE_1S == eParity)
                {
                        cfg.WordLength = USART_WL_8B;
                        cfg.StopBits = USART_STPB_1;
                        cfg.Parity = USART_PE_NO;
                }
                else if (MB_PAR_ODD == eParity)
                {
                        cfg.WordLength = USART_WL_9B;
                        cfg.StopBits = USART_STPB_1;
                        cfg.Parity = USART_PE_ODD;
                }
                else
                {
                        cfg.WordLength = USART_WL_9B;
                        cfg.StopBits = USART_STPB_1;
                        cfg.Parity = USART_PE_EVEN;
                }

                mbObj.run_st.bits.rtu_mode = 1;
        }
        else
        {
                mb_byte_send = mb_asc_byte_send;

                // asc mode
                if (MB_PAR_NONE == eParity)
                {
                        cfg.WordLength = USART_WL_8B;
                        cfg.StopBits = USART_STPB_1;
                        cfg.Parity = USART_PE_NO;
                }
                else if (MB_PAR_NONE_1S == eParity)
                {
                        cfg.WordLength = USART_WL_8B;
                        cfg.StopBits = USART_STPB_1;
                        cfg.Parity = USART_PE_NO;
                }
                else if (MB_PAR_ODD == eParity)
                {
                        cfg.WordLength = USART_WL_8B;
                        cfg.StopBits = USART_STPB_1;
                        cfg.Parity = USART_PE_ODD;
                }
                else
                {
                        cfg.WordLength = USART_WL_8B;
                        cfg.StopBits = USART_STPB_1;
                        cfg.Parity = USART_PE_EVEN;
                }

                mbObj.run_st.bits.rtu_mode = 0;
        }

        // rtu timer
        if (mbObj.run_st.bits.rtu_mode == 0)
        {
                mbObj.rtu_timer_sv = 240;
                mbObj.timeout_set = 500;
        }
        else
        {
                if (ulBaudRate > 19200)
                {
                        mbObj.rtu_timer_sv = 3;
                }
                else
                {
                        mbObj.rtu_timer_sv = (com_timer_cal(ulBaudRate, (35 * 11 + 9) / 10, 300, 12000) + 99) / 100;
                }
        }

        USART_Initializes(mbPORT, &cfg);
        USART_Enable(mbPORT);

        nvic_irq_set(mbURT_IRQn, 0x06, 1);

        mb_tx1_rx0_enable(0);
}
isr服务程序
void mbISR()
{
        volatile uint32_t IntSt;
        volatile uint8_t Data;

        mbObj.timeout_cnt = 0;

        IntSt = mbPORT->STS;

        if (IntSt & USART_STS_RXDNE)
        {
                Data = UART_RCV_DAT();

                if ((IntSt & UART_RX_ERR_FLAG) != 0)
                {
                        if (mbObj.rcv_cnt >= 1)
                        {
                                mbObj.err_st.bits.hal = 1;
                        }
                }

                mb_data_rcv(&mbObj, Data);
        }
        else if ((mbObj.snd_size <= mbObj.snd_cnt) && (IntSt & USART_STS_TXC))
        {
                mb_send_end(&mbObj);
                mb_tx1_rx0_enable(0);
                UART_TX_TC_CLR();
        }
        else if (IntSt & USART_STS_TXDE)
        {
                if (mb_data_send(&mbObj, mb_byte_send, 1))
                {
                        UART_TX_TC_EN();
                }
        }
        else
        {
        }
}
下面附上测试工程,欢迎讨论。

本测试将开发板PB0连接PB11,PB1连接PB10,可令modbus主机和从机进行通信。
===========================================================================
内部资源分配:
===========================================================================
UART1: 调试信息打印
UART3: MODBUS 主机 PB10, PB11
UART4: MODBUS 从机 PB0, PB1
===========================================================================
demo-n32g430.rar (2.26 MB)

另外顺便调了一下串口打印,上电按按键结果如下:

@安小芯  

使用特权

评论回复
沙发
huahuagg| | 2022-7-6 21:06 | 只看该作者
看代码,这个系列的单片机架构跟STM32的很像啊。

使用特权

评论回复
板凳
aple0807|  楼主 | 2022-7-7 08:23 | 只看该作者
huahuagg 发表于 2022-7-6 21:06
看代码,这个系列的单片机架构跟STM32的很像啊。

P2P的,外设结构类似,细节有区别

使用特权

评论回复
地板
daichaodai| | 2022-7-7 08:27 | 只看该作者
正在学RTX,谢谢楼主分享。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

68

主题

309

帖子

2

粉丝