找回密码
 立即注册
楼主: qepuemc

485通信错误用STC单片机和485芯片做USB转串口有错误

[复制链接]
  • 打卡等级:以坛为家II
  • 打卡总天数:548
  • 最近打卡:2025-10-31 07:45:03

50

主题

394

回帖

674

积分

高级会员

积分
674
发表于 2025-10-20 22:19:31 | 显示全部楼层
qepu*** 发表于 2025-10-8 17:24
其实不是这样的。不只是自动换行的问题,最大的问题是数据乱码。这个问题一直没解决。一直没在意。现在我 ...
  1. /*---------------------------------------------------------------------*/
  2. /* --- STC MCU Limited ------------------------------------------------*/
  3. /* --- STC 1T Series MCU Demo Programme -------------------------------*/
  4. /* --- Mobile: (86)13922805190 ----------------------------------------*/
  5. /* --- Fax: 86-0513-55012956,55012947,55012969 ------------------------*/
  6. /* --- Tel: 86-0513-55012928,55012929,55012966 ------------------------*/
  7. /* --- Web: www.STCAI.com ---------------------------------------------*/
  8. /* --- Web: www.STCMCUDATA.com  ---------------------------------------*/
  9. /* --- BBS: www.STCAIMCU.com  -----------------------------------------*/
  10. /* --- QQ:  800003751 -------------------------------------------------*/
  11. /* 如果要在程序中使用此代码,请在程序中注明使用了STC的资料及程序        */
  12. /*---------------------------------------------------------------------*/
  13. /*************  功能说明    **************
  14. 本例程基于STC8H8K64U为主控芯片的实验箱9进行编写测试,STC8G、STC8H系列芯片可通用参考.
  15. 串口1全双工中断方式收发通讯程序。
  16. 通过PC向MCU发送数据, MCU收到后通过串口1把收到的数据原样返回.
  17. 用定时器做波特率发生器,建议使用1T模式(除非低波特率用12T),并选择可被波特率整除的时钟频率,以提高精度。
  18. 下载时, 选择时钟 22.1184MHz (用户可自行修改频率).
  19. ******************************************/
  20. #include "stc8h.h"       //包含此头文件后,不需要再包含"reg51.h"头文件
  21. #define MAIN_Fosc       11059200L   //定义主时钟(精确计算115200波特率)
  22. typedef     unsigned char   u8;
  23. typedef     unsigned int    u16;
  24. typedef     unsigned long   u32;
  25. #define     Baudrate1           115200L
  26. #define     UART1_BUF_LENGTH    64
  27. u8  TX1_Cnt;    //发送计数
  28. u8  RX1_Cnt;    //接收计数
  29. bit B_TX1_Busy; //发送忙标志
  30. bit rx_js=0;                         //串口接收结束
  31. unsigned char   xdata RX1_js[UART1_BUF_LENGTH]; //接收数据存放数组
  32. unsigned int    RX1_js_index; //接收索引
  33. unsigned char   xdata RX1_Buffer[UART1_BUF_LENGTH]; //接收数据存放数组
  34. void UART1_config(u8 brt);   // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
  35. void PrintString1(u8 *puts);
  36. void Timer0_Isr(void) interrupt 1
  37. {
  38.        
  39. rx_js=1;
  40.        
  41. }
  42. void Timer0_Init(void)                //5毫秒@11.0592MHz
  43. {
  44.         AUXR |= 0x80;                        //定时器时钟1T模式
  45.         TMOD &= 0xF0;                        //设置定时器模式
  46.         TL0 = 0x00;                                //设置定时初始值
  47.         TH0 = 0x28;                                //设置定时初始值
  48.         TF0 = 0;                                //清除TF0标志
  49.         TR0 = 0;                                //定时器0开始计时
  50.         ET0 = 0;                                //使能定时器0中断
  51. }
  52. //========================================================================
  53. // 函数: void main(void)
  54. // 描述: 主函数。
  55. // 参数: none.
  56. // 返回: none.
  57. // 版本: VER1.0
  58. // 日期: 2014-11-28
  59. // 备注:
  60. //========================================================================
  61. void main(void)
  62. {
  63.     P_SW2 |= 0x80;  //扩展寄存器(XFR)访问使能
  64. Timer0_Init();
  65.     P0M1 = 0x30;   P0M0 = 0x30;   //设置P0.4、P0.5为漏极开路(实验箱加了上拉电阻到3.3V)
  66.     P1M1 = 0x30;   P1M0 = 0x30;   //设置P1.4、P1.5为漏极开路(实验箱加了上拉电阻到3.3V)
  67.     P2M1 = 0x3c;   P2M0 = 0x3c;   //设置P2.2~P2.5为漏极开路(实验箱加了上拉电阻到3.3V)
  68.     P3M1 = 0x50;   P3M0 = 0x50;   //设置P3.4、P3.6为漏极开路(实验箱加了上拉电阻到3.3V)
  69.     P4M1 = 0x3c;   P4M0 = 0x3c;   //设置P4.2~P4.5为漏极开路(实验箱加了上拉电阻到3.3V)
  70.     P5M1 = 0x0c;   P5M0 = 0x0c;   //设置P5.2、P5.3为漏极开路(实验箱加了上拉电阻到3.3V)
  71.     P6M1 = 0xff;   P6M0 = 0xff;   //设置为漏极开路(实验箱加了上拉电阻到3.3V)
  72.     P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口
  73.     UART1_config(1);    // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
  74.     EA = 1; //允许总中断
  75.     PrintString1("STC8H8K64U UART1 Test Programme!\r\n");  //UART1发送一个字符串
  76.     while (1)
  77.     {
  78.                        
  79.                         /*
  80.                        
  81.         if((TX1_Cnt != RX1_Cnt) && (!B_TX1_Busy))   //收到数据, 发送空闲
  82.         {
  83.                                        
  84.                                        
  85.                                               SBUF = RX1_Cnt;     //把收到的数据远样返回
  86.                                         B_TX1_Busy = 1;
  87.         while(B_TX1_Busy);
  88.                                        
  89.             //SBUF = RX1_Buffer[TX1_Cnt];     //把收到的数据远样返回
  90.             //B_TX1_Busy = 1;
  91.             if(++TX1_Cnt >= UART1_BUF_LENGTH)   TX1_Cnt = 0;
  92.         }
  93.                                
  94.                                 */
  95.                        
  96.                         if (rx_js==1)
  97.                                
  98.                         {
  99.                                         //关闭定时器
  100.                                         TR0 = 0;                                //定时器0开始计时
  101.                                         ET0 = 0;                                //使能定时器0中断
  102.                                
  103.                                 //复位串口
  104.                                 B_TX1_Busy = 0;
  105.                                 TX1_Cnt = 0;
  106.                                 RX1_Cnt = 0;
  107.                                 rx_js=0;
  108.                                
  109.                         SBUF = RX1_Buffer[0];    B_TX1_Busy = 1;    while(B_TX1_Busy);
  110.                         SBUF = RX1_Buffer[1];    B_TX1_Busy = 1;    while(B_TX1_Busy);
  111.                         SBUF = RX1_Buffer[2];    B_TX1_Busy = 1;    while(B_TX1_Busy);
  112.                         SBUF = RX1_Buffer[3];    B_TX1_Busy = 1;    while(B_TX1_Busy);
  113.                         SBUF = RX1_Buffer[4];    B_TX1_Busy = 1;    while(B_TX1_Busy);
  114.                         SBUF = RX1_Buffer[5];    B_TX1_Busy = 1;    while(B_TX1_Busy);
  115.                         SBUF = RX1_Buffer[6];    B_TX1_Busy = 1;    while(B_TX1_Busy);
  116.                         SBUF = RX1_Buffer[7];    B_TX1_Busy = 1;    while(B_TX1_Busy);
  117.                         SBUF = RX1_Buffer[8];    B_TX1_Busy = 1;    while(B_TX1_Busy);
  118.                        
  119.                        
  120.                         }
  121.                                
  122.                                
  123.     }
  124. }
  125. //========================================================================
  126. // 函数: void PrintString1(u8 *puts)
  127. // 描述: 串口1发送字符串函数。
  128. // 参数: puts:  字符串指针.
  129. // 返回: none.
  130. // 版本: VER1.0
  131. // 日期: 2014-11-28
  132. // 备注:
  133. //========================================================================
  134. void PrintString1(u8 *puts) //发送一个字符串
  135. {
  136.     for (; *puts != 0;  puts++)     //遇到停止符0结束
  137.     {
  138.         SBUF = *puts;
  139.         B_TX1_Busy = 1;
  140.         while(B_TX1_Busy);
  141.     }
  142. }
  143. //========================================================================
  144. // 函数: SetTimer2Baudraye(u16 dat)
  145. // 描述: 设置Timer2做波特率发生器。
  146. // 参数: dat: Timer2的重装值.
  147. // 返回: none.
  148. // 版本: VER1.0
  149. // 日期: 2014-11-28
  150. // 备注:
  151. //========================================================================
  152. void SetTimer2Baudraye(u16 dat)  // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
  153. {
  154.     AUXR &= ~(1<<4);    //Timer stop
  155.     AUXR &= ~(1<<3);    //Timer2 set As Timer
  156.     AUXR |=  (1<<2);    //Timer2 set as 1T mode
  157.     T2H = dat / 256;
  158.     T2L = dat % 256;
  159.     IE2  &= ~(1<<2);    //禁止中断
  160.     AUXR |=  (1<<4);    //Timer run enable
  161. }
  162. //========================================================================
  163. // 函数: void UART1_config(u8 brt)
  164. // 描述: UART1初始化函数。
  165. // 参数: brt: 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
  166. // 返回: none.
  167. // 版本: VER1.0
  168. // 日期: 2014-11-28
  169. // 备注:
  170. //========================================================================
  171. void UART1_config(u8 brt)    // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
  172. {
  173.     /*********** 波特率使用定时器2 *****************/
  174.     if(brt == 2)
  175.     {
  176.         AUXR |= 0x01;       //S1 BRT Use Timer2;
  177.         SetTimer2Baudraye(65536UL - (MAIN_Fosc / 4) / Baudrate1);
  178.     }
  179.     /*********** 波特率使用定时器1 *****************/
  180.     else
  181.     {
  182.         TR1 = 0;
  183.         AUXR &= ~0x01;      //S1 BRT Use Timer1;
  184.         AUXR |=  (1<<6);    //Timer1 set as 1T mode
  185.         TMOD &= ~(1<<6);    //Timer1 set As Timer
  186.         TMOD &= ~0x30;      //Timer1_16bitAutoReload;
  187.         TH1 = (u8)((65536UL - (MAIN_Fosc / 4) / Baudrate1) / 256);
  188.         TL1 = (u8)((65536UL - (MAIN_Fosc / 4) / Baudrate1) % 256);
  189.         ET1 = 0;    //禁止中断
  190.         INTCLKO &= ~0x02;   //不输出时钟
  191.         TR1  = 1;
  192.     }
  193.     /*************************************************/
  194.     SCON = (SCON & 0x3f) | 0x40;    //UART1模式, 0x00: 同步移位输出, 0x40: 8位数据,可变波特率, 0x80: 9位数据,固定波特率, 0xc0: 9位数据,可变波特率
  195. //  PS  = 1;    //高优先级中断
  196.     ES  = 1;    //允许中断
  197.     REN = 1;    //允许接收
  198.     P_SW1 &= 0x3f;
  199.     P_SW1 |= 0x80;      //UART1 switch to, 0x00: P3.0 P3.1, 0x40: P3.6 P3.7, 0x80: P1.6 P1.7, 0xC0: P4.3 P4.4
  200. //  PCON2 |=  (1<<4);   //内部短路RXD与TXD, 做中继, ENABLE,DISABLE
  201.     B_TX1_Busy = 0;
  202.     TX1_Cnt = 0;
  203.     RX1_Cnt = 0;
  204. }
  205. //========================================================================
  206. // 函数: void UART1_int (void) interrupt UART1_VECTOR
  207. // 描述: UART1中断函数。
  208. // 参数: nine.
  209. // 返回: none.
  210. // 版本: VER1.0
  211. // 日期: 2014-11-28
  212. // 备注:
  213. //========================================================================
  214. void UART1_int (void) interrupt 4
  215. {
  216.     if(RI)
  217.     {
  218.         RI = 0;
  219.         //开始定时器               
  220.         TL0 = 0x00;                                //设置定时初始值
  221.         TH0 = 0x28;                                //设置定时初始值
  222.         TR0 = 1;                                //定时器0开始计时
  223.         ET0 = 1;                                //使能定时器0中断
  224.                        
  225.                        
  226.         RX1_Buffer[RX1_Cnt] = SBUF;
  227.         if(++RX1_Cnt >= UART1_BUF_LENGTH)   RX1_Cnt = 0;    //防溢出
  228.     }
  229.     if(TI)
  230.     {
  231.         TI = 0;
  232.         B_TX1_Busy = 0;
  233.     }
  234. }
复制代码

这个也是没有问题的。两个电路都可以用。
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-10-31 13:58 , Processed in 0.113946 second(s), 46 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表