久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

標題: stc32單片機modbus-rtu通訊源程序 [打印本頁]

作者: huogq    時間: 2022-5-4 10:28
標題: stc32單片機modbus-rtu通訊源程序
單片機源程序如下:
  1. #include "stc32g.h" //頭文件見下載軟件

  2. #define MAIN_Fosc 11059200L //定義主時鐘

  3. /************* 功能說明 **************

  4. 請先別修改程序, 直接下載"08-串口 1 中斷收發-C 語言-MODBUS 協議"里的"UART1.hex"測試, 主頻選擇 11.0592MHZ.
  5. 測試正常后再修改移植.

  6. 串口 1 按 MODBUS-RTU 協議通信. 本例為從機程序, 主機一般是電腦端.

  7. 本例程只支持多寄存器讀和多寄存器寫, 寄存器長度為 64 個, 別的命令用戶可以根據需要按 MODBUS-RTU 協議自行添
  8. 加.

  9. 本例子數據使用大端模式(與 C51 一致), CRC16 使用小端模式(與 PC 一致).

  10. 默認參數:
  11. 串口 1 設置均為 1 位起始位, 8 位數據位, 1 位停止位, 無校驗.
  12. 串口 1(P3.0 P3.1): 9600bps.

  13. 定時器 0 用于超時計時. 串口每收到一個字節都會重置超時計數, 當串口空閑超過 35bit 時間時(9600bps 對應 3.6ms)則接
  14. 收完成.
  15. 用戶修改波特率時注意要修改這個超時時間.

  16. 本例程只是一個應用例子, 科普 MODBUS-RTU 協議并不在本例子職責范圍, 用戶可以上網搜索相關協議文本參考.
  17. 本例定義了 64 個寄存器, 訪問地址為 0x1000~0x103f.
  18. 命令例子:
  19. 寫入 4 個寄存器(8 個字節):
  20. 10 10 1000 0004 08 1234 5678 90AB CDEF 4930
  21. 返回:
  22. 10 10 10 00 00 04 4B C6
  23. 讀出 4 個寄存器:
  24. 10 03 1000 0004 4388
  25. 返回:
  26. 10 03 08 12 34 56 78 90 AB CD EF 3D D5

  27. 命令錯誤返回信息(自定義):
  28. 0x90: 功能碼錯誤. 收到了不支持的功能碼.
  29. 0x91: 命令長度錯誤.
  30. 0x92: 寫入或讀出寄存器個數或字節數錯誤.
  31. 0x93: 寄存器地址錯誤.

  32. 注意: 收到廣播地址 0x00 時要處理信息, 但不返回應答.

  33. ******************************************/

  34. typedef unsigned char u8;

  35. typedef unsigned int u16;
  36. typedef unsigned long u32;

  37. /************* 本地常量聲明 **************/
  38. #define RX1_Length 128 /* 接收緩沖長度 */
  39. #define TX1_Length 128 /* 發送緩沖長度 */


  40. //
  41. //
  42. //uint gnmbl=7;//1|?ü??±?á?
  43. u16  FREQ;              //
  44. float temp;
  45. //sbit OUTPUT1=P26;               //PWM1
  46. //sbit OUTPUT2=P27;
  47. /************* 本地變量聲明 **************/
  48. u8 xdata RX1_Buffer[RX1_Length]; //接收緩沖
  49. u8 xdata TX1_Buffer[TX1_Length]; //發送緩沖

  50. u8 RX1_cnt; //接收字節計數.
  51. u8 TX1_cnt; //發送字節計數
  52. u8 TX1_number; //要發送的字節數
  53. u8 RX1_TimeOut; //接收超時計時器

  54. bit B_RX1_OK; // 接收數據標志
  55. bit B_TX1_Busy; // 發送忙標志


  56. /************* 本地函數聲明 **************/
  57. void UART1_config(u32 brt, u8 timer, u8 io); // brt: 通信波特率, timer=2: 波特率使用定時器 2, 其它值: 使用 Timer1做波特率. io=0: 串口 1 切換到 P3.0 P3.1, =1: 切換到 P3.6 P3.7, =2: 切換到 P1.6 P1.7, =3: 切換到 P4.3 P4.4.
  58. u8 Timer0_Config(u8 t, u32 reload); //t=0: reload 值是主時鐘周期數, t=1: reload 值是時間(單位 us), 返回 0 正確, 返回 1 裝載值過大錯誤.
  59. u16 MODBUS_CRC16(u8 *p, u8 n);
  60. u8 MODBUS_RTU(void);



  61. #define SL_ADDR 0x01 /* 本從機站號地址 */
  62. #define REG_ADDRESS 0x0000 /* 寄存器首地址 */
  63. #define REG_LENGTH 64 /* 寄存器長度 */
  64. u16 xdata modbus_reg[REG_LENGTH]; /* 寄存器地址 */



  65. //========================================================================
  66. // 函數: void main(void)
  67. // 描述: 主函數
  68. // 參數: none.
  69. // 返回: none.
  70. // 版本: VER1.0
  71. // 日期: 2018-4-2
  72. // 備注:
  73. //========================================================================
  74. void main(void)
  75. {

  76. u8 i;
  77. u16 crc;

  78. EAXFR = 1; //使能訪問 XFR
  79. WTST = 0x00; //設置程序代碼等待參數,
  80. //賦值為 0 可將 CPU 執行程序的速度設置為最快

  81. Timer0_Config(0, MAIN_Fosc / 10000); //t=0: reload 值是主時鐘周期數, (中斷頻率, 20000 次/秒)
  82. UART1_config(9600UL, 1, 0);// brt: 通信波特率, timer=2: 波特率使用定時器2, 其它值: 使用Timer1做波特率. io=0: 串口 1 切換到 P3.0 P3.1, =1: 切換到 P3.6 P3.7, =2: 切換到 P1.6 P1.7, =3: 切換到 P4.3 P4.4.
  83. //  init();
  84. Timer3_Init();
  85.         calculate_F();
  86. EA = 1;

  87.         while (1)
  88.         {
  89.                         if(B_RX1_OK && !B_TX1_Busy) //收到數據, 進行 MODBUS-RTU 協議解析
  90.                         {
  91.                                         if(MODBUS_CRC16(RX1_Buffer, RX1_cnt) == 0) //首先判斷 CRC16 是否正確, 不正確則忽略, 不處理也不返回信息
  92.                                         {
  93.                                                         if((RX1_Buffer[0] == 0x00) || (RX1_Buffer[0] == SL_ADDR)) //然后判斷站號地址是否正確, 或者是否廣播地址(不返回信息)
  94.                                                         {
  95.                                                                 if(RX1_cnt > 2) RX1_cnt -= 2; //去掉 CRC16 校驗字節
  96.                                                                         i = MODBUS_RTU(); //MODBUS-RTU 協議解析
  97.                                                                         if(i != 0) //錯誤處理
  98.                                                                         {
  99.                                                                                 TX1_Buffer[0] = SL_ADDR; //站號地址
  100.                                                                                 TX1_Buffer[1] = i; //錯誤代碼
  101.                                                                                 crc = MODBUS_CRC16(TX1_Buffer, 2);
  102.                                                                                 TX1_Buffer[2] = (u8)(crc>>8); //CRC 是小端模式
  103.                                                                                 TX1_Buffer[3] = (u8)crc;
  104.                                                                                 B_TX1_Busy = 1; //標志發送忙
  105.                                                                                 TX1_cnt = 0; //發送字節計數
  106.                                                                                 TX1_number = 4; //要發送的字節數
  107.                                                                                 TI = 1; //啟動發送
  108.                                                                         }
  109.                                                                 }
  110.                                                 }
  111.                                         RX1_cnt = 0;
  112.                                         B_RX1_OK = 0;
  113.                                 }
  114.                 }
  115. }



  116. /****************************** MODBUS_CRC (shift) *************** past test 06-11-27 *********
  117. 計算 CRC,調用方式 MODBUS_CRC16(&CRC,8); &CRC 為首地址,8 為字節數
  118. CRC-16 for MODBUS
  119. CRC16=X16+X15+X2+1
  120. TEST: ---> ABCDEFGHIJ CRC16=0x0BEE 1627T
  121. */
  122. //========================================================================
  123. // 函數: u16 MODBUS_CRC16(u8 *p, u8 n)
  124. // 描述: 計算 CRC16 函數.
  125. // 參數: *p: 要計算的數據指針.
  126. // n: 要計算的字節數.
  127. // 返回: CRC16 值.
  128. // 版本: V1.0, 2022-3-18 梁工
  129. //========================================================================
  130. u16 MODBUS_CRC16(u8 *p, u8 n)
  131. {
  132. u8 i;
  133. u16 crc16;

  134. crc16 = 0xffff; //預置 16 位 CRC 寄存器為 0xffff(即全為 1)
  135.         do
  136.         {
  137.                         crc16 ^= (u16)*p; //把 8 位數據與 16 位 CRC 寄存器的低位相異或,把結果放于 CRC 寄存器
  138.                         for(i=0; i<8; i++) //8 位數據
  139.                         {
  140.                                 if(crc16 & 1) crc16 = (crc16 >> 1) ^ 0xA001; //如果最低位為 0,把 CRC 寄存器的內容右移一位(朝低位),用 0填補最高位,
  141. //再異或多項式 0xA001
  142.                                 else crc16 >>= 1; //如果最低位為 0,把 CRC 寄存器的內容右移一位(朝低位),用 0 填補最高位
  143.                         }
  144.                         p++;
  145.                 }while(--n != 0);
  146. return (crc16);
  147. }

  148. /********************* modbus 協議 *************************/
  149. /***************************************************************************
  150. 寫多寄存器
  151. 數據: 地址 功能碼 寄存地址 寄存器個數 寫入字節數 寫入數據 CRC16
  152. 偏移: 0 1 2 3 4 5 6 7~ 最后 2 字節
  153. 字節: 1 byte 1 byte 2 byte 2 byte 1byte 2*n byte 2 byte
  154. addr 0x10 xxxx xxxx xx xx....xx xxxx

  155. 返回
  156. 數據: 地址 功能碼 寄存地址 寄存器個數 CRC16
  157. 偏移: 0 1 2 3 4 5 6 7
  158. STC32G 系列技術手冊 官方網站: STCMCUDATA
  159. 深圳國芯人工智能
  160. 字節: 1 byte 1 byte 2 byte 2 byte 2 byte
  161. addr 0x10 xxxx xxxx xxxx


  162. 讀多寄存器
  163. 數據:站號(地址) 功能碼    寄存地址        寄存器個數      CRC16
  164. 偏移: 0          1        2    3         4    5          6 7
  165. 字節: 1 byte     1 byte   2 byte         2 byte 2 byte
  166.      addr       0x03      xxxx           xxxx              xxxx

  167. 返回
  168. 數據:站號(地址) 功能碼 讀出字節數 讀出數據 CRC16
  169. 偏移: 0 1 2 3~ 最后 2 字節
  170. 字節: 1 byte 1 byte 1byte 2*n byte 2 byte
  171. addr 0x03 xx xx....xx xxxx

  172. 返回錯誤代碼
  173. 數據:站號(地址) 錯誤碼 CRC16
  174. 偏移: 0 1 最后 2 字節
  175. 字節: 1 byte 1 byte 2 byte
  176. addr 0x03 xxxx
  177. ***************************************************************************/
  178. u8 MODBUS_RTU(void)
  179. {
  180. u8 i,j,k;
  181. u16 reg_addr; //寄存器地址
  182. u8 reg_len; //寫入寄存器個數
  183. u16 crc;

  184. if(RX1_Buffer[1] == 0x06)//寫多寄存器
  185. {
  186.                 if(RX1_cnt < 9) return 0x91; //命令長度錯誤
  187.                 if((RX1_Buffer[4] != 0) || ((RX1_Buffer[5] *2) != RX1_Buffer[6])) return 0x92; //寫入寄存器個數與字節數錯誤
  188.                 if((RX1_Buffer[5]==0) || (RX1_Buffer[5] > REG_LENGTH)) return 0x92; //寫入寄存器個數錯誤

  189.                 reg_addr = ((u16)RX1_Buffer[2] << 8) + RX1_Buffer[3]; //寄存器地址
  190.                 reg_len = RX1_Buffer[5]; //寫入寄存器個數
  191.                 if((reg_addr+(u16)RX1_Buffer[5]) > (REG_ADDRESS+REG_LENGTH)) return 0x93; //寄存器地址錯誤
  192.                 if(reg_addr < REG_ADDRESS) return 0x93; //寄存器地址錯誤
  193.                 if((reg_len*2+7) != RX1_cnt) return 0x91; //命令長度錯誤

  194.                 j = reg_addr - REG_ADDRESS; //寄存器數據下標
  195.                 for(k=7, i=0; i<reg_len; i++,j++)
  196.                 {
  197.                         modbus_reg[j] = ((u16)RX1_Buffer[k] << 8) + RX1_Buffer[k+1]; //寫入數據, 大端模式
  198.                         k += 2;

  199.                 }

  200.                 if(RX1_Buffer[0] != 0) //非廣播地址則應答
  201.                 {
  202.                                 for(i=0; i<6; i++) TX1_Buffer[i] = RX1_Buffer[i]; //要返回的應答
  203.                                 crc = MODBUS_CRC16(TX1_Buffer, 6);
  204.                                 TX1_Buffer[6] = (u8)(crc>>8); //CRC 是小端模式
  205.                                 TX1_Buffer[7] = (u8)crc;
  206.                                 B_TX1_Busy = 1; //標志發送忙
  207.                                 TX1_cnt = 0; //發送字節計數
  208.                                 TX1_number = 8; //要發送的字節數
  209.                                 TI = 1; //啟動發送
  210.                 }
  211. }
  212. else if(RX1_Buffer[1] == 0x03) //讀多寄存器
  213. {
  214.                 if(RX1_Buffer[0] != 0) //非廣播地址則應答
  215.                 {
  216.                                 if(RX1_cnt != 6) return 0x91; //命令長度錯誤
  217.                                 if(RX1_Buffer[4] != 0) return 0x92; //讀出寄存器個數錯誤
  218.                                 if((RX1_Buffer[5]==0) || (RX1_Buffer[5] > REG_LENGTH)) return 0x92; //讀出寄存器個數錯誤

  219.                                 reg_addr = ((u16)RX1_Buffer[2] << 8) + RX1_Buffer[3]; //寄存器地址
  220.                                 reg_len = RX1_Buffer[5]; //讀出寄存器個數
  221.                                 if((reg_addr+(u16)RX1_Buffer[5]) > (REG_ADDRESS+REG_LENGTH)) return 0x93; //寄存器地址錯誤
  222.                                 if(reg_addr < REG_ADDRESS) return 0x93; //寄存器地址錯誤

  223.                                 j = reg_addr - REG_ADDRESS; //寄存器數據下標
  224.                                 TX1_Buffer[0] = SL_ADDR; //站號地址
  225.                                 TX1_Buffer[1] = 0x03; //讀功能碼
  226.                                 TX1_Buffer[2] = reg_len*2; //返回字節數

  227.                                 for(k=3, i=0; i<reg_len; i++,j++)
  228.                                 {
  229.                                         TX1_Buffer[k++] = (u8)(modbus_reg[j] >> 8);//數據為大端模式
  230.                                         TX1_Buffer[k++] = (u8)modbus_reg[j];
  231.                                 }
  232.                                 crc = MODBUS_CRC16(TX1_Buffer, k);
  233.                                 TX1_Buffer[k++] = (u8)(crc>>8); //CRC 是小端模式
  234.                                 TX1_Buffer[k++] = (u8)crc;
  235.                                 B_TX1_Busy = 1; //標志發送忙
  236.                                 TX1_cnt = 0; //發送字節計數
  237.                                 TX1_number = k; //要發送的字節數
  238.                                 TI = 1; //啟動發送
  239.                 }
  240.         }

  241. else return 0x90; //功能碼錯誤

  242. return 0; //解析正確
  243. }


  244. //========================================================================
  245. // 函數:u8 Timer0_Config(u8 t, u32 reload)
  246. // 描述: timer0 初始化函數.
  247. // 參數: t: 重裝值類型, 0 表示重裝的是系統時鐘數, 其余值表示重裝的是時間(us).
  248. // reload: 重裝值.
  249. // 返回: 0: 初始化正確, 1: 重裝值過大, 初始化錯誤.
  250. // 版本: V1.0, 2018-3-5
  251. //========================================================================
  252. u8 Timer0_Config(u8 t, u32 reload) //t=0: reload 值是主時鐘周期數, t=1: reload 值是時間(單位 us)
  253. {
  254.         TR0 = 0; //停止計數

  255.         if(t != 0) reload = (u32)(((float)MAIN_Fosc * (float)reload)/1000000UL); //重裝的是時間(us), 計算所需要的系統時鐘數.
  256.         if(reload >= (65536UL * 12)) return 1; //值過大, 返回錯誤
  257.         if(reload < 65536UL) AUXR |= 0x80; //1T mode
  258.         else
  259.         {
  260.                         AUXR &= ~0x80; //12T mode
  261.                         reload = reload / 12;
  262.         }
  263.                 reload = 65536UL - reload;
  264.                 TH0 = (u8)(reload >> 8);
  265.                 TL0 = (u8)(reload);

  266.                 ET0 = 1; //允許中斷
  267.                 TMOD &= 0xf0;
  268.                 TMOD |= 0; //工作模式, 0: 16 位自動重裝, 1: 16 位定時/計數, 2: 8 位自動重裝, 3: 16 位自動重裝, 不可屏蔽中斷
  269.                 TR0 = 1; //開始運行
  270.                 return 0;
  271. }

  272. //========================================================================
  273. // 函數: void timer0_ISR (void) interrupt TIMER0_VECTOR
  274. // 描述: timer0 中斷函數.
  275. // 參數: none.
  276. // 返回: none.
  277. // 版本: V1.0, 2016-5-12
  278. //========================================================================
  279. void timer0_ISR (void) interrupt 1

  280. {
  281.         if(RX1_TimeOut != 0)
  282.         {
  283.                         if(--RX1_TimeOut == 0) //超時
  284.                         {
  285.                                 if(RX1_cnt != 0) //接收有數據
  286.                                 {
  287.                                         B_RX1_OK = 1; //標志已收到數據塊
  288.                                 }
  289.                         }
  290.         }
  291. }


  292. //========================================================================
  293. // 函數: SetTimer2Baudraye(u16 dat)
  294. // 描述: 設置 Timer2 做波特率發生器。
  295. // 參數: dat: Timer2 的重裝值.
  296. // 返回: none.
  297. // 版本: VER1.0
  298. // 日期: 2018-4-2
  299. // 備注:
  300. //========================================================================
  301. void SetTimer2Baudraye(u16 dat) // 選擇波特率, 2: 使用 Timer2 做波特率, 其它值: 使用 Timer1 做波特率.
  302. {
  303. AUXR &= ~(1<<4); //Timer stop
  304. AUXR &= ~(1<<3); //Timer2 set As Timer
  305. AUXR |= (1<<2); //Timer2 set as 1T mode
  306. T2H = (u8)(dat >> 8);
  307. T2L = (u8)dat;
  308. IE2 &= ~(1<<2); //禁止中斷
  309. AUXR |= (1<<4); //Timer run enable
  310. }


  311. //========================================================================
  312. // 函數: void UART1_config(u32 brt, u8 timer, u8 io)
  313. // 描述: UART1 初始化函數。
  314. // 參數: brt: 通信波特率.
  315. // timer: 波特率使用的定時器, timer=2: 波特率使用定時器 2, 其它值: 使用 Timer1 做波特率.
  316. // io: 串口 1 切換到的 IO, io=0: 串口 1 切換到 P3.0 P3.1, =1: 切換到 P3.6 P3.7, =2: 切換到 P1.6 P1.7, =3: 切換到 P4.3 P4.4.
  317. // 返回: none.
  318. // 版本: VER1.0
  319. // 日期: 2018-4-2
  320. // 備注:

  321. //========================================================================
  322. void UART1_config(u32 brt, u8 timer, u8 io) // brt: 通信波特率, timer=2: 波特率使用定時器 2, 其它值: 使用 Timer1做波特率. io=0: 串口 1 切換到 P3.0 P3.1, =1: 切換到 P3.6 P3.7, =2: 切換到 P1.6 P1.7, =3: 切換到 P4.3 P4.4.
  323. {
  324. brt = 65536UL - (MAIN_Fosc / 4) / brt;
  325. if(timer == 2) //波特率使用定時器 2
  326. {
  327.                 AUXR |= 0x01; //S1 BRT Use Timer2;
  328.                 SetTimer2Baudraye((u16)brt);
  329. }

  330. else //波特率使用定時器 1
  331. {
  332.                 TR1 = 0;
  333.                 AUXR &= ~0x01; //S1 BRT Use Timer1;
  334.                 AUXR |= (1<<6); //Timer1 set as 1T mode
  335.                 TMOD &= ~(1<<6); //Timer1 set As Timer
  336.                 TMOD &= ~0x30; //Timer1_16bitAutoReload;
  337.                 TH1 = (u8)(brt >> 8);
  338.                 TL1 = (u8)brt;
  339.                 ET1 = 0; // 禁止 Timer1 中斷
  340.                 TR1 = 1; // 運行 Timer1
  341.         }
  342.         P_SW1 &= ~0xc0; //默認切換到 P3.0 P3.1
  343.         if(io == 1)
  344.         {
  345.                 P_SW1 |= 0x40; //切換到 P3.6 P3.7
  346.                 P3M1 &= ~0xc0;
  347.                 P3M0 &= ~0xc0;
  348.         }
  349.         else if(io == 2)
  350.         {
  351.                 P_SW1 |= 0x80; //切換到 P1.6 P1.7
  352.                 P1M1 &= ~0xc0;
  353.                 P1M0 &= ~0xc0;
  354.         }
  355.         else if(io == 3)
  356.         {
  357.                         P_SW1 |= 0xc0; //切換到 P4.3 P4.4
  358.                         P4M1 &= ~0x18;
  359.                         P4M0 &= ~0x18;
  360.         }
  361.         else
  362.         {
  363.                         P3M1 &= ~0x03;
  364.                         P3M0 &= ~0x03;

  365.         }

  366.         SCON = (SCON & 0x3f) | (1<<6); // 8 位數據, 1 位起始位, 1 位停止位, 無校驗
  367. // PS = 1; //高優先級中斷
  368.         ES = 1; //允許中斷
  369.         REN = 1; //允許接收
  370. }


  371. //========================================================================
  372. // 函數: void UART1_ISR (void) interrupt UART1_VECTOR
  373. // 描述: 串口 1 中斷函數
  374. // 參數: none.
  375. // 返回: none.
  376. // 版本: VER1.0
  377. // 日期: 2018-4-2
  378. // 備注:
  379. //========================================================================
  380. void UART1_ISR (void) interrupt 4
  381. {
  382.         if(RI)
  383.         {
  384.                 RI = 0;
  385.                         if(!B_RX1_OK) //接收緩沖空閑
  386.                         {
  387.                                 if(RX1_cnt >= RX1_Length) RX1_cnt = 0;
  388.                                 RX1_Buffer[RX1_cnt++] = SBUF;
  389.                                 RX1_TimeOut = 36; //接收超時計時器, 35 個位時間
  390.                         }
  391. }

  392.         if(TI)
  393.         {
  394.                         TI = 0;
  395.                         if(TX1_number != 0) //有數據要發
  396.                         {
  397.                                         SBUF = TX1_Buffer[TX1_cnt++];
  398.                                         TX1_number--;
  399.                         }
  400.                         else B_TX1_Busy = 0;
  401.         }
  402. }
復制代碼

STC32G.H頭文件下載: STC32-MODBUSRTU.zip (97.02 KB, 下載次數: 235)

作者: 雪玉寐影    時間: 2022-5-4 18:15
一晃眼差點看成了stm32!
作者: gao687    時間: 2022-6-19 09:18
雪玉寐影 發表于 2022-5-4 18:15
一晃眼差點看成了stm32!

正好下載,謝謝
作者: 溫柔的郎    時間: 2022-12-31 10:46
NB的大佬!!向大佬致敬!向大佬學習!!
作者: nickwuqi    時間: 2022-12-31 11:05
編譯都通不過,也是不完整
作者: 大漠孤煙001    時間: 2023-1-3 15:39
     絕對精華,愛的奉獻

STC8G系列-串口相關程序.rar

274.11 KB, 下載次數: 81


作者: 35456    時間: 2023-1-3 19:38
向大佬致敬!向大佬學習。
作者: wjfc123    時間: 2023-1-28 07:46
大漠孤煙001 發表于 2023-1-3 15:39
絕對精華,愛的奉獻

能告訴我那個modbus程序是如何自定義發送數據的?好似沒有看到數據入口,想移植,奈何沒看明白
作者: Hephaestus    時間: 2023-1-28 10:40
wjfc123 發表于 2023-1-28 07:46
能告訴我那個modbus程序是如何自定義發送數據的?好似沒有看到數據入口,想移植,奈何沒看明白

這部分應該沒寫,modbus_reg[]既是接收緩沖區也是發送緩沖區,沒找到寫操作,只能說把接收數據又發回去了,只是個測試代碼,要想好用,你要自行添加寫數據的內容。
作者: roseworld    時間: 2023-10-28 00:15
大漠孤煙001 發表于 2023-1-3 15:39
絕對精華,愛的奉獻

這個好,完整。
作者: lhtlhtl    時間: 2023-11-30 20:43

感謝樓主無私開源
作者: miyuhao    時間: 2023-12-13 16:31
樓主的程序,報錯的那兩條注釋掉就可以了,一個tim3的初始化,一個計算什么




歡迎光臨 (http://www.zg4o1577.cn/bbs/) Powered by Discuz! X3.1
主站蜘蛛池模板: 欧美一区二区三区视频在线观看 | 日本不卡免费新一二三区 | 精品在线一区 | 日韩在线免费视频 | 成人h动漫精品一区二区器材 | 四虎午夜剧场 | 亚洲一区二区久久 | 男女网站视频 | 精品久久久久国产 | 国色天香成人网 | 91福利在线导航 | 亚州精品天堂中文字幕 | 男人的天堂亚洲 | 九一在线 | 亚洲精选一区二区 | 色吧综合网 | 亚洲精彩免费视频 | 国产精品久久久久国产a级 欧美日本韩国一区二区 | 国产精品一区免费 | 草草草影院 | 精品国产乱码久久久久久闺蜜 | 日本不卡视频 | 美人の美乳で授乳プレイ | 久久精品网 | 一区二区三区播放 | a黄在线观看 | 91天堂网| 激情一区二区三区 | 韩日一区 | 一区二区三区四区av | 久久久妇女国产精品影视 | 日韩中文字幕av | 成人免费视频观看视频 | 免费国产成人av | av免费电影在线 | 麻豆视频在线免费观看 | 欧美在线a | 午夜一区二区三区在线观看 | 国产精品爱久久久久久久 | 一a一片一级一片啪啪 | 欧美激情a∨在线视频播放 成人免费共享视频 |