100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > 【PROTEUS-51单片机串口通信仿真】

【PROTEUS-51单片机串口通信仿真】

时间:2024-06-01 05:12:46

相关推荐

【PROTEUS-51单片机串口通信仿真】

proteus-51单片机仿真之双机通信

概要仿真实图程序知识链接1、串口相关寄存器SCON串口控制寄存器TCON定时器控制寄存器TMOD定时器/计数器模式控制寄存器PCON电源控制寄存器IE中断使能寄存器 总结

概要

本次实验对51单片机的串口进行了双机通信的仿真,实现了51单片机的简单双机通信;现对本次仿真的结构及实现的功能做简要的介绍,

本次仿真主要构成:主机U1-MASTER、从机U2-SLAVE、以及LED显示部分(第一部分显示主机接收到的信息、第二部分显示从机接收到的信号);

实现的功能:主机通过串口发送信息给从机,从机接收到信息后通过从机旁边LED显示;从机通过串口发送信息给主机,主机收到后通过旁边LED显示。

简单的通信协议:通信双方均选用9600波特的传输速率,系统的主频为11.0952MHz,主机的呼叫号为0,即主机地址;从机的呼叫号为1,即从机地址,发送的数据以$为结束符号;通信时发送的数据为两部分,一是通信对象,二是内容。

仿真实图

1、主机部分:

2、从机部分:

3、仿真效果图

程序

1、主机程序

uart.c

#include "uart.h"u8 RXstart; //开始接收u16 RXData; //接收数据位u16 temp[10] = {0}; //数组接收int j = 0;//串口初始化,定时器1模式2,波特率为9600bps,晶振频率11.592MHzvoid UartInit(){SCON = 0XD0; //串口模式3,主从+波特率可变,允许接收,清空收发中断标志位//主机SM2不置位,从机SM2要置位TMOD = 0x20; //设置定时器1为模式2,8位自动重装载模式TH1 = 0xfd; //波特率计算式:[256-(K*Fosc)/(384*BaudeRate)]hTL1 = 0XFD; TR1 = 1;//开定时器1中断REN = 1; //允许串口接收PCON &= 0X7F; //禁止波特率倍增K=1;ES = 1; //开串口中断EA = 1; //开总中断}//主机数据发送函数以$结束,主机先发地址TB8=1,后发数据TB8=0;void UartSendData(u8 addr,u8 *str){TB8 = 1; //发送地址SBUF = addr; //通过SBUF发送出去while(!TI); //判断是否发送成功,成功发送TI被置1,要手动复位TI = 0; //复位TB8 = 0; //发送数据while(*str != '\0') //发送数组{SBUF = (*str);while(!TI); //判断是否发送完一组数据TI = 0;str++;}}//主机接收数据,串口中断服务函数void UartRData() interrupt 4 //串口中断服务函数{ES = 0; //关闭串口中断if(RI) //再判断是否接收到数据,接收到数据RI会被置1{RXData = SBUF; //接收数据if(RXData == MasterAddr0) //判断是否呼叫本机{RXstart = 1; //开始接收数据SM2 = 0;//配置为接收数据模式j = 0;}if(RXstart) //判断是否接收过本地址{if(RXData != '$') //判断是否接收到数据结束标志${temp[j] = RXData; //没有接收到结束标志$,正常保存数据j++;}else //接收到数据结束标志${RXstart = 0; //数据接收结束SM2 = 1; //重新配置为只接收地址,下次发送TB8=1才中断j = 0;}}}RI = 0; //清除接收中断标志位ES = 1; // 开串口中断}

uart.h

#ifndef __UART_H#define __UART_H#include "reg52.h"#ifndef u16#define u16 unsigned int#endif#ifndef u8#define u8 unsigned char#endif#define MasterAddr0 0 //主机号/地址extern u16 temp[10]; //数组接收void UartInit();void UartSendData(u8 addr,u8 *str);void UartRData();#endif

main.c

#include "reg52.h"#include "uart.h"//从机地址SlaveAddr:0~9#define SlaveAddr1 1 //从机号(地址)extern u16 temp[10]; //数组接收#define LED P0void delay(u16 i);void main(){u8 i;UartInit();while(1){UartSendData(SlaveAddr1,"168$");for(i=0;i<10;i++){LED = temp[i];delay(50000);}}}void delay(u16 i){while(i--);}

2、从机程序

uart.c

#include "uart.h"u8 RXData; //接收数据u8 RXstart; //接收标志u16 temp[10] = {0}; //数据缓存int j;//串口初始化函数,定时器1模式2,波特率9600bps,晶振频率11.0592MHzvoid UartInit(){SCON = 0XF0; //串口模式3,SM2接收地址,允许接收EN,清空收发标志TMOD = 0X20; //定时器1模式2,8位重装载模式TH1 = 0XFD;TL1 = 0XFD;TR1 = 1; //开定时器中断1PCON &= 0X7F; //波特率不倍增ES = 1; //开串口中断EA = 1; //开总中断}//从机发送函数,从机发送给主机的数据帧要以字符‘0’开头,标识这是发给主机的void SendData(u8 addr,u8 *str){TB8 = 1;//发送地址SBUF = addr; //通过SBUF发送出去while(!TI); //判断是否发送成功TI = 0; //清除发送中断标志位TB8 = 0; //发送数据while(*str != '\0') //发送数组{SBUF = (*str);while(!TI);TI = 0;str++;}}//从机数据接收函数,$是结束标志void ReData() interrupt 4 //串口中断服务函数{ES = 0; //关闭串口中断if(RI) //再判断是否接收到数据{RXData = SBUF; if(RXstart) //判断是否接收过本地址{if(RXData != '\$') //判断是否接收到结束标志${temp[j] = RXData; //没有接收到$,正常接收数据j++;}else{RXstart = 0; //本次接收结束SM2 = 1; //重新配置为只接收地址,下次发送TB8=1才中断j = 0;}}if(RXData == SlaveAddr) //判断是否呼叫本机,地址范围:000-254(00-FE){RXstart = 1; //开始接收数据SM2 = 0;//配置为接收数据模式j = 0;}}RI = 0; //清除接收中断标志位ES = 1; //重开串口中断}

uart.h

#ifndef __UART_H#define __UART_H#include "reg52.h"#ifndef u16#define u16 unsigned int#endif#ifndef u8#define u8 unsigned char#endif#define SlaveAddr 1 //从机号/地址extern u16 temp[10]; //数据缓存void UartInit();void SendData(u8 addr,u8 *str);void ReData();#endif

main.c

#include "reg52.h"#include "uart.h"#define MasterAddr0 0 //主机号(地址)extern u16 temp[10]; //数据缓存#define LED P0void delay(u16 i);void main(){u8 i;UartInit();while(1){for(i=0;i<10;i++){LED = temp[i];delay(50000);}SendData(MasterAddr0,"2$");}}void delay(u16 i){while(i--);}

知识链接

1、串口相关寄存器

SCON串口控制寄存器;

TCON定时器控制寄存器

TMOD定时器/计数器模式控制寄存器

PCON电源控制寄存器

IE中断使用寄存器

SCON串口控制寄存器

SM0、SM1:串口工作方式控制位

SM2:多机通信控制位(方式2、3),1允许,0不允许

REN:允许/禁止串行接收控制位

TB8:要发送的第9位数据,由软件清零,多机通信中地址(1)或数据(0)标志位

RB8:接收到的第九位数据

TI:发送中断请求标志位,软件复位

RI:接收中断请求标志位,软件复位

TCON定时器控制寄存器

TF1:定时器/计数器1溢出标志

TR1:定时器1运行控制位,软件控制

TF0:定时器/计数器0溢出标志

TR0:定时器0运行控制位,软件控制

IE1:外部中断1使能位

IT1:外部中断1触发方式控制位

IE0:外部中断0使能位

IT0:外部中断0触发方式控制位

TMOD定时器/计数器模式控制寄存器

GATE:定时器1门控制位

C/T:计数器/定时器1选择位

M1、M0:定时器计数器1模式控制位

后四位为定时器0相关位

PCON电源控制寄存器

SMOD:波特率选择位,1加倍,0不加倍

IE中断使能寄存器

EA:总中断允许位

ES:串口中断允许位

ET1:定时器1溢出中断允许位

EX1:外部中断1中断位允许

ET0:定时器0溢出中断允许位

EX0:外部中断0中断位允许

总结

这一个拖了好久,一直没整,原因就不多说了,归纳了一下:还是要多尝试,试错的成本可能不低,但错过机会的成本更高,所以还是要多去尝试,不管结果如何。试过总是还是有机会的,没试过就一定没机会。

感觉还不是很熟悉,还是要多看多练习,多总结。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。