开学初装了Proteus 8 Professional和Keil uVision4
2020-06-17安装vspdpro-jie.exe
1.串口调试助手直接运行,无需安装。
2.Virtual Serial Port Driver,先运行vspdpro安装,完成安装后,将vspdpro-jie.exe复制到安装目录,C:\Program Files\Eltima Software\Virtual Serial Port Driver Pro 9.0,运行vspdpro-jie.exe
C:\Program Files\Eltima Software\Virtual Serial Port Driver Pro 9.0
以下是全部程序,从入门到入门
花样流水灯
/* Main.c file generated by New Project wizard * * Created: 周四 4月 2 2020 * Processor: AT89C52 * Compiler: Keil for 8051 */ #include <reg51.h> #include <stdio.h> #include < intrins.h> void delay(void) //延迟函数,当程序输出一个电信号后,CPU做无意义运算,让这个状态维持一段时间(约0.5毫秒), //人眼就能感受到LED灯被点亮了 { unsigned int i,j; for(i=0;i<10;i++) for(j=0;j<5000;j++) { } } void main(void) { // Write your code here unsigned char a,b; signed int i; a=1; b=1; while (1) { for(i=0; i<16; i++) { P1=a;//P1在安装好的keil目录的reg51.h被定义好,是单片机P1端口(共8个)的数据寄存器, //即给它赋值就代表了让P1.0-P.7输出(1,高电平,0,低电平),以驱动外接的LED灯被点亮 P2=b; delay(); a=_crol_(a,1);//定义在intrins.h里的标准C函数,使得a无符号 字符型变量(8位二进制数)循环左移, //然后当把a赋值给P1后,使得P1口每一位(P.0-P1.7)逐次输出一个1(5v高电平) b=_crol_(b,1); } b=_cror_(b,1); for(i=0; i<15; i++)//流水灯都往右 { P1=a; P2=b; delay(); a=_crol_(a,1); b=_cror_(b,1); } for(i=0; i<15; i++)//流水灯都往左 { P1=a; P2=b; delay(); a=_cror_(a,1); b=_crol_(b,1); } a=_cror_(a,1); for(i=0; i<15; i++)//流水灯相对而行 { P1=a; P2=b; delay(); a=_cror_(a,1); b=_cror_(b,1); } for(i=0; i<16; i++) { P1=a; P2=b; delay(); a=_crol_(a,2); b=_crol_(b,2); } } }View Code
流水灯都往左,流水灯都往右,流水灯相对而行,流水灯相向而行
按钮控制流水灯花样
/* Main.c file generated by New Project wizard * * Created: 周三 4月 22 2020 * Processor: AT89C52 * Compiler: Keil for 8051 */ /* 按button0, 流水灯下移;按button1,流水灯上移; 按button2,流水灯双灯下移;按button3,流水灯双灯上移; 按button4, 流水灯双灯下移两格;按button5,流水灯双灯上移两格; 按button6, 流水灯三灯下移;按button7,流水灯四灯间隔闪烁; */ #include<reg52.h> //库文件 #include<intrins.h> #define uchar unsigned char//宏定义无符号字符型 #define uint unsigned int //宏定义无符号整型 /******************************************************************** 初始定义 *********************************************************************/ uchar a,b,c,d; //定义字符型变量 uchar flag; sbit BY0=P2^0; //定义按键的输入端(为单片机P2口的P2.0按键) sbit BY1=P2^1; //定义按键的输入端(为单片机P2口的P2.1按键) sbit BY2=P2^2; sbit BY3=P2^3; sbit BY4=P2^4; sbit BY5=P2^5; sbit BY6=P2^6; sbit BY7=P2^7; /******************************************************************** 延时函数 *********************************************************************/ void delay10ms(void) //延时程序 { uchar i,j; for(i=20;i>0;i--) for(j=248;j>0;j--); } void delay(void) //延迟函数,当程序输出一个电信号后,CPU做无意义运算,让这个状态维持一段时间(约0.5毫秒), //人眼就能感受到LED灯被点亮了 { unsigned int i,j; for(i=0;i<10;i++) for(j=0;j<5000;j++) { } } /******************************************************************** 按键判断函数 *********************************************************************/ void key1() //按键判断程序 { unsigned int k; if(P2!=0xFF)//是否有键按下,进一步通过区分P2的8位二进制数值来判断哪个键按下了 { delay10ms(); //延时,软件去干扰,机械按键在按下和松开时,状态进入稳定前会有微小的不稳定抖动态,重复判断,确定按键的状态 if(BY0==0) flag=0; else if(BY1==0) flag=1; else if(BY2==0) flag=2; else if(BY3==0) flag=3; else if(BY4==0) flag=4; else if(BY5==0) flag=5; else if(BY6==0) flag=6; else flag=7; } } void key() //按键判断程序 { unsigned int i,j=1; if(P2!=0XFF){//判断是否有键按下 没有键被按下时全部为‘1’ for(i=0;i<=7;i++){ if((P2&j)==0){//单片机P2口的P2.i按键被按下 为‘0' delay10ms(); //延时,软件,机械按键在按下和松开时,状态进入稳定前会有微小的不稳定抖动态,重复判断,确定按键的状态 if((P2&j)==0){//确认按键按下 flag=i;//flag用于标识最近一次按下的键 } while((P2&j)==0);//按键锁定 return ; } j*=2; } } } /******************************************************************** 主函数 *********************************************************************/ void main() { a=0xFE, b=0xFC, c=0xF8, d=0xAA; flag=-1; while(1) { key(); //调用按键判断函数 switch(flag) { case 0: P0=a; delay(); a=_crol_(a,1); break; case 1: P0=a; delay(); a=_cror_(a,1); break; case 2: P0=b; delay(); b=_crol_(b,1); break; case 3: P0=b; delay(); b=_cror_(b,1); break; case 4: P0=b; delay(); b=_crol_(b,2); break; case 5: P0=b; delay(); b=_cror_(b,2); break; case 6: P0=c; delay(); c=_crol_(c,1); break; case 7: P0=d; delay(); d=_cror_(d,1); break; default: break; } } } /******************************************************************** 结束 *********************************************************************/View Code
按button0, 流水灯下移;按button1,流水灯上移;
按button2,流水灯双灯下移;按button3,流水灯双灯上移;
按button4, 流水灯双灯下移两格;按button5,流水灯双灯上移两格;
按button6, 流水灯三灯下移;按button7,流水灯四灯间隔闪烁;
外部中断控制流水灯花样
/* Main.c file generated by New Project wizard * * Created: 周三 5月 6 2020 * Processor: AT89C52 * Compiler: Keil for 8051 */ #include <reg51.h> #define uint unsigned int #define uchar unsigned char //花样显示,23个状态 uchar tab[ ]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F, 0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0XFE,0XFF, 0xAA,0x55,0xAA,0x55,0xAA,0x55,0xFF}; //中断显示,10个状态,0号中断 uchar tab1[ ]={0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00}; //中断显示,10个状态,2号中断,中断一次切换中断显示 uchar tab2[ ]={0x3C,0xC3,0x3C,0xC3,0x3C,0xC3,0x3C,0xC3,0x3C,0xC3}; uchar tab3[ ]={0x5A,0xA5,0x5A,0xA5,0x5A,0xA5,0x5A,0xA5,0x5A,0xA5}; uchar tab4[ ]={0xF0,0x0F,0xF0,0x0F,0xAA,0x55,0xAA,0x55,0x00,0xFF}; uint count=-1; //ms延时程序 void delay_ms(uint x) { uint t; while(x--) for(t = 0; t < 120; t++); } void intrp0( ) interrupt 0 { uchar i; for(i=0;i<10;i++) { P0=tab1[i]; delay_ms(300); } } void intrp2( ) interrupt 2 { uchar i; count=(count+1)%3; if(count==0) { for(i=0;i<10;i++) { P1=tab2[i]; delay_ms(300); } } else if(count==1) { for(i=0;i<10;i++) { P1=tab3[i]; delay_ms(300); } } else { for(i=0;i<10;i++) { P1=tab4[i]; delay_ms(300); } } } void main( ) { IT0=1; EX0=1; EA=1; IT1=1; EX1=1; while(1) { uchar x; for(x=0;x<23;x++) { P0=tab[x]; P1=tab[x]; delay_ms(500); } } }View Code
流水灯正常运行,外部中断0触发时P0口显示花样,外部中断1触发时P1口显示花样
定时器实现方波
/* Main.c file generated by New Project wizard * * Created: 周三 5月 20 2020 * Processor: AT89C52 * Compiler: Keil for 8051 */ #include <reg51.h> sbit P2_0=P2^0; void timer0 (void) interrupt 1 { P2_0 = !P2_0; //P2.0取反 TH0 = 55536/256; //计数初值重装载 TL0 = 55536%256; } void main (void) { TMOD = 0x01; //T0定时方式1 P2_0=0; TH0=55536/256; //预置计数初值 定时10ms TL0=55536%256; EA=1; ET0=1; TR0=1; while(1); }View Code
电子琴
/* Main.c file generated by New Project wizard * * Created: 周三 5月 20 2020 * Processor: AT89C52 * Compiler: Keil for 8051 */ #include<reg52.h> //库文件 #include<intrins.h> #define uchar unsigned char//宏定义无符号字符型 #define uint unsigned int //宏定义无符号整型 /******************************************************************** 初始定义 *********************************************************************/ unsigned int T[8]={63628,63835,64021,64103,64260,64400,64524,64580};//低1-低7和中1 音符的频率所对应的T值 unsigned int T_value; unsigned int count=0;//中断服务程序运行的次数,确保一次按键只响一声 sbit BY0=P1^0; //定义按键的输入端(为单片机P1口的P1.0按键) sbit BY1=P1^1; //定义按键的输入端(为单片机P1口的P1.1按键) sbit BY2=P1^2; sbit BY3=P1^3; sbit BY4=P1^4; sbit BY5=P1^5; sbit BY6=P1^6; sbit BY7=P1^7; sbit P2_0=P2^0; /******************************************************************** 延时函数 *********************************************************************/ void delay10ms(void) //延时程序 { uchar i,j; for(i=20;i>0;i--) for(j=248;j>0;j--); } /******************************************************************** 中断函数 *********************************************************************/ void timer(void) interrupt 1//定时计数器T0 中端号为1 { P2_0=!P2_0; TH0=T_value/256; TL0=T_value%256; count++; if(count==2) { count=0; ET0=0; TR0=0; } } /******************************************************************** 主函数 *********************************************************************/ void main() { TMOD=0x01; //T0定时方式1 EA=1; P0=0xFF;//灯初始状态为全关 while(1) { P0=0xFF; if(P1!=0)//是否有键按下,进一步通过区分P1的8位二进制数值来判断哪个键按下了 { delay10ms(); //延时,软件去干扰,机械按键在按下和松开时,状态进入稳定前会有微小的不稳定抖动态,重复判断,确定按键的状态 while(BY0==0) { P0=0xFE;//1111 1110 T_value=T[0]; ET0=1;//开T0中断 TR0=1;//启动定时器0 } while(BY1==0) { P0=0xFD;//1111 1101 T_value=T[1]; ET0=1; TR0=1; } while(BY2==0) { P0=0xFB;//1111 1011 T_value=T[2]; ET0=1; TR0=1; } while(BY3==0) { P0=0xF7;//1111 0111 T_value=T[3]; ET0=1; TR0=1; } while(BY4==0) { P0=0xEF;//1110 1111 T_value=T[4]; ET0=1; TR0=1; } while(BY5==0) { P0=0xDF;//1101 1111 T_value=T[5]; ET0=1; TR0=1; } while(BY6==0) { P0=0xBF;//1011 1111 T_value=T[6]; ET0=1; TR0=1; } while(BY7==0) { P0=0x7F;//0111 1111 T_value=T[7]; ET0=1; TR0=1; } } } } /******************************************************************** 结束 *********************************************************************/View Code
8个音符较少,可弹奏粉刷匠和小毛驴
unsigned int T[8]={63628,63835,64021,64103,64260,64400,64524,64580};//低1-低7和中1 音符的频率所对应的T值
用8255实现数码管60秒计时
/* Main.c file generated by New Project wizard * * Created: 周三 6月 3 2020 * Processor: AT89C52 * Compiler: Keil for 8051 */ #include <reg51.h> #include <intrins.h> #include <absacc.h> #define uint unsigned int #define uchar unsigned char //P0.5和P0.6决定A0和A1,决定选择的寄存器组 #define portA 0X00 #define portB 0x20 #define portC 0x40 #define Cont 0x60 sbit P1_0=P1^0; sbit P1_1=P1^1; uint ten=0; uint one=0; uint count=0;//计数满20次为1s uchar table[]={0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};//共阴数码管段码表 //工作方式1最大计时65.536ms,我们要计算一秒,则计时20次50ms较好, //要计算的机器周期数=50ms/1μs=50000,计数初值=2^16-50000=15536 //中断函数定时计数器T0 中端号为1 void timer0(void) interrupt 1 { TH0=15536/256; TL0=15536%256; count++; if(count==20) { count=0; one++; } if(one==10) { one=0; ten++; if(ten==6) { ten=0; } } } void show() { PBYTE[portA]=table[ten]; PBYTE[portB]=table[one]; } void main(void) { PBYTE[Cont]=0x81;//将控制字写入8255的控制口地址 1000 0001 TMOD=0x01;//T0定时方式1 EA=1; TH0=15536/256; TL0=15536%256; ET0=1;//开T0中断 TR0=1;//启动计时器 while(1) { show(); if(P1_0==0)//P1.0处按键按下,计时暂停,或者是P1==255-1 { TR0=0;//关闭定时器0 } if(P1_1==0)//P1.1处按键按下,计时重置 { ten=0; one=0; TR0=1; } } }View Code
串行口通信
要使用串口调试助手和vspdpro
/* Main.c file generated by New Project wizard * * Created: 周三 6月 17 2020 * Processor: AT89C52 * Compiler: Keil for 8051 */ #include <reg51.h> #include <stdio.h> unsigned char table[]={0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};//共阴数码管段码表 unsigned char mystr[]={0x68,0x65,0x6c,0x6c,0x6f};//hello unsigned int num = 9; sbit P2_0 = P2^0; unsigned int i; //延时函数 void delay_ms(unsigned int x){ unsigned int t; while(x--) for(t=0;t<120;t++); } //串行口初始化 void csh() { SCON=0x50;//设置串行口工作方式,SM0=0,SM1=1,REN=1,TI=RI=0 PCON=0; //波特率不加倍 TH1=0xFD; //波特率设定为9600,计数初值查表可得,晶振频率为11.0592MHz TL1=0XFD; TMOD=0X20;//T1工作于方式2定时方式 TR1=1; //启动T1 } //按键判断函数 void key() { num = 0; if(P1==255-1) {//P1.0按下,下面类似 num = 1; } else if(P1==255-2) { num = 2; } else if(P1==255-4) { num = 3; } else if(P1==255-8) { num = 4; } else if(P1==255-16) { num = 5; } else if(P1==255-32) { num = 6; } else if(P1==255-64) { num = 7; } else if(P1==255-128) { num = 8; } if(num != 0) { P0=table[num]; SBUF = num+0x30; while(!TI); TI = 0; } } void showString(){ for(i=0;i<5;i++){ SBUF=mystr[i]; while(!TI); TI=0; } } void main() { csh(); //串行口初始化 while(1) { while(RI) { RI=0; P0=table[SBUF-0x30]; } while(P1!=255) { delay_ms(10); key(); } if(!P2_0){ P2_0 = 1; delay_ms(10); showString(); } } }View Code
单片机异步串行通讯
通过矩阵键盘,8位数码管,8255,74ls373等器件,完成单片机之间的串口通讯。将两个单片机的串行口连接,进行异步串行通讯。两个单片机能够通过按键,8位数码管,设置输出数据(10个数字和A-F字符组成的字符串,最多输入8个)和显示接收到的数据(最多8个),通过设置发送键(可使用外部中断),发送。 (100分)
/* Main.c file generated by New Project wizard * * Created: 周三 7月 1 2020 * Processor: AT89C52 * Compiler: Keil for 8051 */ #include <reg51.h> extern void delay_ms(unsigned int n); extern void Scan_Key(void); void disp(void);//显示收到的字符 void receive(void); unsigned char ptr,m; unsigned int tno=0,rno=0;//发送和接收时的第几个数码管 sbit P3_2=P3^2;//发送键 unsigned char table[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71 };//共阴极字型码 unsigned char sel[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//位选 unsigned char data tdisbuf[8]={0}; unsigned char data rdisbuf[8]={0}; void delay_ms(unsigned int n) //延时 { unsigned int i,j; for(i=0;i<n;i++) { for(j=0;j<80;j++); } } void intrr0(void) interrupt 0 //判断P3.2是否按下,如按下就发送字符串 { unsigned int i,j; //串行口发送 for(i=0;i<8;i++){ SBUF=tdisbuf[i]; delay_ms(2); } tno=0;//重置,以便下次发送从头开始 for(j=0;j<8;j++){ tdisbuf[i]=0; } } void intrr4(void) interrupt 4 //判断串行口是否发送或接收完数据 { if(TI==1) //若发送完数据 { TI=0; //发送完数据,清TI } if(RI==1) //若接收到数据 { RI=0; //清RI receive(); } } void receive(void) //把接收到数据的数据送给rdisbuf数组 { unsigned char i; rdisbuf[rno]=SBUF; rno=(rno+1)%8; } void disp(void) //把rdisbuf数组内的字符显示在数码管上 { unsigned char i,j; P2=0XFF; //关闭所示数码管显示 for(i=0;i<8;i++) { j=rdisbuf[i]; P2=sel[i]; //得到位选 P0=table[j]; //送段码 delay_ms(2); P2=0XFF; } } void csh() //初始化串口 { SM0=0; SM1=1; REN=1; TI=0; RI=0;//以上两行可用SCON=0x50替换 PCON=0; //波特率不加倍 TH1=0xFD; TL1=0XFD;//波特率设定为9600 TMOD=0X20;//T1工作于方式2定时方式 EA=1; //开总中断 ES=1; //开串行通信中断 TR1=1; //启动T1 } unsigned char Check_Key() { unsigned char i; P1=0xF0; //送全0,向各行送低电平 i=P1; //取P1口值 i=i&0xF0; //屏蔽掉低四位,作为列值 if(i==0xF0) //判断是否有键按下 return 0; else return 0xff; } void Scan_Key(void) // 键盘扫描程序 { char a1,i; bit FLAG0=0; a1=0xfe; //列扫描初值,送1个“0” ptr=0; //第ptr个按钮,A-F时为10-16 if(Check_Key()==0) return; for(i=0;i<4;i++) //键盘4个扫描列 { P1=a1; delay_ms(10); m=P1; switch(m&0xf0) //取行的高4位,检测哪一行有按键被按下 { case 0xe0: ptr=i*4; //第一行被按否? FLAG0=1; //表示有按键 break; case 0xd0: ptr=i*4+1; //第二行被按否? FLAG0=1; break; case 0xb0: ptr=i*4+2; //第三行被按否? FLAG0=1; break; case 0x70: ptr=i*4+3; //第四行被按否? FLAG0=1; break; default: break; } if( FLAG0 ) { if(tno<8) { tdisbuf[tno]=ptr; //第tno个数码管 while((P1&0xf0)==0xe0); while((P1&0xf0)==0xd0); while((P1&0xf0)==0xb0); while((P1&0xf0)==0x70); tno=tno+1; return; } } a1=a1<<1|0x01; } } void main(void) { EX0=1;//开外部中断0 csh(); while(1) { Scan_Key(); //扫描键盘 disp(); } }View Code
注:两个单片机程序一样
unsigned char table[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71 };//共阴极字型码
unsigned char sel[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//位选
为了这个综合设计打过的草稿,参考了一堆程序
双机通信
//单片机甲的程序 #include <reg51.h> void delay_ms(unsigned int x) { unsigned int t; while(x--) for(t=0;t<120;t++); } //初始化串行口 void csh() { SM0=0; SM1=1; REN=1; TI=0; RI=0; PCON=0; TH1=0xF3; TL1=0XF3; TMOD=0X20; EA=1; ET1=0; ES=1; TR1=1; } void main() { char c=0; csh(); while(1) { P0=c; SBUF=c; while(!TI); TI=0; delay_ms(600); c++; if (c>9) c=0; } } void intrr() interrupt 4 { char temp; temp=SBUF; P2=temp; RI=0; }View Code
注:这是单片机甲的程序,乙的程序只在main函数的发送9-0处不同
电子钟
#include "reg51.h" #include "stdio.h" #define uint unsigned int #define uchar unsigned char uchar data second=0,minute=0,hour=0; uchar data disbuf[6]={0}; uchar bdata FLAG=0; sbit H_M=FLAG^1; //小时 分钟切换标志位 启动后默认为分钟设置状态 sbit P1_0=P1^0; //增1键 sbit P3_2=P3^2; //小时,分钟切换键 //定义共阴段码 0-9 uchar code table[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //计数变量 uchar data count=0; //定时器0的中断服务程序 50ms void timer0(void) interrupt 1 using 1 {TH0=-50000/256; TL0=-50000%256; count++; if(count==20) {count=0; second++; if(second==60) {second=0; minute++; if(minute==60) {minute=0; hour++; if(hour==24) {hour=0;} } } } return; } //延时程序 void dlms(void) {uchar i; for(i=2000;i>0;i--){} } //外部中断0的中断服务程序 void int0(void) interrupt 0 using 2 { while(!P3_2) //等待按键弹起 { dlms(); } dlms( ); if(P3_2) //按键弹起 H_M=!H_M; } //显示程序 void disp(void) {uchar i,j; uchar bdata sel; disbuf[0]=second%10; disbuf[1]=second/10; disbuf[2]=minute%10; disbuf[3]=minute/10; disbuf[4]=hour%10; disbuf[5]=hour/10; P2=0XFF; //关闭所示数码管显示 sel=0x01; for(i=0;i<6;i++) {j=disbuf[i]; P2=(sel^0xff); //得到位选 P0=table[j]; //送段码 dlms(); P2=0XFF; sel=sel<<1; //位选左移1位 } } //加1处理程序 void increa(void) {if(H_M) //H_M为1 表示小时设置 {hour++; if(hour==24) {hour=0; disbuf[4]=0; disbuf[5]=0; } } else //H_M为0 表示分钟设置 {minute++; if(minute==60) {minute=0; disbuf[2]=0; disbuf[3]=0; } } } int main( ) { TCON=0x01; TMOD=0x01; TH0=-50000/256; TL0=-50000%256; EA=1; ET0=1; EX0=1; TR0=1; while(1) {disp(); if(!P1_0) {while(!P1_0) dlms(); if(P1_0) increa(); } } }View Code
动态显示数码管(人眼的暂存效应)
#include <reg51.h> #define uchar unsigned char #define uint unsigned int uchar code ledD[6]={0x06,0x5b,0x4f,0x66,0x6d,0x7d};//段码 uchar code ledW[6]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};//位选 //延时函数 void delay_ms(uint x) { uint t; while(x--) for(t=0;t<120;t++); } //主程序 void main( ) { uchar i; while(1) { for(i=0;i<6;i++) { P0=ledD[i]; P2=ledW[i]; delay_ms(2); //参数大于50时能清晰看到数码管一个一个点亮 P2=0xff; } } }View Code
串口方式1
#include <reg52.h> //串行口初始化 void csh() //中断方式串行口初始化 { SCON=0x50;//设置串行口工作方式,SM0=0,SM1=1,REN=1,TI=RI=0 PCON=0; //波特率不加倍 TH1=0xF4; //波特率设定为2400 TL1=0XF4; TMOD=0X20;//T1工作于方式2定时方式 ES=1; //开中断 EA=1; TR1=1; //启动T1 } void main() { csh(); //串行口初始化 P2=0Xff; //设P2为输入端口 SBUF=P2; while(1); } void intrr() interrupt 4 //串行通信中断函数 { if(TI==1) //若发送完数据 { TI=0; //发送完数据,清TI SBUF=P2; //将开关的状态读入并从串行口发送出去 } if(RI==1) //若接收到数据 { RI=0; //清RI P0=SBUF; //将接收到的数据显示在LED上 } }View Code
单片机7例子
老师发的优秀例子,仅供学习之用,不可转载
#include<reg52.h> #include <stdio.h> #define uchar unsigned char #define uint unsigned int uchar table[]={0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f}; uchar a; uchar str[7] = "Hello !"; void delay_ms(uint x) { uchar t; while(x --) for(t = 0; t < 120; t ++); } void csh() { SCON = 0x50; PCON = 0; TH1 = 0xFD; TL1 = 0xFD; TMOD = 0x20; ES = 1; EA = 1; TR1 = 1; } uint Key() { uint k; k = 0; if(P1 != 0xff) { delay_ms(10); switch(P1) { case 0xfe:k = 1; break; case 0xfd: k = 2; break; case 0xfb: k = 3; break; case 0xf7: k = 4; break; case 0xef: k = 5; break; case 0xdf: k = 6; break; case 0xbf: k = 7; break; case 0x7f: k = 8; break; } while(P1 != 0xff); } else if(P2 != 0xff) { delay_ms(10); if(P2 == 0xfe) k = 9; } return k; } void main() { uint i; csh(); P0 = 0x00; while(1) { if(TI == 0) { uint K = Key(); if(K >0 & K< 9 ) { SBUF = (K + 0x30); while(!TI); TI = 0; } else if(K ==9) for(i = 0; i < 7; i ++) { SBUF = str[i]; while(!TI); TI = 0; } } } } void intrr() interrupt 4 { if(RI == 1) { RI = 0; P0 = table[SBUF-0x30]; } }View Code
单片机7例子3
老师发的优秀例子,仅供学习之用,不可转载
#include <reg51.h> #include <stdio.h> #define uchar unsigned char #define uint unsigned int uchar buf; sbit BY0=P1^0; sbit BY1=P1^1; sbit BY2=P1^2; sbit BY3=P1^3; sbit BY4=P1^4; sbit BY5=P1^5; sbit BY6=P1^6; sbit BY7=P1^7; sbit BY8=P2^0;//这是控制向pc机发送一个字符串 unsigned char string[]="hello world!"; //向pc机发送hello world! unsigned char tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//数码管0-9 unsigned int m,n; void delay10ms(void) //延时程序 { unsigned char i,j; for(i=20;i>0;i--) for(j=248;j>0;j--); } void csh() { SCON=0x50; PCON=0; TH1=0xFD; TL1=0xFD; TMOD=0x20; ES=1; EA=1; TR1=1; } void sendString() { for(m=0;m<12;m++) { SBUF=string[m]; while(!TI) ; TI=0; } } void key() //按键判断程序 { if(P1 != 0xff) { delay10ms(); if(BY0==0) {SBUF=1+0x30;while(!TI) ;TI=0;while(!BY0) ;} if(BY1==0) {SBUF=2+0x30;while(!TI) ;TI=0;while(!BY1) ;} if(BY2==0) {SBUF=3+0x30;while(!TI) ;TI=0;while(!BY2) ;} if(BY3==0) {SBUF=4+0x30;while(!TI) ;TI=0;while(!BY3) ;} if(BY4==0) {SBUF=5+0x30;while(!TI) ;TI=0;while(!BY4) ;} if(BY5==0) {SBUF=6+0x30;while(!TI) ;TI=0;while(!BY5) ;} if(BY6==0) {SBUF=7+0x30;while(!TI) ;TI=0;while(!BY6) ;} if(BY7==0) {SBUF=8+0x30;while(!TI) ;TI=0;while(!BY7) ;} } if(BY8==0) { delay10ms(); if(BY8==0) {sendString(); while(!BY8) ;} } } void main(void) { csh(); while(1) key(); } void serial() interrupt 4 { if(RI==1){ RI=0; P0=tab[SBUF-0x30]; } }View Code