这是学单片机以来做的第二个实验内容 ,文件含proteus仿真工程以及keil源文件,功能(如下)都已经实现。新人第一次发分享的帖子,请大家多多指教。
单片机功能;在二个单片机之间编程实现串行口通讯,发送方以流水灯字节码作为发送数据定时发送,并在接收方的 P0 口上显示接收到的字节,在数码屏上以十六进制显示,中间有按钮可以启动和暂停。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
发送方源码- #include<reg51.h>
- #define uchar unsigned char
- uchar code Tab[16]={0xC0,/*0*/
- 0xF9,/*1*/
- 0xA4,/*2*/
- 0xB0,/*3*/
- 0x99,/*4*/
- 0x92,/*5*/
- 0x82,/*6*/
- 0xF8,/*7*/
- 0x80,/*8*/
- 0x90,/*9*/
- 0x88,/*A*/
- 0x83,/*B*/
- 0xC6,/*C*/
- 0xA1,/*D*/
- 0x86,/*E*/
- 0x8E /*F*/};
- uchar Counter=0;Second_1=0,Second_0=0;
- sbit Key = P3^2;
-
- void Display(void);
- void Delay(void);
- void UARTInit(void);
- void UARTSend(uchar data1);
- void timer0Init(void);
-
- void main()
- {
- P1=0xff;//给流水灯初始化值
- UARTInit();//串口初始化
- timer0Init();//定时器初始化
- while(1)
- {
- if(Key == 0)
- {
- EA = 1; //打开总中断
- }
- if(Key == 1)
- {
- EA = 0; //关闭总中断
- }
- Display();//数码管显示函数
- }
- }
- void Display(void)
- {
- switch (P1)//根据P1的值给数码管赋值
- {
- case 0xFE:{Second_1 = 15, Second_0 = 14; break;}
- case 0xFD:{Second_1 = 15, Second_0 = 13; break;}
- case 0xFB:{Second_1 = 15, Second_0 = 11; break;}
- case 0xF7:{Second_1 = 15, Second_0 = 7 ; break;}
- case 0xEF:{Second_1 = 14, Second_0 = 15; break;}
- case 0xDF:{Second_1 = 13, Second_0 = 15; break;}
- case 0xBF:{Second_1 = 11, Second_0 = 15; break;}
- case 0x7F:{Second_1 = 7 , Second_0 = 15; break;}
- default: break;
- }
- P0=Tab[Second_1];
- P2=0x01;
- Delay();
- P2=0x00;
- P0=Tab[Second_0];
- P2=0x02;
- Delay();
- P2=0x00;
- }
- void timer0Init()
- {
- EA = 1; //打开总中断
- ET0 = 1;//打开定时器0中断
- TR0 = 1; //启动定时器0
- REN = 1;//允许串口接收
- TMOD |= 0X01; //定时器工作模式1,16位定时模式
- TH0=0x3c;
- TL0=0xb0;
- }
- //串口初始化
- void UARTInit()
- {
- EA = 1; //打开总中断
- ES = 1; //打开串口中断
- SM0 = 0; SM1 = 1;//串口工作方式1,8位UART波特率可变
- REN = 1;//串口允许接收
- TR1 = 1;//启动定时器1
- TMOD |= 0x20;//定时器1,工作模式2 8位自动重装
- TH1 = 0xfd;
- TL1 = 0xfd;//设置比特率9600
- }
- void Timer0() interrupt 1
- {
- ET0=0;
- TH0=0x3c;
- TL0=0xb0;
- Counter++;
- if(Counter==20)
- {
- Counter=0;
- P1<<=1;//左移一位
- P1|=0x01;//最后一位补1
- if(P1==0xff)//检测是否移到最左端
- {
- P1=0xfe;
- }
- UARTSend(P1);//串口发送流水灯的值
- }
- ET0=1;
- }
- // 串口发送函数
- void UARTSend(uchar data1)
- {
- SBUF = data1;
- while(!TI);
- TI = 0;
- }
- void Delay(void)
- {
- uchar data i;
- for(i=500;i>0;i--);
- }
复制代码 接收方源码- #include <reg51.h>
- #define uchar unsigned char
- uchar code Tab[16]={0xC0,/*0*/
- 0xF9,/*1*/
- 0xA4,/*2*/
- 0xB0,/*3*/
- 0x99,/*4*/
- 0x92,/*5*/
- 0x82,/*6*/
- 0xF8,/*7*/
- 0x80,/*8*/
- 0x90,/*9*/
- 0x88,/*A*/
- 0x83,/*B*/
- 0xC6,/*C*/
- 0xA1,/*D*/
- 0x86,/*E*/
- 0x8E /*F*/};
- uchar Counter=0;Second_1=0,Second_0=0;
- uchar receivedData = 0;//串口接收数据
-
- void Display(void);
- void Delay(void);
- void UARTInit(void);
-
- void main()
- {
- P1=0xff;//给初始化值
- UARTInit(); // 初始化串口
- while (1)
- {
- Display();//数码管显示函数
- }
- }
- void Display(void)
- {
- switch (P1)
- {
- case 0xFE:{Second_1 = 15, Second_0 = 14; break;}
- case 0xFD:{Second_1 = 15, Second_0 = 13; break;}
- case 0xFB:{Second_1 = 15, Second_0 = 11; break;}
- case 0xF7:{Second_1 = 15, Second_0 = 7 ; break;}
- case 0xEF:{Second_1 = 14, Second_0 = 15; break;}
- case 0xDF:{Second_1 = 13, Second_0 = 15; break;}
- case 0xBF:{Second_1 = 11, Second_0 = 15; break;}
- case 0x7F:{Second_1 = 7 , Second_0 = 15; break;}
- default: break;
- }
- P0=Tab[Second_1];
- P2=0x01;
- Delay();
- P2=0x00;
- P0=Tab[Second_0];
- P2=0x02;
- Delay();
- P2=0x00;
- }
- //串口初始化
- void UARTInit()
- {
- EA = 1; //打开总中断
- ES = 1; //打开串口中断
- SM0 = 0; SM1 = 1;//串口工作方式1,8位UART波特率可变
- REN = 1;//串口允许接收
- TR1 = 1;//启动定时器1
- TMOD |= 0x20;//定时器1,工作模式2 8位自动重装
- TH1 = 0xfd;
- TL1 = 0xfd;//设置比特率9600
- }
- // 串口接收函数
- void UART() interrupt 4
- {
- if(RI)
- {
- RI = 0;
- receivedData = SBUF;
- P1 = receivedData;
- }
- else
- TI = 0;
- }
- void Delay(void)
- {
- uchar data i;
- for(i=500;i>0;i--);
- }
复制代码
Proteus8.10 仿真程序:
基于单片机的双机通信电路设计.7z
(66.14 KB, 下载次数: 2)
|