51单片机C语言源代码例程附带电路图.docx
《51单片机C语言源代码例程附带电路图.docx》由会员分享,可在线阅读,更多相关《51单片机C语言源代码例程附带电路图.docx(41页珍藏版)》请在冰点文库上搜索。
51单片机C语言源代码例程附带电路图
闪烁灯
[实验要求]
点亮与单片机P1.0口相连的发光二极管,延时0.2S,然后熄灭,延时0.2S,再点亮,如此循环下去。
[实验目的]
初步了解单片机IO口输出高低电平的作用,延时函数的时间估算。
[硬件电路]
[源代码]
#include
/**********************************************************
上面这行是一个"文件包含"处理。
所谓"文件包含"是指一个文件将另外一个文件的内容全部包含进来这里的程序虽然只写了一行,但C编译器在处理的时候却要处理几十或几百行,这里包含reg51.h的目的在于本程序要使用P1这个符号,而P1是在reg51.h这个头文件中定义的。
大家可以在编译器目录下面用记事本打开这个文件看看。
*********************************************************/
sbitP1_0=P1^0;//定义IO口这步的目的是让编//译器知道P1_0代表的就是单片机的P1.0口
voiddelay02s(void)//延时0.2秒子程序
{
unsignedchari,j,k;//定义3个无符号字符型变量。
for(i=20;i>0;i--)//三个FOR循环用来延时,这里为
for(j=20;j>0;j--)//什么是0.2S大家可以用WAVE
for(k=248;k>0;k--);//高断点仿真一下,就可知道大概
}//是0.2S了。
voidmain(void)//每一个C语言程序有且只有一个主函数,
{
while
(1)//循环条件永远为真,以下程序一直执行下去。
{
P1_0=0;//I/O口P1.0输出低电平,小灯被点亮。
delay02s();//延时经过0.2秒。
P1_0=1;//I/O口P1.0输出高电平,小灯熄灭。
delay02s();//延时经过0.2秒。
}
}
流水灯
[实验要求]
单片机P1口相连的8个发光二极管中的一个循环移位点亮,同时蜂鸣器发出滴滴的响声。
蜂鸣器用一PNP三极管驱动,集电极(C极)通过蜂鸣器线圈接5V电源,基极(B极)是控制端,发射极(E极)接地,当三极管C,B极PN结正偏时,PN结导通,即B极为低电平时,三极管导通,蜂鸣器响。
再不明白去看模电书。
[实验目的]
掌握循环移位的工作原理,学会使用封装好的函数库,
延时函数的时间估算。
[硬件电路]
[源代码]
//flowlightandbeep
#include
#include//后面要用到它里面的_crol_(k,l)函数
//这个函数的意思是把一个字符变量k循环左移l位,关于它的说明//请查看安装KEIL目录下的E:
\ProgramFiles\Keil\C51\HLP文件夹//里面的c51lib,这个文件里面有各种用C语言封装好的函数库,我//们在以后使用其中某些函数时可以直接使用而自己不必再写。
unsignedchara,b,k,j;//定义四个字符变量
sbitbeep=P2^3;//定义蜂鸣器的接口
voiddelay10ms()//延时字程序,大约延时10ms
{
for(a=100;a>0;a--)
for(b=225;b>0;b--);
}
voidmain()
{
k=0xfe;//先给k一个初值11111110等待移位
while
(1)
{
delay10ms();
beep=0;//打开蜂鸣器
delay10ms();//让它响10ms
beep=1;//关闭蜂鸣器
j=_crol_(k,1);//把k循环左移一位
k=j;//把移完的值再送给k
P1=j;//同时把值送到P1口点亮发光二极管
}
}
单键识别
[实验要求]
每按一次独立键盘的S2键,与P1口相连的一个发光二极管往下移动一位。
注意:
关于按键去抖动的解释,我们在手动按键的时候,由于机械抖动或是其它一些非人为的因素很有可能会造成误识别,一般手动按下一次键然后接着释放,按键两片金属膜接触的时间大约为50ms左右,如果我们再首次检测到键被按下后延时10ms左右再去检测,这时如果是干扰信号将不会被检测到,如果确实是有键被按下,则可确认。
以上为按键识别去抖动的原理。
[实验目的]
独立按键的识别。
[硬件电路]
[源代码]
#include
sbitBY1=P3^4;//定义按键的输入端S2键
unsignedcharcount;//按键计数,每按一下,count加1
unsignedchartemp;
unsignedchara,b;
voiddelay10ms(void)//延时程序
{
unsignedchari,j;
for(i=20;i>0;i--)
for(j=248;j>0;j--);
}
key()//按键判断程序
{
if(BY1==0)//判断是否按下键盘,当单片机上电时所有IO口为//高电平,S2键一端接地另一端接P3.4,所以当键被按下时P3.4口//直接接地,此时检测P3.4肯定为低电平。
{
delay10ms();//延时,软件去干扰
if(BY1==0)//确认按键按下
{
count++;//按键计数加1
if(count==8)//计8次重新计数
{
count=0;//将count清零
}
}
while(BY1==0);//等待按键释放,如果键未释放则一直在此等待。
}
}
move()//广告灯向下移动移动函数
{
a=temp<b=temp>>(8-count);//_crol_()函数
P1=a|b;
}
main()
{
count=0;//初始化参数设置
temp=0xfe;
P1=0xff;
P1=temp;
while
(1)//永远循环,扫描判断按键是否按下
{
key();//调用按键识别函数
move();//调用广告灯移动函数
}
}
利用定时器和蜂鸣器唱歌
[实验要求]
用单片机的P2.3口输出不同占空比的方波来控制与它相连的蜂鸣器,当方波的占空比不同时蜂鸣器发出的音调就不同,由此根据歌曲的音调编程实现让蜂鸣器唱歌。
占空比:
一个周期中,高电平的长度比上总周期的长度的值再乘上100%。
标准方波的占空比为50%.
[实验目的]
学会利用单片机的定时器,掌握蜂鸣器的发声操作。
[硬件电路]
[源代码]
#include"reg51.h"
unsignedcharCount;
sbit_Speak=P2^3;//蜂鸣器控制脚
unsignedcharcodeSONG[]={//祝你平安
0x26,0x20,0x20,0x20,0x20,0x20,0x26,0x10,0x20,0x10,0x20,0x80,
0x26,0x20,0x30,0x20,0x30,0x20,0x39,0x10,0x30,0x10,0x30,0x80,
0x26,0x20,0x20,0x20,0x20,0x20,0x1c,0x20,0x20,0x80,0x2b,0x20,
0x26,0x20,0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,0x80,0x26,0x20,
0x30,0x20,0x30,0x20,0x39,0x10,0x26,0x10,0x26,0x60,0x40,0x10,
0x39,0x10,0x26,0x20,0x30,0x20,0x30,0x20,0x39,0x10,0x26,0x10,
0x26,0x80,0x26,0x20,0x2b,0x10,0x2b,0x10,0x2b,0x20,0x30,0x10,
0x39,0x10,0x26,0x10,0x2b,0x10,0x2b,0x20,0x2b,0x40,0x40,0x20,
0x20,0x10,0x20,0x10,0x2b,0x10,0x26,0x30,0x30,0x80,0x18,0x20,
0x18,0x20,0x26,0x20,0x20,0x20,0x20,0x40,0x26,0x20,0x2b,0x20,
0x30,0x20,0x30,0x20,0x1c,0x20,0x20,0x20,0x20,0x80,0x1c,0x20,
0x1c,0x20,0x1c,0x20,0x30,0x20,0x30,0x60,0x39,0x10,0x30,
0x10,0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,0x10,0x26,0x10,0x26,
0x10,0x2b,0x10,0x2b,0x80,0x18,0x20,0x18,0x20,0x26,0x20,0x20,
0x20,0x20,0x60,0x26,0x10,0x2b,0x20,0x30,0x20,0x30,0x20,0x1c,
0x20,0x20,0x20,0x20,0x80,0x26,0x20,0x30,0x10,0x30,0x10,0x30,
0x20,0x39,0x20,0x26,0x10,0x2b,0x10,0x2b,0x20,0x2b,0x40,0x40,
0x10,0x40,0x10,0x20,0x10,
0x20,0x10,0x2b,0x10,0x26,0x30,0x30,0x80,0x00,
//路边的野华不要采
0x30,0x1C,0x10,0x20,0x40,0x1C,0x10,0x18,0x10,0x20,0x10,0x1C,
0x10,0x18,0x40,0x1C,0x20,0x20,0x20,0x1C,0x20,0x18,0x20,0x20,
0x80,0xFF,0x20,0x30,0x1C,0x10,0x18,0x20,0x15,0x20,0x1C,0x20,
0x20,0x20,0x26,0x40,0x20,0x20,0x2B,0x20,0x26,0x20,0x20,0x20,
0x30,0x80,0xFF,0x20,0x20,0x1C,0x10,0x18,0x10,0x20,0x20,0x26,
0x20,0x2B,0x20,0x30,
0x20,0x2B,0x40,0x20,0x20,0x1C,0x10,0x18,0x10,0x20,0x20,0x26,
0x20,0x2B,0x20,0x30,0x20,0x2B,0x40,0x20,0x30,0x1C,0x10,0x18,
0x20,0x15,0x20,0x1C,0x20,0x20,0x20,0x26,0x40,0x20,0x20,0x2B,
0x20,0x26,0x20,0x20,0x20,0x30,0x80,0x20,0x30,0x1C,0x10,0x20,
0x10,0x1C,0x10,0x20,0x20,0x26,0x20,0x2B,0x20,0x30,0x20,0x2B,
0x40,0x20,0x15,0x1F,
0x05,0x20,0x10,0x1C,0x10,0x20,0x20,0x26,0x20,0x2B,0x20,0x30,
0x20,0x2B,0x40,0x20,0x30,0x1C,0x10,0x18,0x20,0x15,0x20,0x1C,
0x20,0x20,0x20,0x26,0x40,0x20,0x20,0x2B,0x20,0x26,0x20,0x20,
0x20,0x30,0x30,0x20,0x30,0x1C,0x10,0x18,0x40,0x1C,0x20,0x20,
0x20,0x26,0x40,0x13,0x60,0x18,0x20,0x15,0x40,0x13,0x40,0x18,
0x80,0x00,
};
voidTime0_Init()//定时器0初始化函数
{
TMOD=0x01;//工作模式选择
IE=0x82;//中断设置
TH0=0xD8;//装初值
TL0=0xEF;//12MZ晶振,10ms
}
voidTime0_Int()interrupt1//定时器0中断子函数
{
TH0=0xD8;
TL0=0xEF;
Count++;//长度加1
}
/*-------------------------------------------------
功能:
1MS延时子程序
-------------------------------------------------*/
voidDelay_xMs(unsignedintx)
{
unsignedinti,j;
for(i=0;i{
for(j=0;j<3;j++);
}
}
/*-------------------------------------------------
功能:
歌曲播放子程序i为播放哪一段曲目
-------------------------------------------------*/
voidPlay_Song(unsignedchari)
{
unsignedcharTemp1,Temp2;
unsignedintAddr;
Count=0;//中断计数器清0
Addr=i*217;
while
(1)
{
Temp1=SONG[Addr++];
if(Temp1==0xFF)//休止符
{
TR0=0;
Delay_xMs(100);
}
elseif(Temp1==0x00)//歌曲结束符
{
return;
}
else
{
Temp2=SONG[Addr++];
TR0=1;
while
(1)
{
_Speak=~_Speak;
Delay_xMs(Temp1);
if(Temp2==Count)
{
Count=0;
break;
}
}
}
}
}
/*-------------------------------------------------
功能:
主程序
-------------------------------------------------*/
voidmain()
{
Time0_Init();//定时器0中断初始化
while
(1)
{
Play_Song(0);//播放
}
}
DS18B20温度测量显示实验
[实验要求]
用单片机控制实验板上的DS18B20数字温度传感器,读取当前环境温度,精度达0.1度,温度范围0-99度,并用数码管的前三位显示出来。
同时实验板上的单片机还能把温度值通过串口线发送到计算机,在计算机上安装该目录下的.exe文件后,打开应用程序可看到温度值。
注意:
DS18B20数字温度传感器是DALLAS公司生产的1-Wire,即单总线器件,具有线路简单,体积小的特点。
因此用它来组成一个测温系统,具有线路简单,在一根通信线,可以挂很多这样的数字温度计。
DS18B20产品的特点
(1)、只要求一个I/O口即可实现通信。
(2)、在DS18B20中的每个器件上都有独一无二的序列号。
(3)、实际应用中不需要外部任何元器件即可实现测温。
(4)、测量温度范围在
-55到+125摄氏度之间。
(5)、数字温度计的分辨率用户可以从9位到12位选择。
(6)、内部有温度上、下限告警设置。
DS18B20详细引脚功能描述1、GND地信号;2、DQ数据输入出引脚。
开漏单总线接口引脚。
当被用在寄生电源下,也可以向器件提供电源;3、VDD可选择的VDD引脚。
当工作于寄生电源时,此引脚必须接地。
DS18B20的使用方法。
由于DS18B20采用的是1-Wire总线协议方式,即在一根数据线实现数据的双向传输,而对AT89S52单片机来说,我们必须采用软件的方法来模拟单总线的协议时序来完成对DS18B20芯片的访问。
由于DS18B20是在一根I/O线上读写数据,因此,对读写的数据位有着严格的时序要求。
DS18B20有严格的通信协议来保证各位数据传输的正确性和完整性。
该协议定义了几种信号的时序:
初始化时序、读时序、写时序。
所有时序都是将主机作为主设备,单总线器件作为从设备。
而每一次命令和数据的传输都是从主机主动启动写时序开始,如果要求单总线器件回送数据,在进行写命令后,主机需启动读时序完成数据接收。
数据和命令的传输都是低位在先。
[实验目的]
学习单总线器件的读写方法,数值合成,数字类型变化等。
[硬件电路]
[源代码]
//安装目录下的EXE文件,通过串口线连接计算机与实验板,打开
//软件后可在软件界面上显示当前温度值。
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitDS=P2^2;//defineinterface定义DS18B20接口
uinttemp;//variableoftemperature
ucharflag1;//signoftheresultpositiveornegative
sbitdula=P2^6;
sbitwela=P2^7;
unsignedcharcodetable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//不带小数点编码。
unsignedcharcodetable1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,
0x87,0xff,0xef};//带小数点编码。
voiddelay(uintcount)//delay
{
uinti;
while(count)
{
i=200;
while(i>0)
i--;
count--;
}
}
///////功能:
串口初始化,波特率9600,方式1///////
voidInit_Com(void)
{
TMOD=0x20;
PCON=0x00;
SCON=0x50;
TH1=0xFd;
TL1=0xFd;
TR1=1;
}
voiddsreset(void)//sendresetandinitializationcommand
{
uinti;//DS18B20初始化
DS=0;
i=103;
while(i>0)i--;
DS=1;
i=4;
while(i>0)i--;
}
bittmpreadbit(void)//readabit读一位
{
uinti;
bitdat;
DS=0;i++;//i++fordelay小延时一下
DS=1;i++;i++;
dat=DS;
i=8;while(i>0)i--;
return(dat);
}
uchartmpread(void)//readabytedate读一个字节
{
uchari,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=tmpreadbit();
dat=(j<<7)|(dat>>1);//读出的数据最低位在最前面,这样刚好//一个字节在DAT里
}
return(dat);//将一个字节数据返回
}
voidtmpwritebyte(uchardat)//writeabytetods18b20
{//写一个字节到DS18B20里
uinti;
ucharj;
bittestb;
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb)//write1写1部分
{
DS=0;
i++;i++;
DS=1;
i=8;while(i>0)i--;
}
else
{
DS=0;//write0写0部分
i=8;while(i>0)i--;
DS=1;
i++;i++;
}
}
}
voidtmpchange(void)//DS18B20beginchange发送温度转换命令
{
dsreset();//初始化DS18B20
delay
(1);//延时
tmpwritebyte(0xcc);//跳过序列号命令
tmpwritebyte(0x44);//发送温度转换命令
}
uinttmp()//getthetemperature获得温度
{
floattt;
uchara,b;
dsreset();
delay
(1);
tmpwritebyte(0xcc);
tmpwritebyte(0xbe);//发送读取数据命令
a=tmpread();//连续读两个字节数据
b=tmpread();
temp=b;
temp<<=8;//twobytecomposeaintvariable
temp=temp|a;//两字节合成一个整型变量。
tt=temp*0.0625;//得到真实十进制温度值,因为DS18B20
//可以精确到0.0625度,所以读回数据的最低位代表的是
//0.0625度。
temp=tt*10+0.5;//放大十倍,这样做的目的将小数点后第一位
//也转换为可显示数字,同时进行一个四舍五入操作。
returntemp;//返回温度值
}
voidreadrom()//readtheserial读取温度传感器的序列号
{//本程序中没有用到此函数
ucharsn1,sn2;
dsreset();
delay
(1);
tmpwritebyte(0x33);
sn1=tmpread();
sn2=tmpread();
}
voiddelay10ms()//delay
{
uchara,b;
for(a=10;a>0;a--)
for(b=60;b>0;b--);
}
voiddisplay(uinttemp)//显示程序
{
ucharA1,A2