单片机实验板使用手册
目录
目录....................................................................................................................2
1.准备工作....................................................................................................3
2学习方法介绍...........................................................................................3
3.实验例程详细解答................................................................................3
3.1闪烁灯.............................................................................................4
3.2流水灯..................................................................................................6
3.3单键识别..........................................................................................8
3.4 59秒计数器.................................................................................10
3.5矩阵键盘检测............................................................................13
3.6利用定时器和蜂鸣器唱歌.............................................................19
3.7 模数转换ADC0804的应用…………………………..………20
3.8 数模转换DAC0832的应用……………………………………….23
3.9 DS18B20温度测量显示实验...........................................................24
3.10 1602字符液晶显示...................................................................................29
3.11 EEPROM AT24C02实验.........................................................................32
3.12 串口通讯实验............................................................................................36
联系方式...................................................................................................................38
4. WAVE使用说明...............................................................................................39
5. KEIL的使用.....................................................................................................43
6. STC-ISP软件的使用.......................................................................................50
1.准备工作
拿到实验板后首先需要做的几件事
当用户拿到实验板后的第一件事是先看实验板供电是否正常、下载程序功能是否正常、各芯片功能是否都能成功实现,检测方法如下所示:
1. 将包装中的USB线两端分别插接实验板左侧的USB供电接口和电脑USB口,打开实验板上电源,这时会看到实验板的电源指示灯会亮,紧接着会看到实验板上数码管或是流水灯都有随机的亮灭现象出现,也有可能只看到电源指示灯亮而无其它现象,这是因为我们在发货前要对产品进行综合测试,单片机内部装有测试时的程序,用户不必奇怪,以上状态说明实验板供电系统正常。
2. 安装STC单片机程序下载软件,下载光盘中写好的例程测试各功能是否正常,安装过程及下载方法在视频中都有详细介绍,关于STC单片机程序下载软件的STC-ISP安装,请查看本手册后面的说明或同光盘中的文档。
3. 安装单片机编程软件KEIL或是WAVE,这两个软件在产品配套光盘里的软件目录下都有,用户可自由选择使用任何一种软件,这两种软件都支持单片机的C语言或是汇编语言编译,我们推荐用户使用KEIL,在OK100E配套的单片机视频教学光盘中全部使用的是KEIL软件讲解,在视频教学的第1讲中有详细的KEIL软件建立工程及编译源代码的介绍,请大家自行查看。我们在手册中也做了详细的介绍,请大家查看本手册后面的说明。
2学习方法介绍
接下来最重要的工作便是跟着配套教学光盘一讲一讲的跟着老师做,把老师每讲的内容都及时的消化,遇到不懂的问题要及时查书,一个个搞明白,不要积累任何小问题,大部分用户都是从零开始学起,讲座中的内容也是从最简单的开始,一步步深入,只要大家愿意学、有信心、有毅力、相信大家跟着教学讲座走10天,之后必将会有非常大的收获。如果用户没有购买配套视频光盘,我们会赠送前三讲的内容,这三讲中非常详细的介绍了KEIL软件的使用方法,讲了流水灯设计流程,实验板上其余的功能就需要靠用户自来对它进行编程并实现它们了,这样学起来只是时间会稍长些,感觉会累点,但只要大家肯努力,终究也一定会学会的。
3.实验例程详细解答
注意:在我要讲具体实验之前这里有必要先介绍一下本实验板上用到的一些元件的操作方法,对于一个电子制作者或是电子爱好者来说学会怎么样搜索自己需要元件的资料是非常重要的,现在市场上各种各样的芯片非常的多,能实现同一个功能的芯片也有很多种,世界各大芯片制造公司都有生产。所以我们不可能把芯片的功能、名称及详细使用方法都记全,也没有这个必要,但是必须要知道在你需要实现某个功能的时候怎么样才能找到合适的芯片,下面先给大家推荐两个搜索网站:
www.baidu.com www.google.com
以上两个网站是中国最大的搜索网站和世界最大的搜索网站,上面几乎可以搜到你需要的任何信息,大家一定要充分利用身边可利用的资源,问别人是最没有办法的办法,当自己在经过多重努力后仍然没有得到最佳答案,这时再去问别人。
另外需要提醒大家一点,大部分芯片的资料全是英文,大家学了这么多年英文,现在正是你用它的时候了,对于电子爱好者来说,看芯片的英文介绍就应该达到看汉语一样的水平,建议大家以后装软件全装英文版的,看电影全看国外原声的,最好连自己电脑的操作系统也装英文版的,从点点滴滴中增长知识。
再给大家介绍两个查芯片资料的网站:
www.21ic.com 这里的芯片资料比较全,如果没有找到你要的资料,那可参考www.alldatasheet.com ,这里有全世界所有的芯片资料,并且每天都在更新。
锁存器(74HC573):顾名思义,就是把输入端的数据锁存(或送)到输出端,请看下图中的U3元件,第11角(锁存端)为高电平的时候,右边D0-D7的输入与左边Q0-Q7的输出是直通的,就是说,输入端是什么电平,输出端就是什么电平,可以把它当作不存在。当第11角为低电平的时候,左右两端就被断开了,无论输入端怎么变化,输出端都不会变化,当第11角由低电平变为高电平的一瞬间,输入端的数据立刻被传送到输出端,并且在11角保持为高电平期间,输出端数据始终的输入端数据相同,如果此时我们再次把第11角设置为低电平,那么以后当输入端无论再怎么变化,输出端都不会变化而是保持刚才第11角在下降沿(由高电平到低电平跳变)之间时输入端的值,这样就达到了锁存数据的目的,这也就是所谓的总线设计思路,一个8位的数据线加一个锁存器后就可以扩接多个元件,当选通哪个元件的片选信号,就送数据给那个元件。先说这个元件,以后用到别的元件我们再解释。下面开始讲解例程。
3.1闪烁灯
[实验要求]
点亮与单片机P1.0口相连的发光二极管,延时约0.2S,然后熄灭,再延时约0.2S,再点亮,如此循环下去。
[实验目的]
初步了解单片机IO口输出高低电平的方法,延时函数的时间估算。
关于延时函数的时间估算问题在视频第二讲有详细演示介绍。
[硬件电路]
[源代码]
#include<reg51.h>
/**********************************************************
上面这行是一个"文件包含"处理。所谓"文件包含"是指一个文件将另外一个文件的内容全部包含进来这里的程序虽然只写了一行,但C编译器在处理的时候却要处理几十或几百行,这里包含reg51.h的目的在于本程序要使用P1这个符号,而P1是在reg51.h这个头文件中定义的。大家可以在编译器目录下面用记事本打开这个文件看看。
*********************************************************/
sbit P1_0=P1^0; //定义IO口这步的目的是让编//译器知//道P1_0代表的就是单片机的P1.0口
void delay02s(void) //延时0.2秒子程序
{
unsigned char i,j,k; //定义3个无符号字符型变量。
for(i=20;i>0;i--) //三个FOR循环用来延时,这里为
for(j=20;j>0;j--) //什么是0.2S大家可以用WAVE或KEIL
for(k=248;k>0;k--); //设置断点仿真,就可知道大概
} //是0.2S了。
void main(void) //每一个C语言程序有且只有一个主函数,
{
while(1) //循环条件永远为真,以下程序一直执行下去。
{
P1_0=0; // I/O口P1.0输出低电平,小灯被点亮。
delay02s(); //延时经过0.2秒。
P1_0=1; // I/O口P1.0输出高电平,小灯熄灭。
delay02s(); //延时经过0.2秒。
}
}
3.2流水灯
[实验要求]
单片机P1口相连的8个发光二极管中的一个循环移位点亮,同时蜂鸣器发出滴滴的响声。
蜂鸣器用一PNP三极管驱动,集电极(C极)通过蜂鸣器线圈接5V电源,基极(B极)是控制端,发射极(E极)接地,当三极管C,B极PN结正偏时,PN结导通,即B极为低电平时,三极管导通,蜂鸣器发声,视频中有介绍,若大家有疑问可参考模电书。
[实验目的]
掌握循环移位的工作原理和操作方法,学会使用C51封装好的函数库C51LIB,延时函数的时间估算。
[硬件电路]
[源代码]
#include <reg51.h>
#include <intrins.h> //后面要用到它里面的_crol_(k,l)函数
这个函数的意思是把一个字符变量k循环左移l位,关于它的说明请查看安装KEIL目录下的\Keil\C51\HLP文件夹里面的c51lib,这个文件里面有各种用C语言封装好的函数库,我们在以后使用其中某些函数时可以直接使用而自己不必再写。
unsigned char a,b,k,j; //定义四个字符变量
sbit beep=P2^3; // 定义蜂鸣器的接口
void delay10ms() //延时子程序,大约延时10ms
{
for(a=100;a>0;a--)
for(b=225;b>0;b--);
}
void main()
{
k=0xfe; //先给k一个初值11111110等待移位
while(1)
{
delay10ms();
beep=0; //打开蜂鸣器
delay10ms(); //让它响10ms
beep=1; //关闭蜂鸣器
j=_crol_(k,1); //把k循环左移一位
k=j; //把移完的值再送给k
P1=j; //同时把值送到P1口点亮发光二极管
} //再次循环
}
3.3单键识别
[实验要求]
每按一次独立键盘的S2键,与P1口相连的八个发光二极管中点亮的一个往下移动一位。
注意:关于按键去抖动的解释,我们在手动按键的时候,由于机械抖动或是其它一些非人为的因素很有可能会造成误识别,一般手动按下一次键然后接着释放,按键两片金属膜接触的时间大约为50ms左右,在按下瞬间到稳定的时间为5-10ms,在松开的瞬间到稳定的时间也为5-10ms,如果我们再首次检测到键被按下后延时10ms左右再去检测,这时如果是干扰信号将不会被检测到,如果确实是有键被按下,则可确认,以上为按键识别去抖动的原理。
[实验目的]
独立按键的识别方法、键盘消抖等。
[硬件电路]
[源代码]
#include <reg52.h>
sbit BY1=P3^4; //定义按键的输入端S2键
unsigned char count; //按键计数,每按一下,count加1
unsigned char temp;
unsigned char a,b;
void delay10ms(void) //延时程序
{
unsigned char i,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<<count; // 这三句为一个循环移位,相当于前面提到的
b=temp>>(8-count);// _crol_()函数,这里是自己写的过程,大家可对比
P1=a|b; //下。
}
main()
{
count=0; //初始化参数设置
temp=0xfe;
P1=0xff;
P1=temp;
while(1) //永远循环,扫描判断按键是否按下
{
key(); //调用按键识别函数
move(); //调用广告灯移动函数
}
}
3.4 59秒计数器
[实验要求]
使用软件延时的方法实现0-59秒自动计数器,用数码管的前两位显示出来。
[实验目的]
练习进位操作,数码管动态显示。
[硬件电路]
[源代码]
//59秒自动计数器
#include<reg51.h>
#define uchar unsigned char
uchar j,k,i,a,A1,A2,second;
sbit dula=P2^6; //锁存器控制端定义
sbit wela=P2^7;
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//数字编码
void delay(uchar i) //延时函数
{
for(j=i;j>0;j--)
for(k=125;k>0;k--);
}
void display(uchar sh_c,uchar g_c) //显示函数
{
dula=0;
P0=table[sh_c]; //显示十位
dula=1;
dula=0;
wela=0;
P0=0xfe;
wela=1;
wela=0;
delay(5); //亮5ms
P0=table[g_c]; //显示个位
dula=1;
dula=0;
P0=0xfd;
wela=1;
wela=0;
delay(5); //亮5ms
}
void main() //主函数
{
while(1)
{
second++; //秒加一
if(second==60) //判断是否到60
second=0; //如果到了则清零
A1=second/10; //没到则分离出十位和个位
A2=second%10;
for(a=50;a>0;a--) //显示部分。至于时间大概是多少
{ //请用户用软件仿真看时间约等于1秒
display(A1,A2);};//便可,如果需要精确定时请用定时器
}
}
3.5矩阵键盘检测
[实验要求]
依次按下4*4矩阵键盘上从第1到第20个键,同时在六位数码管上依次显示0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F。
说明:本实验板上数码管为共阴极。
静态数码管显示原理(视频中有详细介绍):这里就共阴极数码管显示原理进行讲解,一位数码管内一共有8个发光二极管,对共阴极来说其8个发光二极管的阴极在数码管内部全部接在一起,也就是"共阴"说法的来源,阳极是独立的,设计电路时一般把阴极接地,当我们从外部给任一个阳极加一个高电平时这个发光二极管就亮了,如果想要出一个8字,并且把右下角的小数点也点亮的话,那可以给8个阳极全总送高电平,想出几就给相对应的发光二极管送高电平,因此我们在显示数字的时候首先做的就是给0-9十个数字编好码,在要它亮什么数字的时候直接把这个编码送到它的阳极就行了。另外说一下,一般的数码管每一段亮至少需要10个毫安的电流,而单片机的IO口送不出如此大的电流,所以我们需要加数码管的驱动电路,可以用上拉电阻的方法,也可以使用专门的驱动芯片,本实验板使用的74HC573,其输出电流较大,足够点亮数码管。
本实验板上的六位数码管中每个的相同段号(段指a,b,c,d,e,f,g,h)全部是接在一起的,其中每一个位(阴极)是独立的,所以在做静态显示的时候所有的数码管只能显示相同的数字,当然可以控制显示几位,如果让它们显示不同的数字那就得给每一个数码管加一套驱动电路了。但这样做是没有必要的,后面我们会讲到关于数码管动态显示原理。
下面给出本实验板共阴极数码管数字编码
矩阵键盘的四行分别与P3.0-P3.3连接,四列分别与P3.4-P3.7连接。
[实验目的]
学会矩阵键盘的检测,掌握数码管静态显示原理。
[硬件电路]
键盘电路见3.3
[源代码]
//4*4键盘检测程序,按下键后相应的代码显示在数码管上
#include<reg51.h>
sbit beep=P2^3; //蜂鸣器接口
sbit dula=P2^6; //控制数码管段选的锁存器锁存端
sbit wela=P2^7; //控制数码管位选的锁存器锁存端
unsigned char i=100;
unsigned char j,k,temp,key;
void delay(unsigned char i) //可自定义延时长短的延时函数
{ //当i=10时大约为10毫秒
for(j=i;j>0;j--)
for(k=125;k>0;k--);
}
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d, 0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; // 0-F编码
display(unsigned char num) // 显示子函数
{
P0=table[num]; //将第num个显示编码送P0口
dula=1; //一个下降沿将数据锁存
dula=0;
P0=0xc0; //位选通全部的数码管
wela=1; //一个下降沿将数据锁存
wela=0;
}
void main()
{
dula=0; //先关闭两个锁存器
wela=0;
while(1) //进入检测总循环
{
P3=0xfe; //给P3.0送低电平,其余为高电平
temp=P3; //把P3口数据读回来
temp=temp&0xf0; //把P3口与11110000相与
if(temp!=0xf0) //如果有键按下刚一定不相等,于是进入//下一步检测
{
delay(10); //延时去抖动
if(temp!=0xf0) //再次判断是否有键按下
{
temp=P3; //判断为有,再次读P3口数据
switch(temp) //因为我们刚才是将第一行置的低
{ //在这里再判断是第几列
case 0xee: //如果temp=0xee则为第一行和第一列
key=0; //的交叉点,由此我们知道是矩阵键盘
break; //上的第一个键被按下,我们给key=0。
case 0xde: //以后依此类推
key=1;
break;
case 0xbe:
key=2;
break;
case 0x7e:
key=3;
break;
}
while(temp!=0xf0) //这段程序是检测按键是否被释放
{
temp=P3; //如果没有释放就一直等待并且
temp=temp&0xf0;
beep=0; //蜂鸣器一直响
}
beep=1; //释放后关闭蜂鸣器
display(key); //显示按下相应键值的数据
P1=0xfe; //将第一个发光二极管点亮(我写
} //程序的时候测试用的)
}
P3=0xfd;
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(10);
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;
beep=0;
}
beep=1;
display(key);
P1=0xfc;
}
}
P3=0xfb;
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(10);
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;
beep=0;
}
beep=1;
display(key);
P1=0xf8;
}
}
P3=0xf7;
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(10);
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;
beep=0;
}
beep=1;
display(key);
P1=0xf0;
}
}
}
}
3.6利用定时器和蜂鸣器唱歌
[实验要求]
用单片机的P2.3口输出不同占空比的方波来控制与它相连的蜂鸣器,当方波的占空比不同时蜂鸣器发出的音调就不同,由此根据歌曲的音调编程实现让蜂鸣器唱歌。
占空比:一个周期中,高电平的长度比上总周期的长度的值再乘上100%。标准方波的占空比为50%.
[实验目的]
学会利用单片机的定时器,掌握蜂鸣器的发声操作。
[硬件电路]
[源代码]
#include "reg51.h"
unsigned char Count;
sbit _Speak =P2^3 ; //蜂鸣器控制脚
unsigned char code SONG[] ={ //祝你平安,以下为编码
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,
};
void Time0_Init() //定时器0初始化函数
{
TMOD = 0x01; //工作模式选择
IE = 0x82; //中断设置
TH0 = 0xD8; //装初值
TL0 = 0xEF; //12MZ晶振,10ms
}
void Time0_Int() interrupt 1 //定时器0中断子函数
{
TH0 = 0xD8;
TL0 = 0xEF;
Count++; //长度加1
}
/*-------------------------------------------------
1MS延时子程序
-------------------------------------------------*/
void Delay_xMs(unsigned int x)
{
unsigned int i,j;
for( i =0;i < x;i++ )
{
for( j =0;j<3;j++ );
}
}
/*-------------------------------------------------
功能:歌曲播放子程序i为播放哪一段曲目
-------------------------------------------------*/
void Play_Song(unsigned char i)
{
unsigned char Temp1,Temp2;
unsigned int Addr;
Count = 0; //中断计数器清0
Addr = i * 217;
while(1)
{
Temp1 = SONG[Addr++];
if ( Temp1 == 0xFF ) //休止符
{
TR0 = 0;
Delay_xMs(100);
}
else if ( Temp1 == 0x00 ) //歌曲结束符
{
return;
}
else
{
Temp2 = SONG[Addr++];
TR0 = 1;
while(1)
{
_Speak = ~_Speak;
Delay_xMs(Temp1);
if ( Temp2 == Count )
{
Count = 0;
break;
}
}
}
}
}
/*-------------------------------------------------
功能:主程序
-------------------------------------------------*/
void main()
{
Time0_Init(); //定时器0中断初始化
while(1)
{
Play_Song(0); //播放
}
}
3.7模数转换ADC0804的应用
[实验要求]
从ADC0804 的模拟量通道输入0-5V 之间的模拟电压,通过ADC0804 转换成数字量送给单片机,经单片机处理后在数码管上以十进制形成显示出来。
[实验目的]
学习如果用单片机控制ADC0804芯片进行数模转换,掌握数码管动态扫描显示的原理。
动态扫描:就六位数码管显示123456举例说明如下:先让第一个数码管显示1,其余的全部不亮,1大约亮几毫秒,然后熄灭,紧接着立即让第二个数码管显示2,其余的全部不亮,2同样亮几毫秒,依次这样亮到第六个数码管,然后再回来显示1,如此这样以很快的速度不断循环下去,由于人眼的视觉暂留时间大约为20毫秒左右,所以是感觉不出有不亮的数码管存在的,看见的是六个数码管同时在显示,数值是123456,如果我们把这个过程一点点放慢,看见的是从第一个数码管显1,然后移到第二个再显2,。。。也就是说在任一时刻只有一位数码管是亮的。这就是数码管动态扫描显示的原理。
ADC0804: ADC0804是8位全MOS中速A/D 转换器、它是逐次逼近式A/D 转换器,片内有三态数据输出锁存器,可以和单片机直接接口。单通道输入,转换时间大约为100us。ADC0804 转换时序是:当CS=0 许可进行A/D 转换。WR由低到高时,A/D开始转换。CS与WR同时有效时启动A/D转换,转换结束产生INTR 信号(低电平有效),可供查询或者中断信号。在CS和RD 的控制下可以读取数据结果。本实验没有使用INTR信号。
[硬件电路]
[源代码]
//拧动AD旁边的电位器,会在数码管的前三位显示0-255之间的数值。这就是把模拟信号转换成数字信号,即模数转换。说明:由于不同AD的自身特性不同,所以时序如果掌握不好的话,很有可能在数码管上不会动态显示变化数值,但按下实验板上复位键后可更新内容。
#include<reg51.h>
#include <intrins.h>
#define uint unsigned int //宏定义,详情请看C语言书。
#define uchar unsigned char
sbit adrd=P3^7; //AD读引角
sbit adwr=P3^6; //AD写引角
sbit diola=P2^5;
sbit dula=P2^6; //数码管段选锁存
sbit wela=P2^7; //数码管位选锁存
unsigned char j,k,adval;
void delay(unsigned char i) //延时程序
{
for(j=i;j>0;j--)
for(k=125;k>0;k--);
}
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, 0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//数码管编码
void display(uchar bai_c,uchar sh_c,uchar g_c) //显示程序
{
dula=0;
P0=table[bai_c]; //显示百位
dula=1;
dula=0;
wela=0;
P0=0x7e;
wela=1;
wela=0;
delay(5);
dula=0;
P0=table[sh_c]; //显示十位
dula=1;
dula=0;
wela=0;
P0=0x7d;
wela=1;
wela=0;
delay(5);
P0=table[g_c]; //显示个位
dula=1;
dula=0;
P0=0x7b;
wela=1;
wela=0;
delay(5);
}
void main() 主程序
{
uchar a,A1,A2,A2t,A3;
diola=0;
while(1) //主循环程序不断的采样、显示
{
adwr=0; //AD写入(随便写个什么都行,主要是为了启动//AD转换)
_nop_(); //一个延时字函数
adwr=1;
adrd=0;
adval=P1; //AD数据读取
adrd=1;
delay(10);
A1=adval/100; //分出百,十,和个位
A2t=adval%100;
A2=A2t/10;
A3=A2t%10;
for(a=10;a>0;a--) // 显示十次,然后去采集一次电压信号
{
display(A1,A2,A3);} //送去显示各位。
};
}
3.8 数模转换DAC0832的应用
[实验要求]
通过用单片机控制DAC0832输出锯齿波,让实验板上发光二极管D12由暗到亮变化,循环下去。
[实验目的]
学会用单片机控制数模转换芯片DAC0832。
DAC0832:DAC0832是8位全MOS中速D/A 转换器,采用R—2RT 形电阻解码网络,
换结果为一对差动电流输出,转换时间大约为1us。使用单电源+5V―+15V 供电。参考电压为-10V-+10V。在此我们直接选择+5V 作为参考电压。DAC0832 有三种工作方式:直通方式,单缓冲方式,双缓冲方式;在此我们选择直通的工作方式,将XFER、WR2、CS 管脚全部接数字地。管脚8 接参考电压,在此我们接的参考电压是+5V。我们在控制P0口输出数据有规律的变化将可以产生三角波,锯齿波,梯型波等波形了。
[硬件电路]
[源代码]
//TX-1BDA测试程序,下载后可观察到D12发光二极管由暗变亮再熄//灭过程,
#include<reg51.h>
sbit wela=P2^7; //数码管位选
sbit dula=P2^6; //段选
sbit dawr=P3^6; //DA写数据
sbit csda=P3^2; //DA片选
unsigned char a,j,k;
void delay(unsigned char i) //延时
{
for(j=i;j>0;j--)
for(k=125;k>0;k--);
}
void main()
{
wela=0;
dula=0;
csda=0;
a=0;
dawr=0;
while(1)
{
P0=a; //给a不断的加一,然后送给DA
delay(50); // 延时50ms 左右,再加一,再送DA。
a++;
}
}
注意:随着给DA送的数字量的不断增加,其转换成模拟量的电流也不断的增大,所以我们观察发光二极管D12就会从暗变亮,熄灭。。。
3.9 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 <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit DS=P2^2; //define interface 定义DS18B20接口
uint temp; // variable of temperature
uchar flag1; // sign of the result positive or negative
sbit dula=P2^6;
sbit wela=P2^7;
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, 0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//不带小数点编码。
unsigned char code table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,
0x87,0xff,0xef}; // 带小数点编码。
void delay(uint count) //延时子函数
{
uint i;
while(count)
{
i=200;
while(i>0)
i--;
count--;
}
}
///功能:串口初始化,波特率9600,方式1///
void Init_Com(void)
{
TMOD = 0x20;
PCON = 0x00;
SCON = 0x50;
TH1 = 0xFd;
TL1 = 0xFd;
TR1 = 1;
}
void dsreset(void) //发送初始化及复位信号
{
uint i; //DS18B20初始化
DS=0;
i=103;
while(i>0)i--;
DS=1;
i=4;
while(i>0)i--;
}
bit tmpreadbit(void) //read a bit 读一位
{
uint i;
bit dat;
DS=0;i++; //i++ for delay 小延时一下
DS=1;i++;i++;
dat=DS;
i=8;while(i>0)i--;
return (dat);
}
uchar tmpread(void) //read a byte date 读一个字节
{
uchar i,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=tmpreadbit();
dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好//一个字节在DAT里
}
return(dat); //将一个字节数据返回
}
void tmpwritebyte(uchar dat) //write a byte to ds18b20
{ //写一个字节到DS18B20里
uint i;
uchar j;
bit testb;
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb) //write 1 写1部分
{
DS=0;
i++;i++;
DS=1;
i=8;while(i>0)i--;
}
else
{
DS=0; //write 0 写0部分
i=8;while(i>0)i--;
DS=1;
i++;i++;
}
}
}
void tmpchange(void) //DS18B20 begin change 发送温度转换命令
{
dsreset(); //初始化DS18B20
delay(1); //延时
tmpwritebyte(0xcc); // 跳过序列号命令
tmpwritebyte(0x44); //发送温度转换命令
}
uint tmp() //get the temperature 获得温度
{
float tt;
uchar a,b;
dsreset();
delay(1);
tmpwritebyte(0xcc);
tmpwritebyte(0xbe); //发送读取数据命令
a=tmpread(); //连续读两个字节数据
b=tmpread();
temp=b;
temp<<=8; //two byte compose a int variable
temp=temp|a; //两字节合成一个整型变量。
tt=temp*0.0625; //得到真实十进制温度值,因为DS18B20
//可以精确到0.0625度,所以读回数据的最低位代表的是
//0.0625度。
temp=tt*10+0.5; //放大十倍,这样做的目的将小数点后第一位
//也转换为可显示数字,同时进行一个四舍五入操作。
return temp; //返回温度值
}
void readrom() //read the serial 读取温度传感器的序列号
{ //本程序中没有用到此函数
uchar sn1,sn2;
dsreset();
delay(1);
tmpwritebyte(0x33);
sn1=tmpread();
sn2=tmpread();
}
void delay10ms() //delay
{
uchar a,b;
for(a=10;a>0;a--)
for(b=60;b>0;b--);
}
void display(uint temp) //显示程序
{
uchar A1,A2,A2t,A3,ser;
ser=temp/10; //分离出三位要显示的数字
SBUF=ser;
A1=temp/100;
A2t=temp%100;
A2=A2t/10;
A3=A2t%10;
dula=0;
P0=table[A1]; //显示百位
dula=1;
dula=0;
wela=0;
P0=0x7e;
wela=1;
wela=0;
delay(1);
dula=0;
P0=table1[A2]; //显示十位 带小数点的
dula=1;
dula=0;
wela=0;
P0=0x7d;
wela=1;
wela=0;
delay(1);
P0=table[A3]; //显示个位
dula=1;
dula=0;
P0=0x7b;
wela=1;
wela=0;
delay(1);
}
void main() //主函数
{
uchar a;
Init_Com(); //初始化串口
do
{
tmpchange(); //温度转换
for(a=10;a>0;a--)
{
display(tmp()); //显示十次
}
}
while(1);
}
3.10 1602字符液晶显示
[实验要求]
在1602液晶屏上指定的位置显示出自己想要的数字或字符,学会使用1602液晶做滚动字符显示。
[实验目的]
学习1602液晶的操作。
注意:实验板附带的1602安装方法请看光盘里的液晶使用方法,插好液晶后如果显示字符不清楚,请调节1602液晶对比度调节电位器,顺时针拧动直到液晶上面一行能显示出黑色的方格为止。
关于1602液晶的资料请查看光盘里元件资料下的资料。
[硬件电路]
[源代码]
#include<reg52.h>
#define uchar unsigned char //宏定义
#define uint unsigned int //宏定义
sbit rs=P3^5; //液晶数据命令选择端
sbit lcden=P3^4; //液晶写数据控制端
sbit dula=P2^6;
sbit wela=P2^7;
uchar table1[]="OK100E V1.1 MCU \