两个89c51单片机 双机232通信设计

两个89c51单片机 双机232通信设计,第1张

我有一个可以给你参考

#include <reg51h>

//#include <stdioh>

#define SW P2

#define LED P0

unsigned int a;

void delay();

main()

{

a=0x0ff;

PCON=0x80;

SCON=0x90;

while(1)

{

if(a!=SW)

{

a=SW;

SBUF=a;

while(!TI);

TI=0;

}

if(RI)

{

RI=0;

LED=SBUF;

}

//delay();

}

}

void delay()

{

unsigned int i,j;

for(i=0;i<255;i++);

for(j=0;j<255;j++);

}

//两个51单片机,两机的串口交叉连线,双机互发数据

//接收方采用两位数显示收到的数据

//下列双机通信程序,适用于双方同时使用

//经过编译、仿真成功

//显示函数应该根据自己的设备进行改写

//===============================

#include<reg52h>

#define uchar unsigned char

#define uint unsigned int

uchar Rbuf = 0;

uchar code dis_7[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71, 0x00};//共阴段码

//段码表 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, off

//-------------------------------

void delay(uint k)

{

uint i, j;

for(i = 0; i < k; i++) for(j = 0; j < 200; j++);

}

//-------------------------------

void Display(uchar x)

{

P0 = dis_7[x / 16]; //输出高四位

P2 = 0xFE;

delay(2);

P0 = dis_7[x % 16]; //输出低四位

P2 = 0xFD;

delay(2);

}

//-------------------------------

void UART()interrupt 4

{

if(RI) {

RI = 0; //清除中断标志

Rbuf = SBUF;

}

if(TI) {

TI = 0; //清除中断标志

}

}

//-------------------------------

void main() //主函数

{

uchar t1, i;

SCON = 0x50; //串口工作在方式1

PCON &= 0x7F; //SMOD=0

TMOD = 0x20; //定时器1当做波特率发生器

TH1 = 0xFD; //初值, 9600 @ 110592MHz

TL1 = 0xFD;

TR1 = 1;

while (1){

for (i = 0; i < 250; i++) Display(Rbuf);

SBUF = t1; //发送数据

t1++;

}

}

//===============================

#include<reg51h>

#define uchar unsigned char

uchar distab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};

void delay(uchar a)

{

uchar i;

while(a--)for(i=0;i<120;i++);

}

main()

{

uchar i;

TMOD=0x20;

TH1=0xfd;

TL1=0xfd;

TR1=1;

SCON=0x40;

while(1)

{

for(i=0;i<16;i++)

{

SBUF=distab[i];

whileTI==0);

TI=0;

delay(200);

}

}

}

#include<reg51h>

#define uchar unsigned char

main()

{

uchar i;

TMOD=0x20;

TH1=0xfd;

TL1=0xfd;

TR1=1;

SCON=0x50;

while(1)

{

if(RI)

{

RI=0;

P1=SBUF;

}

}

}

单片机a,b,c a为主机,bc为从机。a上有一个外部中断0输入,按第一次a的两个LED亮500ms,再按一下,b机的两个LED灯亮500ms,第三次按下c机的两个LED灯亮500ms,然后周而复始。两个数码管分别显示0/1/2, 和abc(bc由从机反馈)

/

主从通信基本步骤:

1. 主机从机初始化为方式2或者3,从机都置SM2=1,允许中断

2. 主机置TB8=1,发送从机地址

3. 所有从机均接收主机发送要寻址的从机地址

4. 被寻址的从机确认地址后,置本机SM2=0,向主机返回地址,供主机核对

5. 核对无误后,主机向被寻址的从机发送命令,通知从机接受或者发送数据。

6. 本次通信结束后,主从机重置SM2=1,主机可再对其他从机寻址

/

主机a:

#include <reg51h>

#define uchar unsigned char

#define uint unsigned int

uchar leddata[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x40,0x00};

uchar Mode;

sbit P10 = P1^0;

sbit P13 = P1^3;

sbit P17 = P1^7;

sbit P20 = P2^0;

sbit P21 = P2^1;

void UART_init()

{

TMOD = 0x20;

TH1 = 0xfd;

TL1 = 0xfd;

TR1 = 1;

SCON = 0xd0;

ES = 1;

EX0 = 1;

IT0 = 1; //INT0下跳触发

EA = 1;

TI = 0;

}

void DelayMs(int ms)

{

uchar i;

while(ms--)

for(i=0; i<120; i++);

}

void putc_to_SerialPort(uchar c)

{

SBUF = c;

while(TI == 0);

TI = 0;

}

void MasterControl(unsigned char Addr, unsigned char Comd)

{

TB8 = 1;

putc_to_SerialPort(Addr);

DelayMs(50);

TB8 = 0;

putc_to_SerialPort(Comd);

DelayMs(50);

}

Ex0_int(void) interrupt 0

{

P0 = leddata[Mode];

P20 = 0;

if(Mode == 0)

{

P2 = leddata[10];

P10 = 0;

P13 = 0;

DelayMs(500);

P10 = 1;

P13 = 1;

//        MasterControl('b','C');

//        MasterControl('c','C');

}

else if(Mode == 1)

{

P10 = 1;

P13 = 1;

MasterControl('b','O');

//        MasterControl('c','C');

}

else if(Mode == 2)

{

P10 = 1;

P13 = 1;

//        MasterControl('b','C');

MasterControl('c','O');

}

Mode = (Mode + 1) % 3;

}

com_int(void) interrupt 4

{

if(RI)

{

RI = 0;

if(SBUF == 'b')

{

P2 = leddata[11];

}

if(SBUF == 'c')

{

P2 = leddata[12];

}

}

}

void main(void)

{

P0 = 0x00;

P1 = 0xff;

P2 = 0x00;

UART_init();

Mode = 0;

while(1);

}

从机b:

#include <reg51h>

#define uchar unsigned char

uchar RecData;

sbit P10 = P1^0;

sbit P13 = P1^3;

void UART_init()

{

TMOD = 0x21;

TH1 = 0xfd;

TL1 = 0xfd;

TR1 = 1;

SCON = 0xf0;

ES = 1;

PS = 1;

EA = 1;

}

void DelayMs(int ms)

{

uchar i;

while(ms--)

for(i=0; i<120; i++);

}

void putc_to_SerialPort(uchar c)

{

SBUF = c;

while(TI == 0);

TI = 0;

}

com_int(void) interrupt 4

{

if(RI)

{

RecData = SBUF;

RI = 0;

if(RB8 == 1)  //地址

{

if(RecData == 'b')  //是自己的地址,置SM2=0,准备接受数据

{

SM2 = 0;

putc_to_SerialPort('b');

}

else  //不是自己的地址

{

SM2 = 1;

}

}

if(RB8 == 0)  //数据

{

if(RecData=='O')

{

P10 = 0;

P13 = 0;

DelayMs(500);

P10 = 1;

P13 = 1;

}

if(RecData=='C')

{

P10 = 1;

P13 = 1;

}

SM2 = 1;

}

}

}

void main(void)

{

P0 = 0xff;

P1 = 0xff;

UART_init();

while(1);

}

从机c:

#include <reg51h>

#define uchar unsigned char

uchar RecData;

sbit P10 = P1^0;

sbit P13 = P1^3;

void UART_init()

{

TMOD = 0x21;

TH1 = 0xfd;

TL1 = 0xfd;

TR1 = 1;

SCON = 0xf0;

ES = 1;

PS = 1;

EA = 1;

}

void DelayMs(int ms)

{

uchar i;

while(ms--)

for(i=0; i<120; i++);

}

void putc_to_SerialPort(uchar c)

{

SBUF = c;

while(TI == 0);

TI = 0;

}

com_int(void) interrupt 4

{

if(RI)

{

RecData = SBUF;

RI = 0;

if(RB8 == 1)  //地址

{

if(RecData == 'c')  //是自己的地址,置SM2=0,准备接受数据

{

SM2 = 0;

putc_to_SerialPort('c');

}

else  //不是自己的地址

{

SM2 = 1;

}

}

if(RB8 == 0)  //数据

{

if(RecData=='O')

{

P10 = 0;

P13 = 0;

DelayMs(500);

P10 = 1;

P13 = 1;

SM2 = 1;

}

if(RecData=='C')

{

P10 = 1;

P13 = 1;

SM2 = 1;

}

}

}

}

void main(void)

{

P0 = 0xff;

P1 = 0xff;

UART_init();

while(1);

}

#include <reg52h>

#include <intrinsh>

#define uchar unsigned char

#define uint unsigned int

sbit LCD_RS = P2^0;

sbit LCD_RW = P2^1;

sbit LCD_EN = P2^2;

#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};

uchar data RXDdata[ ] = {0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,

0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20 };

uchar temp,buf,m,count;

bit playflag=0;

uchar code cdis1[ ] = {" SERILA TRANFER "};

uchar code cdis2[ ] = {" "};

/

延时子程序

/

char code SST516[3] _at_ 0x003b;

void delay1(uint ms)

{

uchar k;

while(ms--)

{

for(k = 0; k < 120; k++);

}

}

//

/ /

/检查LCD忙状态 /

/lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。 /

/ /

//

bit lcd_busy()

{

bit result;

LCD_RS = 0;

LCD_RW = 1;

LCD_EN = 1;

delayNOP();

result = (bit)(P0&0x80);

LCD_EN = 0;

return(result);

}

//

/ /

/写指令数据到LCD /

/RS=L,RW=L,E=高脉冲,D0-D7=指令码。 /

/ /

//

void lcd_wcmd(uchar cmd)

{

while(lcd_busy());

LCD_RS = 0;

LCD_RW = 0;

LCD_EN = 0;

_nop_();

_nop_();

P0 = cmd;

delayNOP();

LCD_EN = 1;

delayNOP();

LCD_EN = 0;

}

//

/ /

/写显示数据到LCD /

/RS=H,RW=L,E=高脉冲,D0-D7=数据。 /

/ /

//

void lcd_wdat(uchar dat)

{

while(lcd_busy());

LCD_RS = 1;

LCD_RW = 0;

LCD_EN = 0;

P0 = dat;

delayNOP();

LCD_EN = 1;

delayNOP();

LCD_EN = 0;

}

//

/ /

/ LCD初始化设定 /

/ /

//

void lcd_init()

{

delay1(15);

lcd_wcmd(0x01); //清除LCD的显示内容

lcd_wcmd(0x38); //162显示,57点阵,8位数据

delay1(5);

lcd_wcmd(0x38);

delay1(5);

lcd_wcmd(0x38);

delay1(5);

lcd_wcmd(0x0c); //开显示,显示光标,光标闪烁

delay1(5);

lcd_wcmd(0x01); //清除LCD的显示内容

delay1(5);

}

//

/ /

/ 设定显示位置 /

/ /

//

void lcd_pos(uchar pos)

{

lcd_wcmd(pos | 0x80); //数据指针=80+地址变量

}

/

发送数据函数

/

void senddata(uchar dat)

{

SBUF =dat;

while(!TI);

TI = 0;

}

/

串行中断服务函数

/

void serial() interrupt 4

{

ES = 0; //关闭串行中断

RI = 0; //清除串行接受标志位

buf = SBUF; //从串口缓冲区取得数据

playflag=1;

switch(buf)

{

case 0x31: senddata('X');break; //接受到1,发送字符'W'给计算机

case 0x32: senddata('L');break; //接受到2,发送字符'I'给计算机

case 0x33: senddata('1');break; //接受到3,发送字符'L'给计算机

case 0x34: senddata('0');break; //接受到4,发送字符'L'给计算机

case 0x35: senddata('0');break; //接受到5,发送字符'A'给计算机

case 0x36: senddata('0');break; //接受到5,发送字符'R'给计算机

default: senddata(buf);break; //接受到其它数据,将其发送给计算机

}

if(buf!=0x0D)

{

if(buf!=0x0A)

{

temp =buf;

if(count<16)

{

RXDdata[count]=temp;

count++;

}

}

}

ES = 1; //允许串口中断

}

/

数据显示函数

/

void play()

{

if(playflag)

{

lcd_pos(0x40); //设置位置为第二行

for(m=0;m<16;m++)

lcd_wdat(cdis2[m]); //清LCD1602第二行

for(m=0;m<16;m++)

{

lcd_pos(0x40+m); //设置显示位置为第二行

lcd_wdat(RXDdata[m]); //显示字符

}

playflag=0;

count=0x00;

for(m=0;m<16;m++)

RXDdata[m]=0x20; //清显存单元

}

}

/

主函数

/

void main(void)

{

P0 = 0xff;

P2 = 0xff;

SCON=0x50; //设定串口工作方式

PCON=0x00; //波特率不倍增

TMOD=0x20; //定时器1工作于8位自动重载模式, 用于产生波特率

EA=1;

ES = 1; //允许串口中断

TL1=0xf3;

TH1=0xf3; //波特率2400

TR1=1;

lcd_init();

lcd_pos(0x00); //设置显示位置为第一行

for(m=0;m<16;m++)

lcd_wdat(cdis1[m]); //显示字符

lcd_pos(0x40); //设置显示位置为第二行

for(m=0;m<16;m++)

lcd_wdat(cdis2[m]); //显示字符

while(1)

{

play();

}

}

这个串口通信程序在我的开发版上已经全部验证通过,你可以根据实际,攸 改里面某些参数,满足你自己的需要就行。

比如你你点亮小灯,这部分你只可在相应位置添加代码即可。单片机都是51的。

其中1602的显示程序是用来验证是否通信成功,这部分你可作为参考。这部分你大可用小灯显示程序来替代。

以上就是关于两个89c51单片机 双机232通信设计全部的内容,包括:两个89c51单片机 双机232通信设计、单片机双机通信系统设计、单片机双机通信,两个单片机的一方作为发送,另一方作为接收,分别调等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9515413.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-29
下一篇 2023-04-29

发表评论

登录后才能评论

评论列表(0条)

保存