微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > DSP学习交流 > + 实现RS485与Modbus协议

+ 实现RS485与Modbus协议

时间:10-02 整理:3721RD 点击:
一、主要功能
电脑发命令到开发板,开发板通过RS485总线读取终端数据,再把数据发回电脑。


二、准备
RS-485的电气特性:采用差分信号负逻辑,逻辑"1”以两线间的电压差为+(2~6)V表示;逻辑"0"以两线间的电压差为-(2~6)V表示。接口信号电平比RS-232-C降低了,就不易损坏接口电路的芯片, 且该电平与TTL电平兼容,可方便与TTL电路连接。
ModBus网络是一个工业通信系统,由带智能终端的可编程序控制器和计算机通过公用线路或局部专用线路连接而成。其系统结构既包括硬件、亦包括软件。它可应用于各种数据采集和过程监控。
485转232模块:


自己做的RS485模块


三、过程
RS485只是物理上的总线,对于今天 的开发,它只是物理媒介。
主要的还是Modbus的开发。
使用到的外设是串口0。
首先,当然是设置串口0 了。
初始化函数如下。

  1. void UARTInit(void)
  2. {
  3.         PSCModuleControl(SOC_PSC_0_REGS, HW_PSC_UART0, PSC_POWERDOMAIN_ALWAYS_ON,PSC_MDCTL_NEXT_ENABLE);

  4.         // UART0 禁用流控
  5.         UARTPinMuxSetup(0, FALSE);

  6.         // 初始化 DSP 中断控制器
  7.         IntDSPINTCInit();

  8.         // 使能 DSP 全局中断
  9.         IntGlobalEnable();

  10.         // 配置 UART20 参数
  11.         // 波特率 115200 数据位 8 停止位 1 无校验位
  12.     UARTConfigSetExpClk(SOC_UART_0_REGS, UART_0_FREQ, BAUD_115200,
  13.                                   UART_WORDL_8BITS, UART_OVER_SAMP_RATE_16);
  14.         // 使能 UART2
  15.         UARTEnable(SOC_UART_0_REGS);

  16.     // 使能接收 / 发送 FIFO
  17.     UARTFIFOEnable(SOC_UART_0_REGS);

  18.     // 设置 FIFO 级别
  19.     UARTFIFOLevelSet(SOC_UART_0_REGS, UART_RX_TRIG_LEVEL_1);

  20.     /*              UART 中断初始化                                             */
  21.         IntRegister(C674X_MASK_INT4, UARTIsr);
  22.         IntEventMap(C674X_MASK_INT4, SYS_INT_UART0_INT);
  23.         IntEnable(C674X_MASK_INT4);

  24.         // 使能中断
  25.         unsigned int intFlags = 0;
  26.     intFlags |= (UART_INT_LINE_STAT  |  \
  27.                  UART_INT_TX_EMPTY |    \
  28.                  UART_INT_RXDATA_CTI);
  29.     UARTIntEnable(SOC_UART_0_REGS, intFlags);
  30. }

复制代码


这里是用中断方式,可以提高Modbus的实时性。
Modbus主要的发送帧格式如下


接收帧格式为:


发送时,就按这个格式向串口中发数据。
接收时,
1、先判断设备地址是不是与发送的数据的设备地址一样,否则丢弃。
2、再判断功能码,与设备地址一样的逻辑。
3、根据寄存器地址,确定这个数据的含意,是电压、电流、开入量......
4、读取数据。
5、计算CRC,若一样就是数据正确,否则丢弃。

  1.                 if((ReceiveBuffer[0] == Set_Data.Addr)||(ReceiveBuffer[0] == 0xff))//设备地址
  2.                 {
  3.                         crcData.all=crc16(ReceiveBuffer,rc-2);//CRC检验
  4.                         i=(crcData.bit.U16L==ReceiveBuffer[rc-2])&&(crcData.bit.U16H==ReceiveBuffer[rc-1]);
  5.                         //if(((crcData.bit.U16L==ReceiveBuffer[rc-2])&&(crcData.bit.U16H==ReceiveBuffer[rc-1])))
  6.                         if(i)
  7.                         {
  8.                                 switch(ReceiveBuffer[1]){//功能码
  9.                                         case 1:
  10.                                                         break;
  11.                                         case 3:
  12.                                        
  13.                                                         read_registers_0304();
  14.                                                         BeginSend();
  15.                                                         break;
  16.                                         default:break;
  17.                                 }
  18.                         }

  19.                 }

复制代码


其中CRC的程序为:

  1. unsigned int CRC16 ( uchar *arr_buff, uchar len)
  2. {

  3. uint crc=0xFFFF;
  4. uchar i, j, Data;
  5. for ( j=0; j
  6. {

  7.    crc=crc ^*arr_buff++;
  8.    for ( i=0; i 0)

  9.        {

  10.            crc=crc>>1;

  11.            crc=crc^ 0xa001;

  12.         }
  13.       else

  14.           crc=crc>>1;
  15.    }
  16. }
  17. return ( crc);

  18. }

复制代码


四、结果


读取了电压值为220.2V

不错的文档,小编太棒了

向师傅学习。谢谢分享。

----------------------------------------

好文章,讲解很详细,图文并茂

看框图的意思是电力仪表和485转232都挂在485总线上,dsp主控?

测试的时候是的,就是为了测试modbus,之后 ,DSP也是做为一个终端设备,与仪表是一样的。通讯管理机去读取这些设备的数据上传到PC上。
多捧场     http://bbs.elecfans.com/jishu_531047_1_1.html

谢谢分享。

多捧场     http://bbs.elecfans.com/jishu_531047_1_1.html

期待小编上源码

谢谢分享。

上一篇:+ fatfs移植的注意事项
下一篇:+ 定时器

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top