PC 机与单片机通信(RS232 协议) 目录: 1、单片机串口通信的应用 2、PC控制单片机IO口输出 3、单片机控制实训指导及综合应用实例 4、单片机给计算机发送数据:
[实验任务] 单片机串口通信的应用,通过串口,我们的个人电脑和单片机系统进行通信。 个人电脑作为上位机,向下位机单片机系统发送十六进制或者ASCLL码,单片机 系统接收后,用LED显示接收到的数据和向上位机发回原样数据。 [硬件电路图] file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image002.jpg [实验原理] RS-232是美国电子工业协会正式公布的串行总线标准,也是目前最常用的串 行接口标准,用来实现计算机与计算机之间、计算机与外设之间的数据通讯。 RS-232串行接口总线适用于:设备之间的通讯距离不大于15m,传输速率最大为 20kBps。RS-232协议以-5V-15V表示逻辑1;以+5V-15V 表示逻辑0。 我们是 用MAX232芯片将RS232电平转换为TTL电平的。 一个完整的RS-232接口有22 根线,采用标准的25芯插头座。我们在 这里使用的是简化的9芯插头座。 注意我们在这里使用的晶振是11.0592M的,而不是12M。因为波特率的设置 需要11.0592M的。 “串口调试助手V2.1.exe” 软件的使用很简单,只要将串口选择‘CMO1’波 特率设置为‘9600’ 数据位为 8 位。打开串口(如果关闭)。然后在发送区里 输入要发送的数据,单击手动发送就将数据发送出去了。注意,如果选中‘十六 进制发送’那么发送的数据是十六进制的,必须输入两位数据。如果没有选中, 则发送的是ASCLL码,那么单片机控制的数码管将显示ASCLL码值。 ASCII常用代码表
| 字符 | 代码 | 字符 | 代码 | 字符 | 代码 | 字符 | 代码 | 字符 | 32 | | 52 | 4 | 72 | H | 92 | \ | 112 | p | 33 | ! | 53 | 5 | 73 | I | 93 | | 113 | q | 34 | ” | 54 | 6 | 74 | J | 94 | ^ | 114 | r | 35 | # | 55 | 7 | 75 | K | 95 | _ | 115 | s | 36 | $ | 56 | 8 | 76 | L | 96 | ` | 116 | t | 37 | % | 57 | 9 | 77 | M | 97 | a | 117 | u | 38 | & | 58 | : | 78 | N | 98 | b | 118 | v | 39 | ’ | 59 | ; | 79 | O | 99 | c | 119 | w | 40 | ( | 60 | < | 80 | P | 100 | d | 120 | x | 41 | ) | 61 | = | 81 | Q | 101 | e | 121 | y | 42 | * | 62 | > | 82 | R | 102 | f | 122 | z | 43 | + | 63 | ? | 83 | S | 103 | g | 123 | { | 44 | , | 64 | @ | 84 | T | 104 | h | 124 | | | 45 | - | 65 | A | 85 | U | 105 | i | 125 | } | 46 | . | 66 | B | 86 | V | 106 | j | 126 | ~ | 47 | / | 67 | C | 87 | W | 107 | k | | | 48 | 0 | 68 | D | 88 | X | 108 | l | | | 49 | 1 | 69 | E | 89 | Y | 109 | m | | | 50 | 2 | 70 | F | 90 | Z | 110 | n | | | 51 | 3 | 71 | G | 91 | [ | 111 | o | | |
[C语言源程序] #include"reg52.h" //包函8051 内部资源的定义 unsigned char dat;//用于存储单片机接收发送缓冲寄存器SBUF里面的内容 sbit gewei=P2^4;//个位选通定义 sbit shiwei=P2^5;//十位选通定义 sbit baiwei=P2^6;//百位选通定义 unsigned char codetable[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,}; //1~10 voidDelay(unsigned int tc) //延时程序 { while( tc != 0 ) {unsigned int i; for(i=0; i<100;i++); tc--;} } void LED() //LED显示接收到的数据(十进制) { gewei=0;P0=table[dat%10]; Delay(10); gewei=1; shiwei=0;P0=table[dat/10]; Delay(10); shiwei=1; baiwei=0;P0=table[dat/100]; Delay(10); baiwei=1; } ///////功能:串口初始化,波特率9600,方式1///////// voidInit_Com(void) { TMOD = 0x20; PCON = 0x00; SCON = 0x50; TH1 = 0xFd; TL1 = 0xFd; TR1 = 1; } /////主程序功能:实现接收数据并把接收到的数据原样发送回去/////// void main() { Init_Com();//串口初始化 while(1) { if ( RI ) //扫描判断是否接收到数据, { dat = SBUF; //接收数据SBUF赋与dat RI=0; //RI 清零。 SBUF = dat; //在原样把数据发送回去(接收数据为发送数据的ASCII码,如发送q显示为113) } LED(); //显示接收到的数据 } } ///这一个例子是以扫描的方式编写的,还可以以中断的方式编写,请大家思考////// [实验任务1]PC控制单片机IO口输出 #include"reg52.h" //包函8051 内部资源的定义 unsigned char dat;//用于存储单片机接收发送缓冲寄存器SBUF里面的内容 voidDelay(unsigned int tc) //延时程序 { while( tc != 0 ) {unsigned int i; for(i=0; i<100;i++); tc--;} } ///////功能:串口初始化,波特率9600,方式1///////// voidInit_Com(void) { TMOD = 0x20; PCON = 0x00; SCON = 0x50; TH1 = 0xFd; TL1 = 0xFd; TR1 = 1; } /////主程序功能:实现接收数据并把接收到的数据原样发送回去/////// void main() { Init_Com();//串口初始化 while(1) { if ( RI ) //扫描判断是否接收到数据, { dat = SBUF; //接收数据SBUF赋与dat if(dat==0x00) //如果PC发送十六进制00,单片机P1口全亮。 P1=0x00; else if(dat==0x01) P1=0x01; else if(dat==0x02) P1=0x02; else if(dat==0x03) P1=0x03; else if(dat==0x04) P1=0x04; RI=0; //RI 清零。 SBUF = dat; //在原样把数据发送回去(接收数据为发送数据的ASCII码,如发送q显示为113) } } } [实验任务2]单片机控制实训指导及综合应用实例 #include"reg52.h" //包函AT89S52 内部资源的定义(注视参看书160页) #define ucharunsigned char //宏定义 uchar led[10]={0xbf,0x06,0xdb,0xcf,0x66,0xed,0xfd,0x87,0xff,0xef}; //数字1~10,字符串 uchar led1[64]; //存储接收数据 unsigned inti,j,t,k; sbit P32=P3^2; voidscjs(void)interrupt 4 //定义中断 { ES=0;// 使能串行口的中断 k=1; while(1) { RI=0; led1[k-1]=SBUF; //将接收数据送段码表 k++; TH0=0x3c; //t0定时50sm内接收不到数据跳过接收 TL0=0xb0; TR0=1; while(!RI) { if(!TF0) goto FH; } } FH:TF0=0;//TF0不清零不能重新接收 TR0=0; P32=1; for(j=1;j<k;j++) { SBUF=led[j-1];//数据送回给pc while(!TI); TI=0; } P32=0; } delay(t) { ES=1; SCON=0x50; for(i=0;i<t;i++); ES=0; SCON=0x00; } void main (void) { int a,c; TMOD=0x21; TH1=0Xfd; TL1=0xfd; SCON=0x50; PCON=0x00; IE=0x90; TR1=1; k=1; P32=0; while(1) { ES=0; SCON=0x00; for(a=0;a<=k+1/k*8;a++) { for(c=5;c>=0;c--) { if(a+c<k+1/k*8+1) { if(k==1)SBUF=led[a+c]; elseSBUF=led1[a+c]; } else SBUF=0x00; while(!TI); TI=0; } delay(39000); } } } #include"reg52.h" //包函8051 内部资源的定义 #define ucharunsigned char sbit P3_2=P3^2; uchar zdzt=0x0c; uchar zsgw=0x02; uchar zsdw=0x00; uchar bs=0; uchar zqsbw=0; uchar zqssw=0; uchar zqsgw=0; uchar yxsj=0x11; uchar zs=20; int zqs=0; uchar zqsgzj=0x00; uchar zqsdzj=0x00; uchar zsscgw=0x1f; uchar zsscdw=0x00; uchar bzsj; uchar ztsj; void key (void); void keyprc(); void binbcd(); void disp(); void delay(); code uchartab[13]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x7f,0x6f,0x77,0x7c,0x39}; code ucharzssc[160]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x7f,0x6f,0x77,0x7c, 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x7f,0x6f,0x77,0x7c,0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x7f,0x6f,0x77,0x7c,0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x7f, 0x6f,0x77,0x7c,0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x7f,0x6f,0x77,0x7c,0x3f, 0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x7f,0x6f,0x77,0x7c,0x3f,0x06,0x5b,0x4f,0x66, 0x6d,0x7d,0x7f,0x6f,0x77,0x7c,0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x7f,0x6f, 0x77,0x7c,0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x7f,0x6f,0x77,0x7c,0x3f,0x06, 0x5b,0x4f,0x66,0x6d,0x7d,0x7f,0x6f,0x77,0x7c,}; void key(void) { TR0=0; if(!(P2&0X01)) { delay(); while(!(P2&0X01)); zdzt=0x0a; disp(); } elseif(!(P3&0X08)) { delay(); while(!(P3&0X08)); zdzt=0x0b; disp(); } elseif(!(P3&0X10)) { delay(); while(!(P3&0X10)); zs=zs+1; keyprc(); disp(); } elseif(!(P2&0X02)) { delay(); while(!(P2&0X02)); zs=zs-1; keyprc(); disp(); } } void keyprc() { if(zs<20) zs=20; if(zs>99) zs=99; zsgw=zs/10; zsdw=zs%10; } void djzd(void)interrupt 1 { TH0=zssc[(zs-20)*2]; TL0=zssc[(zs-20)*2+1]; if(zdzt==0x0a) yxsj=yxsj<<1|yxsj>>7; else if(zdzt==0x0b) yxsj=yxsj<<7|yxsj>>1; else if(zdzt==0x0c) { P1=0xff; goto LP; } P1=yxsj; bs++; if(bs==48) { bs=0; zqs++; } LP:binbcd(); disp(); } void binbcd() { zqsbw=zqs/100; zqssw=zqs%100/10; zqsgw=zqs%10; } void disp() { TR1=0; ES=0; SCON=0x00; TMOD=0x01; SBUF=tab[zqsgw]; while(!TI);TI=0; SBUF=tab[zqssw]; while(!TI);TI=0; SBUF=tab[zqsbw]; while(!TI);TI=0; SBUF=tab[zsdw]; while(!TI);TI=0; SBUF=tab[zsgw]; while(!TI);TI=0; SBUF=tab[zdzt]; while(!TI);TI=0; TMOD=0x02; TH1=0Xfd; TL1=0xfd; SCON=0x50; TR1=1; ES=1; } void delay() { int k; for(k=0;k<1200;k++); } voidsin()interrupt 4 { P1=0xff; ES=0; bzsj=SBUF; RI=0; while(!RI); RI=0; ztsj=SBUF; if(bzsj==0x30) zdzt=ztsj-0x37; if(bzsj==0x31) { if(ztsj==0x49) zs++; else zs--; } ES=1; P3_2=0; keyprc(); zqs=0; disp(); } main() { TMOD=0x21; TH1=0xfd; TL1=0xfd; SCON=0x50; PCON=0x00; IE=0X92; PS=1; TR1=1; P3_2=0; TH0=0x1f; TL0=0x00; SP=0x60; disp(); while(1) { key(); if(zdzt==0x0c) { TR0=0; P1=0xff; } else TR0=1; } } 单片机给计算机发送数据: #include"reg52.h" //包函8051 内部资源的定义 unsigned char dat;//用于存储单片机接收发送缓冲寄存器SBUF里面的内容 unsigned char fan; int i,j; void Delay() //延时程序 { for(i=0; i<100;i++) for(j=0; j<100;j++); } void delays() { int k; for(k=0;k<1200;k++); } ///////功能:串口初始化,波特率9600,方式1///////// voidInit_Com(void) { TMOD = 0x20; PCON = 0x00; SCON = 0x50; TH1 = 0xFd; TL1 = 0xFd; TR1 = 1; } /////主程序功能:实现接收数据并把接收到的数据原样发送回去/////// void main() { Init_Com();//串口初始化 while(1) { if ( RI ) //扫描判断是否接收到数据, { dat = SBUF; //接收数据SBUF赋与dat if(dat==0x30) //如果PC发送十六进制00,单片机P1口全亮。 {P1=0x00; Delay(); } else if(dat==0x31) {P1=0x01; Delay();} else if(dat==0x32) {P1=0x03; Delay();} else if(dat==0x33) {P1=0x07; Delay(); } else if(dat==0x34) {P1=0x0f; Delay(); } else if(dat==0x35) {P1=0x1f; Delay();} else if(dat==0x06) {P1=0x3f; Delay(); } else if(dat==0x07) {P1=0x7f; Delay();} else if(dat==0x08) {P1=0xff; Delay(); } elseif(!(P2&0x01)) { delays(); while(!(P2&0x01)); fan = 0x36;} elseif(!(P2&0x02)) { delays(); while(!(P2&0x02)); fan = 0x37;} elseif(!(P2&0x04)) { delays(); while(!(P2&0x04)); fan = 0x38;} elseif(!(P2&0x08)) { delays(); RI=0; //RI 清零。 SBUF =dat; //在原样把数据发送回去(接收数据为发送数据的ASCII码,如发送q显示为113) } } }
|