|
我做的是兩個(gè)單片機(jī)之間進(jìn)行串行通信,用的89c52.通過(guò)按主機(jī)p27口"啟動(dòng)鍵",主機(jī)向從機(jī)發(fā)送一個(gè)四位數(shù)據(jù),LED顯示。從機(jī)經(jīng)過(guò)CRC校驗(yàn),如果接收到正確數(shù)據(jù),與其相連的LED顯示所接收的數(shù)據(jù)。如果經(jīng)校驗(yàn)后接收錯(cuò)誤,則四位LED顯示0xFFFF。
仿真時(shí)從機(jī)一點(diǎn)反應(yīng)也沒有,也許是我程序有問(wèn)題,或通信協(xié)議編的不行。
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載):
主機(jī)單片機(jī)源碼:
- #define _PPDATAT_H
- #include <reg51.h>
- #include <string.h>
- #define uchar unsigned char
- #define uint unsigned int
- /* 握手信號(hào)宏定義 */
- #define CALL 0x24 // 主機(jī)呼叫
- #define OK 0x00 // 從機(jī)準(zhǔn)備好
- #define MAXLEN 64 // 緩沖區(qū)最大長(zhǎng)度
- uchar buf[MAXLEN];
- sbit p00 = P0^0; sbit p01 = P0^1; sbit p02 = P0^2; sbit p03 = P0^3;
- 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 p23 = P2^3;sbit p25 = P2^5;sbit p27 = P2^7;
- unsigned char a;
- unsigned char b;
- unsigned char c;
- unsigned char d;
- unsigned char in1,in2,in3,count;
- unsigned char j1,j2;
- unsigned char z1,z2,z3;
- unsigned int x=1234;
- bit qidong;
- void delay();
- //********************八段碼*************************//
- code unsigned char LEDMAP[] = {
- 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,
- 0x7f, 0x6f, 0x00,0x71//共陽(yáng)顯示碼,分別顯示0、1、2、3、4、5、6、7、8、9、滅、F。
- };
- //***********************顯示碼選擇**********************//
- int DisplayLED(unsigned char j)
- {
- unsigned int i=0;
- unsigned int x1;
- x1= LEDMAP[(i+j) & 0x0f];
- return x1;
- }
- //***********************轉(zhuǎn)換*************************//
- void si()
- {
- unsigned int M;
- a=x%10;
- M=x/10;
- b=M%10;
- M=M/10;
- c=M%10;
- d=M/10;//a取出第四位,b取出第三位,c取出第二位,d取出第一位
- }
- //***********************顯示**********************//
- void display()
- {
- si();
- P0=0xf7;
- P1=DisplayLED(a);
- delay();
- P0=0xfb;
- P1=DisplayLED(b);
- delay();
- P0=0xfd;
- P1=DisplayLED(c);
- delay();
- P0=0xfe;
- P1=DisplayLED(d);
- delay();
- }
- //************************掃描按鍵**********************//
- void timer0() interrupt 1 using 1
- {
- in1=p23;
- in2=p25;
- in3=p27;
- TH0=0xc3;
- TL0=0x50;
- count++;
- if(in1==0)
- z1++;
- if(in2==0)
- z2++;
- if(in3==0)
- z3++;
- if(count==40)
- {
- //*************************x+***********************//
- if((0<z1)&(z1<40))
- x++;
- if (z1==40)
- j1++;
- count=0;
- z1=0;
- if((0<j1)&(j1<6))
- x++;
- if((5<j1)&(j1<11))
- x=x+10;
- if(10<j1)
- x=x+100;
- if(in1==1)
- j1=0;
- //************************x-*******************//
- if((0<z2)&(z2<40))
- x--;
- if (z2==40)
- j2++;
- z2=0;
- if((0<j2)&(j2<6))
- x--;
- if((5<j2)&(j2<11))
- x=x-10;
- if(10<j2)
- x=x-100;
- if(in1==1)
- j2=0;
- //************************啟動(dòng)*******************//
- if(z3>5)
- qidong=1;
- }
- }
- void init()
- {
- TMOD=0x21; //定時(shí)器0工作于方式1,定時(shí)器1工作于方式2
- TH1 = 250; // 設(shè)置初值
- TL1 = 250;
- PCON = 0x80; // SMOD = 1
- SCON = 0x50; //工作方式1,波特率9600bps,允許接收
- ET0=1; //允許定時(shí)器0中斷
- TR0=1; //定時(shí)器0開始工作
- TR1 = 1; //定時(shí)器1開始工作
- EA=1; //打開所有中斷
- }
- //*************************delay*********************//
- void delay()
- {
- unsigned int i,n;
- n=100;
- for (i=0; i<n; i++) {}
- }
- //************************CRC計(jì)算****************************************//
- uint getcrc(uchar *s,uchar len)
- {
- uint acc=0,i,j=0;
- while(len--)
- {
- acc=acc^(*s++<<8);
- for(i=0;i++<8;)
- if(acc&0x8000)
- acc=(acc<<1)^0x1021;
- else
- acc=acc<<1;
- }
- return(acc);
- }
- //************************串口通信程序****************************************//
- /* 發(fā)送數(shù)據(jù)函數(shù) */
- void senddata(uchar *buf)
- {
- uchar i;
- uchar len; // 保存數(shù)據(jù)長(zhǎng)度
- uint ecc; // 保存校驗(yàn)字節(jié)
- len = strlen(buf); // 計(jì)算要發(fā)送數(shù)據(jù)的長(zhǎng)度
- /* 發(fā)送數(shù)據(jù)長(zhǎng)度 */
- TI = 0;
- SBUF = len; // 發(fā)送長(zhǎng)度
- while(!TI);
- TI = 0;
- /* 發(fā)送數(shù)據(jù)和校驗(yàn)字節(jié) */
- ecc=getcrc(buf,len);
- buf[len]=ecc/256;
- buf[len+1]=ecc%256;
- for (i=0;i<len+2;i++)
- {
- SBUF = *buf;
- buf++;
- while(!TI);
- TI = 0;
- }
- }
- void tongxin()
- {
- uchar i = 0;
- uchar tmp;
- /* 發(fā)送呼叫信號(hào)CALL并接收應(yīng)答信息,如果沒有接收到從機(jī)準(zhǔn)備好的信號(hào),則重新發(fā)送呼叫幀 */
- while(tmp!=OK)
- {
- /* 發(fā)送呼叫信號(hào)CALL */
- TI = 0;
- SBUF = CALL;
- while(!TI);
- TI = 0;
- /* 接收從機(jī)應(yīng)答 */
- RI = 0;
- while(!RI);
- tmp = SBUF;
- RI = 0;
- }
-
- }
- //*************************主函數(shù)***********************//
- void main()
- {
- init();
- while(1)
- {
- display();
- if(qidong==1)
- {
- si();
- buf[0]=a;buf[1]=b;
- buf[2]=c;buf[3]=d;
- senddata(buf);
- tongxin();
- qidong=0;
- }
- }
- }
復(fù)制代碼
叢機(jī)單片機(jī)源程序如下:
- #define _PPDATAR_H
- #include <reg51.h>
- #include <string.h>
- #define uchar unsigned char
- #define uint unsigned int
- /* 握手信號(hào)宏定義 */
- #define CALL 0x24 // 主機(jī)呼叫
- #define OK 0x00 // 從機(jī)準(zhǔn)備好
- #define MAXLEN 64 // 緩沖區(qū)最大長(zhǎng)度
- uchar buf[MAXLEN];
- sbit p00 = P0^0; sbit p01 = P0^1; sbit p02 = P0^2; sbit p03 = P0^3;
- 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;
- bit err;
- void delay();
- //********************八段碼*************************//
- code unsigned char LEDMAP[] = {
- 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,
- 0x7f, 0x6f, 0x00,0x71//共陽(yáng)顯示碼,分別顯示0、1、2、3、4、5、6、7、8、9、滅、F。
- };
- //***********************顯示碼選擇**********************//
- int DisplayLED(unsigned char j)
- {
- unsigned int i=0;
- unsigned int x1;
- x1= LEDMAP[(i+j) & 0x0f];
- return x1;
- }
- //***********************顯示**********************//
- void display()
- {
- P0=0xf7;
- P1=DisplayLED(buf[0]);
- delay();
- P0=0xfb;
- P1=DisplayLED(buf[1]);
- delay();
- P0=0xfd;
- P1=DisplayLED(buf[2]);
- delay();
- P0=0xfe;
- P1=DisplayLED(buf[3]);
- delay();
- }
- //////////////////////顯示FFFF//////////////////////////////
- void display_f()
- {
- P0=0xfe;
- P1=DisplayLED(11);
- delay();
- P0=0xfd;
- P1=DisplayLED(11);
- delay();
- P0=0xfb;
- P1=DisplayLED(11);
- delay();
- P0=0xf7;
- P1=DisplayLED(11);
- delay();
- }
- //************************CRC計(jì)算****************************************//
- uint getcrc(uchar *s,uchar len)
- {
- uint acc=0,i,j=0;
- while(len--)
- {
- acc=acc^(*s++<<8);
- for(i=0;i++<8;)
- if(acc&0x8000)
- acc=(acc<<1)^0x1021;
- else
- acc=acc<<1;
- }
- return(acc);
- }
- //*************************delay*********************//
- void delay()
- {
- unsigned int i,n;
- n=100;
- for (i=0; i<n; i++) {}
- }
- //************************進(jìn)行數(shù)據(jù)校驗(yàn)****************************************//
- int chkcrc(uchar *buf,uchar len)
- {
- uint strcrc;
- strcrc=getcrc(buf,len); //生成接收數(shù)據(jù)的CRC碼
- if(((0xff&buf[len])==(0xff&(strcrc/256)))&&((0xff&buf[len+1])==(0xff&(strcrc%256))))
- //接收的CRC碼和生成的CRC碼進(jìn)行比較
- return(0);
- else
- return(-1);
- }
- /* 接收數(shù)據(jù)函數(shù) */
- bit recvdata(uchar *buf)
- {
- uchar i;
- uchar len; // 保存數(shù)據(jù)長(zhǎng)度
- int ecc; // 保存校驗(yàn)字節(jié)
-
- /* 接收數(shù)據(jù)長(zhǎng)度字節(jié) */
- RI = 0;
- while(!RI);
- len = SBUF;
- RI = 0;
- /* 接收數(shù)據(jù)及校驗(yàn)字節(jié) */
- for (i=0;i<len+2;i++)
- {
- while(!RI);
- *buf = SBUF;
- RI = 0;
- buf++;
- }
- *buf = 0; // 表示接收結(jié)束
-
- /* 進(jìn)行數(shù)據(jù)校驗(yàn) */
- ecc = chkcrc(buf,len);
- if (ecc!=0) // 如果校驗(yàn)錯(cuò)誤
-
- return 1; // 返回1表示校驗(yàn)錯(cuò)誤
- else
- return 0; // 校驗(yàn)成功,返回0
-
- }
- void init_serial()
- {
- TMOD = 0x20; // 定時(shí)器T1使用工作方式2
- TH1 = 250;
- TL1 = 250;
- TR1 = 1; // 開始計(jì)時(shí)
- PCON = 0x80; // SMOD = 1
- SCON = 0x50; // 工作方式1,波特率9600kbit/s,允許接收
- }
- /*串口通信程序 */
- void tongxin()
- {
- uchar tmp=0;
- init_serial();
- EA = 0; // 關(guān)閉所有中斷
- /* 如果接收到的數(shù)據(jù)不是CALL,則繼續(xù)等待 */
- while (tmp!=CALL)
- {
- RI = 0;
- while(!RI)
- tmp = SBUF;
- RI = 0;
- }
-
- /* 發(fā)送OK信號(hào),表示從機(jī)可以接收數(shù)據(jù) */
- TI = 0;
- SBUF = OK;
- while(!TI);
- ……………………
- …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼
所有資料51hei提供下載:
CRC串行通信.zip
(86.14 KB, 下載次數(shù): 41)
2018-3-19 17:05 上傳
點(diǎn)擊文件名下載附件
|
評(píng)分
-
查看全部評(píng)分
|