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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2494|回復: 13
收起左側

STC8a8k64d4單片機芯片與RS485通信

[復制鏈接]
ID:1082545 發表于 2023-7-6 10:53 | 顯示全部樓層 |閱讀模式
PC機是主機,擴展板是從機,主機發送字符串,從機接收并把字符串發送至PC機。串口助手現象:發送字符串,返回數據是拆分成的單個字符分多次發送。
求大佬分析分析

00_test0_uart2.rar

49.25 KB, 下載次數: 21

代碼

回復

使用道具 舉報

ID:1006638 發表于 2023-7-6 15:09 | 顯示全部樓層
最好把程序和調試畫面截圖,你整個這,別人給你指導還得費時間下載,大師們很忙的
回復

使用道具 舉報

ID:161164 發表于 2023-7-7 16:14 | 顯示全部樓層
阻塞式延時令串口助手認為數據是分開的
2023-07-07_160930.png



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

回復

使用道具 舉報

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

使用道具 舉報

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

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

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

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

  9. u8  TX3_Cnt;    //發送計數
  10. u8  RX3_Cnt;    //接收計數
  11. bit B_TX3_Busy; //發送忙標志

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

  17. //延時10us函數
  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. //指示燈檢測運行函數
  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 發送
  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 設置為接收方向
  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位數據, 使用Timer3做波特率發生器, 允許接收
  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. // 函數: void PrintString3(u8 *puts)
  111. // 描述: 串口3發送字符串函數。
  112. // 參數: puts:  字符串指針.
  113. // 返回: none.
  114. // 版本: VER1.0
  115. // 日期: 2014-11-28
  116. // 備注:
  117. //========================================================================
  118. void PrintString3(u8 *puts)
  119. {
  120.         RS485_DIR = 1; //RS485 設置為發送
  121.         delay10us(100); //等待最后的停止位完成,延時時間由波特率決定
  122.     for (; *puts != 0;  puts++)     //遇到停止符0結束
  123.     {
  124.         S3BUF = *puts;
  125.         B_TX3_Busy = 1;
  126.         while(B_TX3_Busy);
  127.     }
  128.         delay10us(100); //等待最后的停止位完成,延時時間由波特率決定
  129.         RS485_DIR = 0;
  130. }

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


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

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

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

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

  9. u8  TX3_Cnt;    //發送計數
  10. u8  RX3_Cnt;    //接收計數
  11. bit B_TX3_Busy; //發送忙標志

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

  17. //延時10us函數
  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. //指示燈檢測運行函數
  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 發送
  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 設置為接收方向
  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位數據, 使用Timer3做波特率發生器, 允許接收
  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. // 函數: void PrintString3(u8 *puts)
  112. // 描述: 串口3發送字符串函數。
  113. // 參數: puts:  字符串指針.
  114. // 返回: none.
  115. // 版本: VER1.0
  116. // 日期: 2014-11-28
  117. // 備注:
  118. //========================================================================
  119. void PrintString3(u8 *puts)
  120. {
  121.         RS485_DIR = 1; //RS485 設置為發送
  122.         delay10us(100); //等待最后的停止位完成,延時時間由波特率決定
  123.     for (; *puts != 0;  puts++)     //遇到停止符0結束
  124.     {
  125.         S3BUF = *puts;
  126.         B_TX3_Busy = 1;
  127.         while(B_TX3_Busy);
  128.     }
  129.         delay10us(100); //等待最后的停止位完成,延時時間由波特率決定
  130.         RS485_DIR = 0;
  131. }

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

使用道具 舉報

ID:1082545 發表于 2023-7-10 10:28 | 顯示全部樓層
大IGBT 發表于 2023-7-6 15:09
最好把程序和調試畫面截圖,你整個這,別人給你指導還得費時間下載,大師們很忙的

謝謝您的建議。
回復

使用道具 舉報

ID:1082545 發表于 2023-7-10 10:35 | 顯示全部樓層
lkc8210 發表于 2023-7-7 16:14
阻塞式延時令串口助手認為數據是分開的

謝謝您的建議,我修改后發現,第一個字節可以發送并正確回傳給串口助手,第二個字節變成“.”,之后字節回傳不了
回復

使用道具 舉報

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

最新現象:發送aaaaaa,接收aaaaaa
改動點2:在while(1)中去掉play,增加Delay1ms();延時,達到發送aaaaaa,接收aaaaaa

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

評分

參與人數 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

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

485通信還是等接收超時后再傳會吧
回復

使用道具 舉報

ID:1082545 發表于 2023-7-11 11:06 | 顯示全部樓層
有個思路問題,PC機發送多個字節字符串后,數據是通過串口中斷RX3_Buffer[RX3_Cnt] = S3BUF;從接收SBUF里傳給接收緩沖數組RX3_Buffer[RX3_Cnt],RX3_Cnt會不斷增加嗎
在收到數據后,準備發送時,while(1)循環中if語句是怎么變化的,以及當一個字節數據傳給發送寄存器SBUF后,串口檢測到SBUF中數據后,直接發給PC機嗎
回復

使用道具 舉報

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

沒聽說過單片機直接帶485驅動,什么型號的?485驅動一般可以容忍12V,而單片機通常都不行。
回復

使用道具 舉報

ID:1034262 發表于 2023-7-11 13:28 | 顯示全部樓層
異步串口轉發的,一定要開收發緩沖。
回復

使用道具 舉報

ID:1082545 發表于 2023-7-12 09:06 | 顯示全部樓層
coody_sz 發表于 2023-7-11 13:27
沒聽說過單片機直接帶485驅動,什么型號的?485驅動一般可以容忍12V,而單片機通常都不行。

485芯片:SP485EEN-L/TR
回復

使用道具 舉報

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

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 人人爽日日躁夜夜躁尤物 | 日本精品一区二区 | 亚洲精品自拍视频 | 久草网站 | 91精品国产高清久久久久久久久 | 久草.com | 国产一区二区三区免费观看视频 | 中文字幕在线免费视频 | 国产婷婷在线视频 | 国产精品综合视频 | 久久久久久毛片免费观看 | 欧美日韩黄色一级片 | 欧美电影免费观看 | 久久久高清 | 精品91久久| 久久精品久久久久久 | 色视频在线播放 | 东京av男人的天堂 | 精品国产一区二区三区性色av | 亚洲 中文 欧美 日韩 在线观看 | 密色视频 | 国产在线不卡 | 国产精品久久久久久 | 在线91 | 国产精品无码久久久久 | 欧美成人一级 | 最新超碰 | 国产精品国产自产拍高清 | 最新av在线网址 | 黄色网址av| 国产东北一级毛片 | 日韩一区二区三区在线播放 | 久久成人av | 日韩图区| 亚洲午夜精品视频 | 日中文字幕在线 | 欧美精品一区二区三区在线四季 | 青春草国产 | 久久久久亚洲 | 网站一区二区三区 | 婷婷去俺也去 |