我有一个可以给你参考
#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++);
}
//接收方采用两位数显示收到的数据
//下列双机通信程序,适用于双方同时使用
//经过编译、仿真成功
//显示函数应该根据自己的设备进行改写
//===============================
#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通信设计、单片机双机通信系统设计、单片机双机通信,两个单片机的一方作为发送,另一方作为接收,分别调等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)