标题: STM8 RS485的modbus通迅(主机及从机)程序代码 [打印本页]

作者: flit1    时间: 2017-8-24 15:49
标题: STM8 RS485的modbus通迅(主机及从机)程序代码
如题,两份源码程序,STVD打开
STM8主控的RS485的modbus通迅所有资料51hei提供下载(含主机和从机程序):
STM8RS485通迅(主机).rar (572.8 KB, 下载次数: 1152)
STM8RS485通迅(从机).rar (613.53 KB, 下载次数: 930)

stm8单片机源程序(从机)如下:
  1. /* Includes ------------------------------------------------------------------*/
  2. #include "stm8s_lib.h"
  3. #include "functions.h"
  4. //#include "STM8S103F.h"
  5. #include "stm8s_tim1.h"

  6. /* Private typedef -----------------------------------------------------------*/
  7. /* Private define ------------------------------------------------------------*/

  8. u16                                          re_CRC16;
  9. u8                                                 CRC_Len;
  10. u8                                                 Data_Len;
  11. u8                                                 OffsetAdr;
  12. u8                                                 SlaveAdr;
  13. u8                                                 ModbusFC;
  14. ModBusData                 ModbusRAM[ModBusRAM_LEN_MAX];

  15. void Respond_ModbusREQ(void);
  16. void Init_Clock(void);
  17. /*
  18. void Init_GPIO(void);
  19. void Init_GPIO(void)
  20. {
  21.     GPIO_Init(GPIOD, GPIO_PIN_6, GPIO_MODE_IN_FL_NO_IT);                                //UART1 RX
  22.           GPIO_Init(GPIOD, GPIO_PIN_5, GPIO_MODE_OUT_PP_HIGH_FAST);                //UART1 TX
  23. }
  24. */
  25. void Init_Clock(void)//
  26. {
  27.     /* Select fCPU = 16MHz*/
  28.                 CLK_DeInit();
  29.     CLK_HSICmd(ENABLE);
  30.     CLK_HSECmd(DISABLE);
  31.                 CLK_SYSCLKConfig(CLK_PRESCALER_HSIDIV1);//CLK_PRESCALER_CPUDIV1 16mhz
  32.                 nop();nop();nop();nop();nop();nop();
  33.     //CLK_CCOConfig(CLK_OUTPUT_CPU);                                /* For test purpose output Fcpu on MCO pin */
  34. }
  35. /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
  36. void Respond_ModbusREQ(void)
  37.         {               
  38.                 u8 tmpMODBUS[RX_LEN_MAX];
  39.                 u8 i;
  40.                
  41.                 ModbusFC = MODBUS[1];
  42.                 Data_Len = MODBUS[5];
  43.                
  44.                 switch(ModbusFC)
  45.                         {
  46.                                 case 0x03:
  47.                                         i = 8;
  48.                                         break;
  49.                                        
  50.                                 case 0x10:
  51.                                         i = (u8)(9 +  (Data_Len * 2));
  52.                                         break;
  53.                                 
  54.                                 default:
  55.                                         i = 0;
  56.                                         break;
  57.                         }
  58.                 if(i>0)
  59.                         {
  60.                                 CRC_Len = (u8)(i - 2);
  61.                                 
  62.                                 while(i>0)
  63.                                 {
  64.                                         tmpMODBUS[i-1] = MODBUS[i-1];
  65.                                         i--;
  66.                                 }
  67.                                 
  68.                                 re_CRC16 = tmpMODBUS[CRC_Len + 1];
  69.                                 re_CRC16 = (re_CRC16<<8)+tmpMODBUS[CRC_Len];                                //寻找接收的CRC码
  70.                                 CRC16    = crc16(tmpMODBUS,CRC_Len);                                                                //计算接收数据的CRC
  71.                                 if((re_CRC16 == CRC16)&&(OffsetAdr<ModBusRAM_LEN_MAX))//如果校验正确  判断功能码和数据起始地址
  72.                                         {
  73.                                                 OffsetAdr = (u8)((tmpMODBUS[3]) * 2);                                                //OffsetAdr = tmpMODBUS[2] * 256 + tmpMODBUS[3];
  74.                                                 Data_Len  = (u8)(tmpMODBUS[5] * 2);                                                        //读写寄存器数量
  75.                                                 switch(ModbusFC)
  76.                                                         {  
  77.                                                                 case 0x03:                                                                                                                                         //判断功能码响应指令 发送被召唤数据
  78.                                                                 {
  79.                                                                         //if(tmpMODBUS[3] == 0x01)
  80.                                                                         //        {                                       
  81.                                                                         tmpMODBUS[2] = Data_Len;                                                                        //字节数=寄存器数量*2
  82.                                                                         for(i=0;i<Data_Len;i++)
  83.                                                                         {
  84.                                                                                 if(i & 0x01)
  85.                                                                                         tmpMODBUS[3 + i] = (u8)(ModbusRAM[((OffsetAdr+i)>>1)].ModBus16Word % 0x100);
  86.                                                                                 else
  87.                                                                                         tmpMODBUS[3 + i] = (u8)(ModbusRAM[((OffsetAdr+i)>>1)].ModBus16Word / 0x100);
  88.                                                                         }
  89.                                                                         
  90.                                                                         CRC_Len = (u8)(3 + Data_Len);
  91.                                                                         CRC16   = crc16(tmpMODBUS,CRC_Len);                                //计算接收数据的CRC
  92.                                                                         tmpMODBUS[CRC_Len]=(u8)(CRC16);                                                //LSB
  93.                                                                         tmpMODBUS[CRC_Len+1]=(u8)(CRC16>>8);                        //MSB
  94.                                                                         SEND_ON
  95.                                                                         for(i=0;i<CRC_Len+2;i++)                                                                        //发送应答数据        多寄存器读命令返回
  96.                                                                                 {
  97.                                                                                         UART1->DR=tmpMODBUS[i];
  98.                                                                                         while (UART1_GetFlagStatus(UART1_FLAG_TXE) == RESET);                        //
  99.                                                                                 }
  100.                                                                         while (UART1_GetFlagStatus(UART1_FLAG_TC) == RESET);
  101.                                                                         SEND_OFF
  102.                                                                                 //}                        
  103.                                                                 }
  104.                                                                 break;
  105.                                                         
  106.                                                                 case 0x10:                                                                                                                                         //如果检测到是多字节写入指令
  107.                                                                 {
  108.                                                                         /*
  109.                                                                         FLASH_SetProgrammingTime(FLASH_PROGRAMTIME_STANDARD);                        //写EEPROM准备
  110.                                                                         FLASH_Unlock(FLASH_MEMTYPE_DATA);        
  111.                                                                         
  112.                                                                         for(i=0;i<Data_Len;i++)                                                                        //写EEP        
  113.                                                                                 {
  114.                                                                                         FLASH_ProgramByte((EEPROM_Start_Adr + OffsetAdr + i), tmpMODBUS[i + 7]);
  115.                                                                                 }
  116.                                                                         */
  117.                                                                         CRC_Len = 3 + 4;                                                                                                //发送应答数据
  118.                                                                         CRC16   = crc16(tmpMODBUS,CRC_Len);                        //计算接收数据的CRC

  119.                                                                         tmpMODBUS[CRC_Len]=(u8)(CRC16);                                        //LSB
  120.                                                                         tmpMODBUS[CRC_Len+1]=(u8)(CRC16>>8);                //MSB
  121.                                                                         SEND_ON
  122.                                                                         for(i=0;i<CRC_Len+2;i++)                                                                //发送应答数据
  123.                                                                                 {
  124.                                                                                         UART1->DR = tmpMODBUS[i];
  125.                                                                                         while (UART1_GetFlagStatus(UART1_FLAG_TXE) == RESET);
  126.                                                                                 }
  127.                                                                         while (UART1_GetFlagStatus(UART1_FLAG_TC) == RESET);
  128.                                                                         SEND_OFF
  129.                                                                 }
  130.                                                                 break;
  131.                                                                
  132.                                                                 default:
  133.                                                                         break;
  134.                                                         }
  135.                                                 return;                                                                                                                                                                        //直接退出中断函数,不执行CT=CT+1;语句
  136.                                         }
  137.                                  else                                                                                                                                                                                         //如果校验出错  发送自定义异常代码 80||03||10,04读写指令ERROR
  138.                                         {        
  139.                                                                                                                                                                                                                                                 //发送异常代码
  140.                                                 tmpMODBUS[1] |= 0x80;                                                                                                                //异常指令 OR
  141.                                                 tmpMODBUS[2]        =        0x04;                                                                                                                //异常代码

  142.                                                 CRC16   = crc16(tmpMODBUS,3);                                                                                //计算接收数据的CRC
  143.                                                 tmpMODBUS[3]         =        (u8)(CRC16);                                                                                //LSB
  144.                                                 tmpMODBUS[4]        =        (u8)(CRC16>>8);                                                                        //MSB
  145.                                                 
  146.                                                 SEND_ON
  147.                                                 for(CRC16=0;CRC16<5;CRC16++)                                                                                //发送应答数据
  148.                                                         {
  149.                                                                 UART1->DR=tmpMODBUS[CRC16];
  150.                                                                 while (UART1_GetFlagStatus(UART1_FLAG_TXE) == RESET);
  151.                                                         }
  152.                                                 while (UART1_GetFlagStatus(UART1_FLAG_TC) == RESET);
  153.                                                 SEND_OFF
  154.                                                 return;
  155.                                         }
  156.                         }
  157.         }
复制代码






作者: stn13135    时间: 2017-9-4 20:45
好东西,正在学习
作者: armauk    时间: 2017-9-25 11:06
好东西,顶顶
作者: ache0105    时间: 2017-9-27 17:18
这是用什么软件写的?
作者: ache0105    时间: 2017-10-19 20:27
请问这是用什么软件编写的?
作者: kkfy888    时间: 2017-10-20 01:07
STVD写的
作者: my_lcs    时间: 2017-10-21 11:03
好东西啊,谢谢啊
作者: my_lcs    时间: 2017-10-21 11:04

学习学习,非常感谢!!!!
作者: laxsystem01    时间: 2017-10-22 18:49
大赞一个,虽然自己已经用了RS485通信好几年了
作者: ahljj    时间: 2017-10-23 09:06
好东西啊
作者: ahljj    时间: 2017-10-23 20:25
STM8 RS485的modbus通迅(主机及从机)程序代码
作者: 12345687    时间: 2017-10-24 20:50
谢谢分享
作者: 狄利克雷    时间: 2017-10-25 00:39
不错的程序哦
作者: flit1    时间: 2017-11-12 03:18
楼主宅心仁厚!谢谢,有没相关图纸?
作者: sunonline2000    时间: 2017-12-5 18:24
非常感谢
作者: ditozy    时间: 2017-12-14 09:57

好东西啊,谢谢啊
作者: zcs1975421    时间: 2017-12-15 15:58
楼主雪中送炭!
作者: viwe    时间: 2018-1-3 15:35
非常感谢,学习1中
作者: yangjf    时间: 2018-1-4 11:35
好东西,正在学习
作者: twjccmx    时间: 2018-1-5 14:42
好东西,谢谢分享
作者: candura    时间: 2018-1-10 10:39
发现一个问题啊,用这个的从机代码出现这样一个情况。
如果之前发送的没问题的话,那么从机反馈的数据也正常。
但是一旦发送过一次有问题的数据,使其返回错误代码了的话,之后即便再发送正确的数据,也是返回错误代码。
作者: dreamflylau007    时间: 2018-1-12 08:17
回复了是不是就可以下载
作者: kfjust    时间: 2018-1-15 11:43
一直再寻找,非常感谢
作者: jmx1124    时间: 2018-1-18 13:25
STM8L的可以用吗
作者: stn13135    时间: 2018-1-27 22:31

好东西,顶顶
作者: zhuangfeng    时间: 2018-1-29 21:24
这没用过stvd,特地下载了一个,但是要打开哪个文件啊
作者: CHao.chen    时间: 2018-2-28 17:39
candura 发表于 2018-1-10 10:39
发现一个问题啊,用这个的从机代码出现这样一个情况。
如果之前发送的没问题的话,那么从机反馈的数据也正 ...

怎么好像进不了中断?还有,你们是用的什么串口工具啊
作者: CHao.chen    时间: 2018-2-28 19:10
楼主有没有相应的PC端工具
作者: jmx1124    时间: 2018-3-6 17:40
学习一下,有没有IAR的
作者: robin97172    时间: 2018-3-7 09:02
谢谢楼主,下来学习
作者: dfl448866    时间: 2018-3-14 00:21
谢谢了 很不错 棒棒的
作者: dfl448866    时间: 2018-3-14 00:21
大赞一个,RS485通信很经典
作者: 15861476366    时间: 2018-3-28 20:08
好东西
作者: picc16    时间: 2018-4-5 21:06
谢谢分享
作者: liushouchao1    时间: 2018-4-9 12:46

谢谢分享
作者: tp80986735    时间: 2018-5-15 19:34
主机模式怎么跟从机是一样的呢?
作者: tyron_chen    时间: 2018-5-16 23:33
向楼主多学习
作者: xode    时间: 2018-5-24 16:12
谢谢分享
作者: zhangshanqiao    时间: 2018-5-26 23:17
不错,程序结构非常好。CRC16   = crc16(tmpMODBUS,3);  中的unsigned int CRC16(unsinge char *dat,unsigned char len)函数没有看到呢?我其实是想找CRC算法来的。
作者: meqqme    时间: 2018-6-9 16:20

一直再寻找,非常感谢
作者: xiao5    时间: 2018-6-16 12:55
好资料,学习
作者: licongjian55    时间: 2018-8-9 23:48
学习一下,谢谢
作者: blue153    时间: 2018-8-15 16:26
一直再寻找,非常感谢

作者: hesan621    时间: 2018-8-17 19:58
Thanks a lot my dear friend

作者: oliverlau2k11    时间: 2018-8-23 10:39
感谢分享,正好需要,谢谢
作者: ztx2168    时间: 2018-8-23 11:26
谢谢,正在找这个。
作者: ztx2168    时间: 2018-8-24 07:46
太好了,正在找这方面程序,谢谢楼主
作者: sundaybadboy    时间: 2018-9-2 11:14
正在学习Modbus ,希望有帮助
作者: stn13135    时间: 2018-9-20 10:32
一直再寻找,非常感谢
作者: stn13135    时间: 2018-9-20 10:33

正在学习Modbus ,希望有帮助
作者: creamy    时间: 2018-9-21 16:57
谢谢楼主分享
作者: zs9999    时间: 2018-9-23 17:28
谢谢分享
作者: c5435    时间: 2018-9-28 10:45
感谢分享
作者: hesan921    时间: 2018-10-14 19:50
Thanks A lot.Thats a Very good library
作者: hesan921    时间: 2018-10-14 19:50
Thanks for sharing
作者: 15158296    时间: 2018-10-19 11:13
谢谢,我参考一下
作者: 领会至爱    时间: 2018-11-1 19:46
好资料,谢谢楼主分享
作者: dfadfad    时间: 2018-11-7 10:44
学习一下
作者: gongkailin    时间: 2018-12-3 00:09
好东西,学习了。
作者: gongkailin    时间: 2018-12-3 00:12
软件结构很好
作者: gongkailin    时间: 2018-12-3 00:15
谢谢楼主分享,宅心仁厚。
作者: 18978722314    时间: 2018-12-25 13:55
主机就一个回应函数呀。。没有别的发送
作者: nanyuanqi    时间: 2019-1-7 20:07
看看。谢谢
作者: pm1981    时间: 2019-1-8 08:51
非常实用
作者: 357881011@qq.co    时间: 2019-1-10 16:05
谢谢,膜拜,膜拜
作者: nashion    时间: 2019-1-10 17:48
正在学习Modbus ,希望有帮助
作者: ABCD12    时间: 2019-1-11 10:21
stn13135 发表于 2017-9-4 20:45
好东西,正在学习

好东西,找了好久

作者: 520good    时间: 2019-1-11 11:03
谢谢分享
作者: xode    时间: 2019-1-13 21:32
谢谢分享,学习了
作者: y790247101    时间: 2019-1-14 19:14
非常好 谢谢
作者: pm1981    时间: 2019-1-16 09:19
谢谢分享
作者: qq3417    时间: 2019-1-20 16:03
学习一下
作者: 962164789    时间: 2019-1-28 01:31
好东西  学习了了
作者: WFX777888    时间: 2019-1-29 08:16
好东西,正在学习
作者: clnbcl    时间: 2019-1-31 13:57
没怎么用stm芯片了,学习。
作者: 乐独    时间: 2019-2-14 16:31
感谢










作者: crossfan    时间: 2019-2-15 15:37
大师,可以帮改成IAR环境的吗,
作者: koethen    时间: 2019-2-28 08:18
非常好的东西!
作者: pm1981    时间: 2019-2-28 09:35
值得学习
作者: diedmen    时间: 2019-3-14 22:01
好东西,顶顶,正好需要
作者: wo411322    时间: 2019-3-27 21:23
正好用上,谢谢楼主奉献
作者: lnpeanut    时间: 2019-3-27 22:06
程序结构蛮不错的,我之前写过一个,不过稍微复杂点
串口接受中断中,数据进一个fifo队列,主程序在队列中筛选modbus指令,判据是ID和命令号
楼主这个和大多数一样的根据延时判断指令的
作者: hou980730    时间: 2019-3-28 11:12
好厉害
作者: wo411322    时间: 2019-3-28 17:14
非常感谢,楼主
作者: wo411322    时间: 2019-3-28 20:41
非常感谢楼主分享,帮大忙了
作者: 蓝少    时间: 2019-3-29 13:56
好东西啊,谢谢啊
作者: nolimit    时间: 2019-4-3 14:08
感谢楼主分享
作者: limuzi20    时间: 2019-5-20 15:26
太感谢楼主了!准备测试
作者: yywd4    时间: 2019-5-20 22:01
下载学习,谢谢发帖。
作者: pcicarl    时间: 2019-6-3 20:13
怎么我编译不成功!
作者: anllon-cao    时间: 2019-6-29 14:40
好东西,顶顶
作者: anllon-cao    时间: 2019-6-29 21:21


一直再寻找,非常感谢
作者: panpufeng2353    时间: 2019-7-6 12:17
stn13135 发表于 2017-9-4 20:45
好东西,正在学习

很好的代码,先学习学习。
作者: anllon-cao    时间: 2019-7-26 23:41
candura 发表于 2018-1-10 10:39
发现一个问题啊,用这个的从机代码出现这样一个情况。
如果之前发送的没问题的话,那么从机反馈的数据也正 ...

你用什么调试工具啊?
作者: anllon-cao    时间: 2019-7-27 00:26
candura 发表于 2018-1-10 10:39
发现一个问题啊,用这个的从机代码出现这样一个情况。
如果之前发送的没问题的话,那么从机反馈的数据也正 ...

你这个用的是什么调试工具啊?if(Flag_Uart2_RX)  为什么总停到这里
作者: aygc    时间: 2019-7-27 14:42
lnpeanut 发表于 2019-3-27 22:06
程序结构蛮不错的,我之前写过一个,不过稍微复杂点
串口接受中断中,数据进一个fifo队列,主程序在队列中 ...

能否分享学习一下,谢谢
作者: 1468216262    时间: 2019-9-17 10:54
大神们。有没有stm32 用keil写的
作者: 1468216262    时间: 2019-9-17 10:55
lnpeanut 发表于 2019-3-27 22:06
程序结构蛮不错的,我之前写过一个,不过稍微复杂点
串口接受中断中,数据进一个fifo队列,主程序在队列中 ...

大师,可否分享下,一起学习
作者: bbb168    时间: 2019-9-26 21:50
学习了,谢谢分享。
作者: bigye    时间: 2019-10-18 10:20
标记一下,下载来看看!!




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1