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

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 6545|回復(fù): 11
打印 上一主題 下一主題
收起左側(cè)

stc32單片機(jī)modbus-rtu通訊源程序

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
單片機(jī)源程序如下:
  1. #include "stc32g.h" //頭文件見下載軟件

  2. #define MAIN_Fosc 11059200L //定義主時(shí)鐘

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

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

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

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

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

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

  13. 定時(shí)器 0 用于超時(shí)計(jì)時(shí). 串口每收到一個(gè)字節(jié)都會(huì)重置超時(shí)計(jì)數(shù), 當(dāng)串口空閑超過 35bit 時(shí)間時(shí)(9600bps 對(duì)應(yīng) 3.6ms)則接
  14. 收完成.
  15. 用戶修改波特率時(shí)注意要修改這個(gè)超時(shí)時(shí)間.

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

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

  32. 注意: 收到廣播地址 0x00 時(shí)要處理信息, 但不返回應(yīng)答.

  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 /* 發(fā)送緩沖長度 */


  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]; //發(fā)送緩沖

  50. u8 RX1_cnt; //接收字節(jié)計(jì)數(shù).
  51. u8 TX1_cnt; //發(fā)送字節(jié)計(jì)數(shù)
  52. u8 TX1_number; //要發(fā)送的字節(jié)數(shù)
  53. u8 RX1_TimeOut; //接收超時(shí)計(jì)時(shí)器

  54. bit B_RX1_OK; // 接收數(shù)據(jù)標(biāo)志
  55. bit B_TX1_Busy; // 發(fā)送忙標(biāo)志


  56. /************* 本地函數(shù)聲明 **************/
  57. void UART1_config(u32 brt, u8 timer, u8 io); // brt: 通信波特率, timer=2: 波特率使用定時(shí)器 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 值是主時(shí)鐘周期數(shù), t=1: reload 值是時(shí)間(單位 us), 返回 0 正確, 返回 1 裝載值過大錯(cuò)誤.
  59. u16 MODBUS_CRC16(u8 *p, u8 n);
  60. u8 MODBUS_RTU(void);



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



  65. //========================================================================
  66. // 函數(shù): void main(void)
  67. // 描述: 主函數(shù)
  68. // 參數(shù): 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; //設(shè)置程序代碼等待參數(shù),
  80. //賦值為 0 可將 CPU 執(zhí)行程序的速度設(shè)置為最快

  81. Timer0_Config(0, MAIN_Fosc / 10000); //t=0: reload 值是主時(shí)鐘周期數(shù), (中斷頻率, 20000 次/秒)
  82. UART1_config(9600UL, 1, 0);// brt: 通信波特率, timer=2: 波特率使用定時(shí)器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) //收到數(shù)據(jù), 進(jìn)行 MODBUS-RTU 協(xié)議解析
  90.                         {
  91.                                         if(MODBUS_CRC16(RX1_Buffer, RX1_cnt) == 0) //首先判斷 CRC16 是否正確, 不正確則忽略, 不處理也不返回信息
  92.                                         {
  93.                                                         if((RX1_Buffer[0] == 0x00) || (RX1_Buffer[0] == SL_ADDR)) //然后判斷站號(hào)地址是否正確, 或者是否廣播地址(不返回信息)
  94.                                                         {
  95.                                                                 if(RX1_cnt > 2) RX1_cnt -= 2; //去掉 CRC16 校驗(yàn)字節(jié)
  96.                                                                         i = MODBUS_RTU(); //MODBUS-RTU 協(xié)議解析
  97.                                                                         if(i != 0) //錯(cuò)誤處理
  98.                                                                         {
  99.                                                                                 TX1_Buffer[0] = SL_ADDR; //站號(hào)地址
  100.                                                                                 TX1_Buffer[1] = i; //錯(cuò)誤代碼
  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; //標(biāo)志發(fā)送忙
  105.                                                                                 TX1_cnt = 0; //發(fā)送字節(jié)計(jì)數(shù)
  106.                                                                                 TX1_number = 4; //要發(fā)送的字節(jié)數(shù)
  107.                                                                                 TI = 1; //啟動(dòng)發(fā)送
  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. 計(jì)算 CRC,調(diào)用方式 MODBUS_CRC16(&CRC,8); &CRC 為首地址,8 為字節(jié)數(shù)
  118. CRC-16 for MODBUS
  119. CRC16=X16+X15+X2+1
  120. TEST: ---> ABCDEFGHIJ CRC16=0x0BEE 1627T
  121. */
  122. //========================================================================
  123. // 函數(shù): u16 MODBUS_CRC16(u8 *p, u8 n)
  124. // 描述: 計(jì)算 CRC16 函數(shù).
  125. // 參數(shù): *p: 要計(jì)算的數(shù)據(jù)指針.
  126. // n: 要計(jì)算的字節(jié)數(shù).
  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; //預(yù)置 16 位 CRC 寄存器為 0xffff(即全為 1)
  135.         do
  136.         {
  137.                         crc16 ^= (u16)*p; //把 8 位數(shù)據(jù)與 16 位 CRC 寄存器的低位相異或,把結(jié)果放于 CRC 寄存器
  138.                         for(i=0; i<8; i++) //8 位數(shù)據(jù)
  139.                         {
  140.                                 if(crc16 & 1) crc16 = (crc16 >> 1) ^ 0xA001; //如果最低位為 0,把 CRC 寄存器的內(nèi)容右移一位(朝低位),用 0填補(bǔ)最高位,
  141. //再異或多項(xiàng)式 0xA001
  142.                                 else crc16 >>= 1; //如果最低位為 0,把 CRC 寄存器的內(nèi)容右移一位(朝低位),用 0 填補(bǔ)最高位
  143.                         }
  144.                         p++;
  145.                 }while(--n != 0);
  146. return (crc16);
  147. }

  148. /********************* modbus 協(xié)議 *************************/
  149. /***************************************************************************
  150. 寫多寄存器
  151. 數(shù)據(jù): 地址 功能碼 寄存地址 寄存器個(gè)數(shù) 寫入字節(jié)數(shù) 寫入數(shù)據(jù) CRC16
  152. 偏移: 0 1 2 3 4 5 6 7~ 最后 2 字節(jié)
  153. 字節(jié): 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. 數(shù)據(jù): 地址 功能碼 寄存地址 寄存器個(gè)數(shù) CRC16
  157. 偏移: 0 1 2 3 4 5 6 7
  158. STC32G 系列技術(shù)手冊(cè) 官方網(wǎng)站: STCMCUDATA
  159. 深圳國芯人工智能
  160. 字節(jié): 1 byte 1 byte 2 byte 2 byte 2 byte
  161. addr 0x10 xxxx xxxx xxxx


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

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

  172. 返回錯(cuò)誤代碼
  173. 數(shù)據(jù):站號(hào)(地址) 錯(cuò)誤碼 CRC16
  174. 偏移: 0 1 最后 2 字節(jié)
  175. 字節(jié): 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; //寫入寄存器個(gè)數(shù)
  183. u16 crc;

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

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

  194.                 j = reg_addr - REG_ADDRESS; //寄存器數(shù)據(jù)下標(biāo)
  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]; //寫入數(shù)據(jù), 大端模式
  198.                         k += 2;

  199.                 }

  200.                 if(RX1_Buffer[0] != 0) //非廣播地址則應(yīng)答
  201.                 {
  202.                                 for(i=0; i<6; i++) TX1_Buffer[i] = RX1_Buffer[i]; //要返回的應(yīng)答
  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; //標(biāo)志發(fā)送忙
  207.                                 TX1_cnt = 0; //發(fā)送字節(jié)計(jì)數(shù)
  208.                                 TX1_number = 8; //要發(fā)送的字節(jié)數(shù)
  209.                                 TI = 1; //啟動(dòng)發(fā)送
  210.                 }
  211. }
  212. else if(RX1_Buffer[1] == 0x03) //讀多寄存器
  213. {
  214.                 if(RX1_Buffer[0] != 0) //非廣播地址則應(yīng)答
  215.                 {
  216.                                 if(RX1_cnt != 6) return 0x91; //命令長度錯(cuò)誤
  217.                                 if(RX1_Buffer[4] != 0) return 0x92; //讀出寄存器個(gè)數(shù)錯(cuò)誤
  218.                                 if((RX1_Buffer[5]==0) || (RX1_Buffer[5] > REG_LENGTH)) return 0x92; //讀出寄存器個(gè)數(shù)錯(cuò)誤

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

  223.                                 j = reg_addr - REG_ADDRESS; //寄存器數(shù)據(jù)下標(biāo)
  224.                                 TX1_Buffer[0] = SL_ADDR; //站號(hào)地址
  225.                                 TX1_Buffer[1] = 0x03; //讀功能碼
  226.                                 TX1_Buffer[2] = reg_len*2; //返回字節(jié)數(shù)

  227.                                 for(k=3, i=0; i<reg_len; i++,j++)
  228.                                 {
  229.                                         TX1_Buffer[k++] = (u8)(modbus_reg[j] >> 8);//數(shù)據(jù)為大端模式
  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; //標(biāo)志發(fā)送忙
  236.                                 TX1_cnt = 0; //發(fā)送字節(jié)計(jì)數(shù)
  237.                                 TX1_number = k; //要發(fā)送的字節(jié)數(shù)
  238.                                 TI = 1; //啟動(dòng)發(fā)送
  239.                 }
  240.         }

  241. else return 0x90; //功能碼錯(cuò)誤

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


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

  255.         if(t != 0) reload = (u32)(((float)MAIN_Fosc * (float)reload)/1000000UL); //重裝的是時(shí)間(us), 計(jì)算所需要的系統(tǒng)時(shí)鐘數(shù).
  256.         if(reload >= (65536UL * 12)) return 1; //值過大, 返回錯(cuò)誤
  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 位自動(dòng)重裝, 1: 16 位定時(shí)/計(jì)數(shù), 2: 8 位自動(dòng)重裝, 3: 16 位自動(dòng)重裝, 不可屏蔽中斷
  269.                 TR0 = 1; //開始運(yùn)行
  270.                 return 0;
  271. }

  272. //========================================================================
  273. // 函數(shù): void timer0_ISR (void) interrupt TIMER0_VECTOR
  274. // 描述: timer0 中斷函數(shù).
  275. // 參數(shù): 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) //超時(shí)
  284.                         {
  285.                                 if(RX1_cnt != 0) //接收有數(shù)據(jù)
  286.                                 {
  287.                                         B_RX1_OK = 1; //標(biāo)志已收到數(shù)據(jù)塊
  288.                                 }
  289.                         }
  290.         }
  291. }


  292. //========================================================================
  293. // 函數(shù): SetTimer2Baudraye(u16 dat)
  294. // 描述: 設(shè)置 Timer2 做波特率發(fā)生器。
  295. // 參數(shù): 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. // 函數(shù): void UART1_config(u32 brt, u8 timer, u8 io)
  313. // 描述: UART1 初始化函數(shù)。
  314. // 參數(shù): brt: 通信波特率.
  315. // timer: 波特率使用的定時(shí)器, timer=2: 波特率使用定時(shí)器 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: 波特率使用定時(shí)器 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) //波特率使用定時(shí)器 2
  326. {
  327.                 AUXR |= 0x01; //S1 BRT Use Timer2;
  328.                 SetTimer2Baudraye((u16)brt);
  329. }

  330. else //波特率使用定時(shí)器 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; // 運(yùn)行 Timer1
  341.         }
  342.         P_SW1 &= ~0xc0; //默認(rèn)切換到 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 位數(shù)據(jù), 1 位起始位, 1 位停止位, 無校驗(yàn)
  367. // PS = 1; //高優(yōu)先級(jí)中斷
  368.         ES = 1; //允許中斷
  369.         REN = 1; //允許接收
  370. }


  371. //========================================================================
  372. // 函數(shù): void UART1_ISR (void) interrupt UART1_VECTOR
  373. // 描述: 串口 1 中斷函數(shù)
  374. // 參數(shù): 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; //接收超時(shí)計(jì)時(shí)器, 35 個(gè)位時(shí)間
  390.                         }
  391. }

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

STC32G.H頭文件下載: STC32-MODBUSRTU.zip (97.02 KB, 下載次數(shù): 235)
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏11 分享淘帖 頂1 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:99525 發(fā)表于 2022-5-4 18:15 | 只看該作者
一晃眼差點(diǎn)看成了stm32!
回復(fù)

使用道具 舉報(bào)

板凳
ID:915491 發(fā)表于 2022-6-19 09:18 | 只看該作者
雪玉寐影 發(fā)表于 2022-5-4 18:15
一晃眼差點(diǎn)看成了stm32!

正好下載,謝謝
回復(fù)

使用道具 舉報(bào)

地板
ID:476652 發(fā)表于 2022-12-31 10:46 | 只看該作者
NB的大佬!!向大佬致敬!向大佬學(xué)習(xí)!!
回復(fù)

使用道具 舉報(bào)

5#
ID:1022244 發(fā)表于 2022-12-31 11:05 | 只看該作者
編譯都通不過,也是不完整
回復(fù)

使用道具 舉報(bào)

6#
ID:1042619 發(fā)表于 2023-1-3 15:39 | 只看該作者
     絕對(duì)精華,愛的奉獻(xiàn)

STC8G系列-串口相關(guān)程序.rar

274.11 KB, 下載次數(shù): 81

回復(fù)

使用道具 舉報(bào)

7#
ID:1060196 發(fā)表于 2023-1-3 19:38 | 只看該作者
向大佬致敬!向大佬學(xué)習(xí)!!
回復(fù)

使用道具 舉報(bào)

8#
ID:1057468 發(fā)表于 2023-1-28 07:46 | 只看該作者
大漠孤煙001 發(fā)表于 2023-1-3 15:39
絕對(duì)精華,愛的奉獻(xiàn)

能告訴我那個(gè)modbus程序是如何自定義發(fā)送數(shù)據(jù)的?好似沒有看到數(shù)據(jù)入口,想移植,奈何沒看明白
回復(fù)

使用道具 舉報(bào)

9#
ID:883242 發(fā)表于 2023-1-28 10:40 | 只看該作者
wjfc123 發(fā)表于 2023-1-28 07:46
能告訴我那個(gè)modbus程序是如何自定義發(fā)送數(shù)據(jù)的?好似沒有看到數(shù)據(jù)入口,想移植,奈何沒看明白

這部分應(yīng)該沒寫,modbus_reg[]既是接收緩沖區(qū)也是發(fā)送緩沖區(qū),沒找到寫操作,只能說把接收數(shù)據(jù)又發(fā)回去了,只是個(gè)測試代碼,要想好用,你要自行添加寫數(shù)據(jù)的內(nèi)容。
回復(fù)

使用道具 舉報(bào)

10#
ID:1091922 發(fā)表于 2023-10-28 00:15 | 只看該作者
大漠孤煙001 發(fā)表于 2023-1-3 15:39
絕對(duì)精華,愛的奉獻(xiàn)

這個(gè)好,完整。
回復(fù)

使用道具 舉報(bào)

11#
ID:933601 發(fā)表于 2023-11-30 20:43 | 只看該作者

感謝樓主無私開源
回復(fù)

使用道具 舉報(bào)

12#
ID:419072 發(fā)表于 2023-12-13 16:31 | 只看該作者
樓主的程序,報(bào)錯(cuò)的那兩條注釋掉就可以了,一個(gè)tim3的初始化,一個(gè)計(jì)算什么
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 欧美1页 | 免费在线观看成人 | 国产精品国产三级国产aⅴ入口 | www.久久久久久久久 | 亚洲一区二区在线播放 | 久久久xxx| 成人性视频免费网站 | 毛片网站免费观看 | 婷婷桃色网| 国产日韩欧美在线 | 911精品美国片911久久久 | 成人欧美一区二区三区1314 | 午夜理伦三级理论三级在线观看 | 欧美一级欧美三级在线观看 | 亚洲国产一区在线 | 久视频在线观看 | 国产成在线观看免费视频 | 日韩欧美综合 | 久久精品国产一区二区电影 | 久久精品亚洲欧美日韩久久 | 国产一区二区三区视频免费观看 | 国产69精品久久99不卡免费版 | 亚洲精品二区 | 国产福利在线 | 国产999精品久久久 午夜天堂精品久久久久 | 日韩成人中文字幕 | 男女在线网站 | 成人免费视频网站在线看 | 国产免费福利在线 | 男人天堂午夜 | 精品国产精品三级精品av网址 | 99国产精品99久久久久久粉嫩 | 欧美日韩亚洲一区 | 久久久激情视频 | 欧美高清性xxxxhd | av免费观看网站 | 国产欧美日韩一区二区三区 | 天天干天天爱天天 | 国产精品免费av | 成年人视频免费在线观看 | 精品中文字幕视频 |