51单片机C语言学习知识程序设计源代码.doc

收藏

编号:2569339    类型:共享资源    大小:124.50KB    格式:DOC    上传时间:2020-04-20
20
金币
关 键 词:
51 单片机 语言 学习 知识 程序设计 源代码
资源描述:
,. 51单片机C语言教程 例2.2.1编写程序,点亮第一个发光二极管(part2_1.c P27) #include //52系列单片机头文件 sbit led1=P1^0; //声明单片机P1口的第一位 void main() //主函数 { led1=0; /*点亮第一个发光二极管*/ } 例2.2.2编写程序,点亮P1口的若干二极管(part2_2.c P39) #include //52系列单片机头文件 void main() //主函数 { P1=0xaa; //while(1); } 例2.5.1利用for语句延时特性,编写第一个发光二极管以间隔1S亮灭闪动的程序(part2_3.c P42) #include //52系列单片机头文件 #define uint unsigned int //宏定义 sbit led1=P1^0; //声明单片机P1口的第一位 uint i,j; void main() //主函数 { while(1) //大循环 { led1=0; /*点亮第一个发光二极管*/ for(i=1;i>0;i--) //延时 for(j=110;j>0;j--); led1=1; /*关闭第一个发光二极管*/ for(i=1000;i>0;i--) //延时 for(j=110;j>0;j--); } } 例2.6.1编写程序使第一个发光二极管以间隔500ms亮灭闪动。(part2_4.c P48) #include //52系列单片机头文件 #define uint unsigned int //宏定义 sbit led1=P1^0; //声明单片机P1口的第一位 void delay1s(); //声明子函数 void main() //主函数 { while(1) //大循环 { led1=0; /*点亮第一个发光二极管*/ delay1s(); //调用延时子函数 led1=1; /*关闭第一个发光二极管*/ delay1s(); //调用延时子函数 } } void delay1s() //子函数体 { uint i,j; for(i=500;i>0;i--) for(j=110;j>0;j--); } 例2.7.1编写程序使第一个二极管以亮200ms、灭800ms的方式闪动。(part2_5.c P49) #include //52系列单片机头文件 #define uint unsigned int //宏定义 sbit led1=P1^0; //声明单片机P1口的第一位 void delayms(uint); //声明子函数 void main() //主函数 { while(1) //大循环 { led1=0; /*点亮第一个发光二极管*/ delayms(200); //延时200毫秒 led1=1; /*关闭第一个发光二极管*/ delayms(800); //延时800毫秒 } } void delayms(uint xms) { uint i,j; for(i=xms;i>0;i--) //i=xms即延时约xms毫秒 for(j=110;j>0;j--); } 例2.8.3利用C51自带库_crol_(),以间隔500ms,实现流水灯程序(part2_6.c P53) #include //52系列单片机头文件 #include #define uint unsigned int //宏定义 #define uchar unsigned char void delayms(uint); //声明子函数 uchar aa; void main() //主函数 { aa=0xfe; //赋初值11111110 while(1) //大循环 { P1=aa; delayms(500); //延时500毫秒 aa=_crol_(aa,1); //将aa循环左移1位后再赋给aa } } void delayms(uint xms) { uint i,j; for(i=xms;i>0;i--) //i=xms即延时约xms毫秒 for(j=110;j>0;j--); } 例3.2.1编写程序使第一个数码管显示8(part2.1_.1c P59) #include //52系列单片机头文件 sbit dula=P2^6; //申明U1锁存器的锁存端 sbit wela=P2^7; //申明U2锁存器的锁存端 void main() { wela=1; //打开U2锁存器 P0=0xFE; //送入位选信号 wela=0; //关闭U2锁存器 dula=1; //打开U1锁存器 P0=0x7F; //送入段选信号 dula=0; //关闭U2锁存器 while(1); //程序停止到这里 } 例3.2.2让实验板上6个数码管同时点亮,依次显示0到F,时间间隔为0.5ms,循环下去。(part2.1_2.c P61) #include //52系列单片机头文件 #define uchar unsigned char #define uint unsigned int sbit dula=P2^6; //申明U1锁存器的锁存端 sbit wela=P2^7; //申明U2锁存器的锁存端 uchar num; unchar code table[]={ 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; void delayms(uint); void main() { wela=1; //打开U2锁存端 P0=0xco;//送入位选信号 wela=0; //关闭U2锁存端 while(1) { for(num=0;num<16;num++) //16个数循环显示 { dula=1; //打开U1锁存端 P0=table[num]; //送入段选信号 dula=0; //关闭U1锁存端 delay(500); //延时0.5秒 } } } void delayms(uint xms) { uint i,j; for(i=xms;i>0;i--) //i=xms即延时约xms毫秒 for(j=110;j>0;j--); } 例3.3.1第一个数码管显示1,时间为0.5s,然后关闭它,立即让第二个数码管显示2,时间为0.5s,在关闭它……一直到最后一个数码管显示6,时间同样为0.5s,关闭它之后再回来显示第一个数码管,一直循环下去。(part2.1_3.c P62) 例3.5.2用定时器0的方式1实现第一个发光二极管以200ms间隔闪烁,用定时器1的方式1实现数码管前两位59s循环计时。(part2.1_5.c P75) 例4.1.1用数码管前两位显示一个十进制数,变化范围为00~59,开始时显示00,每按下S2键一次,数值加1;每按下S3键一次,数值减1;每按下S4键一次,数值归零;按下S5键一次,利用定时器功能使数值开始自动每秒加1,再次按下S5键,数值停止加1,保持显示原数。(part2.2_1.c P82) #include //52系列单片机头文件 #define uchar unsigned char #define uint unsigned int sbit key1=P3^4; sbit key2=P3^5; sbit key3=P3^6; sbit key4=P3^7; sbit dula=P2^6; //申明U1锁存器的锁存端 sbit wela=P2^7; //申明U2锁存器的锁存端 uchar code table[]={ 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; void delayms(uint); uchar numt0,num; void display(uchar numdis) //显示子函数 { uchar shi,ge; //分离两个分别要显示的数 shi=numdis/10; ge=numdis%10; dula=1; P0=table[shi]; //送十位段选数据 dula=0; P0=0xff; //送位选数据前关闭所有显示,防止打开位选锁存时 wela=1; //原来段选数据通过位选锁存器造成混乱 P0=0xfe; //送位选数据 wela=0; delayms(5); //延时 dula=1; P0=table[ge]; //送个位段选数据 dula=0; P0=0xff; wela=1; P0=0xfd; wela=0; delayms(5); } void delayms(uint xms) { uint i,j; for(i=xms;i>0;i--) //i=xms即延时约xms毫秒 for(j=110;j>0;j--); } void init() //初始化函数 { TMOD=0x01;//设置定时器0为工作方式1(0000 0001) TH0=(65536-45872)/256;//装初值50ms一次中断 TL0=(65536-45872)%256; EA=1; //开总中断 ET0=1; //开定时器0中断 } void keyscan() { if(key1==0) { delayms(10); if(key1==0) { num++; if(num==60)//当到60时重新归0 num=0; while(!key1);//等待按键释放 } } if(key2==0) { delayms(10); if(key2==0) { if(num==0)//当到0时重新归60 num=60; num--; while(!key2); } } if(key3==0) { delayms(10); if(key3==0) { num=0; //清0 while(!key3); } } if(key4==0) { delayms(10); if(key4==0) { while(!key4); TR0=~TR0;//启动或停止定时器0 } } } void main() { init();//初始化函数 while(1) { keyscan(); display(num); } } void T0_time() interrupt 1 { TH0=(65536-45872)/256;//重装初值 TL0=(65536-45872)%256; numt0++; if(numt0==20) //如果到了20次,说明1秒时间到 { numt0=0; //然后把num清0重新再计20次 num++; if(num==60) num=0; } } 例4.2.1实验班上电时,数码管不显示,顺序按下矩阵键盘后,数码管上依次显示0~F,六个数码管同时静态显示即可。(part2.2_2.c P87) #include //52系列单片机头文件 #define uchar unsigned char #define uint unsigned int sbit dula=P2^6; //申明U1锁存器的锁存端 sbit wela=P2^7; //申明U2锁存器的锁存端 uchar code table[]={ 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; void delayms(uint xms) { uint i,j; for(i=xms;i>0;i--) //i=xms即延时约xms毫秒 for(j=110;j>0;j--); } void display(uchar num) { P0=table[num]; //显示函数只送段选数据 dula=1; dula=0; } void matrixkeyscan() { uchar temp,key; P3=0xfe; temp=P3; temp=temp&0xf0; if(temp!=0xf0) { delayms(10); temp=P3; temp=temp&0xf0; if(temp!=0xf0) { temp=P3; switch(temp) { case 0xee: key=0; break; case 0xde: key=1; break; case 0xbe: key=2; break; case 0x7e: key=3; break; } while(temp!=0xf0) { temp=P3; temp=temp&0xf0; } display(key); } } P3=0xfd; temp=P3; temp=temp&0xf0; if(temp!=0xf0) { delayms(10); temp=P3; temp=temp&0xf0; if(temp!=0xf0) { temp=P3; switch(temp) { case 0xed: key=4; break; case 0xdd: key=5; break; case 0xbd: key=6; break; case 0x7d: key=7; break; } while(temp!=0xf0) { temp=P3; temp=temp&0xf0; } display(key); } } P3=0xfb; temp=P3; temp=temp&0xf0; if(temp!=0xf0) { delayms(10); temp=P3; temp=temp&0xf0; if(temp!=0xf0) { temp=P3; switch(temp) { case 0xeb: key=8; break; case 0xdb: key=9; break; case 0xbb: key=10; break; case 0x7b: key=11; break; } while(temp!=0xf0) { temp=P3; temp=temp&0xf0; } display(key); } } P3=0xf7; temp=P3; temp=temp&0xf0; if(temp!=0xf0) { delayms(10); temp=P3; temp=temp&0xf0; if(temp!=0xf0) { temp=P3; switch(temp) { case 0xe7: key=12; break; case 0xd7: key=13; break; case 0xb7: key=14; break; case 0x77: key=15; break; } while(temp!=0xf0) { temp=P3; temp=temp&0xf0; } display(key); } } } void main() { P0=0; //关闭所有数码管段选 dula=1; dula=0; P0=0xc0;//位选中所有数码管 wela=1; wela=0; while(1) { matrixkeyscan();//不停调用键盘扫描程序 } } 例5.3.1用单片机控制ADC0804进行数模转换,当拧动实验板上A/D旁边的电位时,在数码管的前三位以十进制方式显示出A/D转换后的数字量(8位A/D转换后数值在0~255变化)。(part2.3_1.c P107) #include //52系列单片机头文件 #include #define uchar unsigned char #define uint unsigned int sbit dula=P2^6; //申明U1锁存器的锁存端 sbit wela=P2^7; //申明U2锁存器的锁存端 sbit adwr=P3^6; //定义AD的WR端口 sbit adrd=P3^7; //定义AD的RD端口 uchar code table[]={ 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; void delayms(uint xms) { uint i,j; for(i=xms;i>0;i--) //i=xms即延时约xms毫秒 for(j=110;j>0;j--); } void display(uchar bai,uchar shi,uchar ge) //显示子函数 { dula=1; P0=table[bai]; //送段选数据 dula=0; P0=0xff; //送位选数据前关闭所有显示,防止打开位选锁存时 wela=1; //原来段选数据通过位选锁存器造成混乱 P0=0x7e; //送位选数据 wela=0; delayms(5); //延时 dula=1; P0=table[shi]; dula=0; P0=0xff; wela=1; P0=0x7d; wela=0; delayms(5); dula=1; P0=table[ge]; dula=0; P0=0xff; wela=1; P0=0x7b; wela=0; delayms(5); } void main() // 主程序 { uchar a,A1,A2,A3,adval; wela=1; P0=0x7f; //置CSAD为0,选通ADCS 以后不必再管ADCS wela=0; while(1) { adwr=1; _nop_(); adwr=0; //启动AD转换 _nop_(); adwr=1; for(a=10;a>0;a--) //TX-1C实验板AD工作频率较低,所以启动转换后要多留点时间用来转换 { //这里把显示部分放这里的原因也是为了延长转换时间 display(A1,A2,A3); } P1=0xff; //读取P1口之前先给其写全1 adrd=1; //选通ADCS _nop_(); adrd=0; //AD读使能 _nop_(); adval=P1; //AD数据读取赋给P1口 adrd=1; A1=adval/100; //分出百,十,和个位 A2=adval%100/10; A3=adval%10; } } 例5.5.1用单片机控制DAC0832芯片输出电流,让发光二级管D12由灭均匀变到最亮,再由最亮均匀熄灭。在最亮和最暗时使用蜂鸣器分别警报一声,完成整个周期时间控制在5S左右,循环变化。(part2.3_2.c P121) #include #define uchar unsigned char #define uint unsigned int sbit dula=P2^6; //申明U1锁存器的锁存端 sbit wela=P2^7; //申明U2锁存器的锁存端 sbit dawr=P3^6; //定义DA的WR端口 sbit dacs=P3^2; //定义DA的CS端口 sbit beep=P2^3; //定义蜂鸣器端口 void delayms(uint xms) { uint i,j; for(i=xms;i>0;i--) //i=xms即延时约xms毫秒 for(j=110;j>0;j--); } void main() { uchar val,flag; dula=0; wela=0; dacs=0; dawr=0; P0=0; while(1) { if(flag==0) { val+=5; P0=val; //通过P0口给DA数据口赋值 if(val==255) { flag=1; beep=0; delayms(100); beep=1; } delayms(50); } else { val-=5; P0=val; //通过P0口给DA数据口赋值 if(val==0) { flag=0; beep=0; delayms(100); beep=1; } delayms(50); } } } 例6.5.1在上位机上用串口调试助手发送一个字符X,单片机收到字符后返回给上位机“I get X”,串口波特率设为9600bps。(part2.4_1.c P137) #include #define uchar unsigned char #define uint unsigned int unsigned char flag,a,i; uchar code table[]="I get "; //uchar code table[]={I, ,g,e,t, }; void init() { TMOD=0x20; TH1=0xfd; TL1=0xfd; TR1=1; REN=1; SM0=0; SM1=1; EA=1; ES=1; } void main() { init(); while(1) { if(flag==1) { ES=0; for(i=0;i<6;i++) { SBUF=table[i]; while(!TI); TI=0; } SBUF=a; while(!TI); TI=0; ES=1; flag=0; } } } void ser() interrupt 4 { RI=0; a=SBUF; flag=1; } 例6.6.1单片机上电后等待从上位机串口发来的命令,同时在数码管的前三位以十进制方式显示A/D采集的数值,在未收到上位机发送来的启动A/D转换命令之前数码管始终显示000。当收到上位机以十六进制发送来的01后,向上位机发送字符串“Turn on ad!”同时间隔1s读取一次A/D的值,然后把A/D采集回来的8位二进制转换成十进制表示的实际电压浮点数,并且从串口发送给上位机,形式如“The voltage is 3.398438V”,发送周期也是一秒一次,同时在数码管上也要每秒刷新现实的数值。当收到上位机以十六进制发送过来的02后,向上位机发送字符串“Turn off ad!”,然后停止发送电压值,数码管上显示上次结束时保持的值。当收到上位机发来的其他任何数时,向上位机发送字符串“Error!”。 (part2.4_2.c P140) #include #include #include #define uchar unsigned char #define uint unsigned int sbit dula=P2^6; //申明U1锁存器的锁存端 sbit wela=P2^7; //申明U2锁存器的锁存端 sbit adwr=P3^6; //定义AD的WR端口 sbit adrd=P3^7; //定义AD的RD端口 uchar flag,a; unsigned char flag_uart,flag_time,flag_on,a,i,t0_num,ad_val; float ad_vo; uchar code table[]={ 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; void delayms(uint xms) { uint i,j; for(i=xms;i>0;i--) //i=xms即延时约xms毫秒 for(j=110;j>0;j--); } void init() { TMOD=0x21; // SCON=0x50; TH0=(65536-50000)/256; TL0=(65536-50000)%256; TH1=0xfd; TL1=0xfd; TR1=1; ET0=1; SM0=0; SM1=1; REN=1; EA=1; ES=1; } void display(uchar value) //显示子函数 { uchar bai,shi,ge; bai=value/100; //分出百,十,和个位 shi=value%100/10; ge=value%10; dula=1; P0=table[bai]; //送段选数据 dula=0; P0=0xff; //送位选数据前关闭所有显示,防止打开位选锁存时 wela=1; //原来段选数据通过位选锁存器造成混乱 P0=0x7e; //送位选数据 wela=0; delayms(5); //延时 dula=1; P0=table[shi]; dula=0; P0=0xff; wela=1; P0=0x7d; wela=0; delayms(5); dula=1; P0=table[ge]; dula=0; P0=0xff; wela=1; P0=0x7b; wela=0; delayms(5); } uchar get_ad() { uchar adval; adwr=1; _nop_(); adwr=0; //启动AD转换 _nop_(); adwr=1; P1=0xff; //读取P1口之前先给其写全1 adrd=1; _nop_(); adrd=0; //AD读使能 _nop_(); adval=P1; //AD数据读取 adrd=1; return adval; } void main() { init(); wela=1; P0=0x7f; //置CSAD为0,选通ADCS 以后不必再管ADCS wela=0; while(1) { if(flag_uart==1) { flag_uart=0; ES=0; TI=1; switch(flag_on) { case 0: puts("Turn on ad!\n"); TR0=1; break; case 1: printf("Turn off ad!\n"); TR0=0; break; case 2: puts("Error!\n"); break; } while(!TI);//必须要加 TI=0; ES=1; } if(flag_time==1) { flag_time=0; ad_val=get_ad(); ad_vo=(float)ad_val*5.0/256.0; ES=0; TI=1; printf("The voltage is %fV\n",ad_vo); while(!TI); TI=0; ES=1; } display(ad_val); } } void timer0() interrupt 1 { TH0=(65536-50000)/256; TL0=(65536-50000)%256; t0_num++; if(t0_num==20) { t0_num=0; flag_time=1; } } void ser() interrupt 4 { RI=0; a=SBUF; flag_uart=1; if(a==1) flag_on=0; else if(a==2) flag_on=1; else flag_on=2; } 例7.2.1实现1602液晶的第一行显示“I LOVE MCU!”,
展开阅读全文
提示  淘文阁 - 分享文档赚钱的网站所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。
关于本文
本文标题:51单片机C语言学习知识程序设计源代码.doc
链接地址:https://www.taowenge.com/p-2569339.html
关于淘文阁 - 版权申诉 - 用户使用规则 - 积分规则 - 联系我们

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号 © 2020-2023 www.taowenge.com 淘文阁 

收起
展开