找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 9168|回复: 18
收起左侧

stc单片机双串口中断收发源程序

  [复制链接]
ID:187220 发表于 2017-4-7 18:22 | 显示全部楼层 |阅读模式
双串口中断收发源代码:
0.png

  1. /*---------------------------------------------------------------------*/
  2. /* --- STC MCU International 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. /* --- QQ:  800003751 -------------------------------------------------*/
  8. /* 如果要在程序中使用此代码,请在程序中注明使用了宏晶科技的资料及程序   */
  9. /*---------------------------------------------------------------------*/


  10. #define MAIN_Fosc                22118400L        //定义主时钟

  11. #include        "STC15Fxxxx.H"

  12. #define                Baudrate1        115200UL
  13. #define                Baudrate2        115200UL



  14. /*************        功能说明        **************

  15. 双串口全双工中断方式收发通讯程序。

  16. 通过PC向MCU发送数据, MCU收到后通过串口把收到的数据原样返回.

  17. ******************************************/


  18. #define        UART1_BUF_LENGTH        32
  19. #define        UART2_BUF_LENGTH        32



  20. u8        TX1_Cnt;        //发送计数
  21. u8        RX1_Cnt;        //接收计数
  22. u8        TX2_Cnt;        //发送计数
  23. u8        RX2_Cnt;        //接收计数
  24. bit        B_TX1_Busy;        //发送忙标志
  25. bit        B_TX2_Busy;        //发送忙标志

  26. u8         idata RX1_Buffer[UART1_BUF_LENGTH];        //接收缓冲
  27. u8         idata RX2_Buffer[UART2_BUF_LENGTH];        //接收缓冲


  28. void        UART1_config(u8 brt);        // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
  29. void        UART2_config(u8 brt);        // 选择波特率, 2: 使用Timer2做波特率, 其它值: 无效.
  30. void         PrintString1(u8 *puts);
  31. void         PrintString2(u8 *puts);



  32. //========================================================================
  33. // 函数: void main(void)
  34. // 描述: 主函数。
  35. // 参数: none.
  36. // 返回: none.
  37. // 版本: VER1.0
  38. // 日期: 2014-11-28
  39. // 备注:
  40. //========================================================================
  41. void main(void)
  42. {
  43.         P0M1 = 0;        P0M0 = 0;        //设置为准双向口
  44.         P1M1 = 0;        P1M0 = 0;        //设置为准双向口
  45.         P2M1 = 0;        P2M0 = 0;        //设置为准双向口
  46.         P3M1 = 0;        P3M0 = 0;        //设置为准双向口
  47.         P4M1 = 0;        P4M0 = 0;        //设置为准双向口
  48.         P5M1 = 0;        P5M0 = 0;        //设置为准双向口
  49.         P6M1 = 0;        P6M0 = 0;        //设置为准双向口
  50.         P7M1 = 0;        P7M0 = 0;        //设置为准双向口

  51.         UART1_config(1);        // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
  52.         UART2_config(2);        // 选择波特率, 2: 使用Timer2做波特率, 其它值: 无效.
  53.         EA = 1;                                //允许全局中断

  54.         
  55.         PrintString1("STC15F2K60S2 UART1 Test Prgramme!\r\n");        //SUART1发送一个字符串
  56.         PrintString2("STC15F2K60S2 UART2 Test Prgramme!\r\n");        //SUART2发送一个字符串

  57.         while (1)
  58.         {
  59.                 if((TX1_Cnt != RX1_Cnt) && (!B_TX1_Busy))        //收到数据, 发送空闲
  60.                 {
  61.                         SBUF = RX1_Buffer[TX1_Cnt];
  62.                         B_TX1_Busy = 1;
  63.                         if(++TX1_Cnt >= UART1_BUF_LENGTH)        TX1_Cnt = 0;
  64.                 }

  65.                 if((TX2_Cnt != RX2_Cnt) && (!B_TX2_Busy))        //收到数据, 发送空闲
  66.                 {
  67.                         S2BUF = RX2_Buffer[TX2_Cnt];
  68.                         B_TX2_Busy = 1;
  69.                         if(++TX2_Cnt >= UART2_BUF_LENGTH)        TX2_Cnt = 0;
  70.                 }
  71.         }
  72. }


  73. //========================================================================
  74. // 函数: void PrintString1(u8 *puts)
  75. // 描述: 串口1发送字符串函数。
  76. // 参数: puts:  字符串指针.
  77. // 返回: none.
  78. // 版本: VER1.0
  79. // 日期: 2014-11-28
  80. // 备注:
  81. //========================================================================
  82. void PrintString1(u8 *puts)
  83. {
  84.     for (; *puts != 0;        puts++)           //遇到停止符0结束
  85.         {
  86.                 SBUF = *puts;
  87.                 B_TX1_Busy = 1;
  88.                 while(B_TX1_Busy);
  89.         }
  90. }

  91. //========================================================================
  92. // 函数: void PrintString2(u8 *puts)
  93. // 描述: 串口2发送字符串函数。
  94. // 参数: puts:  字符串指针.
  95. // 返回: none.
  96. // 版本: VER1.0
  97. // 日期: 2014-11-28
  98. // 备注:
  99. //========================================================================
  100. void PrintString2(u8 *puts)
  101. {
  102.     for (; *puts != 0;        puts++)           //遇到停止符0结束
  103.         {
  104.                 S2BUF = *puts;
  105.                 B_TX2_Busy = 1;
  106.                 while(B_TX2_Busy);
  107.         }
  108. }

  109. //========================================================================
  110. // 函数: SetTimer2Baudraye(u16 dat)
  111. // 描述: 设置Timer2做波特率发生器。
  112. // 参数: dat: Timer2的重装值.
  113. // 返回: none.
  114. // 版本: VER1.0
  115. // 日期: 2014-11-28
  116. // 备注:
  117. //========================================================================
  118. void        SetTimer2Baudraye(u16 dat)
  119. {
  120.         AUXR &= ~(1<<4);        //Timer stop
  121.         AUXR &= ~(1<<3);        //Timer2 set As Timer
  122.         AUXR |=  (1<<2);        //Timer2 set as 1T mode
  123.         TH2 = dat / 256;
  124.         TL2 = dat % 256;
  125.         IE2  &= ~(1<<2);        //禁止中断
  126.         AUXR |=  (1<<4);        //Timer run enable
  127. }

  128. //========================================================================
  129. // 函数: void        UART1_config(u8 brt)
  130. // 描述: UART1初始化函数。
  131. // 参数: brt: 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
  132. // 返回: none.
  133. // 版本: VER1.0
  134. // 日期: 2014-11-28
  135. // 备注:
  136. //========================================================================
  137. void        UART1_config(u8 brt)
  138. {
  139.         /*********** 波特率使用定时器2 *****************/
  140.         if(brt == 2)
  141.         {
  142.                 AUXR |= 0x01;                //S1 BRT Use Timer2;
  143.                 SetTimer2Baudraye(65536UL - (MAIN_Fosc / 4) / Baudrate1);
  144.         }

  145.         /*********** 波特率使用定时器1 *****************/
  146.         else
  147.         {
  148.                 TR1 = 0;
  149.                 AUXR &= ~0x01;                //S1 BRT Use Timer1;
  150.                 AUXR |=  (1<<6);        //Timer1 set as 1T mode
  151.                 TMOD &= ~(1<<6);        //Timer1 set As Timer
  152.                 TMOD &= ~0x30;                //Timer1_16bitAutoReload;
  153.                 TH1 = (u8)((65536UL - (MAIN_Fosc / 4) / Baudrate1) / 256);
  154.                 TL1 = (u8)((65536UL - (MAIN_Fosc / 4) / Baudrate1) % 256);
  155.                 ET1 = 0;        //禁止中断
  156.                 INT_CLKO &= ~0x02;        //不输出时钟
  157.                 TR1  = 1;
  158.         }
  159.         /*************************************************/

  160.         SCON = (SCON & 0x3f) | 0x40;        //UART1模式, 0x00: 同步移位输出, 0x40: 8位数据,可变波特率, 0x80: 9位数据,固定波特率, 0xc0: 9位数据,可变波特率
  161. //        PS  = 1;        //高优先级中断
  162.         ES  = 1;        //允许中断
  163.         REN = 1;        //允许接收
  164.         P_SW1 &= 0x3f;
  165.         P_SW1 |= 0x80;                //UART1 switch to, 0x00: P3.0 P3.1, 0x40: P3.6 P3.7, 0x80: P1.6 P1.7 (必须使用内部时钟)
  166. //        PCON2 |=  (1<<4);        //内部短路RXD与TXD, 做中继, ENABLE,DISABLE

  167.         B_TX1_Busy = 0;
  168.         TX1_Cnt = 0;
  169.         RX1_Cnt = 0;
  170. }


  171. //========================================================================
  172. // 函数: void        UART2_config(u8 brt)
  173. // 描述: UART2初始化函数。
  174. // 参数: brt: 选择波特率, 2: 使用Timer2做波特率, 其它值: 无效.
  175. // 返回: none.
  176. // 版本: VER1.0
  177. // 日期: 2014-11-28
  178. // 备注:
  179. //========================================================================
  180. void        UART2_config(u8 brt)        // 选择波特率, 2: 使用Timer2做波特率, 其它值: 无效.
  181. {
  182.         if(brt == 2)
  183.         {
  184.                 SetTimer2Baudraye(65536UL - (MAIN_Fosc / 4) / Baudrate2);

  185.                 S2CON &= ~(1<<7);        // 8位数据, 1位起始位, 1位停止位, 无校验
  186.                 IE2   |= 1;                        //允许中断
  187.                 S2CON |= (1<<4);        //允许接收
  188.                 P_SW2 &= ~0x01;        
  189.                 P_SW2 |= 1;                        //UART2 switch to: 0: P1.0 P1.1,  1: P4.6 P4.7

  190.                 B_TX2_Busy = 0;
  191.                 TX2_Cnt = 0;
  192.                 RX2_Cnt = 0;
  193.         }
  194. }


  195. //========================================================================
  196. // 函数: void UART1_int (void) interrupt UART1_VECTOR
  197. // 描述: UART1中断函数。
  198. // 参数: nine.
  199. // 返回: none.
  200. // 版本: VER1.0
  201. // 日期: 2014-11-28
  202. // 备注:
  203. //========================================================================
  204. void UART1_int (void) interrupt UART1_VECTOR
  205. {
  206.         if(RI)
  207.         {
  208.                 RI = 0;
  209.                 RX1_Buffer[RX1_Cnt] = SBUF;
  210.                 if(++RX1_Cnt >= UART1_BUF_LENGTH)        RX1_Cnt = 0;
  211.         }

  212.         if(TI)
  213.         {
  214.                 TI = 0;
  215.                 B_TX1_Busy = 0;
  216.         }
  217. }

  218. //========================================================================
  219. // 函数: void UART2_int (void) interrupt UART2_VECTOR
  220. // 描述: UART2中断函数。
  221. // 参数: nine.
  222. // 返回: none.
  223. // 版本: VER1.0
  224. // 日期: 2014-11-28
  225. // 备注:
  226. //========================================================================
  227. void UART2_int (void) interrupt UART2_VECTOR
  228. {
  229.         if((S2CON & 1) != 0)
  230.         {
  231.                 S2CON &= ~1;        //Clear Rx flag
  232.                 RX2_Buffer[RX2_Cnt] = S2BUF;
  233.                 if(++RX2_Cnt >= UART2_BUF_LENGTH)        RX2_Cnt = 0;
  234.         }


  235. …………限于本文篇幅 余下代码请从51黑下载附件…………

复制代码

下载:
C语言.rar (20.45 KB, 下载次数: 117)
回复

使用道具 举报

ID:94867 发表于 2017-12-27 11:00 | 显示全部楼层
标记谢谢分享
回复

使用道具 举报

ID:94867 发表于 2017-12-27 11:03 | 显示全部楼层
我要测试下这个可不可以用
回复

使用道具 举报

ID:225369 发表于 2017-12-28 15:31 | 显示全部楼层
谢谢!谢谢!非常感谢!!
回复

使用道具 举报

ID:225369 发表于 2017-12-28 15:31 | 显示全部楼层
我正要找 这个,可不可以用?
回复

使用道具 举报

ID:225369 发表于 2017-12-28 15:32 | 显示全部楼层
谢谢谢谢!非常感谢!!
回复

使用道具 举报

ID:323951 发表于 2018-5-7 16:29 | 显示全部楼层
谢谢谢谢!非常感谢!!
回复

使用道具 举报

ID:283906 发表于 2018-5-8 15:24 | 显示全部楼层
谢谢分享,初学很懵逼
回复

使用道具 举报

ID:189673 发表于 2018-5-29 19:50 来自手机 | 显示全部楼层
无常 发表于 2018-5-8 15:24
谢谢分享,初学很懵逼

要测试下这个可不可以用
回复

使用道具 举报

ID:65956 发表于 2018-7-12 08:51 | 显示全部楼层
谢谢分享,帮助很大,谢谢
回复

使用道具 举报

ID:381135 发表于 2018-7-31 09:52 | 显示全部楼层
谢谢分享
回复

使用道具 举报

ID:66287 发表于 2018-8-1 10:40 | 显示全部楼层
学习了,谢谢分享!
回复

使用道具 举报

ID:120672 发表于 2018-9-29 18:19 | 显示全部楼层
谢谢分享,正在找相关资料呢!
回复

使用道具 举报

ID:434016 发表于 2018-11-27 10:44 | 显示全部楼层
谢谢提供,测试看看...
回复

使用道具 举报

ID:43121 发表于 2019-5-24 09:38 | 显示全部楼层
谢谢分享,收获很大
回复

使用道具 举报

ID:535790 发表于 2019-5-26 16:24 | 显示全部楼层
谢谢,学习了
回复

使用道具 举报

ID:299740 发表于 2019-7-1 08:27 | 显示全部楼层
非常感谢,正在被这个串口2收发问题困扰,赶紧下下来测试。
回复

使用道具 举报

ID:596723 发表于 2019-8-7 11:39 | 显示全部楼层
标记,下载测试下
回复

使用道具 举报

ID:1044540 发表于 2022-9-12 14:47 | 显示全部楼层
#include "UART.h"
#include "Key.h"
#include "Record.h"

uint8_t Rcv_Buf[RCV_LENGTH];
uint8_t Snd_Buf[SND_LENGTH];

volatile uint8_t        recvbyte=0;
uint8_t RcvFlag = 0;

volatile uint16_t         ScanTimeMs;
volatile uint16_t SysOverTime;
uint8_t InitStartEnable;

uint8_t SendAdd;

uint16_t SysCallStatus1=0;
uint16_t SysCallStatus2=0;

uint16_t SysCallStatus1Bak=0;
uint16_t SysCallStatus2Bak=0;
uint16_t alarm = 0;

bit MyAddStart;
bit Over1min;

bit OverTimeFlag;

bit OtherMaster;
bit OtherMasterChecked;

volatile uint16_t DisableSendTimeMs;

volatile uint16_t u16_OverTimeMs;

void UART1_ISR() interrupt 4 using 1
{
        if(RI)
        {
                RI = 0;
                SysOverTime = 0;
                UartErr = 0;
                Rcv_Buf[recvbyte] = SBUF;                        //接收数据
                if(Rcv_Buf[0] == 0x53)
                {
                        recvbyte++;
                }
               
                if((Rcv_Buf[recvbyte-1]==0x0a) && (Rcv_Buf[recvbyte-2]==0x0d))                 //接收到帧尾
                {
                        RcvFlag = 1;                        //置位接收标志
                        recvbyte = 0;                        //接收下标清零
                }
        }
}

void Uart1_Init(void)
{
//        SCON = 0x50;
//        TMOD &= 0x0f;
//       
//        TH1 = BAUD>>8;
//        TL1 = BAUD;
//       
//        TR1 = 1;
//        AUXR |= 0x40;
//         ES = 1;
//        EA = 1;
//       
//       
//        RS485_RcevEnable();
                        TR1 = 0;
                AUXR &= ~0x01;                //S1 BRT Use Timer1;
                AUXR |=  (1<<6);        //Timer1 set as 1T mode
                TMOD &= ~(1<<6);        //Timer1 set As Timer
                TMOD &= ~0x30;                //Timer1_16bitAutoReload;
                TH1 = (uint8_t)(BAUD >> 8);
                TL1 = (uint8_t)BAUD;
                ET1 = 0;                                                // 禁止Timer1中断
//                INT_CLKO &= ~0x02;        // Timer1不输出高速时钟
        //        INT_CLKO |=  0x02;        // Timer1输出高速时钟
                TR1  = 1;                        // 运行Timer1
       
        SCON = (SCON & 0x3f) | (1<<6);        // 8位数据, 1位起始位, 1位停止位, 无校验
//        PS  = 1;        //高优先级中断
        ES  = 1;        //允许中断
        REN = 1;        //允许接收       
       
//        if(MasterAdd !=0)
//        {
//                        MyAddStart = 0;
//        }
       
       
       
        OtherMaster = 1;
        OtherMasterChecked = 0;
        DisableSendTimeMs = 0;
       
        SysOverTime = 0;
        Over1min = 0;
       
        RS485_RcevEnable();
}
void UART1_Send_Char(unsigned char c)
{
        RS485_SendEnable();
        _nop_();
        _nop_();
        _nop_();
        SBUF = c;
        while(!TI);       
        TI = 0;
       
        _nop_();
        _nop_();
        _nop_();
        RS485_RcevEnable();
}
void UART1_Send_String(unsigned char *s)
{
        while(*s)
        {
                UART1_Send_Char(*s++);
        }
}
void UART1_Send_Int(unsigned int c)
{
        UART1_Send_Char(c/10000+0x30);
        UART1_Send_Char(c%10000/1000+0x30);
        UART1_Send_Char(c%1000/100+0x30);
        UART1_Send_Char(c%100/10+0x30);
        UART1_Send_Char(c%10+0x30);
        UART1_Send_Char(0x0d);
        UART1_Send_Char(0x0a);
}
void UART1_Send_Buf(unsigned char *s,unsigned char len)
{
        unsigned char i;
       
        for(i=0;i<len;i++)
        {
                UART1_Send_Char(s[i]);
        }
}

void UART_Timer_Ms(void)
{
        SysOverTime++;
        if(SysOverTime > 10000)
        {
                UartErr = 1;
                MyAddStart = InitStartEnable;
                ScanTimeMs = 0;
        }
        if(MyAddStart)
        {
                ScanTimeMs++;
请教一下,这个程序中初始波特率是多少呢
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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