51单片机 多机串口通讯实验与双机串口通讯实验及proteus仿真
生活随笔
收集整理的這篇文章主要介紹了
51单片机 多机串口通讯实验与双机串口通讯实验及proteus仿真
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
51單片機 多機串口通訊實驗與雙機串口通訊實驗及proteus仿真
文章目錄
- 51單片機 多機串口通訊實驗與雙機串口通訊實驗及proteus仿真
- 實驗內容
- 一、實驗一 多機串口通訊實驗 數碼管顯示
- 1.仿真圖
- 2.代碼
- 二、實驗二 雙機串口通訊實驗 LCD顯示
- 1.仿真圖
- 2.代碼
- 總結
實驗內容
串口通訊實驗,設計一個甲、乙、丙多機通信實驗,甲機發送數據給乙機,乙機收到后反饋一個內容給甲機,甲機收到反饋內容再加上原來發送內容再發給到乙機,乙機收到信息,進行確認對比,內容正確就在顯示終端顯示相應內容,三個收發端都可以按照此方式收發。當甲機連續通過按鍵發送同一個內容三次,就對三個收發端的數碼管清零。
從一個單片機發送5個給另一個單片機,另一個單片機接收到后完成數據相加,并通過數碼管顯示出來,要求所有數據為十進制格式。
一、實驗一 多機串口通訊實驗 數碼管顯示
1.仿真圖
2.代碼
#include<reg51.h> #define uchar unsigned charunsigned char code str1[]="1"; //設置需要發送的協議代碼 unsigned char code str2[]="2"; unsigned char code str3[]="3";sbit P1_0=P1^0; //給相應端口一個編號 sbit P1_1=P1^1; sbit P1_2=P1^2; sbit led0 = P1^6; // 作為主機,接收到從機反饋信號,顯示 sbit led1 = P1^7; // 作為從機,接收到主機信號,顯示 sbit key = P3^3; //主從機運行選擇 按下時,無法通信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};//函數的功能是:向PC端發送一個字節數據 void send(unsigned char dat) {SBUF=dat;while(TI==0);TI=0; }void delay(unsigned int n) //延時函數的設置 {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,設置定時器T1工作于方式二SCON=0x60; //SCON=0100 0000,設置串口的工作方式為方式1PCON=0x00; //PCON=0000 0000,波特率為9600 晶振為11.0592TH1=0xfd; //設置定時器T1的初值TL1=0xfd; //定時器T1自動填充的值TR1=1; //啟動定時器T1REN=1; //允許接收EA=1; //開起總中斷開關ES=1; //需要用到串行口的中斷所以ES=1就是把串行口的中斷打開了EX1 = 1; //INT1中斷允許EA = 1; //全局中斷打開IT1 = 1; //觸發方式為下降沿觸發led1 = 0;led0 = 0;while(1){if(P1_0==0) //判斷P1_0口的開關狀態 U1->U2{i=0;while(str1[i]!='\0') //循環發送相應數組中的數據{send(str1[i]);//P0=table[str1[i]];i++;delay(1);}send('\0'); //最后一位補上\0作為接收機判斷結束的標準delay(1000);}// if(key==0) // { // flag=0; // }if(flag==1) //等待中斷的來臨,然后flag就會被賦值為1{if(P1_1==0 & P1_2==0) // 同時按下按鍵2 與按鍵3 ,處于發送狀態 否則處于接收狀態{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'); //最后一位補上\0作為接收機判斷結束的標準led0 = 1;delay(1000); }} //處于接收狀態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 //設置中斷函數 {temp=SBUF; //當有中斷時把傳過來的數據暫存到temp中RI=0; //把設置中斷的標志初始化,等待下一中斷if(temp==0x00) //當到達最后一位{a[count]=temp; count=0; //計數器初始化為下一次中斷準備flag=1; //標志置1進入主函數,進行端口的賦值}else{a[count]=temp;count=count+1;} }void jump_low() interrupt 2 {flag=0; //無法進入串口中斷delay(1000); }二、實驗二 雙機串口通訊實驗 LCD顯示
1.仿真圖
2.代碼
/** 功能描述: 甲機發數據!”**/ #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; /***********函數申明***********************************/ 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); //發送字符串 // address=0x00; //發送完數據 地址就歸零 從頭再來 // delay(1000); // write_command(0x01); //發送完一幀數據 清屏 } }//串口初始化 void UART_Init(void) {SCON=0x50;TMOD=0x20;PCON=0x00;TH1 =0xf4;TL1 =0xf4; //預置初值,設波特率為2400TR1 =1; }//串口發送一個字節的數據 void UART_SendData(uchar dat) {SBUF=dat; //發送數據while(!TI); //判斷是否發送完TI=0; //軟件清0delay(100);dis_char(address++,dat); //發送完一個數據 顯示一個數據if(address==0x10) address=0x40;//顯示完第一行 就顯示第二行if(address==0x50){ write_command(0x01);address=0x00;//顯示完第二行 清屏后又顯示第一行} }//串口發送多字節數據 void UART_SendString(uchar *p) {while(*p!='\0'){UART_SendData(*p);p++;} }//1ms延時程序 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); } //寫數據指令 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的點陣字符write_command(0x0C);//開整體顯示,光標關,無黑塊write_command(0x06);//光標右移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(); }總結
大佬們,可以支持一下。謝謝!!!
實驗一 多機串口通訊實驗 數碼管顯示
實驗二 雙機串口通訊實驗 LCD顯示
總結
以上是生活随笔為你收集整理的51单片机 多机串口通讯实验与双机串口通讯实验及proteus仿真的全部內容,希望文章能夠幫你解決所遇到的問題。