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

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 2505|回復(fù): 13
收起左側(cè)

STC8a8k64d4單片機(jī)芯片與RS485通信

[復(fù)制鏈接]
ID:1082545 發(fā)表于 2023-7-6 10:53 | 顯示全部樓層 |閱讀模式
PC機(jī)是主機(jī),擴(kuò)展板是從機(jī),主機(jī)發(fā)送字符串,從機(jī)接收并把字符串發(fā)送至PC機(jī)。串口助手現(xiàn)象:發(fā)送字符串,返回?cái)?shù)據(jù)是拆分成的單個(gè)字符分多次發(fā)送。
求大佬分析分析

00_test0_uart2.rar

49.25 KB, 下載次數(shù): 21

代碼

回復(fù)

使用道具 舉報(bào)

ID:1006638 發(fā)表于 2023-7-6 15:09 | 顯示全部樓層
最好把程序和調(diào)試畫(huà)面截圖,你整個(gè)這,別人給你指導(dǎo)還得費(fèi)時(shí)間下載,大師們很忙的
回復(fù)

使用道具 舉報(bào)

ID:161164 發(fā)表于 2023-7-7 16:14 | 顯示全部樓層
阻塞式延時(shí)令串口助手認(rèn)為數(shù)據(jù)是分開(kāi)的
2023-07-07_160930.png



建議改為非阻塞式
2023-07-07_161119.png

回復(fù)

使用道具 舉報(bào)

ID:624769 發(fā)表于 2023-7-7 23:27 來(lái)自觸屏版 | 顯示全部樓層
建議直接用帶485接口的單片機(jī),也不比stc8a8k64d 貴。
回復(fù)

使用道具 舉報(bào)

ID:1082545 發(fā)表于 2023-7-10 10:27 | 顯示全部樓層
按照三樓修改前后對(duì)比
修改前
  1. #include <STC8A8K64D4.H>
  2. #include <intrins.h>
  3. #include <main.h>

  4. #define MAIN_Fosc       11059200L   //定義主時(shí)鐘(精確計(jì)算115200波特率)

  5. #define Baudrate3   115200L
  6. #define UART3_BUF_LENGTH    64

  7. sbit RS485_DIR = P3^6; //RS485 方向選擇引腳
  8. sbit         LED = P1^5;//檢測(cè)代碼指示燈引腳

  9. u8  TX3_Cnt;    //發(fā)送計(jì)數(shù)
  10. u8  RX3_Cnt;    //接收計(jì)數(shù)
  11. bit B_TX3_Busy; //發(fā)送忙標(biāo)志

  12. u8  idata RX3_Buffer[UART3_BUF_LENGTH]; //接收緩沖
  13. u8  idata TX3_Buffer[UART3_BUF_LENGTH]; //發(fā)送緩沖
  14. void         play();
  15. void        delay_10us(u16 ten_us);
  16. void PrintString3(u8 *puts);

  17. //延時(shí)10us函數(shù)
  18. void delay10us(u16 i)
  19. {
  20.         do
  21.         {
  22.                 _nop_();
  23.                 _nop_();
  24.                 _nop_();
  25.                 _nop_();
  26.                 _nop_();
  27.                 _nop_();
  28.                 _nop_();
  29.                 _nop_();
  30.         }while(--i);
  31. }

  32. void Delay1ms()                //@11.0592MHz
  33. {
  34.         unsigned char i, j;

  35.         i = 15;
  36.         j = 90;
  37.         do
  38.         {
  39.                 while (--j);
  40.         } while (--i);
  41. }

  42. //指示燈檢測(cè)運(yùn)行函數(shù)
  43. void play()
  44. {
  45.        
  46.        
  47.         LED = 0;
  48.         delay10us(500000);       
  49.         LED = 1;
  50.         delay10us(500000);       
  51. }
  52. void Uart3Isr() interrupt 17
  53. {
  54.        
  55.     if((S3CON & 0x01) != 0)//RI 接收
  56.     {       
  57.                 S3CON &= ~0x01;    //Clear Rx flag
  58.         
  59.         OUT1 = !OUT1;
  60.                
  61.                 RX3_Buffer[RX3_Cnt] = S3BUF;
  62.                
  63.         if(++RX3_Cnt >= UART3_BUF_LENGTH)   RX3_Cnt = 0;
  64.                
  65.     }

  66.     if((S3CON & 0x02) != 0) //TI 發(fā)送
  67.     {
  68.                 S3CON &= ~0x02;    //Clear Tx flag
  69.                
  70.                 OUT5 = !OUT5;
  71.         
  72.         B_TX3_Busy = 0;

  73.                
  74.     }
  75. }



  76. void Uart3Init()
  77. {
  78.         RS485_DIR = 0; //RS485 設(shè)置為接收方向
  79.         P0M0 = 0xfb; P0M1 = 0x00;
  80.     P1M0 = 0x1f; P1M1 = 0x1e;
  81.     P2M0 = 0xff; P2M1 = 0x07;
  82.     P3M0 = 0xb8; P3M1 = 0xb0;
  83.     P4M0 = 0x1f; P4M1 = 0x16;
  84.     P5M0 = 0x2e; P5M1 = 0x2d;
  85.        
  86.         OUT1 = 0;        OUT7 = 0;        OUT13 = 0;
  87.     OUT2 = 0;   OUT8 = 0;        OUT14 = 0;
  88.         OUT3 = 0;        OUT9 = 0;        OUT15 = 1;
  89.         OUT4 = 0;        OUT10 = 0;        OUT16 = 1;
  90.         OUT5 = 0;        OUT11 = 0;
  91.         OUT6 = 0;        OUT12 = 0;
  92.        
  93.        
  94.        
  95.         S3CON = 0x50;       //8位數(shù)據(jù), 使用Timer3做波特率發(fā)生器, 允許接收
  96.     T3H = (65536UL - (MAIN_Fosc / 4) / Baudrate3) / 256;
  97.     T3L = (65536UL - (MAIN_Fosc / 4) / Baudrate3) % 256;
  98.     T4T3M = 0x0a;
  99.        
  100.         IE2 |= 0x08;          //允許UART3中斷

  101.     B_TX3_Busy = 0;
  102.     TX3_Cnt = 0;
  103.     RX3_Cnt = 0;
  104.        
  105.         P_SW2 &= ~0x02;
  106.     P_SW2 |= 0x02;      //UART3 switch bit1 to: 0: P0.0 P0.1,  1: P5.0 P5.1
  107.        
  108. }

  109. //========================================================================
  110. // 函數(shù): void PrintString3(u8 *puts)
  111. // 描述: 串口3發(fā)送字符串函數(shù)。
  112. // 參數(shù): puts:  字符串指針.
  113. // 返回: none.
  114. // 版本: VER1.0
  115. // 日期: 2014-11-28
  116. // 備注:
  117. //========================================================================
  118. void PrintString3(u8 *puts)
  119. {
  120.         RS485_DIR = 1; //RS485 設(shè)置為發(fā)送
  121.         delay10us(100); //等待最后的停止位完成,延時(shí)時(shí)間由波特率決定
  122.     for (; *puts != 0;  puts++)     //遇到停止符0結(jié)束
  123.     {
  124.         S3BUF = *puts;
  125.         B_TX3_Busy = 1;
  126.         while(B_TX3_Busy);
  127.     }
  128.         delay10us(100); //等待最后的停止位完成,延時(shí)時(shí)間由波特率決定
  129.         RS485_DIR = 0;
  130. }

  131. //========================================================================
  132. // 函數(shù): void main(void)
  133. // 描述: 主函數(shù)。
  134. // 參數(shù): none.
  135. // 返回: none.
  136. // 版本: VER1.0
  137. // 日期: 2014-11-28
  138. // 備注:
  139. //========================================================================
  140. void main()
  141. {
  142.     Uart3Init();
  143.     //IE2 = 0x08;
  144.     EA = 1;//開(kāi)總中斷
  145.        
  146.     PrintString3("STC");  //UART3發(fā)送一個(gè)字符串
  147.    
  148.         while (1)
  149.     {
  150.                 play();
  151.                
  152.                 if((TX3_Cnt != RX3_Cnt) && (!B_TX3_Busy))   //收到數(shù)據(jù), 發(fā)送空閑
  153.         {
  154.                         RS485_DIR = 1; //RS485 設(shè)置為發(fā)送
  155.                         Delay1ms(); //等待最后的停止位完成,延時(shí)時(shí)間由波特率決定
  156.                        
  157.                         B_TX3_Busy = 1;
  158.                         S3BUF = RX3_Buffer[TX3_Cnt];
  159.                        
  160.             if(++TX3_Cnt >= UART3_BUF_LENGTH)   TX3_Cnt = 0;
  161.                
  162.                        
  163.                         Delay1ms(); //等待最后的停止位完成,延時(shí)時(shí)間由波特率決定
  164.                         RS485_DIR = 0;
  165.         }
  166.         
  167.                
  168.     }
  169. }
復(fù)制代碼


修改后
  1. #include <STC8A8K64D4.H>
  2. #include <intrins.h>
  3. #include <main.h>

  4. #define MAIN_Fosc       11059200L   //定義主時(shí)鐘(精確計(jì)算115200波特率)

  5. #define Baudrate3   115200L
  6. #define UART3_BUF_LENGTH    64

  7. sbit RS485_DIR = P3^6; //RS485 方向選擇引腳
  8. sbit         LED = P1^5;//檢測(cè)代碼指示燈引腳

  9. u8  TX3_Cnt;    //發(fā)送計(jì)數(shù)
  10. u8  RX3_Cnt;    //接收計(jì)數(shù)
  11. bit B_TX3_Busy; //發(fā)送忙標(biāo)志

  12. u8  idata RX3_Buffer[UART3_BUF_LENGTH]; //接收緩沖
  13. u8  idata TX3_Buffer[UART3_BUF_LENGTH]; //發(fā)送緩沖
  14. void         play();
  15. void        delay_10us(u16 ten_us);
  16. void PrintString3(u8 *puts);

  17. //延時(shí)10us函數(shù)
  18. void delay10us(u16 i)
  19. {
  20.         do
  21.         {
  22.                 _nop_();
  23.                 _nop_();
  24.                 _nop_();
  25.                 _nop_();
  26.                 _nop_();
  27.                 _nop_();
  28.                 _nop_();
  29.                 _nop_();
  30.         }while(--i);
  31. }

  32. void Delay1ms()                //@11.0592MHz
  33. {
  34.         unsigned char i, j;

  35.         i = 15;
  36.         j = 90;
  37.         do
  38.         {
  39.                 while (--j);
  40.         } while (--i);
  41. }

  42. //指示燈檢測(cè)運(yùn)行函數(shù)
  43. void play()
  44. {
  45.         static u32 delayLed = 0;
  46.         if(++delayLed >= 5000)
  47.         {
  48.                 delayLed = 0;
  49.                 LED = !LED;
  50.         }
  51.                
  52. }
  53. void Uart3Isr() interrupt 17
  54. {
  55.        
  56.     if((S3CON & 0x01) != 0)//RI 接收
  57.     {       
  58.                 S3CON &= ~0x01;    //Clear Rx flag
  59.         
  60.         OUT1 = !OUT1;
  61.                
  62.                 RX3_Buffer[RX3_Cnt] = S3BUF;
  63.                
  64.         if(++RX3_Cnt >= UART3_BUF_LENGTH)   RX3_Cnt = 0;
  65.                
  66.     }

  67.     if((S3CON & 0x02) != 0) //TI 發(fā)送
  68.     {
  69.                 S3CON &= ~0x02;    //Clear Tx flag
  70.                
  71.                 OUT5 = !OUT5;
  72.         
  73.         B_TX3_Busy = 0;

  74.                
  75.     }
  76. }



  77. void Uart3Init()
  78. {
  79.         RS485_DIR = 0; //RS485 設(shè)置為接收方向
  80.         P0M0 = 0xfb; P0M1 = 0x00;
  81.     P1M0 = 0x1f; P1M1 = 0x1e;
  82.     P2M0 = 0xff; P2M1 = 0x07;
  83.     P3M0 = 0xb8; P3M1 = 0xb0;
  84.     P4M0 = 0x1f; P4M1 = 0x16;
  85.     P5M0 = 0x2e; P5M1 = 0x2d;
  86.        
  87.         OUT1 = 0;        OUT7 = 0;        OUT13 = 0;
  88.     OUT2 = 0;   OUT8 = 0;        OUT14 = 0;
  89.         OUT3 = 0;        OUT9 = 0;        OUT15 = 1;
  90.         OUT4 = 0;        OUT10 = 0;        OUT16 = 1;
  91.         OUT5 = 0;        OUT11 = 0;
  92.         OUT6 = 0;        OUT12 = 0;
  93.        
  94.        
  95.        
  96.         S3CON = 0x50;       //8位數(shù)據(jù), 使用Timer3做波特率發(fā)生器, 允許接收
  97.     T3H = (65536UL - (MAIN_Fosc / 4) / Baudrate3) / 256;
  98.     T3L = (65536UL - (MAIN_Fosc / 4) / Baudrate3) % 256;
  99.     T4T3M = 0x0a;
  100.        
  101.         IE2 |= 0x08;          //允許UART3中斷

  102.     B_TX3_Busy = 0;
  103.     TX3_Cnt = 0;
  104.     RX3_Cnt = 0;
  105.        
  106.         P_SW2 &= ~0x02;
  107.     P_SW2 |= 0x02;      //UART3 switch bit1 to: 0: P0.0 P0.1,  1: P5.0 P5.1
  108.        
  109. }

  110. //========================================================================
  111. // 函數(shù): void PrintString3(u8 *puts)
  112. // 描述: 串口3發(fā)送字符串函數(shù)。
  113. // 參數(shù): puts:  字符串指針.
  114. // 返回: none.
  115. // 版本: VER1.0
  116. // 日期: 2014-11-28
  117. // 備注:
  118. //========================================================================
  119. void PrintString3(u8 *puts)
  120. {
  121.         RS485_DIR = 1; //RS485 設(shè)置為發(fā)送
  122.         delay10us(100); //等待最后的停止位完成,延時(shí)時(shí)間由波特率決定
  123.     for (; *puts != 0;  puts++)     //遇到停止符0結(jié)束
  124.     {
  125.         S3BUF = *puts;
  126.         B_TX3_Busy = 1;
  127.         while(B_TX3_Busy);
  128.     }
  129.         delay10us(100); //等待最后的停止位完成,延時(shí)時(shí)間由波特率決定
  130.         RS485_DIR = 0;
  131. }

  132. //========================================================================
  133. // 函數(shù): void main(void)
  134. // 描述: 主函數(shù)。
  135. // 參數(shù): none.
  136. // 返回: none.
  137. // 版本: VER1.0
  138. // 日期: 2014-11-28
  139. // 備注:
  140. //========================================================================
  141. void main()
  142. {
  143.     Uart3Init();
  144.     //IE2 = 0x08;
  145.     EA = 1;//開(kāi)總中斷
  146.        
  147.     PrintString3("STC");  //UART3發(fā)送一個(gè)字符串
  148.    
  149.         while (1)
  150.     {
  151.                 play();
  152.                
  153.                 if((TX3_Cnt != RX3_Cnt) && (!B_TX3_Busy))   //收到數(shù)據(jù), 發(fā)送空閑
  154.         {
  155.                         RS485_DIR = 1; //RS485 設(shè)置為發(fā)送
  156.                         Delay1ms(); //等待最后的停止位完成,延時(shí)時(shí)間由波特率決定
  157.                        
  158.                         B_TX3_Busy = 1;
  159.                         S3BUF = RX3_Buffer[TX3_Cnt];
  160.                        
  161.             if(++TX3_Cnt >= UART3_BUF_LENGTH)   TX3_Cnt = 0;
  162.                
  163.                        
  164.                         Delay1ms(); //等待最后的停止位完成,延時(shí)時(shí)間由波特率決定
  165.                         RS485_DIR = 0;
  166.         }
  167.         
  168.                
  169.     }
  170. }
復(fù)制代碼
屏幕截圖 2023-07-10 102148.png
屏幕截圖 2023-07-10 102610.png
回復(fù)

使用道具 舉報(bào)

ID:1082545 發(fā)表于 2023-7-10 10:28 | 顯示全部樓層
大IGBT 發(fā)表于 2023-7-6 15:09
最好把程序和調(diào)試畫(huà)面截圖,你整個(gè)這,別人給你指導(dǎo)還得費(fèi)時(shí)間下載,大師們很忙的

謝謝您的建議。
回復(fù)

使用道具 舉報(bào)

ID:1082545 發(fā)表于 2023-7-10 10:35 | 顯示全部樓層
lkc8210 發(fā)表于 2023-7-7 16:14
阻塞式延時(shí)令串口助手認(rèn)為數(shù)據(jù)是分開(kāi)的

謝謝您的建議,我修改后發(fā)現(xiàn),第一個(gè)字節(jié)可以發(fā)送并正確回傳給串口助手,第二個(gè)字節(jié)變成“.”,之后字節(jié)回傳不了
回復(fù)

使用道具 舉報(bào)

ID:1082545 發(fā)表于 2023-7-10 14:41 | 顯示全部樓層
改動(dòng)點(diǎn)1:在play()中,delay10us(500000)修改成delay(5000);
  1. LED = 0;
  2.         delay10us(5000);       
  3.         LED = 1;
  4.         delay10us(5000);
復(fù)制代碼

最新現(xiàn)象:發(fā)送aaaaaa,接收aaaaaa
改動(dòng)點(diǎn)2:在while(1)中去掉play,增加Delay1ms();延時(shí),達(dá)到發(fā)送aaaaaa,接收aaaaaa

屏幕截圖 2023-07-10 144055.png

評(píng)分

參與人數(shù) 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

ID:161164 發(fā)表于 2023-7-10 15:01 | 顯示全部樓層
Jisuzai 發(fā)表于 2023-7-10 10:35
謝謝您的建議,我修改后發(fā)現(xiàn),第一個(gè)字節(jié)可以發(fā)送并正確回傳給串口助手,第二個(gè)字節(jié)變成“.”,之后字節(jié) ...

485通信還是等接收超時(shí)后再傳會(huì)吧
回復(fù)

使用道具 舉報(bào)

ID:1082545 發(fā)表于 2023-7-11 11:06 | 顯示全部樓層
有個(gè)思路問(wèn)題,PC機(jī)發(fā)送多個(gè)字節(jié)字符串后,數(shù)據(jù)是通過(guò)串口中斷RX3_Buffer[RX3_Cnt] = S3BUF;從接收SBUF里傳給接收緩沖數(shù)組RX3_Buffer[RX3_Cnt],RX3_Cnt會(huì)不斷增加嗎
在收到數(shù)據(jù)后,準(zhǔn)備發(fā)送時(shí),while(1)循環(huán)中if語(yǔ)句是怎么變化的,以及當(dāng)一個(gè)字節(jié)數(shù)據(jù)傳給發(fā)送寄存器SBUF后,串口檢測(cè)到SBUF中數(shù)據(jù)后,直接發(fā)給PC機(jī)嗎
回復(fù)

使用道具 舉報(bào)

ID:1034262 發(fā)表于 2023-7-11 13:27 | 顯示全部樓層
188610329 發(fā)表于 2023-7-7 23:27
建議直接用帶485接口的單片機(jī),也不比stc8a8k64d 貴。

沒(méi)聽(tīng)說(shuō)過(guò)單片機(jī)直接帶485驅(qū)動(dòng),什么型號(hào)的?485驅(qū)動(dòng)一般可以容忍12V,而單片機(jī)通常都不行。
回復(fù)

使用道具 舉報(bào)

ID:1034262 發(fā)表于 2023-7-11 13:28 | 顯示全部樓層
異步串口轉(zhuǎn)發(fā)的,一定要開(kāi)收發(fā)緩沖。
回復(fù)

使用道具 舉報(bào)

ID:1082545 發(fā)表于 2023-7-12 09:06 | 顯示全部樓層
coody_sz 發(fā)表于 2023-7-11 13:27
沒(méi)聽(tīng)說(shuō)過(guò)單片機(jī)直接帶485驅(qū)動(dòng),什么型號(hào)的?485驅(qū)動(dòng)一般可以容忍12V,而單片機(jī)通常都不行。

485芯片:SP485EEN-L/TR
回復(fù)

使用道具 舉報(bào)

ID:1082545 發(fā)表于 2023-7-12 09:06 | 顯示全部樓層
原理圖
6dfc910fa25a278b24f07ff1b17facb.jpg
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表