一、实验目的
1、了解单片机串口接收与发送方法。
2、了解串口助手使用方法。
3、了解数码管动态显示方法。
4、了解单片机串口中断服务函数用法。
二、实验内容
1、完成单片机串口往电脑发送数据实验。
2、完成电脑串口助手往单片机发送学号,并通过单片机串口完成学号回传,并利用数码管动态显示功能显示学号。
三、实验原理
四、实验电路与程序
1、软件实验一:完成单片机串口往电脑发送数据实验
1)实验要求:单片机通过串口向电脑的串口助手发送“MCS51”字符串
2)实验目的:了解单片机串口接收与发送方法;了解串口助手使用方法。
3)实验说明:通过本实验,可以了解单片机串口接收与发送方法;了解串口助手使用方法。
4)、程序框图
5)、代码
main.c
- #include <reg52.h>
- #include <uart.h>
- void delay_main(unsigned int z)
- {
- unsigned int x,y;
- for(x = z; x > 0; x–)
- for(y = 114; y > 0 ; y–);
- }
- void main()
- {
- unsigned char *string=“MCS51\r\n”;
- UART_init(); //串口初始化
- while(1)
- {
- UART_send(string);
- delay_main(1000);
- }
- }
uart.h - #ifndef _UART_H
- #define _UART_H
- #include <reg52.h>
- void UART_Init(void);
- void UART(void);
- void delay(unsigned int z);
- void UART_send(unsigned char *str);
- extern unsigned char num;
- #endif
uart.c
- #include <tube.h>
- void delay_uart(unsigned int z)
- {
- unsigned int x,y;
- for(x = z; x > 0; x–)
- for(y = 114; y > 0 ; y–);
- }
- void UART_init()
- {
- TMOD = 0x20; //T1工作模式2 8位自动重装
- TH1 = 0xfd;
- TL1 = 0xfd; //波特率9600
- TR1 = 1; //启动T1定时器
- SM0 = 0;
- SM1 = 1; //串口工作方式1 10位异步
- REN = 1; //串口允许接收
- EA = 1; //开总中断
- ES = 1; //串口中断打开
- }
- void UART_send(unsigned char *str)
- {
- while(*str != 0) //判断字符串是否发送完毕
- {
- SBUF=*str; //发送单个字符
- while(!TI);
- TI=0;
- str++; //字符地址加1,指向先下一个字符
- delay_uart(5);
- }
- }
6)、仿真结果
利用VSDP软件将电脑的com1和com2配对,proteus中的COMPIM设置为连上com1,串口助手设置为连上com2。单片机发送的数据是0xF1。
2、软件实验二:完成数码管显示数字每秒加一,八个数码管全亮。
1)实验要求:完成电脑串口助手往单片机发送学号,并通过单片机串口完成学号回传,并利用数码管动态显示功能显示学号。
2)实验目的:了解数码管共阴极和共阳极接法;了解数码管的段选和位选方式;了解定时器用法。
3)实验说明:通过本实验,可以了解了解数码管共阴极和共阳极接法;了解数码管的段选和位选方式;了解定时器用法;同时也可以了解单片机编程,调试方法。
4)、程序框图
5)、代码
main.c
- #include <reg52.h>
- #include <uart.h>
- #include <tube.h>
- unsigned char num[8];
- void delay_main(unsigned int z)
- {
- unsigned int x,y;
- for(x = z; x > 0; x–)
- for(y = 114; y > 0 ; y–);
- }
- void main()
- {
- unsigned char *string=“MCS51”;
- UART_init(); //串口初始化
- while(1)
- {
- tube_light(num);
- }
- }
uart.h
- #ifndef _UART_H
- #define _UART_H
- #include <reg52.h>
- void UART_Init(void);
- void UART(void);
- void delay(unsigned int z);
- extern unsigned char num[8];
- #endif
uart.c
- #include <uart.h>
- #include <tube.h>
- void delay(unsigned int z)
- {
- unsigned int x,y;
- for(x = z; x > 0; x–)
- for(y = 114; y > 0 ; y–);
- }
- void UART_init()
- {
- TMOD = 0x20; //T1工作模式2 8位自动重装
- TH1 = 0xfd;
- TL1 = 0xfd; //波特率9600
- TR1 = 1; //启动T1定时器
- SM0 = 0;
- SM1 = 1; //串口工作方式1 10位异步
- REN = 1; //串口允许接收
- EA = 1; //开总中断
- ES = 1; //串口中断打开
- }
- void UART() interrupt 4
- {
- static int count=0;
- if(RI) //检测是否接收完成
- {
- num[count] = SBUF; //num 取出接收缓存器的值
- P1 = SBUF;
- RI = 0;
- SBUF = num[count];
- while(!TI);
- TI = 0;
- count++;
- if(count>=8)
- {
- count=0;
- }
- }
- }
tube.h
- #ifndef _TUBE_H
- #define _TUBE_H
- #include <reg52.h>
- sbit WE = P2^7; //位定义数码管位选锁存器接口
- sbit DU = P2^6; //位定义数码管段选锁存器接口
- void tube_init(void);
- void tube_light(unsigned char number[8]);
- void delay1(unsigned int z);
- #endif
tube.c
- #include <tube.h>
- //数码管段选表
- unsigned char code leddata[]={
-
0x3F, //"0"
-
0x06, //"1"
-
0x5B, //"2"
-
0x4F, //"3"
-
0x66, //"4"
-
0x6D, //"5"
-
0x7D, //"6"
-
0x07, //"7"
-
0x7F, //"8"
-
0x6F, //"9"
-
0x77, //"A"
-
0x7C, //"B"
-
0x39, //"C"
-
0x5E, //"D"
-
0x79, //"E"
-
0x71, //"F"
-
0x76, //"H"
-
0x38, //"L"
-
0x37, //"n"
-
0x3E, //"u"
-
0x73, //"P"
-
0x5C, //"o"
-
0x40, //"-"
-
0x00, //熄灭
-
0x00 //自定义
-
};
- unsigned char code weidata[]={
- 0xEF,
- 0xDF,
- 0xBF,
- 0x7F,
- 0xFE,
- 0xFD,
- 0xFB,
- 0xF7
- };
- void delay1(unsigned int z)
- {
- unsigned int x,y;
- for(x = z; x > 0; x–)
- for(y = 114; y > 0 ; y–);
- }
- void tube_light(unsigned char number[8])
- {
- int i=0;
- for(i=0;i<8;i++)
- {
- P0=0;
- DU=1;
- delay1(1);
- DU=0;
- delay1(1);
- //位选
- P0=weidata[i];
- WE=1;
- delay1(1);
- WE=0;
- delay1(1);
- //段选
- P0=leddata[number[i]];
- DU=1;
- delay1(1);
- DU=0;
- delay1(1);
- }
- }
6)仿真结果
五、实验总结
- 动态数码管在位选之前,应该将段选清零,否则会有鬼影。
- proteus的串口发送数据会自动加上80,并且会被正点原子的串口助手识别成汉字,得用十六进制显示查看才行。
3.如果proteus的串口连上虚拟终端,收发会有问题。
4.串口有没有经过max232进行电平转换都没有什么影响。