新概念51单片机C语言教程实例代码_第1页
新概念51单片机C语言教程实例代码_第2页
新概念51单片机C语言教程实例代码_第3页
新概念51单片机C语言教程实例代码_第4页
新概念51单片机C语言教程实例代码_第5页
已阅读5页,还剩133页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、一亩三分地收藏-1-新概念51 单片机 C 语言教程-入门、提高、开发、拓展全攻略郭天祥编著电子工业出版社例 2.2.1 编写程序,点亮第一个发光二极管(part2_1.c#include <reg52.h> /52 系列单片机头文件sbit led1=P10;/声明单片机 P1 口的第一位void main()/主函数 led1=0;/*点亮第一个发光二极管*/例 2.2.2 编写程序,点亮 P1 口的若干二极管(part2_2.c#include <reg52.h> /52 系列单片机头文件void main()/主函数 P1=0xaa; /while(1);P27

2、 )P39 )例 2.5.1 利用 for 语句延时特性,编写第一个发光二极管以间隔 1S 亮灭闪动的程序(part2_3.cP42)#include <reg52.h>/52 系列单片机头文件#define uint unsigned int /宏定义sbit led1=P10;/声明单片机 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

3、>0;i-)/延时 for(j=110;j>0;j-); 2012-1-28一亩三分地收藏-2-例 2.6.1 编写程序使第一个发光二极管以间隔 500ms 亮灭闪动。(part2_4.c#include <reg52.h>/52 系列单片机头文件#define uint unsigned int/宏定义sbit led1=P10;/声明单片机 P1 口的第一位void delay1s();/声明子函数void main()/主函数 while(1)/大循环 led1=0;/*点亮第一个发光二极管*/ delay1s();/调用延时子函数 led1=1;/*关闭第一个发

4、光二极管*/ delay1s();/调用延时子函数 void delay1s()/子函数体 uint i,j; for(i=500;i>0;i-) for(j=110;j>0;j-);P48)例 2.7.1 编写程序使第一个二极管以亮 200ms、灭 800ms 的方式闪动。(part2_5.c#include <reg52.h>/52 系列单片机头文件#define uint unsigned int/宏定义sbit led1=P10;/声明单片机 P1 口的第一位void delayms(uint);/声明子函数void main()/主函数 while(1)/大循

5、环 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-);P49)2012-1-28一亩三分地收藏-3-例 2.8.3 利用 C51 自带库_crol_(),以间隔 500ms,实现流水灯程序(part2_6.c#include <reg52.h>/52 系列单片机头文件

6、#include <intrins.h>#define uint unsigned int/宏定义#define uchar unsigned charvoid 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 即延时约

7、 xms 毫秒 for(j=110;j>0;j-);P53)2012-1-28一亩三分地收藏-4-例 3.2.1 编写程序使第一个数码管显示 8(part2.1_.1c P59)#include <reg52.h>/52 系列单片机头文件sbit dula=P26;/申明 U1 锁存器的锁存端sbit wela=P27;/申明 U2 锁存器的锁存端void main() wela=1;/打开 U2 锁存器 P0=0xFE;/送入位选信号 wela=0;/关闭 U2 锁存器dula=1;P0=0x7F;dula=0;while(1);例 3.2.2 让实验板上 6 个数码管同时

8、点亮,依次显示 0 到 F,时间间隔为 0.5ms,循环下去。(part2.1_2.c P61)#include <reg52.h>/52 系列单片机头文件#define uchar unsigned char#define uint unsigned intsbit dula=P26;/申明 U1 锁存器的锁存端sbit wela=P27;/申明 U2 锁存器的锁存端uchar num;unchar code table=0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71;

9、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=tablenum;/送入段选信号 dula=0; /关闭 U1 锁存端 delay(500);/延时 0.5 秒 /打开 U1 锁存器/送入段选信号/关闭 U2 锁存器 /程序停止到这里2012-1-28一亩三分地收藏-5-void delayms(uint xms) uint i,j; for

10、(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)2012-1-28一亩三分地收藏-6-例 4.

11、1.1 用数码管前两位显示一个十进制数,变化范围为 0059,开始时显示 00,每按下 S2键一次,数值加 1;每按下 S3 键一次,数值减 1;每按下 S4 键一次,数值归零;按下 S5键一次,利用定时器功能使数值开始自动每秒加 1,再次按下 S5 键,数值停止加 1,保持显示原数。(part2.2_1.c P82)#include <reg52.h>/52 系列单片机头文件#define uchar unsigned char#define uint unsigned intsbit key1=P34;sbit key2=P35;sbit key3=P36;sbit key4=

12、P37;sbit dula=P26;/申明 U1 锁存器的锁存端sbit wela=P27;/申明 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=tableshi;/

13、送十位段选数据dula=0;P0=0xff;/送位选数据前关闭所有显示,防止打开位选锁存时wela=1;/原来段选数据通过位选锁存器造成混乱P0=0xfe;/送位选数据wela=0;delayms(5); /延时dula=1;P0=tablege;dula=0;P0=0xff;wela=1;P0=0xfd;wela=0;delayms(5);/送个位段选数据2012-1-28一亩三分地收藏-7-void delayms(uint xms) uint i,j; for(i=xms;i>0;i-)/i=xms 即延时约 xms 毫秒 for(j=110;j>0;j-);void ini

14、t()/初始化函数 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 时重新归

15、60 num=60; num-; while(!key2); if(key3=0) delayms(10); if(key3=0) num=0; /清 02012-1-28一亩三分地收藏-8-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=(65

16、536-45872)%256; numt0+; if(numt0=20)/如果到了 20 次,说明 1 秒时间到 numt0=0;/然后把 num 清 0 重新再计 20 次 num+; if(num=60) num=0; 例 4.2.1 实验班上电时,数码管不显示,顺序按下矩阵键盘后,数码管上依次显示 0F,六个数码管同时静态显示即可。(part2.2_2.c P87)#include <reg52.h>/52 系列单片机头文件#define uchar unsigned char#define uint unsigned intsbit dula=P26;/申明 U1 锁存器的

17、锁存端sbit wela=P27;/申明 U2 锁存器的锁存端uchar code table=2012-1-28一亩三分地收藏-9-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=tablenum; /显示函数只送段选数据 dula=1; dul

18、a=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;2012-1-28一亩三分地收藏- 10 - while

19、(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

20、) temp=P3; temp=temp&0xf0; display(key); P3=0xfb;2012-1-28一亩三分地收藏- 11 -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; wh

21、ile(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;2012-1-28一亩三分地收藏- 12 -switch(temp) case 0xe7: key=12; break; case 0xd7: key=13; break; case 0xb7: key=14; break; case 0x77: ke

22、y=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();/不停调用键盘扫描程序 2012-1-28一亩三分地收藏- 13 -例 5.3.1 用单片机控制 ADC0804 进行数模转换,当拧动实验板上 A/D 旁边的电位时,在数码管的前三位以十进制方式显示出 A/D 转换后的数字量(8 位 A/D 转换

23、后数值在 0255 变化)(part2.3_1.c P107)。#include <reg52.h>/52 系列单片机头文件#include <intrins.h>#define uchar unsigned char#define uint unsigned intsbit dula=P26;/申明 U1 锁存器的锁存端sbit wela=P27;/申明 U2 锁存器的锁存端sbit adwr=P36;/定义 AD 的 WR 端口sbit adrd=P37;/定义 AD 的 RD 端口uchar code table=0x3f,0x06,0x5b,0x4f,0x66,

24、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=tablebai;/送段选数据 dula=0; P0=0xff;/送位选数据前关闭所有显示,防止打开位选锁存时 wela=1;/原来段选数据通过位选锁存器造成混乱 P0=0x7e;/

25、送位选数据 wela=0; delayms(5);/延时dula=1;P0=tableshi;dula=0;P0=0xff;wela=1;P0=0x7d;wela=0;delayms(5);dula=1;2012-1-28一亩三分地收藏- 14 -P0=tablege;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

26、_(); 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%1

27、0; 2012-1-28一亩三分地收藏- 15 -例 5.5.1 用单片机控制 DAC0832 芯片输出电流,让发光二级管 D12 由灭均匀变到最亮,再由最亮均匀熄灭。在最亮和最暗时使用蜂鸣器分别警报一声,完成整个周期时间控制在 5S左右,循环变化。(part2.3_2.c P121)#include <reg52.h>#define uchar unsigned char#define uint unsigned intsbit dula=P26;/申明 U1 锁存器的锁存端sbit wela=P27;/申明 U2 锁存器的锁存端sbit dawr=P36;/定义 DA 的 WR

28、 端口sbit dacs=P32;/定义 DA 的 CS 端口sbit beep=P23;/定义蜂鸣器端口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; delaym

29、s(100); beep=1; delayms(50); else val-=5;2012-1-28一亩三分地收藏- 16 -P0=val;/通过 P0 口给 DA 数据口赋值if(val=0) flag=0; beep=0; delayms(100); beep=1;delayms(50);2012-1-28一亩三分地收藏- 17 -例 6.5.1 在上位机上用串口调试助手发送一个字符 X,单片机收到字符后返回给上位机 get“IX”,串口波特率设为 9600bps。(part2.4_1.c P137)#include <reg52.h>#define uchar unsigne

30、d char#define uint unsigned intunsigned 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)

31、ES=0; for(i=0;i<6;i+) SBUF=tablei; while(!TI); TI=0; SBUF=a; while(!TI); TI=0; ES=1; flag=0; void ser() interrupt 42012-1-28一亩三分地收藏- 18 -RI=0;a=SBUF;flag=1;例 6.6.1 单片机上电后等待从上位机串口发来的命令,同时在数码管的前三位以十进制方式显示 A/D 采集的数值,在未收到上位机发送来的启动 A/D 转换命令之前数码管始终显示000。当收到上位机以十六进制发送来的 01 后,向上位机发送字符串“Turn on ad!”同时间隔 1

32、s 读取一次 A/D 的值,然后把 A/D 采集回来的 8 位二进制转换成十进制表示的实际电压浮点数,并且从串口发送给上位机,形式如“The voltage is 3.398438V”,发送周期也是一秒一次,同时在数码管上也要每秒刷新现实的数值。当收到上位机以十六进制发送过来的 02后,向上位机发送字符串“Turn off ad!”,然后停止发送电压值,数码管上显示上次结束时保持的值。当收到上位机发来的其他任何数时,向上位机发送字符串“Error!”。(part2.4_2.c P140)#include <reg52.h>#include <intrins.h>#inc

33、lude <stdio.h>#define uchar unsigned char#define uint unsigned intsbit dula=P26;/申明 U1 锁存器的锁存端sbit wela=P27;/申明 U2 锁存器的锁存端sbit adwr=P36;/定义 AD 的 WR 端口sbit adrd=P37;/定义 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

34、,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;2012-1-28一亩三分地收藏- 19 -TH1=0xfd;TL1=0xfd;TR1=1;ET0=1;SM0=0;SM1

35、=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=tablebai;/送段选数据 dula=0; P0=0xff;/送位选数据前关闭所有显示,防止打开位选锁存时 wela=1;/原来段选数据通过位选锁存器造成混乱 P0=0x7e;/送位选数据 wela=0; delayms(5);/延时 dula=1; P0=tableshi; dula=0; P0=0xff; wela=

36、1; P0=0x7d; wela=0; delayms(5); dula=1; P0=tablege; dula=0; P0=0xff; wela=1; P0=0x7b; wela=0; delayms(5);uchar get_ad()2012-1-28一亩三分地收藏- 20 -uchar adval;adwr=1;_nop_();adwr=0;_nop_();adwr=1;P1=0xff;adrd=1;_nop_();adrd=0;_nop_();adval=P1;adrd=1;return adval;/启动 AD 转换/读取 P1 口之前先给其写全 1/AD 读使能/AD 数据读取vo

37、id 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(!

38、TI);/必须要加 TI=0; ES=1; if(flag_time=1)2012-1-28一亩三分地收藏- 21 -flag_time=0;ad_val=get_ad();ad_vo=(float)ad_val*5.0/256.0;ES=0;TI=1;printf("The voltage is %fVn",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

39、=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;2012-1-28一亩三分地收藏- 22 -例 7.2.1 实现 1602 液晶的第一行显示 LOVE MCU!,“I”在第二行显示 WWW.TXMCU.COM。(part2.5_1.c P152)#include<reg52.h>#define uchar unsigned char#define uint un

40、signed intuchar code table="I LOVE MCU!"uchar code table1="WWW.TXMCU.COM"sbit lcden=P34; /液晶使能端sbit lcdrs=P35; /液晶数据命令选择端sbit dula=P26;/申明 U1 锁存器的锁存端sbit wela=P27;/申明 U2 锁存器的锁存端uchar num;void delay(uint z) uint x,y; for(x=z;x>0;x-) for(y=110;y>0;y-);void write_com(uchar com

41、) lcdrs=0; P0=com; delay(5); lcden=1; delay(5); lcden=0;void write_data(uchar date) lcdrs=1; P0=date; delay(5); lcden=1; delay(5); lcden=0;void init() dula=0; wela=0; lcden=0; write_com(0x38);/设置 16X2 显示,5X7 点阵,8 位数据接口 write_com(0x0c);/设置开显示,不显示光标 write_com(0x06);/写一个字符后地址指针加 12012-1-28一亩三分地收藏- 23 -write_com(0x01);/显示清零,数据指针清零void main() init(); write_com(0x80); for(num=0;num<11;num+) write_data(tablenum); delay(5); write_com(0x80+0x40); for(num=0;num<13;num+) write_data(table1num); delay(5); while(1);例 7.2.2 实现 1602 第一行从左侧移入“Hell

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论