你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F的232口简易MODBUS-RTU通讯程序

[复制链接]
incompletely 发布时间:2008-9-3 20:07
/*****************************************************
          modbus-rtu 通讯规约
通讯方式:rs-485 半双功
校验方式:crc16
停止位:2位
编写:孙可
编程思路:
    1.串口中断允许自动接收总线上的信息,当接收的字节后超过3.5个字节时间没有新的字节认为本次接收完成,接收完成标志置1;如果接收完成标志已经置1又有数据进来则丢弃新来的数据。
    2.串口接收数据的处理, 当接收完成标志置1进入接收数据处理, (1)首先判断接收的第一位数据与本机地址是否相同,如果不相同清空接收缓存不发送任何信息; (2)接收的第一位数据与本机地址相同,则对接收缓存中的数据进行crc16校验,如果接收的校验位与本校验结果不相同清空接收缓存不发送任何信息;(3)如果crc16校验正确则根据数据串中的命令码进行相应的处理。
******************************************************/

#include "modbus.h"
u8 Com0_id = 0x05;//本机串口0的通讯地址
u8 Uart0_rev_buff[100];//com0串口接收缓冲区
u8 Uart0_send_buff[100];//com0串口发送缓冲区
vu8 Uart0_rev_count;
vs8 Uart0_send_counter = 0;
vu8 Uart0_rev_comflag;
vu8 Crc_counter = 0;//com0校验计数器
vu8 *Uart0_send_pointer = Uart0_send_buff;//com0串口发送指针
vu16 Mkgz_bz = 0;//模块故障标志1:输入异常,2:过压,3:欠压,4:过温
vu16 Out_current = 50;//输出电流
vu16 Out_voltage = 240;//输出电压
vu16 Mkzt_bz = 0;//模块状态标志
vu16 OutX_current = 1000;//输出限流
vu16 Jc_voltage = 2530;//均充电压
vu16 Fc_voltage = 2400;//浮充电压
vu16 user_day = 1825;//使用天数

void Delay(vu32 nCount);
unsigned short getCRC16(volatile unsigned char *ptr,unsigned char len) ;
void mov_data(u8 a[100],u8 b[100],u8 c);
void Modbus_Function_3(void);
void Modbus_Function_6(void);      
/***************************************
函数名称:crc16校验
函数功能:crc16校验
函数输入:字节指针*ptr,数据长度len
函数返回:双字节crc
函数编写:孙可
编写日期:2008年6月9日
函数版本:v0.2
****************************************/
unsigned short getCRC16(volatile unsigned char *ptr,unsigned char len)
{
    unsigned char i;
    unsigned short crc = 0xFFFF;
    if(len==0)
    {
        len = 1;
    }
    while(len--)  
    {   
        crc ^= *ptr;
        for(i=0; i>= 1;  
                crc ^= 0xA001;
         }  
         else
      {
                crc >>= 1;
         }
        }         
        ptr++;
    }
    return(crc);
}
/***************************************
    块数据复制数据函数
功能:把数组a的c个数据复制到数组b中
输入:指针a,指针b,数据个数c
返回:无
编写:孙可
编写日期:2008年3月28日
版本:v0.1
****************************************/
void mov_data(u8 a[100],u8 b[100],u8 c)
{
    u8 i;
    for(i=c; i>0; i--)
    {
            a = b;
    }
}
///////////////////////////////////////////////////////////////////////
void Modbus_Function_3(void)
{
    u16 tempdress = 0;
    u8 i = 3;
    u16 crcresult;         
    tempdress = (Uart0_rev_buff[2] = 0x0120) & (tempdress + Uart0_rev_buff[5] < 0x0132))
    {
        Uart0_send_buff[0] = Com0_id;
        Uart0_send_buff[1] = 0x03;
        Uart0_send_buff[2] = 2 * Uart0_rev_buff[5];
        Uart0_send_counter = 2 * Uart0_rev_buff[5] + 3;
        switch(tempdress)
     {
            case 0x0120:
      {
                Uart0_send_buff = Mkgz_bz & 0xff;
          i++;
                Uart0_send_buff = (Mkgz_bz >> 8) & 0xff;
             i++;
            }//后面不放break的目的是继续往下执行
            case 0x0122:
      {
                Uart0_send_buff = Out_voltage & 0xff;
          i++;
                Uart0_send_buff = (Out_voltage >> 8) & 0xff;
             i++;
      }
            case 0x0124:
      {
                Uart0_send_buff = Out_current & 0xff;
          i++;
                Uart0_send_buff = (Out_current >> 8) & 0xff;
             i++;
      }
            case 0x0126:
      {
                Uart0_send_buff = Mkzt_bz & 0xff;
          i++;
                Uart0_send_buff = (Mkzt_bz >> 8) & 0xff;
             i++;
      }
            case 0x0128://这个地址是备用的里面的数据没有意义
      {
                Uart0_send_buff = 0x00;
          i++;
                Uart0_send_buff = 0x00;
             i++;
      }
            case 0x012A:
      {
                Uart0_send_buff = OutX_current & 0xff;
          i++;
                Uart0_send_buff = (OutX_current >> 8) & 0xff;
          i++;
      }
            case 0x012C:
      {
                Uart0_send_buff = Jc_voltage & 0xff;
          i++;
                Uart0_send_buff = (Jc_voltage >> 8) & 0xff;
          i++;
      }
            case 0x012E:
      {
                Uart0_send_buff = Fc_voltage & 0xff;
          i++;
                Uart0_send_buff = (Fc_voltage >> 8) & 0xff;
          i++;
      }
            case 0x0130:
      {
                Uart0_send_buff = 0x00;
          i++;
                Uart0_send_buff = 0x00;
          i++;
      }
     }
        //UCSRB |= (1
收藏 评论10 发布时间:2008-9-3 20:07

举报

10个回答
qsj 回答时间:2008-12-28 14:27:45

RE:STM32F的232口简易MODBUS-RTU通讯程序

qazwsx333-13599 回答时间:2009-6-19 10:41:44

RE:STM32F的232口简易MODBUS-RTU通讯程序

billylu06 回答时间:2009-9-3 09:31:35

RE:STM32F的232口简易MODBUS-RTU通讯程序

真的實用,省了時間
judge1 回答时间:2012-12-9 19:39:49

RE:STM32F的232口简易MODBUS-RTU通讯程序

谢谢楼主无私分享。
hai2000 回答时间:2013-7-25 10:15:01

回复:STM32F的232口简易MODBUS-RTU通讯程序

大哥有几个地方,我不太明白:1----Crc_counter似乎只有定义,但是没有赋值;2---Uart0_rev_comflag 问题同上  3----似乎没有主函数MAIN
为方便沟通,特此留下QQ1024829053
walkout 回答时间:2013-7-26 14:01:17

RE:STM32F的232口简易MODBUS-RTU通讯程序

看看
horseman 回答时间:2017-10-23 07:36:56
Thanks!
owenqll 回答时间:2017-10-23 08:47:13
void mov_data(u8 a[100],u8 b[100],u8 c)
{
    u8 i;
    for(i=c; i>0; i--)
    {
            a = b;
    }
}

这个函数有问题吧? a、b分别是数组名称,能直接用a=b吗?
awxcd 回答时间:2018-7-9 18:01:28
谢谢
超声波¹³⁹⁶²²²²³¹³ 回答时间:2021-2-13 00:48:33
正好研究MODBUS。学习了。
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版