[活动专区] 【N32G430开发板试用】RTX+MODBUS测试

[复制链接]
 楼主| aple0807 发表于 2022-6-29 21:18 | 显示全部楼层 |阅读模式
本帖最后由 aple0807 于 2022-7-2 19:57 编辑

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

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

分享一个IO配置模板程序,个人感觉这样更直观一些
  1. typedef const struct
  2. {
  3.         GPIO_Module *port;
  4.         uint32_t mode;
  5.         uint32_t pull;
  6.         uint32_t rate;
  7.         uint32_t current;
  8.         uint32_t alt;
  9.         uint32_t val_init;
  10.         uint32_t pin;

  11. } gpio_init_cfg_type;

  12. static gpio_init_cfg_type gpio_cfg[] = {
  13.         {GPIOA, GPIO_MODE_AF_PP, GPIO_NO_PULL, GPIO_SLEW_RATE_FAST, GPIO_DS_8MA, GPIO_AF5_USART1, 1, GPIO_PIN_9},
  14.         {GPIOA, GPIO_MODE_AF_PP, GPIO_PULL_UP, GPIO_SLEW_RATE_FAST, GPIO_DS_8MA, GPIO_AF5_USART1, 1, GPIO_PIN_10},
  15.         
  16.         {GPIOB, GPIO_MODE_AF_PP, GPIO_NO_PULL, GPIO_SLEW_RATE_FAST, GPIO_DS_8MA, GPIO_AF10_UART3, 1, GPIO_PIN_10},
  17.         {GPIOB, GPIO_MODE_AF_PP, GPIO_PULL_UP, GPIO_SLEW_RATE_FAST, GPIO_DS_8MA, GPIO_AF10_UART3, 1, GPIO_PIN_11},
  18.         
  19.         {GPIOB, GPIO_MODE_AF_PP, GPIO_NO_PULL, GPIO_SLEW_RATE_FAST, GPIO_DS_8MA, GPIO_AF7_UART4, 1, GPIO_PIN_0},
  20.         {GPIOB, GPIO_MODE_AF_PP, GPIO_PULL_UP, GPIO_SLEW_RATE_FAST, GPIO_DS_8MA, GPIO_AF7_UART4, 1, GPIO_PIN_1},
  21.         
  22.         {GPIOA, GPIO_MODE_OUT_PP, GPIO_NO_PULL, GPIO_SLEW_RATE_FAST, GPIO_DS_8MA, 0, 1, GPIO_PIN_15},
  23.         {GPIOB, GPIO_MODE_OUT_PP, GPIO_NO_PULL, GPIO_SLEW_RATE_FAST, GPIO_DS_8MA, 0, 1, GPIO_PIN_3},
  24.         {GPIOB, GPIO_MODE_OUT_PP, GPIO_NO_PULL, GPIO_SLEW_RATE_FAST, GPIO_DS_8MA, 0, 1, GPIO_PIN_4},
  25. };

  26. void bsp_gpio_init(void)
  27. {
  28.         int index;

  29.         // clock enable
  30.         RCC_APB2_Peripheral_Clock_Enable(RCC_APB2_PERIPH_AFIO);
  31.         
  32.         RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOA);
  33.         RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOB);
  34.         RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOC);
  35.         RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOD);
  36.         
  37.         
  38.         for(int index = 0;index < sizeof(gpio_cfg)/sizeof(gpio_cfg[0]);index++)
  39.         {
  40.                 GPIO_InitType GPIO_InitStructure;

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

  44.                 GPIO_InitStructure.GPIO_Mode    = gpio_cfg[index].mode;

  45.                 GPIO_InitStructure.GPIO_Current = gpio_cfg[index].current;
  46.                
  47.                 GPIO_InitStructure.GPIO_Alternate = gpio_cfg[index].alt;
  48.                
  49.                 GPIO_InitStructure.GPIO_Slew_Rate = gpio_cfg[index].rate;
  50.                
  51.                 GPIO_InitStructure.GPIO_Pull = gpio_cfg[index].pull;

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

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

  4.         mb_port_hal_cfg();

  5.         mbObjInit(mbMode);

  6.         mb_byte_send = mb_rtu_byte_send;

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

  10.         if (mbMode == MB_RTU_MASTER || mbMode == MB_RTU_SLAVE)
  11.         {
  12.                 // rtu mode
  13.                 if (MB_PAR_NONE == eParity)
  14.                 {
  15.                         cfg.WordLength = USART_WL_8B;
  16.                         cfg.StopBits = USART_STPB_2;
  17.                         cfg.Parity = USART_PE_NO;
  18.                 }
  19.                 else if (MB_PAR_NONE_1S == eParity)
  20.                 {
  21.                         cfg.WordLength = USART_WL_8B;
  22.                         cfg.StopBits = USART_STPB_1;
  23.                         cfg.Parity = USART_PE_NO;
  24.                 }
  25.                 else if (MB_PAR_ODD == eParity)
  26.                 {
  27.                         cfg.WordLength = USART_WL_9B;
  28.                         cfg.StopBits = USART_STPB_1;
  29.                         cfg.Parity = USART_PE_ODD;
  30.                 }
  31.                 else
  32.                 {
  33.                         cfg.WordLength = USART_WL_9B;
  34.                         cfg.StopBits = USART_STPB_1;
  35.                         cfg.Parity = USART_PE_EVEN;
  36.                 }

  37.                 mbObj.run_st.bits.rtu_mode = 1;
  38.         }
  39.         else
  40.         {
  41.                 mb_byte_send = mb_asc_byte_send;

  42.                 // asc mode
  43.                 if (MB_PAR_NONE == eParity)
  44.                 {
  45.                         cfg.WordLength = USART_WL_8B;
  46.                         cfg.StopBits = USART_STPB_1;
  47.                         cfg.Parity = USART_PE_NO;
  48.                 }
  49.                 else if (MB_PAR_NONE_1S == eParity)
  50.                 {
  51.                         cfg.WordLength = USART_WL_8B;
  52.                         cfg.StopBits = USART_STPB_1;
  53.                         cfg.Parity = USART_PE_NO;
  54.                 }
  55.                 else if (MB_PAR_ODD == eParity)
  56.                 {
  57.                         cfg.WordLength = USART_WL_8B;
  58.                         cfg.StopBits = USART_STPB_1;
  59.                         cfg.Parity = USART_PE_ODD;
  60.                 }
  61.                 else
  62.                 {
  63.                         cfg.WordLength = USART_WL_8B;
  64.                         cfg.StopBits = USART_STPB_1;
  65.                         cfg.Parity = USART_PE_EVEN;
  66.                 }

  67.                 mbObj.run_st.bits.rtu_mode = 0;
  68.         }

  69.         // rtu timer
  70.         if (mbObj.run_st.bits.rtu_mode == 0)
  71.         {
  72.                 mbObj.rtu_timer_sv = 240;
  73.                 mbObj.timeout_set = 500;
  74.         }
  75.         else
  76.         {
  77.                 if (ulBaudRate > 19200)
  78.                 {
  79.                         mbObj.rtu_timer_sv = 3;
  80.                 }
  81.                 else
  82.                 {
  83.                         mbObj.rtu_timer_sv = (com_timer_cal(ulBaudRate, (35 * 11 + 9) / 10, 300, 12000) + 99) / 100;
  84.                 }
  85.         }

  86.         USART_Initializes(mbPORT, &cfg);
  87.         USART_Enable(mbPORT);

  88.         nvic_irq_set(mbURT_IRQn, 0x06, 1);

  89.         mb_tx1_rx0_enable(0);
  90. }
isr服务程序
  1. void mbISR()
  2. {
  3.         volatile uint32_t IntSt;
  4.         volatile uint8_t Data;

  5.         mbObj.timeout_cnt = 0;

  6.         IntSt = mbPORT->STS;

  7.         if (IntSt & USART_STS_RXDNE)
  8.         {
  9.                 Data = UART_RCV_DAT();

  10.                 if ((IntSt & UART_RX_ERR_FLAG) != 0)
  11.                 {
  12.                         if (mbObj.rcv_cnt >= 1)
  13.                         {
  14.                                 mbObj.err_st.bits.hal = 1;
  15.                         }
  16.                 }

  17.                 mb_data_rcv(&mbObj, Data);
  18.         }
  19.         else if ((mbObj.snd_size <= mbObj.snd_cnt) && (IntSt & USART_STS_TXC))
  20.         {
  21.                 mb_send_end(&mbObj);
  22.                 mb_tx1_rx0_enable(0);
  23.                 UART_TX_TC_CLR();
  24.         }
  25.         else if (IntSt & USART_STS_TXDE)
  26.         {
  27.                 if (mb_data_send(&mbObj, mb_byte_send, 1))
  28.                 {
  29.                         UART_TX_TC_EN();
  30.                 }
  31.         }
  32.         else
  33.         {
  34.         }
  35. }
下面附上测试工程,欢迎讨论。

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

另外顺便调了一下串口打印,上电按按键结果如下:
G430.png
@安小芯  
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,谢谢楼主分享。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

77

主题

326

帖子

2

粉丝
快速回复 返回顶部 返回列表