找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 57625|回復: 135
打印 上一主題 下一主題
收起左側

STM8 RS485的modbus通迅(主機及從機)程序代碼

  [復制鏈接]
跳轉(zhuǎn)到指定樓層
#
ID:155774 發(fā)表于 2017-8-24 15:49 | 只看該作者 回帖獎勵 |正序瀏覽 |閱讀模式
如題,兩份源碼程序,STVD打開
STM8主控的RS485的modbus通迅所有資料51hei提供下載(含主機和從機程序):
STM8RS485通迅(主機).rar (572.8 KB, 下載次數(shù): 1152)
STM8RS485通迅(從機).rar (613.53 KB, 下載次數(shù): 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);                                                                //計算接收數(shù)據(jù)的CRC
  71.                                 if((re_CRC16 == CRC16)&&(OffsetAdr<ModBusRAM_LEN_MAX))//如果校驗正確  判斷功能碼和數(shù)據(jù)起始地址
  72.                                         {
  73.                                                 OffsetAdr = (u8)((tmpMODBUS[3]) * 2);                                                //OffsetAdr = tmpMODBUS[2] * 256 + tmpMODBUS[3];
  74.                                                 Data_Len  = (u8)(tmpMODBUS[5] * 2);                                                        //讀寫寄存器數(shù)量
  75.                                                 switch(ModbusFC)
  76.                                                         {  
  77.                                                                 case 0x03:                                                                                                                                         //判斷功能碼響應指令 發(fā)送被召喚數(shù)據(jù)
  78.                                                                 {
  79.                                                                         //if(tmpMODBUS[3] == 0x01)
  80.                                                                         //        {                                       
  81.                                                                         tmpMODBUS[2] = Data_Len;                                                                        //字節(jié)數(shù)=寄存器數(shù)量*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);                                //計算接收數(shù)據(jù)的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++)                                                                        //發(fā)送應答數(shù)據(jù)        多寄存器讀命令返回
  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:                                                                                                                                         //如果檢測到是多字節(jié)寫入指令
  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;                                                                                                //發(fā)送應答數(shù)據(jù)
  118.                                                                         CRC16   = crc16(tmpMODBUS,CRC_Len);                        //計算接收數(shù)據(jù)的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++)                                                                //發(fā)送應答數(shù)據(jù)
  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;                                                                                                                                                                        //直接退出中斷函數(shù),不執(zhí)行CT=CT+1;語句
  136.                                         }
  137.                                  else                                                                                                                                                                                         //如果校驗出錯  發(fā)送自定義異常代碼 80||03||10,04讀寫指令ERROR
  138.                                         {        
  139.                                                                                                                                                                                                                                                 //發(fā)送異常代碼
  140.                                                 tmpMODBUS[1] |= 0x80;                                                                                                                //異常指令 OR
  141.                                                 tmpMODBUS[2]        =        0x04;                                                                                                                //異常代碼

  142.                                                 CRC16   = crc16(tmpMODBUS,3);                                                                                //計算接收數(shù)據(jù)的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++)                                                                                //發(fā)送應答數(shù)據(jù)
  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.         }
復制代碼





評分

參與人數(shù) 1黑幣 +5 收起 理由
lxmxyw + 5 好東西,學習

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏39 分享淘帖 頂3 踩
回復

使用道具 舉報

135#
ID:253986 發(fā)表于 2024-9-15 23:15 | 只看該作者
正需要,感謝感謝
回復

使用道具 舉報

134#
ID:315723 發(fā)表于 2023-10-22 21:08 | 只看該作者
CRC算法是不是都不一樣,感覺怪怪的
回復

使用道具 舉報

133#
ID:850464 發(fā)表于 2023-10-3 18:39 | 只看該作者
正準備搞一個modbus主機程序 希望用的上
回復

使用道具 舉報

132#
ID:462629 發(fā)表于 2023-3-30 09:53 | 只看該作者
好東西啊,
有STC的更好了
回復

使用道具 舉報

131#
ID:667696 發(fā)表于 2023-2-7 20:00 | 只看該作者
一直再尋找,非常感謝666666
回復

使用道具 舉報

130#
ID:1061214 發(fā)表于 2023-1-15 11:58 | 只看該作者
可以可以 一直在學習485
回復

使用道具 舉報

129#
ID:984669 發(fā)表于 2022-8-28 10:14 | 只看該作者
非常感謝,下載試試,51單片機能用嗎?
回復

使用道具 舉報

128#
ID:27788 發(fā)表于 2022-3-24 09:01 | 只看該作者
怎么主機與從機代碼是一樣的,是不是發(fā)錯了?樓主
回復

使用道具 舉報

127#
ID:965139 發(fā)表于 2021-9-19 17:11 | 只看該作者
一直再尋找,非常感謝
回復

使用道具 舉報

126#
ID:965139 發(fā)表于 2021-9-9 18:43 | 只看該作者
一直再尋找,非常感謝
回復

使用道具 舉報

125#
ID:825737 發(fā)表于 2020-10-12 07:23 | 只看該作者
謝謝了,下載下來學習學習
回復

使用道具 舉報

124#
ID:659888 發(fā)表于 2020-6-1 22:03 | 只看該作者
好帖,拿走了,謝謝
回復

使用道具 舉報

123#
ID:467062 發(fā)表于 2020-6-1 20:34 | 只看該作者
謝謝摟住分享這么好的資料!
回復

使用道具 舉報

122#
ID:739657 發(fā)表于 2020-5-13 21:05 | 只看該作者
源碼還能下載嗎,最近在做這類的測試
回復

使用道具 舉報

121#
ID:742045 發(fā)表于 2020-4-30 22:25 | 只看該作者
想要IAR環(huán)境的
回復

使用道具 舉報

120#
ID:739657 發(fā)表于 2020-4-27 21:58 | 只看該作者
mark。。。。。。。。。。
回復

使用道具 舉報

119#
ID:720819 發(fā)表于 2020-4-2 11:17 | 只看該作者
好東西,學習學習
回復

使用道具 舉報

118#
ID:459415 發(fā)表于 2020-3-8 14:57 | 只看該作者
好東西,頂頂
回復

使用道具 舉報

117#
ID:137005 發(fā)表于 2020-3-8 10:49 | 只看該作者
這個從機模式編譯出現(xiàn)這個,是什么問題?


Compiling c\main.c...
cxstm8 +warn +mods0 +debug -pxp +split -pp -l -isrc\h -istm8sfwlib_v1.1.1\fwlib\library\inc -ih -iF:\0_Soft\en.stvd-stm8\CXSTM8\Hstm8  -clDebug\ -coDebug\ c\main.c
#error cpstm8 c\main.c:23(17+6) incompatible types in struct/union assignment
c\main.c:
The command: "cxstm8 +warn +mods0 +debug -pxp +split -pp -l -isrc\h -istm8sfwlib_v1.1.1\fwlib\library\inc -ih -iF:\0_Soft\en.stvd-stm8\CXSTM8\Hstm8  -clDebug\ -coDebug\ c\main.c" has failed, the returned value is: 1
exit code=1.

bacfull.elf - 3 error(s), 1 warning(s)
回復

使用道具 舉報

116#
ID:145282 發(fā)表于 2020-2-24 21:38 | 只看該作者

好東西,正在學習
回復

使用道具 舉報

115#
ID:697100 發(fā)表于 2020-2-23 20:43 | 只看該作者
謝謝分享,請問怎么免費下載呢?正想用modbus組一個智能冠家居的有線網(wǎng)絡,云上的智能家居系統(tǒng)和平臺總是不放心。
回復

使用道具 舉報

114#
ID:622299 發(fā)表于 2020-2-13 14:43 | 只看該作者
謝謝分享
回復

使用道具 舉報

113#
ID:692024 發(fā)表于 2020-2-11 13:32 | 只看該作者
請問怎么免費下載呢?
回復

使用道具 舉報

112#
ID:692024 發(fā)表于 2020-2-11 13:28 | 只看該作者
真是好東西!
回復

使用道具 舉報

111#
ID:444694 發(fā)表于 2020-1-8 16:13 | 只看該作者
好東西,感謝分享~
回復

使用道具 舉報

110#
ID:444694 發(fā)表于 2020-1-8 16:13 | 只看該作者
難得的好文!
回復

使用道具 舉報

109#
ID:678785 發(fā)表于 2020-1-5 16:09 | 只看該作者
zhangshanqiao 發(fā)表于 2018-5-26 23:17
不錯,程序結構非常好。CRC16   = crc16(tmpMODBUS,3);  中的unsigned int CRC16(unsinge char *dat,unsign ...

@39樓 我從樓主處,也學到不少東東,但同樣關心CRC16的計算。
或者參考這篇試試----https://blog.csdn.net/qq_19875391/article/details/60875010
回復

使用道具 舉報

108#
ID:678785 發(fā)表于 2020-1-4 16:26 | 只看該作者
先學習學習,我也只用過STM8S103,正準備RS485的編程。謝謝樓主分享!
回復

使用道具 舉報

107#
ID:494559 發(fā)表于 2019-12-27 21:31 | 只看該作者

好東西,謝謝分享
回復

使用道具 舉報

106#
ID:494559 發(fā)表于 2019-12-27 21:16 | 只看該作者
謝謝分享
回復

使用道具 舉報

105#
ID:76408 發(fā)表于 2019-11-16 09:16 | 只看該作者
謝謝樓主,辛苦了,,,,,
回復

使用道具 舉報

104#
ID:54018 發(fā)表于 2019-10-27 21:05 | 只看該作者
還不錯,非常 感謝
回復

使用道具 舉報

103#
ID:82944 發(fā)表于 2019-10-27 14:26 | 只看該作者
一直再尋找,非常感謝
回復

使用道具 舉報

102#
ID:29667 發(fā)表于 2019-10-26 18:57 | 只看該作者
謝謝分享
回復

使用道具 舉報

101#
ID:92810 發(fā)表于 2019-10-25 11:53 | 只看該作者
謝謝樓主分享咯。好東西來的
回復

使用道具 舉報

100#
ID:603394 發(fā)表于 2019-10-18 10:20 | 只看該作者
標記一下,下載來看看!
回復

使用道具 舉報

99#
ID:592524 發(fā)表于 2019-9-26 21:50 | 只看該作者
學習了,謝謝分享。
回復

使用道具 舉報

98#
ID:407940 發(fā)表于 2019-9-17 10:55 | 只看該作者
lnpeanut 發(fā)表于 2019-3-27 22:06
程序結構蠻不錯的,我之前寫過一個,不過稍微復雜點
串口接受中斷中,數(shù)據(jù)進一個fifo隊列,主程序在隊列中 ...

大師,可否分享下,一起學習
回復

使用道具 舉報

97#
ID:407940 發(fā)表于 2019-9-17 10:54 | 只看該作者
大神們。有沒有stm32 用keil寫的
回復

使用道具 舉報

96#
ID:47541 發(fā)表于 2019-7-27 14:42 | 只看該作者
lnpeanut 發(fā)表于 2019-3-27 22:06
程序結構蠻不錯的,我之前寫過一個,不過稍微復雜點
串口接受中斷中,數(shù)據(jù)進一個fifo隊列,主程序在隊列中 ...

能否分享學習一下,謝謝
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表