【51单片机实验】4

您所在的位置:网站首页 显示北京时间然后有秒表的那种软件叫啥 【51单片机实验】4

【51单片机实验】4

2023-12-30 22:51| 来源: 网络整理| 查看: 265

目录

一、实验目的

二、实验设备

三、实验内容

四、实验操作提示

五、实验总结

本实验对应实验报告

一、实验目的

1.掌握51单片机定时/计数器的应用设计

2.掌握查询方式和中断方式定时的设计和编程

3.熟悉中断应用程序的调试以及软硬件联合调试的方法

二、实验设备

1.微机一台,Keil C集成开发环境

2.DP-51PRO.NET综合实验箱

3.Proteus仿真软件

注:本实验报告采用的单片机为AT89C51,1、2题晶振频率为1MHz,3题晶振为12MHz

三、实验内容

1、51单片机的P1.0接一个发光二极管,定时/计数器T0的方式1产生500ms的定时,在P1.0上输出周期为1s的方波。设单片机的晶振频率为1MHz。(采用查询方式延时实现定时功能)

程序及必要的注释:

/*采用查询方式延时实现定时功能*/ #include sbit LED1 = P1^0;  /*P1.0口接LED小灯*/ void main() {        unsigned char num;   /*定义计数变量*/        TMOD = 0x01;   /*T0方式1定时*/        TR0  = 1; /*启动T0定时*/        while(1)        {               for(num = 0;num < 2;num++) /*循环两次,实现1s定时*/               {                      TH0=(65536-(500000/12))/256;  //初始化,赋初值                      TL0=(65536-(500000/12))%256;                      /*共(500000/12)次"加1",机器周期为12us时, 每次加1耗时12us,全程耗时500ms*/                      while(!TF0);  //查询TF0是否为1,以定时1s                      TF0 = 0; //TF0软件清零                      LED1 = ~LED1;  //取反,输出周期为1s的方波               }            } }

分析与验证:

题目分析:题目中要求51单片机的P1.0接一个发光二极管,所以我将LED小灯与AT89C51的P1.0口相连,同时加一个上拉电阻与电源相连,那么当P1.0口输出为低电平时,LED灯有电流流过而亮,当P1.0口输出高电平时,LED灯截止而灭。

要求“采用定时/计数器T0的方式1产生500ms的定时,在P1.0上输出周期为1s的方波”,即产生周期为1s的方波由P1.0口输出,小灯以1Hz的频率进行闪烁。

“设单片机的晶振频率为1MHz”,可知单片机的机器周期为12微秒。如果采用定时器T0方式1,16位的定时器进行定时,其最大定时为2^16×12微秒=786.432ms,可以满足定时500ms的要求。因而可以采用T0定时500ms,定时的初值为65536-(500000/12),然后对T0定时进行两次的计数,从而达到定时1s的目的。

代码分析:按照上述分析采用查询方式延时实现定时功能,根据代码建立工程,然后在Proteus中进行仿真,可以看到LED小灯闪烁时间确实为1s,同时验证了有周期为1s的方波从P1.0口输出。

程序实现的功能:单片机的P1.0接一个发光二极管,在P1.0上输出周期为1s的方波,实现LED小灯以1Hz的频率进行闪烁。

以下为Proteus仿真电路图

在仿真时,芯片默认的时钟频率为12MHz,所以在开始仿真之前,一定要修改芯片的时钟频率为1MHz,同样在进行硬件仿真时也要在Settings里修改时钟为1MHz(如下图所示哦)。

当看到LED小灯闪烁的时候,你的❤是不是也跟着闪烁起来了呢👀

别急着否认,我已经看到你嘴角上扬了✨

2、51单片机的P1.0接一个发光二极管,定时/计数器T1的方式1产生500ms的定时,在P1.0上输出周期为1s的方波。设单片机的晶振频率为1MHz。(要求中断方式来实现定时功能)

程序及必要的注释:

/*要求中断方式来实现定时功能*/ #include unsigned char num; sbit LED1=P1^0; void time0() interrupt 1 /*T0中断服务子函数 中断源:"定时/计数器0(T0)"*/ { TH0=(65536-(500000/12))/256;//初始化,赋初值 TL0=(65536-(500000/12))%256; num++; //计数变量自增 /*方式1是对每一个机器周期进行计数,直到计满后,溢出,申请中断 这里是从23869=65536-(500000/12)位置开始计数,逐次加1, 直到65535位置即将溢出,再加1,回到0*/ /*共(500000/12)次"加1",机器周期为12us时, 每次加1耗时12us,全程耗时500ms*/ } void main() { num=0; //初始化计数变量 EA=1; //打开特殊功能寄存器IE内的总开关EA ET0=1; //打开特殊功能寄存器IE内的开关ET0 TMOD=0X01; //0000 0001 //低四位,GATE=0,C/T=0,M1M0=01;选用中断源T0,方式1,16位定时器 TH0=(65536-(500000/12))/256; //初始化,赋初值 TL0=(65536-(500000/12))%256; TR0=1;//启动定时器 while(1) { if(num==2) { num=0; //中断函数每执行2次,初始化计数变量 LED1=~LED1; //取反,输出周期为1s的方波 } } //中断函数每执行2次,led1取反一次,2*500ms=1s,即led1以1s的间隔交替点亮熄灭 }

分析与验证:

题目分析部分与第1题相同。

代码分析:按照上述分析采用中断方式来实现定时功能,除了建立主函数以外还要建立定时器T0中断服务函数定时500ms,然后在主函数中将中断服务函数执行两次实现1s定时。根据代码建立工程,然后在Proteus中进行仿真,可以看到LED小灯闪烁时间确实为1s,同时验证了有周期为1s的方波从P1.0口输出。

程序实现的功能(附电路图):单片机的P1.0接一个发光二极管,在P1.0上输出周期为1s的方波,实现LED小灯以1Hz的频率进行闪烁。Proteus仿真电路图与第1题相同

3、编写程序驱动蜂鸣器。蜂鸣器及其驱动电路如图5.1所示。(本题时钟为12MHZ,别忘记修改)

图5.1  蜂鸣器及其驱动电路

(1) P1.0接扬声器,利用定时器产生频率为1KHz的方波(音频信号),从扬声器输出。

(2) 模拟报警器:P1.0接扬声器,交替输出两种不同频率的信号,如输出1K信号0.5s,再输出2K信号0.5s,如此反复。

提示:

1、用定时器T1来输出1K或2K的频率信号。

2、用定时器T0实现0.5s定时,改变定时器T1的初值选择。

程序及必要的注释:

第一问代码及注释

//P1.0接扬声器,利用定时器产生频率为1KHz的方波(音频信号),从扬声器输出。 //晶振频率为12MHz,机器周期为1μs #include sbit BUZZ = P1^0; unsigned char num; void time0() interrupt 1 /*T0中断服务子函数 中断源:"定时/计数器0(T0)"*/ { TH0 = (65536-500) / 256; //初始化,赋初值 TL0 = (65536-500) % 256; num++; //计数变量自增 } void main () { num=0; //初始化计数变量 EA=1; //打开特殊功能寄存器IE内的总开关EA ET0=1; //打开特殊功能寄存器IE内的开关ET0 TMOD=0X10; //0000 0001 //低四位,GATE=0,C/T=0,M1M0=10;选用中断源T0,方式2,8位定时器 TH0=(65536-500)/256; //初始化,赋初值 TL0=(65536-500)%256; TR0=1; //启动定时器 while(1) { if(num==2) { num=0; //中断函数每执行2次,初始化计数变量 BUZZ=~BUZZ; //取反,输出周期为1ms的方波 } } }

接下来是第二问的代码及注释

/*模拟报警器:P1.0接扬声器,交替输出两种不同频率的信号, 如输出1K信号0.5s,再输出2K信号0.5s,如此反复*/ #include #define uchar unsigned char /*为了简便,把unsigned char定义为uchar*/ uchar cnt; bit flag; sbit pulse=P1^0; void tim0() interrupt 1 //定时器(计数器)T0溢出中断 { TH0 = (65536-50000) / 256; //T0定时0.05s TL0 = (65536-50000) % 256; cnt++; if(cnt>=10) //T0定时计数10次,实现定时0.5s { cnt=0; flag = ~flag; //设置标志位,用于选择1K和2K信号 } } void tim1() interrupt 3 //定时器(计数器)T1溢出中断 { if(flag) //flag为1 { TH1 = (65536-500) / 256; //输出1K方波 TL1 = (65536-500) % 256; } else //flag为0 { TH1 = (65536-250) / 256; //输出2K方波 TL1 = (65536-250) % 256; } pulse = ~pulse; } void main() { TMOD=0x11; //定时器模式3 TH0 = (65536-50000) / 256; TL0 = (65536-50000) % 256; TH1 = (65536-500) / 256; TL1 = (65536-500) % 256; /*定时器赋初值*/ flag=1; TR0=1; TR1=1; EA=1; /*CPU开中断*/ ET0=1; ET1=1; /*允许定时器T0、T1中断*/ while(1); }

分析与验证:具体思路已经写在注释中了,这里说下第二问。采用T0定时,设置flag标志位去选择输出的频率这点我确实没有想到,感谢我的同学们为我提供的思路。

程序实现的功能:第一问用定时器产生了频率为1KHz的方波(音频信号),从扬声器输出。第二问在P1口交替输出了两种不同频率的信号,输出1K信号0.5s,再输出2K信号0.5s,如此反复,形成了一个简易的报警器。

以下为Proteus仿真电路图

按照电路图进行连接时,发现如果连接蜂鸣器(BUZZER)的话,无论我怎么设置参数蜂鸣器都没有发出鸣声(百度了很多方法,连接了N个电路图,改三极管、改电源、改BUZZER;侧面说明了网上的各种博客、帖子不一定都可(有)靠(用),还不如来看我的博客呢😂),所以我改用了喇叭(SPEAKER)和压电发声模型(SOUNDER),这才有了鸣声(戴耳机的同学注意保护耳朵,别问我怎么知道的😭)。

四、实验操作提示

1、软件设置:时钟的设置:第一题中我已经给出了如何去修改Proteus中芯片的时钟频率。

2、硬件连接:用导线将A2区J61中的P10引脚与D4区J8中任意引脚相连。(实验箱上的操作,如果你只是仿真的话,请忽略这一条😄)

五、实验总结

Emmm,这次实验做的我是百感交集、感慨万千、感同身受、汗流浃背、激情四射。。。额,孩子已经开始说胡话了,不正常了,等我掐亿下我自己。

唉,掐完了,我又回来了。

正常一点,实验课前我上网查了很多关于这几个题的代码、电路图,花了半个下午去鼓捣,然后前两题成功破解了,实际上前两题就是一个题嘛🙄,然后第3题就各种查、各种改、蜂鸣器就是不响。。。。。。再然后,我就直接去上课了,将代码在实验室电脑上进行运行,连接实验箱,执行之后蜂鸣器它就响了???这是啥子情况,仿真弄了半天它不响,实验室一下就响了?我带着满头的问号回来了,现在还没弄清楚这到底是为什么。回来后,再次向度娘求助,换成了喇叭或者压电发声模型就可以响了。

此处友情提示:耳机党运行之前把耳机离耳朵远一点,不然运行成功人就傻了。

如果有知道怎么让蜂鸣器成功响起来的小伙伴别忘了评论或者私信告诉我呀༼ つ ◕_◕ ༽つ



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3