51单片机 多机串口通讯实验与双机串口通讯实验及proteus仿真
51單片機(jī) 多機(jī)串口通訊實(shí)驗(yàn)與雙機(jī)串口通訊實(shí)驗(yàn)及proteus仿真
文章目錄
- 51單片機(jī) 多機(jī)串口通訊實(shí)驗(yàn)與雙機(jī)串口通訊實(shí)驗(yàn)及proteus仿真
- 實(shí)驗(yàn)內(nèi)容
- 一、實(shí)驗(yàn)一 多機(jī)串口通訊實(shí)驗(yàn) 數(shù)碼管顯示
- 1.仿真圖
- 2.代碼
- 二、實(shí)驗(yàn)二 雙機(jī)串口通訊實(shí)驗(yàn) LCD顯示
- 1.仿真圖
- 2.代碼
- 總結(jié)
實(shí)驗(yàn)內(nèi)容
串口通訊實(shí)驗(yàn),設(shè)計(jì)一個(gè)甲、乙、丙多機(jī)通信實(shí)驗(yàn),甲機(jī)發(fā)送數(shù)據(jù)給乙機(jī),乙機(jī)收到后反饋一個(gè)內(nèi)容給甲機(jī),甲機(jī)收到反饋內(nèi)容再加上原來(lái)發(fā)送內(nèi)容再發(fā)給到乙機(jī),乙機(jī)收到信息,進(jìn)行確認(rèn)對(duì)比,內(nèi)容正確就在顯示終端顯示相應(yīng)內(nèi)容,三個(gè)收發(fā)端都可以按照此方式收發(fā)。當(dāng)甲機(jī)連續(xù)通過按鍵發(fā)送同一個(gè)內(nèi)容三次,就對(duì)三個(gè)收發(fā)端的數(shù)碼管清零。
從一個(gè)單片機(jī)發(fā)送5個(gè)給另一個(gè)單片機(jī),另一個(gè)單片機(jī)接收到后完成數(shù)據(jù)相加,并通過數(shù)碼管顯示出來(lái),要求所有數(shù)據(jù)為十進(jìn)制格式。
一、實(shí)驗(yàn)一 多機(jī)串口通訊實(shí)驗(yàn) 數(shù)碼管顯示
1.仿真圖
2.代碼
#include<reg51.h> #define uchar unsigned charunsigned char code str1[]="1"; //設(shè)置需要發(fā)送的協(xié)議代碼 unsigned char code str2[]="2"; unsigned char code str3[]="3";sbit P1_0=P1^0; //給相應(yīng)端口一個(gè)編號(hào) sbit P1_1=P1^1; sbit P1_2=P1^2; sbit led0 = P1^6; // 作為主機(jī),接收到從機(jī)反饋信號(hào),顯示 sbit led1 = P1^7; // 作為從機(jī),接收到主機(jī)信號(hào),顯示 sbit key = P3^3; //主從機(jī)運(yùn)行選擇 按下時(shí),無(wú)法通信uchar temp,flag; uchar a[10]; uchar count = 0; uchar code table[]={0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71};//函數(shù)的功能是:向PC端發(fā)送一個(gè)字節(jié)數(shù)據(jù) void send(unsigned char dat) {SBUF=dat;while(TI==0);TI=0; }void delay(unsigned int n) //延時(shí)函數(shù)的設(shè)置 {unsigned int i,j;for(i=0;i<n;i++)for(j=249;j>0;j--); }void main(void) {unsigned int i;TMOD=0x20; //TMOD=0010 0000,設(shè)置定時(shí)器T1工作于方式二SCON=0x60; //SCON=0100 0000,設(shè)置串口的工作方式為方式1PCON=0x00; //PCON=0000 0000,波特率為9600 晶振為11.0592TH1=0xfd; //設(shè)置定時(shí)器T1的初值TL1=0xfd; //定時(shí)器T1自動(dòng)填充的值TR1=1; //啟動(dòng)定時(shí)器T1REN=1; //允許接收EA=1; //開起總中斷開關(guān)ES=1; //需要用到串行口的中斷所以ES=1就是把串行口的中斷打開了EX1 = 1; //INT1中斷允許EA = 1; //全局中斷打開IT1 = 1; //觸發(fā)方式為下降沿觸發(fā)led1 = 0;led0 = 0;while(1){if(P1_0==0) //判斷P1_0口的開關(guān)狀態(tài) U1->U2{i=0;while(str1[i]!='\0') //循環(huán)發(fā)送相應(yīng)數(shù)組中的數(shù)據(jù){send(str1[i]);//P0=table[str1[i]];i++;delay(1);}send('\0'); //最后一位補(bǔ)上\0作為接收機(jī)判斷結(jié)束的標(biāo)準(zhǔn)delay(1000);}// if(key==0) // { // flag=0; // }if(flag==1) //等待中斷的來(lái)臨,然后flag就會(huì)被賦值為1{if(P1_1==0 & P1_2==0) // 同時(shí)按下按鍵2 與按鍵3 ,處于發(fā)送狀態(tài) 否則處于接收狀態(tài){if(a[0]==0x32) { i=0;a[1] = str1[0];while(a[i] != '\0') {//p0 = 0x00;send(a[i]);//P0=table[a[i]];i++;delay(1);}send('\0'); //最后一位補(bǔ)上\0作為接收機(jī)判斷結(jié)束的標(biāo)準(zhǔn)led0 = 1;delay(1000); }} //處于接收狀態(tài)else{ if(a[0]==0x31) { i=0;while(str2[i]!='\0') { send(str2[i]);i++;delay(1);}send('\0'); led1 = 1;delay(1000); }if(a[0]==0x32 && a[1]==0x31){P0=table[2];delay(500);P0=table[1];delay(500);}} flag=0;led0=0;led1=0;P0=0xff;} } }void serial() interrupt 4 //設(shè)置中斷函數(shù) {temp=SBUF; //當(dāng)有中斷時(shí)把傳過來(lái)的數(shù)據(jù)暫存到temp中RI=0; //把設(shè)置中斷的標(biāo)志初始化,等待下一中斷if(temp==0x00) //當(dāng)?shù)竭_(dá)最后一位{a[count]=temp; count=0; //計(jì)數(shù)器初始化為下一次中斷準(zhǔn)備flag=1; //標(biāo)志置1進(jìn)入主函數(shù),進(jìn)行端口的賦值}else{a[count]=temp;count=count+1;} }void jump_low() interrupt 2 {flag=0; //無(wú)法進(jìn)入串口中斷delay(1000); }二、實(shí)驗(yàn)二 雙機(jī)串口通訊實(shí)驗(yàn) LCD顯示
1.仿真圖
2.代碼
/** 功能描述: 甲機(jī)發(fā)數(shù)據(jù)!”**/ #include <reg52.h> #include <intrins.h> #define uchar unsigned char #define uint unsigned int #define lcd_out P0/***********端口定義********************************/ sbit rs=P2^0; sbit rw=P2^1; sbit e=P2^2;sbit p10=P1^0; sbit p11=P1^1; sbit p12=P1^2; sbit p13=P1^3; sbit p14=P1^4; sbit p15=P1^5; sbit p16=P1^6; sbit p17=P1^7;sbit led=P3^7; /***********函數(shù)申明***********************************/ void UART_Init(void); void UART_SendData(uchar dat); void UART_SendString(uchar *p); void delay(uint j);void check_busy(void); void write_command(uchar com); void write_data(uchar dat); void LCD_initial(void); void dis_char(uchar ad, uchar input);void shaomiao(void); void panduan(void); void display1(void); void display2(void); /***********變量定義********************************/ uchar address=0x00; //顯示地址uchar sting[]="0123456";unsigned char code str[]="0123456789";uchar code temp[]="0123456789"; uchar temp1[8],mm[4],temp2[8]; float q; uchar num,num1,k,r=0,n,h,d,w; float sum; long uu;void main(void) {LCD_initial(); //LCD1602 初始化UART_Init(); //串口初始化 led=0;while(1){shaomiao();panduan(); // UART_SendString(sting); //發(fā)送字符串 // address=0x00; //發(fā)送完數(shù)據(jù) 地址就歸零 從頭再來(lái) // delay(1000); // write_command(0x01); //發(fā)送完一幀數(shù)據(jù) 清屏 } }//串口初始化 void UART_Init(void) {SCON=0x50;TMOD=0x20;PCON=0x00;TH1 =0xf4;TL1 =0xf4; //預(yù)置初值,設(shè)波特率為2400TR1 =1; }//串口發(fā)送一個(gè)字節(jié)的數(shù)據(jù) void UART_SendData(uchar dat) {SBUF=dat; //發(fā)送數(shù)據(jù)while(!TI); //判斷是否發(fā)送完TI=0; //軟件清0delay(100);dis_char(address++,dat); //發(fā)送完一個(gè)數(shù)據(jù) 顯示一個(gè)數(shù)據(jù)if(address==0x10) address=0x40;//顯示完第一行 就顯示第二行if(address==0x50){ write_command(0x01);address=0x00;//顯示完第二行 清屏后又顯示第一行} }//串口發(fā)送多字節(jié)數(shù)據(jù) void UART_SendString(uchar *p) {while(*p!='\0'){UART_SendData(*p);p++;} }//1ms延時(shí)程序 void delay(uint j) {uchar i=250;for(;j>0;j--){while(--i);i=249;while(--i);i=250;} } 查忙程序 //void check_busy(void) //{ // uchar dt; // do // { // dt=0xff; // e=0; // rs=0; // rw=1; // e=1; // dt=lcd_out; // }while(dt&0x80); // e=0; //} //寫控制指令 void write_command(uchar com) {//check_busy();e=0;rs=0;rw=0;lcd_out=com;e=1;_nop_();e=0;delay(1); } //寫數(shù)據(jù)指令 void write_data(uchar dat) {//check_busy();e=0;rs=1;rw=0;lcd_out=dat;e=1;_nop_();e=0;delay(1); } //液晶屏初始化 void LCD_initial(void) {write_command(0x38);//8位總線,雙行顯示,5X7的點(diǎn)陣字符write_command(0x0C);//開整體顯示,光標(biāo)關(guān),無(wú)黑塊write_command(0x06);//光標(biāo)右移write_command(0x01);//清屏delay(1); }// 輸出字符void dis_char(uchar ad, uchar input){write_command(ad+0x80);//ad是顯示位置信息write_data(input);delay(10);}void shaomiao() {uchar i,s;for (i=0,s=0xfe;i<4;i++){P1=s;if(p14==0|p15==0|p16==0|p17==0){delay(10);if(p14==0|p15==0|p16==0|p17==0){if(p14==0){if(p10==0){ num=7;UART_SendData(str[7]);}if(p11==0){ num=4;UART_SendData(str[4]);}if(p12==0){ num=1;UART_SendData(str[1]);}if(p13==0)num=10;} if(p15==0){if(p10==0){ num=8;UART_SendData(str[8]);}if(p11==0){ num=5;UART_SendData(str[5]);}if(p12==0){ num=2;UART_SendData(str[2]);}if(p13==0){ num=0;UART_SendData(str[0]);}} if(p16==0){if(p10==0){ num=9;UART_SendData(str[9]);}if(p11==0){ num=6;UART_SendData(str[6]);}if(p12==0){ num=3;UART_SendData(str[3]);}if(p13==0)num=11;}if(p17==0){if(p10==0)num=15;if(p11==0)num=14;if(p12==0)num=13;if(p13==0)num=12;}while(p14==0|p15==0|p16==0|p17==0); }if(num<10){k++;w=0;} if(d==1){d=0;sum=-sum;}}s=s<<1|0x01;s=s|0xf0; } } void display1() {uchar i;uu=(long)(sum);temp1[7]=uu/10000000;temp1[6]=uu%10000000/1000000;temp1[5]=uu%10000000%1000000/100000;temp1[4]=uu%10000000%1000000%100000/10000;temp1[3]=uu%10000000%1000000%100000%10000/1000;temp1[2]=uu%10000000%1000000%100000%10000%1000/100;temp1[1]=uu%10000000%1000000%100000%10000%1000%100/10;temp1[0]=uu%10;if(h==1){h=2;write_command(0x80+15-k);write_data(0x2d);} if(r==0)write_command(0x80+15);if(r==1)write_command(0xc0+15);write_command(0x04);for (i=0;i<k;i++){ write_data(temp[temp1[i]]);delay(5);}} void display2() {uchar i;temp2[7]=uu%10000000/1000000;temp2[6]=uu%10000000%1000000/100000;temp2[5]=uu%10000000%1000000%100000/10000;temp2[4]=uu%10000000%1000000%100000%10000/1000;temp2[2]=uu%10000000%1000000%100000%10000%1000/100;temp2[1]=uu%10000000%1000000%100000%10000%1000%100/10;temp2[0]=uu%10;if(h==1){h=2;write_command(0x80+15-k-4);write_data(0x2d);} if(r==0)write_command(0x80+15);if(r==1)write_command(0xc0+15);write_command(0x04);for (i=0;i<k+4;i++){ if(i==3){write_data(0x2e);i++;} write_data(temp[temp2[i]]);delay(5);} }void panduan() {if(n==1&num==0){write_command(0x01);write_command(0x80+15);write_data(temp[0]);k=0;n=0;}if(num==10){write_command(0x01);k=0;n=0;r=0; }if(n==1&num>=1&num<10){write_command(0x01);k=1;n=0;r=0;} if(num<10&k==1){sum=num;mm[0]=num;if(num==0)k=0;}if(num<10&k==2){sum=mm[0]*10+num; mm[1]=num; } if(num<10&k==3){sum=mm[0]*100+mm[1]*10+num;mm[2]=num; }if(num<10&k==4){sum=mm[0]*1000+mm[1]*100+mm[2]*10+num;mm[3]=num; }if(num<10&k==5){num=10;}if (num>=12&num<16){r=1;k=0;q=sum;if(num==12){write_command(0xc0);write_data(0x2b);}if(num==13){write_command(0xc0);write_data(0x2d);}if(num==14){write_command(0xc0);write_data(0x2a);}if(num==15){write_command(0xc0);write_data(0xfd);}num1=num;n=0;}if(num==11&w==0){w=1;n=1;r=0; num=16; write_command(0x01); if(num1==12) sum=q+sum;if(num1==13) sum=q-sum; if(num1==14)sum=q*sum;if(num1==15)sum=q/sum; if(sum>=0)h=0;else{h=1;sum=-sum;d=1;}if(sum<100000000)k=8;if(sum<10000000)k=7;if(sum<1000000)k=6;if(sum<100000)k=5;if(sum<10000)k=4;if(sum<1000)k=3;if(sum<100)k=2; if(sum<10)k=1; if(sum!=(long)(sum)){uu=sum*10000;display2();} } if(sum==(long)(sum)) display1(); }總結(jié)
大佬們,可以支持一下。謝謝!!!
實(shí)驗(yàn)一 多機(jī)串口通訊實(shí)驗(yàn) 數(shù)碼管顯示
實(shí)驗(yàn)二 雙機(jī)串口通訊實(shí)驗(yàn) LCD顯示
總結(jié)
以上是生活随笔為你收集整理的51单片机 多机串口通讯实验与双机串口通讯实验及proteus仿真的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。