51串口proteus仿真实验

一、实验目的
1、了解单片机串口接收与发送方法。
2、了解串口助手使用方法。
3、了解数码管动态显示方法。
4、了解单片机串口中断服务函数用法。
二、实验内容
1、完成单片机串口往电脑发送数据实验。
2、完成电脑串口助手往单片机发送学号,并通过单片机串口完成学号回传,并利用数码管动态显示功能显示学号。
三、实验原理
在这里插入图片描述

四、实验电路与程序
1、软件实验一:完成单片机串口往电脑发送数据实验
1)实验要求:单片机通过串口向电脑的串口助手发送“MCS51”字符串
2)实验目的:了解单片机串口接收与发送方法;了解串口助手使用方法。
3)实验说明:通过本实验,可以了解单片机串口接收与发送方法;了解串口助手使用方法。
4)、程序框图
在这里插入图片描述

5)、代码

main.c

  1. #include <reg52.h>
  2. #include <uart.h>
  3. void delay_main(unsigned int z)
  4. {
  5. unsigned int x,y;
  6. for(x = z; x > 0; x–)
  7. for(y = 114; y > 0 ; y–);
  8. }
  9. void main()
  10. {
  11. unsigned char *string=“MCS51\r\n”;
  12. UART_init(); //串口初始化
  13. while(1)
  14. {
  15. UART_send(string);
  16. delay_main(1000);
  17. }
  18. }
    uart.h
  19. #ifndef _UART_H
  20. #define _UART_H
  21. #include <reg52.h>
  22. void UART_Init(void);
  23. void UART(void);
  24. void delay(unsigned int z);
  25. void UART_send(unsigned char *str);
  26. extern unsigned char num;
  27. #endif

uart.c

  1. #include <tube.h>
  2. void delay_uart(unsigned int z)
  3. {
  4. unsigned int x,y;
  5. for(x = z; x > 0; x–)
  6. for(y = 114; y > 0 ; y–);
  7. }
  8. void UART_init()
  9. {
  10. TMOD = 0x20; //T1工作模式2 8位自动重装
  11. TH1 = 0xfd;
  12. TL1 = 0xfd; //波特率9600
  13. TR1 = 1; //启动T1定时器
  14. SM0 = 0;
  15. SM1 = 1; //串口工作方式1 10位异步
  16. REN = 1; //串口允许接收
  17. EA = 1; //开总中断
  18. ES = 1; //串口中断打开
  19. }
  20. void UART_send(unsigned char *str)
  21. {
  22. while(*str != 0) //判断字符串是否发送完毕
  23. {
  24. SBUF=*str; //发送单个字符
  25. while(!TI);
  26. TI=0;
  27. str++; //字符地址加1,指向先下一个字符
  28. delay_uart(5);
  29. }
  30. }

6)、仿真结果
利用VSDP软件将电脑的com1和com2配对,proteus中的COMPIM设置为连上com1,串口助手设置为连上com2。单片机发送的数据是0xF1。
在这里插入图片描述

2、软件实验二:完成数码管显示数字每秒加一,八个数码管全亮。
1)实验要求:完成电脑串口助手往单片机发送学号,并通过单片机串口完成学号回传,并利用数码管动态显示功能显示学号。
2)实验目的:了解数码管共阴极和共阳极接法;了解数码管的段选和位选方式;了解定时器用法。
3)实验说明:通过本实验,可以了解了解数码管共阴极和共阳极接法;了解数码管的段选和位选方式;了解定时器用法;同时也可以了解单片机编程,调试方法。
4)、程序框图
在这里插入图片描述

5)、代码
main.c

  1. #include <reg52.h>
  2. #include <uart.h>
  3. #include <tube.h>
  4. unsigned char num[8];
  5. void delay_main(unsigned int z)
  6. {
  7. unsigned int x,y;
  8. for(x = z; x > 0; x–)
  9. for(y = 114; y > 0 ; y–);
  10. }
  11. void main()
  12. {
  13. unsigned char *string=“MCS51”;
  14. UART_init(); //串口初始化
  15. while(1)
  16. {
  17. tube_light(num);
  18. }
  19. }

uart.h

  1. #ifndef _UART_H
  2. #define _UART_H
  3. #include <reg52.h>
  4. void UART_Init(void);
  5. void UART(void);
  6. void delay(unsigned int z);
  7. extern unsigned char num[8];
  8. #endif

uart.c

  1. #include <uart.h>
  2. #include <tube.h>
  3. void delay(unsigned int z)
  4. {
  5. unsigned int x,y;
  6. for(x = z; x > 0; x–)
  7. for(y = 114; y > 0 ; y–);
  8. }
  9. void UART_init()
  10. {
  11. TMOD = 0x20; //T1工作模式2 8位自动重装
  12. TH1 = 0xfd;
  13. TL1 = 0xfd; //波特率9600
  14. TR1 = 1; //启动T1定时器
  15. SM0 = 0;
  16. SM1 = 1; //串口工作方式1 10位异步
  17. REN = 1; //串口允许接收
  18. EA = 1; //开总中断
  19. ES = 1; //串口中断打开
  20. }
  21. void UART() interrupt 4
  22. {
  23. static int count=0;
  24. if(RI) //检测是否接收完成
  25. {
  26. num[count] = SBUF; //num 取出接收缓存器的值
  27. P1 = SBUF;
  28. RI = 0;
  29. SBUF = num[count];
  30. while(!TI);
  31. TI = 0;
  32. count++;
  33. if(count>=8)
  34. {
  35. count=0;
  36. }
  37. }
  38. }

tube.h

  1. #ifndef _TUBE_H
  2. #define _TUBE_H
  3. #include <reg52.h>
  4. sbit WE = P2^7; //位定义数码管位选锁存器接口
  5. sbit DU = P2^6; //位定义数码管段选锁存器接口
  6. void tube_init(void);
  7. void tube_light(unsigned char number[8]);
  8. void delay1(unsigned int z);
  9. #endif

tube.c

  1. #include <tube.h>
  2. //数码管段选表
  3. unsigned char code leddata[]={
  4.              0x3F,  //"0"
    
  5.              0x06,  //"1"
    
  6.              0x5B,  //"2"
    
  7.              0x4F,  //"3"
    
  8.              0x66,  //"4"
    
  9.             0x6D,  //"5"
    
  10.             0x7D,  //"6"
    
  11.             0x07,  //"7"
    
  12.             0x7F,  //"8"
    
  13.             0x6F,  //"9"
    
  14.             0x77,  //"A"
    
  15.             0x7C,  //"B"
    
  16.             0x39,  //"C"
    
  17.             0x5E,  //"D"
    
  18.             0x79,  //"E"
    
  19.             0x71,  //"F"
    
  20.             0x76,  //"H"
    
  21.             0x38,  //"L"
    
  22.             0x37,  //"n"
    
  23.             0x3E,  //"u"
    
  24.             0x73,  //"P"
    
  25.             0x5C,  //"o"
    
  26.             0x40,  //"-"
    
  27.             0x00,  //熄灭
    
  28.             0x00  //自定义
    
  29.                      };
    
  30. unsigned char code weidata[]={
  31. 0xEF,
  32. 0xDF,
  33. 0xBF,
  34. 0x7F,
  35. 0xFE,
  36. 0xFD,
  37. 0xFB,
  38. 0xF7
  39. };
  40. void delay1(unsigned int z)
  41. {
  42. unsigned int x,y;
  43. for(x = z; x > 0; x–)
  44. for(y = 114; y > 0 ; y–);
  45. }
  46. void tube_light(unsigned char number[8])
  47. {
  48. int i=0;
  49. for(i=0;i<8;i++)
  50. {
  51. P0=0;
  52. DU=1;
  53. delay1(1);
  54. DU=0;
  55. delay1(1);
  56. //位选
  57. P0=weidata[i];
  58. WE=1;
  59. delay1(1);
  60. WE=0;
  61. delay1(1);
  62. //段选
  63. P0=leddata[number[i]];
  64. DU=1;
  65. delay1(1);
  66. DU=0;
  67. delay1(1);
  68. }
  69. }

6)仿真结果
在这里插入图片描述

五、实验总结

  1. 动态数码管在位选之前,应该将段选清零,否则会有鬼影。
  2. proteus的串口发送数据会自动加上80,并且会被正点原子的串口助手识别成汉字,得用十六进制显示查看才行。
    3.如果proteus的串口连上虚拟终端,收发会有问题。
    4.串口有没有经过max232进行电平转换都没有什么影响。
  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值