找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 10025|回复: 10
收起左侧

STC15w4k58s4单片机4串口中断收发通信程序源码(C语言和汇编都有)

  [复制链接]
ID:297734 发表于 2018-3-27 14:05 | 显示全部楼层 |阅读模式
0.png

C语言-库函数版本和寄存器版本以及汇编语言的源码都有提供

单片机源程序如下:

  1. /*------------------------------------------------------------------*/
  2. /* --- STC MCU International Limited -------------------------------*/
  3. /* --- STC 1T Series MCU RC Demo -----------------------------------*/
  4. /* If you want to use the program or the program referenced in the  */
  5. /* article, please specify in which data and procedures from STC    */
  6. /*------------------------------------------------------------------*/


  7. /*********************************************************/
  8. #define MAIN_Fosc                22118400L        //定义主时钟
  9. //#define MAIN_Fosc                11059200L        //定义主时钟

  10. #include        "STC15Fxxxx.H"


  11. /*************        功能说明        **************

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

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

  14. 默认参数:
  15. 所有设置均为 1位起始位, 8位数据位, 1位停止位, 无校验.
  16. 每个串口可以使用不同的波特率.
  17. 串口1(P3.0 P3.1): 115200bps.
  18. 串口2(P1.0 P1.1):  57600bps.
  19. 串口3(P0.0 P0.1):  38400bps.
  20. 串口4(P0.2 P0.3):  19200bps.


  21. ******************************************/

  22. /*************        本地常量声明        **************/
  23. #define        RX1_Length        128                /* 接收缓冲长度 */
  24. #define        RX2_Length        128                /* 接收缓冲长度 */
  25. #define        RX3_Length        128                /* 接收缓冲长度 */
  26. #define        RX4_Length        128                /* 接收缓冲长度 */

  27. #define        UART_BaudRate1        115200UL         /* 波特率 */
  28. #define        UART_BaudRate2         57600UL         /* 波特率 */
  29. #define        UART_BaudRate3         38400UL         /* 波特率 */
  30. #define        UART_BaudRate4         19200UL         /* 波特率 */


  31. /*************        本地变量声明        **************/
  32. u8        xdata        RX1_Buffer[RX1_Length];        //接收缓冲
  33. u8        xdata        RX2_Buffer[RX2_Length];        //接收缓冲
  34. u8        xdata        RX3_Buffer[RX3_Length];        //接收缓冲
  35. u8        xdata        RX4_Buffer[RX4_Length];        //接收缓冲

  36. u8        TX1_read,RX1_write;        //读写索引(指针).
  37. u8        TX2_read,RX2_write;        //读写索引(指针).
  38. u8        TX3_read,RX3_write;        //读写索引(指针).
  39. u8        TX4_read,RX4_write;        //读写索引(指针).

  40. bit        B_TX1_Busy,B_TX2_Busy,B_TX3_Busy,B_TX4_Busy;        // 发送忙标志


  41. /*************        本地函数声明        **************/
  42. void        UART1_config(u8 brt);        // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
  43. void        UART2_config(u8 brt);        // 选择波特率, 2: 使用Timer2做波特率, 其它值: 无效.
  44. void        UART3_config(u8 brt);        // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer3做波特率.
  45. void        UART4_config(u8 brt);        // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer4做波特率.
  46. void         PrintString1(u8 *puts);
  47. void         PrintString2(u8 *puts);
  48. void         PrintString3(u8 *puts);
  49. void         PrintString4(u8 *puts);




  50. /**********************************************/
  51. void main(void)
  52. {

  53.         P0n_standard(0xff);        //设置为准双向口
  54.         P1n_standard(0xff);        //设置为准双向口
  55.         P2n_standard(0xff);        //设置为准双向口
  56.         P3n_standard(0xff);        //设置为准双向口
  57.         P4n_standard(0xff);        //设置为准双向口
  58.         P5n_standard(0xff);        //设置为准双向口
  59.        
  60.         UART1_config(1);        // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
  61.         UART2_config(2);        // 选择波特率, 2: 使用Timer2做波特率, 其它值: 无效.
  62.         UART3_config(3);        // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer3做波特率.
  63.         UART4_config(4);        // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer4做波特率.
  64.        
  65.         EA = 1;

  66.         PrintString1("STC15F4K60S4 USART1 Test Prgramme!\r\n");
  67.         PrintString2("STC15F4K60S4 USART2 Test Prgramme!\r\n");
  68.         PrintString3("STC15F4K60S4 USART3 Test Prgramme!\r\n");
  69.         PrintString4("STC15F4K60S4 USART4 Test Prgramme!\r\n");

  70.         while (1)
  71.         {
  72.                 if((TX1_read != RX1_write) && !B_TX1_Busy)        //收到过数据, 并且发送空闲
  73.                 {
  74.                         B_TX1_Busy = 1;                //标志发送忙
  75.                         SBUF = RX1_Buffer[TX1_read];        //发一个字节
  76.                         if(++TX1_read >= RX1_Length)        TX1_read = 0;        //避免溢出处理
  77.                 }

  78.                 if((TX2_read != RX2_write) && !B_TX2_Busy)        //收到过数据, 并且发送空闲
  79.                 {
  80.                         B_TX2_Busy = 1;                //标志发送忙
  81.                         S2BUF = RX2_Buffer[TX2_read];        //发一个字节
  82.                         if(++TX2_read >= RX2_Length)        TX2_read = 0;        //避免溢出处理
  83.                 }

  84.                 if((TX3_read != RX3_write) && !B_TX3_Busy)        //收到过数据, 并且发送空闲
  85.                 {
  86.                         B_TX3_Busy = 1;                //标志发送忙
  87.                         S3BUF = RX3_Buffer[TX3_read];        //发一个字节
  88.                         if(++TX3_read >= RX3_Length)        TX3_read = 0;        //避免溢出处理
  89.                 }

  90.                 if((TX4_read != RX4_write) && !B_TX4_Busy)        //收到过数据, 并且发送空闲
  91.                 {
  92.                         B_TX4_Busy = 1;                //标志发送忙
  93.                         S4BUF = RX4_Buffer[TX4_read];        //发一个字节
  94.                         if(++TX4_read >= RX4_Length)        TX4_read = 0;        //避免溢出处理
  95.                 }
  96.         }
  97. }


  98. //========================================================================
  99. // 函数: SetTimer2Baudraye(u16 dat)
  100. // 描述: 设置Timer2做波特率发生器。
  101. // 参数: dat: Timer2的重装值.
  102. // 返回: none.
  103. // 版本: VER1.0
  104. // 日期: 2014-11-28
  105. // 备注:
  106. //========================================================================
  107. void        SetTimer2Baudraye(u16 dat)        // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
  108. {
  109.         AUXR &= ~(1<<4);        //Timer stop
  110.         AUXR &= ~(1<<3);        //Timer2 set As Timer
  111.         AUXR |=  (1<<2);        //Timer2 set as 1T mode
  112.         TH2 = dat / 256;
  113.         TL2 = dat % 256;
  114.         IE2  &= ~(1<<2);        //禁止中断
  115.         AUXR |=  (1<<4);        //Timer run enable
  116. }


  117. //========================================================================
  118. // 函数: void        UART1_config(u8 brt)
  119. // 描述: UART1初始化函数。
  120. // 参数: brt: 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
  121. // 返回: none.
  122. // 版本: VER1.0
  123. // 日期: 2014-11-28
  124. // 备注:
  125. //========================================================================
  126. void        UART1_config(u8 brt)        // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
  127. {
  128.         u8        i;
  129.         /*********** 波特率使用定时器2 *****************/
  130.         if(brt == 2)
  131.         {
  132.                 AUXR |= 0x01;                //S1 BRT Use Timer2;
  133.                 SetTimer2Baudraye(65536UL - (MAIN_Fosc / 4) / UART_BaudRate1);
  134.         }

  135.         /*********** 波特率使用定时器1 *****************/
  136.         else
  137.         {
  138.                 TR1 = 0;
  139.                 AUXR &= ~0x01;                //S1 BRT Use Timer1;
  140.                 AUXR |=  (1<<6);        //Timer1 set as 1T mode
  141.                 TMOD &= ~(1<<6);        //Timer1 set As Timer
  142.                 TMOD &= ~0x30;                //Timer1_16bitAutoReload;
  143.                 TH1 = (65536UL - (MAIN_Fosc / 4) / UART_BaudRate1) / 256;
  144.                 TL1 = (65536UL - (MAIN_Fosc / 4) / UART_BaudRate1) % 256;
  145.                 ET1 = 0;        //禁止中断
  146.                 INT_CLKO &= ~0x02;        //不输出时钟
  147.                 TR1  = 1;
  148.         }
  149.         /*************************************************/

  150.         SCON = (SCON & 0x3f) | (1<<6);        // 8位数据, 1位起始位, 1位停止位, 无校验
  151. //        PS  = 1;        //高优先级中断
  152.         ES  = 1;        //允许中断
  153.         REN = 1;        //允许接收
  154.         P_SW1 = P_SW1 & 0x3f;        //切换到 P3.0 P3.1
  155. //        P_SW1 = (P_SW1 & 0x3f) | (1<<6);        //切换到P3.6 P3.7
  156. //        P_SW1 = (P_SW1 & 0x3f) | (2<<6);        //切换到P1.6 P1.7 (必须使用内部时钟)

  157.         for(i=0; i<RX1_Length; i++)                RX1_Buffer[i] = 0;
  158.         B_TX1_Busy  = 0;
  159.         TX1_read    = 0;
  160.         RX1_write   = 0;
  161. }


  162. //========================================================================
  163. // 函数: void        UART2_config(u8 brt)
  164. // 描述: UART2初始化函数。
  165. // 参数: brt: 选择波特率, 2: 使用Timer2做波特率, 其它值: 无效.
  166. // 返回: none.
  167. // 版本: VER1.0
  168. // 日期: 2014-11-28
  169. // 备注:
  170. //========================================================================
  171. void        UART2_config(u8 brt)        // 选择波特率, 2: 使用Timer2做波特率, 其它值: 无效.
  172. {
  173.         u8        i;
  174.         /*********** 波特率固定使用定时器2 *****************/
  175.         if(brt == 2)        SetTimer2Baudraye(65536UL - (MAIN_Fosc / 4) / UART_BaudRate2);

  176.         S2CON &= ~(1<<7);        // 8位数据, 1位起始位, 1位停止位, 无校验
  177.         IE2   |= 1;                        //允许中断
  178.         S2CON |= (1<<4);        //允许接收
  179.         P_SW2 &= ~1;                //切换到 P1.0 P1.1
  180. //        P_SW2 |= 1;                        //切换到 P4.6 P4.7

  181.         for(i=0; i<RX2_Length; i++)                RX2_Buffer[i] = 0;
  182.         B_TX2_Busy  = 0;
  183.         TX2_read    = 0;
  184.         RX2_write   = 0;
  185. }

  186. //========================================================================
  187. // 函数: void        UART3_config(u8 brt)
  188. // 描述: UART3初始化函数。
  189. // 参数: brt: 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer3做波特率.
  190. // 返回: none.
  191. // 版本: VER1.0
  192. // 日期: 2014-11-28
  193. // 备注:
  194. //========================================================================
  195. void        UART3_config(u8 brt)        // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer3做波特率.
  196. {
  197.         u8        i;
  198.         /*********** 波特率固定使用定时器2 *****************/
  199.         if(brt == 2)
  200.         {
  201.                 S3CON &= ~(1<<6);        //BRT select Timer2
  202.                 SetTimer2Baudraye(65536UL - (MAIN_Fosc / 4) / UART_BaudRate3);
  203.         }
  204.         /*********** 波特率使用定时器3 *****************/
  205.         else
  206.         {
  207.                 S3CON |= (1<<6);        //BRT select Timer3
  208.                 T4T3M &= 0xf0;                //停止计数, 清除控制位
  209.                 IE2  &= ~(1<<5);        //禁止中断
  210.                 T4T3M |=  (1<<1);        //1T
  211.                 T4T3M &= ~(1<<2);        //定时
  212.                 T4T3M &= ~1;                //不输出时钟
  213.                 TH3 = (65536UL - (MAIN_Fosc / 4) / UART_BaudRate3) / 256;
  214.                 TL3 = (65536UL - (MAIN_Fosc / 4) / UART_BaudRate3) % 256;
  215.                 T4T3M |=  (1<<3);        //开始运行
  216.         }
  217.        
  218.         S3CON &= ~(1<<5);        //禁止多机通讯方式
  219.         S3CON &= ~(1<<7);        // 8位数据, 1位起始位, 1位停止位, 无校验
  220.         IE2   |=  (1<<3);        //允许中断
  221.         S3CON |=  (1<<4);        //允许接收
  222.         P_SW2 &= ~2;                //切换到 P0.0 P0.1
  223. //        P_SW2 |= 2;                        //切换到 P5.0 P5.1

  224.         for(i=0; i<RX3_Length; i++)                RX3_Buffer[i] = 0;
  225.         B_TX3_Busy  = 0;
  226.         TX3_read    = 0;
  227.         RX3_write   = 0;
  228. }

  229. //========================================================================
  230. // 函数: void        UART4_config(u8 brt)
  231. // 描述: UART4初始化函数。
  232. // 参数: brt: 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer4做波特率.
  233. // 返回: none.
  234. // 版本: VER1.0
  235. // 日期: 2014-11-28
  236. // 备注:
  237. //========================================================================
  238. void        UART4_config(u8 brt)        // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer4做波特率.
  239. {
  240.         u8        i;
  241.         /*********** 波特率固定使用定时器2 *****************/
  242.         if(brt == 2)
  243.         {
  244.                 S4CON &= ~(1<<6);        //BRT select Timer2
  245.                 SetTimer2Baudraye(65536UL - (MAIN_Fosc / 4) / UART_BaudRate4);
  246.         }
  247.         /*********** 波特率使用定时器3 *****************/
  248.         else
  249.         {
  250.                 S4CON |= (1<<6);        //BRT select Timer4
  251.                 T4T3M &= 0x0f;                //停止计数, 清除控制位
  252.                 IE2   &= ~(1<<6);        //禁止中断
  253.                 T4T3M |=  (1<<5);        //1T
  254.                 T4T3M &= ~(1<<6);        //定时
  255.                 T4T3M &= ~(1<<4);        //不输出时钟
  256.                 TH4 = (65536UL - (MAIN_Fosc / 4) / UART_BaudRate4) / 256;
  257.                 TL4 = (65536UL - (MAIN_Fosc / 4) / UART_BaudRate4) % 256;
  258.                 T4T3M |=  (1<<7);        //开始运行
  259.         }
  260.        
  261.         S4CON &= ~(1<<5);        //禁止多机通讯方式
  262.         S4CON &= ~(1<<7);        // 8位数据, 1位起始位, 1位停止位, 无校验
  263.         IE2   |=  (1<<4);        //允许中断
  264.         S4CON |=  (1<<4);        //允许接收
  265.         P_SW2 &= ~4;                //切换到 P0.2 P0.3
  266. //        P_SW2 |= 4;                        //切换到 P5.2 P5.3

  267.         for(i=0; i<RX4_Length; i++)                RX4_Buffer[i] = 0;
  268.         B_TX4_Busy  = 0;
  269.         TX4_read    = 0;
  270.         RX4_write   = 0;
  271. }


  272. void PrintString1(u8 *puts)
  273. {
  274.     for (; *puts != 0;        puts++)
  275.         {
  276.                 B_TX1_Busy = 1;                //标志发送忙
  277.                 SBUF = *puts;                //发一个字节
  278.                 while(B_TX1_Busy);        //等待发送完成
  279.         }
  280. }

  281. void PrintString2(u8 *puts)
  282. {
  283.     for (; *puts != 0;        puts++)
  284.         {
  285.                 B_TX2_Busy = 1;                //标志发送忙
  286.                 S2BUF = *puts;                //发一个字节
  287.                 while(B_TX2_Busy);        //等待发送完成
  288.         }
  289. }

  290. void PrintString3(u8 *puts)
  291. {
  292.     for (; *puts != 0;        puts++)
  293.         {
  294.                 B_TX3_Busy = 1;                //标志发送忙
  295.                 S3BUF = *puts;                //发一个字节
  296.                 while(B_TX3_Busy);        //等待发送完成
  297.         }
  298. }

  299. void PrintString4(u8 *puts)
  300. {
  301.     for (; *puts != 0;        puts++)
  302.         {
  303.                 B_TX4_Busy = 1;                //标志发送忙
  304.                 S4BUF = *puts;                //发一个字节
  305.                 while(B_TX4_Busy);        //等待发送完成
  306.         }
  307. }



  308. /********************* UART1中断函数************************/
  309. void UART1_int (void) interrupt UART1_VECTOR
  310. {
  311.         if(RI)
  312.         {
  313.                 RI = 0;
  314.                 RX1_Buffer[RX1_write] = SBUF;
  315.                 if(++RX1_write >= RX1_Length)        RX1_write = 0;
  316.         }

  317.         if(TI)
  318.         {
  319.                 TI = 0;
  320.                 B_TX1_Busy = 0;
  321.         }
  322. }

  323. /********************* UART2中断函数************************/
  324. void UART2_int (void) interrupt UART2_VECTOR
  325. {
  326.         if(RI2)
  327.         {
  328.                 CLR_RI2();
  329.                 RX2_Buffer[RX2_write] = S2BUF;
  330.                 if(++RX2_write >= RX2_Length)        RX2_write = 0;
  331.         }

  332.         if(TI2)
  333.         {
  334.                 CLR_TI2();
  335.                 B_TX2_Busy = 0;
  336.         }

  337. }

  338. /********************* UART3中断函数************************/
  339. void UART3_int (void) interrupt UART3_VECTOR
  340. {
  341.         if(RI3)
  342.         {
  343.                 CLR_RI3();
  344.                 RX3_Buffer[RX3_write] = S3BUF;
  345.                 if(++RX3_write >= RX3_Length)        RX3_write = 0;
  346.         }

  347.         if(TI3)
  348.         {
  349.                 CLR_TI3();
  350.                 B_TX3_Busy = 0;
  351.         }

  352. }

  353. /********************* UART4中断函数************************/
  354. void UART4_int (void) interrupt UART4_VECTOR
  355. {
  356.         if(RI4)
  357.         {
  358.                 CLR_RI4();
  359.                 RX4_Buffer[RX4_write] = S4BUF;
  360.                 if(++RX4_write >= RX4_Length)        RX4_write = 0;
  361.         }

  362.         if(TI4)
  363.         {
  364.                 CLR_TI4();
  365.                 B_TX4_Busy = 0;
  366.         }

  367. }



复制代码

所有资料51hei提供下载:
15W4K-4串口中断收发.rar (88.77 KB, 下载次数: 227)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:401462 发表于 2018-9-23 00:54 | 显示全部楼层
谢楼主分享,正好最近用到
回复

使用道具 举报

ID:398543 发表于 2018-9-23 07:59 | 显示全部楼层
很好,值得学习
回复

使用道具 举报

ID:401532 发表于 2018-9-23 11:56 | 显示全部楼层
谢楼主分享,正好最近用到!
回复

使用道具 举报

ID:492594 发表于 2019-3-17 15:41 | 显示全部楼层
多谢楼主分享
回复

使用道具 举报

ID:90212 发表于 2019-6-5 22:21 | 显示全部楼层
多谢分享,下了另一个坛友的4串口版,感觉还是楼主的注释更多,更能理解
回复

使用道具 举报

ID:234782 发表于 2019-7-8 13:12 | 显示全部楼层
楼主代码注释很不错
回复

使用道具 举报

ID:85480 发表于 2019-8-19 15:38 | 显示全部楼层
u8        xdata        RX1_Buffer[RX1_Length];        //接收缓冲
这个 u8  表示的是  8位  unsigned 吗?

#define        UART_BaudRate1        115200UL
115200UL  后面 UL 是固定格式吗 一定要加这个UL吗?
菜鸟咨询一下,多谢!
回复

使用道具 举报

ID:71535 发表于 2020-2-20 14:37 | 显示全部楼层

谢楼主分享,值得学习
回复

使用道具 举报

ID:128722 发表于 2022-2-9 13:08 | 显示全部楼层
这个可以,谢谢分享串口程序,刚好用到,完美。
回复

使用道具 举报

ID:691218 发表于 2022-2-10 12:50 | 显示全部楼层
感谢分享,最近刚好需要用到。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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