Modbus TCP throught DM9051

AN0211

应用笔记

Modbus TCP throught DM9051

                                                                               

前言

Modbus是一种串行通讯协议,在工业领域为事实上的业界标准,是工业电子装置之间常用的连接方式;本应用笔记将介绍Modbus TCP, 透过TCP/IP来实现Modbus协议。

支持型号列表:

支持型号

AT32F423xx

目录

1              Modbus概述... 5

1.1      网络拓朴... 5

1.2      封包格式... 5

2              例  Modbus TCP. 7

2.1      功能简介... 7

2.2      资源准备... 7

2.3      软件设计... 8

2.4      操作方式... 12

3              文档版本历史.. 17

表目录

表1. DM9051脚位对照... 8

表2. 文档版本历史... 17

图目录

图1. Modbus network topology. 5

图2. Modbus TCP packet format 6

图3. AT-START-F423开发板及DM9051, 电机和温度传感器... 7

图4. Modbus Poll Connection Page. 13

图5. LED Control 14

图6. 读取温度传感器... 15

图7. 控制步进电机... 16

  1. Modbus概述

关于Modbus详细的协议内容,请参阅Modbus组织的参考指南,这篇应用笔记只会提及关键的网络拓朴与封包格式。

    1. 网络拓朴

Modbus协议是一个master/slave架构的协议,有一个节点是master节点,其他使用Modbus协议参与通讯的节点是slave节点。本应用笔记提供的sample code是作为slave参与Modbus协议通讯。

1. Modbus network topology

    1. 封包格式

在传输过程中,client与server的讯息至少会有Function Code与Data两部份:

  •   Function Code: 代表要执行的动作代码,例如读取或写入。
  •   Data: 代表动作执行代码的相关参数,例如读取某个地址上的数据,或是回传某个地址上的数据作为结果。

Function Code和Data是整个Modbus沟通最基本的单元,也称作Protocol Data Unit(PDU)。

除此之外,根据传输方式不同可能还会在头尾加上一些附加信息,附加后的整个讯息称为Application Data Unit(ADU)。

2. Modbus TCP packet format

Function Code的详细定义,可以参考Modbus的参考指南。

  1. 例  Modbus TCP
    1. 功能简介

透过DM9051参与Modbus TCP协议,提供以下功能:

  1. LED开关
  2. 读取温度传感器数据
  3. 控制步进电机的正反转
    1. 资源准备
  1. 硬件环境:

对应产品型号的AT-START BOARD

3. AT-START-F423开发板及DM9051, 电机和温度传感器

  1. 软件环境

Source Code\utilities\demo\mdk_v5

  1. 上位机软件: Modbus Poll
    1. 软件设计
  1. 配置流程
  1. 初始化DM9051,DM9051对应的脚位请参照表1
  2. 初始化LwIP
  3. 启动Modbus Task
  4. 配置ADC读取温度传感器数值
  5. 配置GPIO控制电机

1. DM9051脚位对照

  1. 代码介绍
  1. main函数代码描述

int main(void)

{

       error_status status;

       system_clock_config();

       at32_board_init();

       uart_print_init(115200);

       status = env_dm9051f_system_init();

       while(status == ERROR);  

       tcpip_stack_init();

       modbus_task();

#ifdef en_temperature

       adc_pin_config();

       adc_config();

       adc_ordinary_software_trigger_enable(ADC1, TRUE);

#endif   

#ifdef en_motor

       motor_pin_init();

       motor_init();

#endif          

       while(1)

       {

              /* lwip receive handle */

              lwip_rx_loop_handler();

              /*timeout handle*/

              lwip_periodic_handle(local_time);

              eMBPoll();

#ifdef en_motor

              motor_run(Motor_Postion,motor_en);

#endif                 

       }

}

  1. DM9051初始化函数代码描述

error_status env_dm9051f_system_init(void)

{

       printf("dm9051_pins_configuration\r\n");

  dm9051_pins_configuration();

       dm9051_HW_reset();

       printf("dm9051_(%x %x %x %x)\r\n",DM9051_Read_Reg(0x28),DM9051_Read_Reg(0x29),DM9051_Read_Reg(0x2A),DM9051_Read_Reg(0x2B));

       dm9051_tmr3_init();

       printf("dm9051_tmr3_init end\r\n");

  return SUCCESS;

}

             

  1. Modbus Task初始化函数代码描述

void modbus_task(void)

{

  eMBErrorCode    eStatus;

 

 /* ucPort: select port_uart.

  * this parameter can be one of the following values:

  * 0: USART2: tx--PA2,  rx--PA3,  de--PA1;

  * 1: USART3: tx--PB10, rx--PB11, de--PB14;

  * other: invalid.

  */

  eStatus = eMBInit(MB_TCP, MB_SLAVE_ADDRESS, 0, MB_BAUDRATE, MB_PAR_NONE);

  if(MB_ENOERR == eStatus)

  {

    printf("modbus init ok\r\n");

    eStatus = eMBEnable();

    if(MB_ENOERR == eStatus)

    {

      printf("modbus enable ok\r\n");

    }

    else

    {

      printf("modbus enable fail, error code: %u\r\n", eStatus);

    }

  }

  else

  {

    printf("modbus init fail, error code: %u\r\n", eStatus);

  }

 

  if(MB_ENOERR != eStatus)

  {

    printf("exit modbus task.\r\n");

    return;

  }

}

  1. ADC初始化函数代码描述

void adc_config(void)

{

  adc_common_config_type adc_common_struct;

  adc_base_config_type adc_base_struct;

  crm_periph_clock_enable(CRM_ADC1_PERIPH_CLOCK, TRUE);

  nvic_irq_enable(ADC1_IRQn, 0, 0);

  crm_adc_clock_select(CRM_ADC_CLOCK_SOURCE_HCLK);

  adc_common_default_para_init(&adc_common_struct);

  /* config division,adcclk is division by hclk */

  adc_common_struct.div = ADC_HCLK_DIV_4;

  /* config inner temperature sensor and vintrv */

  adc_common_struct.tempervintrv_state = FALSE;

  adc_common_config(&adc_common_struct);

  adc_base_default_para_init(&adc_base_struct);

  adc_base_struct.sequence_mode = TRUE;

  //adc_base_struct.repeat_mode = FALSE;

  adc_base_struct.repeat_mode = TRUE;

  adc_base_struct.data_align = ADC_RIGHT_ALIGNMENT;

  adc_base_struct.ordinary_channel_length = 1;

  adc_base_config(ADC1, &adc_base_struct);

  adc_resolution_set(ADC1, ADC_RESOLUTION_12B);

  /* config ordinary channel */

  adc_ordinary_channel_set(ADC1, ADC_CHANNEL_1, 1, ADC_SAMPLETIME_92_5);

  /* config ordinary trigger source and trigger edge */

  adc_ordinary_conversion_trigger_set(ADC1, ADC_ORDINARY_TRIG_TMR1CH1, ADC_ORDINARY_TRIG_EDGE_NONE);

  /* config dma mode,it's not useful when common dma mode is use */

  adc_dma_mode_enable(ADC1, TRUE);

  /* config dma request repeat,it's not useful when common dma mode is use */

  adc_dma_request_repeat_enable(ADC1, FALSE);

  /* enable adc overflow interrupt */

  adc_interrupt_enable(ADC1, ADC_OCCO_INT, TRUE);

  /* adc enable */

  adc_enable(ADC1, TRUE);

  while(adc_flag_get(ADC1, ADC_RDY_FLAG) == RESET);

  /* adc calibration */

  adc_calibration_init(ADC1);

  while(adc_calibration_init_status_get(ADC1));

  adc_calibration_start(ADC1);

  while(adc_calibration_status_get(ADC1));

}

  1. 电机初始化函数代码描述

void motor_init(void)

{

       printf("motor_init\r\n");

       gpio_bits_write(IO0,FALSE);

       gpio_bits_write(IO1,FALSE);

       gpio_bits_write(IO2,FALSE);

       gpio_bits_write(IO3,FALSE);

       motor_en=0;  

}

    1. 操作方式
  1. 开启Modbus Poll当作Modbus Master并联机,请参照图3
  2. 控制LED的方法为透过Modbus Poll上的Write Single Coil(0x05)设定开关, 请参照图4
  3. 读取温度传感器的数值方法为读取holding register, 请参照图5
  4. 控制Motor的方式为:
    •   先设定holding registerAddress 5为正转(1)或反转(2
    •   再设定holding registerAddress 6决定要走几步(4096步为一圈)

4. Modbus Poll Connection Page

5. LED Control

6. 读取温度传感器

图7. 制步进电机

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值