/*单片机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 <reg51.h> #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 <reg51.h> #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 <reg51.h> #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); }
|