项目三 51项目(使用外部按键倒计时)

项目三 51项目(使用外部按键倒计时)

【实验内容】

1.熟悉软件流程(Proteus 8 Professional,Keil uVision5),熟悉烧录流程,熟悉51芯片的引脚。

2.编写程序代码

3.用软件搭建实验电路,实现倒计时的功能。

【实验原理】

使用外部按键进行倒计时的实验原理如下:

  1. 外部按键输入:在单片机开发板上连接一个或多个外部按键,通过端口将外部按键与单片机连接。当按下外部按键时,对应的端口信号会发生变化。
  2. 中断服务函数:通过单片机的中断服务函数,可以检测外部按键的状态变化。当外部按键被按下时,中断服务函数会被触发执行相应的操作。
  3. 倒计时功能:当外部按键被按下时,触发中断服务函数来开始倒计时。倒计时的实现可以通过单片机的定时器功能来完成,例如可以使用定时器中断来进行倒计时操作。
  4. 数码管显示:倒计时过程中,将剩余时间通过数码管显示出来可以通过修改display()函数来实现倒计时数字的显示。

总的来说,实验原理是通过中断服务函数检测外部按键状态变化,启动倒计时功能,然后通过数码管显示剩余时间。这样就可以实现使用外部按键进行倒计时的功能。

【实验记录与结果分析】

电路原理图:

程序代码:

程序主要分为以下几个部分:

1.头文件和全局变量的定义。使用reg51.h头文件,定义了8个无符号字符型变量和一个数组,用于存储数码管需要显示的数字。

2.display()函数。该函数用于循环调用,实现数码管的显示功能。在函数内部,通过P0端口给数码管发送对应的显示编码,再通过P1端口选择哪个数码管进行显示,并通过delay()函数控制LED的闪烁速度和频率。

3.delay()函数。该函数是一个简单的延时函数,通过两重循环实现一定的延时效果。

4.tree()函数。该函数是定时器0中断服务函数,主要用于计时器的功能实现。在每次中断时将temp自增,并根据temp计算出需要显示的数码管显示的内容。

在main()函数中,启用定时器0并开启总中断允许,然后进入一个死循环,不断调用display()函数,实现程序的运行。

#include <reg51.h>    // 包含 8051 单片机的头文件

#define u8 unsigned char  // 定义无符号 8 位字符类型

#define u16 unsigned int   // 定义无符号 16 位整型类型

u8 a,b,c,d,e,f,g,h,temp;  // 定义全局变量 a h temp,用于数码管显示和临时存储

u8 lzs[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};  // 定义共阳极数码管显示 0-9 的编码

void display();  // 声明数码管显示函数

void delay(u8 x);  // 声明延时函数

void main()  // 主函数

{

       EA=1;    // 开启总中断允许

       ET0=1;   // 开启定时器 0 中断允许

       TMOD=0x06;  // 设置定时器 0 工作在方式 18 位自动重装)并启用定时器 1 工作在方式 1

       TH0=TL0=255;  // 定时器 0 初始值设为 255

       TR0=1;  // 启动定时器 0

       while(1)  // 无限循环

       {

              display();  // 调用数码管显示函数

       }

}

void delay(u8 x)  // 定义延时函数,参数为延时时间

{

       u8 i , j;  // 定义局部变量 i j

       for(i=0;i<x;i++)  // 循环 x

       {

              for(j=0;j<10;j++)  // 再次循环 10 次,延时

              {

                    

              }

       }

}

void tree() interrupt 1  // 定义定时器 0 中断服务函数

{

       temp++;  // temp 自增

       a=temp%10;  // a temp 10 取余

       b=temp/10;  // b temp 除以 10 的商

}

void display()  // 定义数码管显示函数

{

       P0=lzs[a]; P1=0x80; delay(50); P1=0x00;  // 显示 a 位数码管,并控制选择端口

       P0=lzs[b]; P1=0x40; delay(50); P1=0x00;  // 显示 b 位数码管,并控制选择端口

       P0=lzs[c]; P1=0x20; delay(50); P1=0x00;  // 显示 c 位数码管,并控制选择端口

       P0=lzs[d]; P1=0x10; delay(50); P1=0x00;  // 显示 d 位数码管,并控制选择端口

       P0=lzs[e]; P1=0x08; delay(50); P1=0x00;  // 显示 e 位数码管,并控制选择端口

       P0=lzs[f]; P1=0x04; delay(50); P1=0x00;  // 显示 f 位数码管,并控制选择端口

       P0=lzs[g]; P1=0x02; delay(50); P1=0x00;  // 显示 g 位数码管,并控制选择端口

       P0=lzs[h]; P1=0x01; delay(50); P1=0x00;  // 显示 h 位数码管,并控制选择端口

}

【实验小结】

在完成外部按键进行倒计时项目的过程中,我获得了很多宝贵的经验和体会。

首先,我深入理解了单片机的中断服务功能。通过连接外部按键到单片机的中断引脚,我学会了如何利用外部事件来触发中断,并在中断服务函数中实现倒计时逻辑。这让我对单片机的中断处理有了更深入的了解。

其次,我掌握了单片机定时器的使用方法。在倒计时功能中,我使用了单片机的定时器模块来实现精确的时间计数,从而实现了准确的倒计时功能。这让我对单片机定时器的原理和使用有了更清晰的认识。

另外,通过这个项目,我也加深了对数字电路的理解。在将剩余时间显示在数码管上时,我需要对数码管的工作原理和接口连接有所了解,这让我对数字电路的应用有了更多的实践经验。

总的来说,通过这个外部按键进行倒计时的项目,我不仅学会了具体的硬件连接和编程实现,还提升了自己在单片机、中断处理、定时器和数字电路方面的能力。

中断原理总结:

中断是计算机系统中一种重要的机制,用于在处理器执行程序时,对特定事件的发生做出及时响应。中断可以分为外部中断和内部中断两种类型。

1.外部中断:外部中断是由外部设备(如传感器、按键等)发送的信号触发的中断。当外部设备发生特定事件时(如按下按键),会向处理器发送一个中断请求信号。处理器在接收到中断请求信号后,会立即中断当前执行的程序,保存当前状态并跳转到相应的中断处理程序来处理这个事件。处理完中断服务程序后,再返回到之前被中断的程序继续执行。

2.内部中断:内部中断是由处理器内部某些特定事件(如定时器溢出、指令执行错误等)引起的中断。处理器在内部发生这些事件时,会自动发起中断请求,跳转到相应的中断服务程序进行处理,处理完后再返回到原程序继续执行。

在处理中断时,通常会有中断优先级的概念,处理器会根据中断请求的优先级来确定响应的顺序。同时,中断处理过程中需要保存和恢复相关的寄存器和状态,以保证中断处理完后能够正确返回到原程序。

总的来说,中断机制使得处理器能够及时响应外部或内部事件,提高了系统的实时性和可靠性,广泛应用于各种计算机系统和嵌入式系统中。

要将Keil uVision5中的代码烧录到Proteus 8 Professional中,可以按照以下步骤进行操作:

1)在Keil uVision5 中编写、调试并生成可执行文件(通常是.hex格式)。

2)打开Proteus 8 Professional,创建一个新的电路设计或打开现有的设计。

3)在 Proteus 8 Professional 的工具栏中选择 "PICK DEVICE" 工具来选择目标芯片。在弹出的窗口中输入芯片型号,并选择正确的芯片。

4)在 Proteus 8 Professional 的库管理器中,找到 "Virtual Instruments" 分类下的 "Hex File" 组件,并将其拖放到电路设计中。

5)右键单击"Hex File"组件,选择"Edit Properties"

6)在"Edit Hex File Properties" 窗口中,点击"..."按钮来浏览并选择生成的可执行文件(.hex文件)。

7)确认所选文件的地址范围与目标芯片的存储器空间匹配。如果需要,可以修改"Start Address" 字段来设置代码的起始地址。

  1. 单击"OK"按钮,关闭"Edit Hex File Properties"窗口。
  1. 连接所需的外部元件和引脚,确保与代码中的引脚连接一致。

10)单击Proteus 8 Professional的仿真按钮(通常是绿色播放按钮)来开始仿真。

  • 30
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
99分钟倒计时器报警器实验例程C51单片机KEIL工程源码文件: /*----------------------------------------------- 名称:99分钟倒计时数码管显示 内容:99分钟倒计时器,可以通过按键上调下调时间,定时器到时喇叭发声报警 带有点按和连按功能 ------------------------------------------------*/ #include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义 #define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0 替换 sbit LATCH1=P2^2;//定义锁存使能端口 段锁存 sbit LATCH2=P2^3;// 位锁存 sbit BEEP = P1^1;//定义喇叭端口 bit BeepFlag; sbit KEY_ADD=P3^0; //定义按键输入端口 sbit KEY_DEC=P3^1; unsigned char hour,minute,second;//定义时分 bit UpdateTimeFlag;//定义读时间标志 unsigned char code dofly_DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值0~9 unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码 unsigned char TempData[8]; //存储显示值的全局变量 void DelayUs2x(unsigned char t);//us级延时函数声明 void DelayMs(unsigned char t); //ms级延时 void Display(unsigned char FirstBit,unsigned char Num);//数码管显示函数 void Init_Timer0(void);//定时器初始化 void Beep_OFF(void); void Beep_ON(void); void Display_Data_Operation(void); /*------------------------------------------------ 显示数据处理函数 ------------------------------------------------*/ void Display_Data_Operation(void) { TempData[2]=dofly_DuanMa[minute/10];//分解显示信息,如要显示68,则68/10=6 68%10=8 TempData[3]=dofly_DuanMa[minute%10];//分解显示信息,如要显示68,则68/10=6 68%10=8 TempData[4]=0x40; TempData[5]=dofly_DuanMa[second/10];//分解显示信息,如要显示68,则68/10=6 68%10=8 TempData[6]=dofly_DuanMa[second%10];//分解显示信息,如要显示68,则68/10=6 68%10=8 } /*------------------------------------------------ 主函数 ------------------------------------------------*/ void main (void) { unsigned char key_press_num; Init_Timer0(); while (1) //主循环 { if(!KEY_ADD) //如果检测到低电平,说明按键按下 { DelayMs(10); //延时去抖,一般10-20ms if(!KEY_ADD) //再次确认按键是否按下,没有按下则退出 { while(!KEY_ADD) { key_press_num++; DelayMs(10); //10x200=2000ms=2s if(key_press_num==200) /
#include #include //自定义头文件,KeyScan用于键盘扫描。 #include //用于I2C总线。 #define uchar unsigned char #define uint unsigned int unsigned char b[7]={50,58,9,1,15,6,15},clock1[2]={0,12},clock2[2]={0,0}; //b[7]的元素含义:,分,时,星期,日,月,年 clock的元素含义:分,时。 code unsigned char tab[11]={0x03,0xf3,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09,0x00}; //数码管0-9的编码列表,0x00点亮全部管。 code unsigned char tab2[2]={0x6d,0xff}; //ox6d: 表示横图标。 unsigned char time[7]; //时间设置函数的参数。 void delay(unsigned int cnt); //延时函数声明。 unsigned char getkey1(); //unsigned char getkey2(); //读键盘函数声明。 void tim(void); //中断函数声明。 void KeyDelay(unsigned int KeyJsTime); //键盘扫描延时函数声明。 void display(uchar bit7,uchar bit6,uchar bit5,uchar bit4, uchar bit3,uchar bit2,uchar bit1,uchar bit0); //数码管显示函数。 void ReadTime(unsigned char TIME[7]); //DS1307读时间函数。 void SetTime(unsigned char TIME[7]); //设置时间初值函数。 void SwitchRTC(unsigned char SWITCH); //时间修改的使能函数:SWITCH=1禁止修改时间,SWITCH=0可以修改时间。 uchar dis_num_h; //显示记录数据的组别十位 uchar dis_num_l; //显示记录数据的组别个位 uchar dis_min_h; //要显示的分的十位; uchar dis_min_l; //要显示的分的个位; uchar dis_sec_h; //要显示的的十位; uchar dis_sec_l; //要显示的的个位; uchar dis_dsec; //要显示的0.1; uchar min=0x00; //防止意外,赋初值。分······· uchar sec=0x00; // uchar dsec=0x00; //十分之一。 uchar en,i,clocken1=0,clocken2=0; main() { unsigned char quzhi,xianshi,symbol=0x55,set,set1=0x55,ce; unsigned char c[30]; unsigned char num,num1,j,k,stop=1; //注意stop必须先赋初值1。 PLLCON&=0xf8; //设置频率为12.582912MHz TMOD=0x01; //选定定时器及其工作模式。 TH0=0xce; //赋初值:52736,则总共的计数次数为:65536-52736=12800,即12.8毫。 TL0=0x00; IE=0x82; //中断控制,10000010,EA=1开总中断,ET0=1:定时器0中断允许。0x82:1000 0010 I2CCON=0xE8; //开启I2C总线通信,具体含义参阅ADuC848英文版说明资料。 SetTime(b); //设定初始时间。 SwitchRTC(1); //调用时间保持函数。 while(1) //设置死循环,实现循环执行。 { ReadTime(time); //调用读时间函数,读取当前的时间,并保留在time数组中。 if(((clock1[0]==time[1])&&(clock1
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值