atmega16(AVR)单片机数码管动态显示,按键控制流水灯

本文详细描述了一项实验,涉及数码管动态显示和矩阵键盘的编程,目标是实现按键控制流水灯模式和数码管显示。学生需设计电路,编写程序以响应不同按键,包括启动/暂停流水灯和控制数码管显示。实验还涉及中断处理和优化数码管显示速度。
摘要由CSDN通过智能技术生成

                                             实验二    人机交互接口实验

一、实验目的

1. 掌握多位数码管动态显示编程方法。

2. 掌握矩阵键盘编程方法。

 

二、实验内容

1. 验证课堂例题

编译下载运行课堂例题,查看运行结果。理解程序的编程思想和程序执行过程。

2. 设计程序

参考上述例题的编程思路,自行设计LED、数码管和矩阵键盘电路,对所设计的电路进行编程,实现按键控制流水灯模式并在数码管进行模式显示的程序编写与调试。

具体要求如下:

(1)初始状态下,数码管显示“P00001”,默认样式为样式1,流水灯不运行,LED全部点亮;

(2)按下1键后,LED按照模式1进行运行,立即改变,数码管显示“000001”;

(3)按下2键后,LED按照模式2进行运行,立即改变,数码管显示“000002”;

(4)按键A为启动/暂停键,控制当前样式下流水灯的启动和暂停,暂停时在数码管最左侧显示“P”,其它位不变。。

(5)按下其余按键,当前LED运行状态和数码管显示无变化。

样式1:每次仅一个LED熄灭,熄灭LED从L0至L7转移,如此循环运行。

样式2:每次仅一个LED熄灭,熄灭LED从L7至L0转移,如此循环运行。

在设计报告中,需进行总体设计思路描述,给出所涉及到的主程序、中断程序、关键功能子函数的流程图和设计代码。描述程序调试结果及出现的问题。

 

 

proteus仿真原理图

d744fe6124d04b1aa46f21570eac27c2.png

六位数码管选用型号为   7SEG-MPX6-CA  左侧8个引脚为段选引脚,控制数码管显示的具体内容(如0,1,2等等);右侧六个引脚为位选引脚,这个7SEG-MPX6-CA型号数码管为共阳极,所以对应引脚接入高电平代表这一位数码管将被点亮。

流水灯采用共阳极,单片机io低电平点亮。

单片机主频设置为8Mhz

 

 

源代码

#include <iom16v.h>
#include <macros.h>


#define uchar unsigned char
#define uint unsigned int
//#define interrupt_handler exter1:3

void delay(uint x)//延时函数
{
 	 uint tt,hh;
	 for(tt=0;tt<x;tt++)
	 {
	    for(hh=0;hh<x;hh++);
	 }
	// for(tt=0;tt<x;tt++);
}

uchar yangshi1[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};//样式1数组
uchar yangshi2[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};//样式2数组


uchar shumaguan[5]={0x03,0x9f,0x25,0x0d,0x31};///定义数码管显示数组,分别对应0123p

数码管显示函数
void shownumber(uint a,uint b)///变量a控制数码管第一位数值,b控制最后一位
{
 	 uint z;
	 uint ii,jj;
	 DDRA=0xff;///数码管位选
	 for(ii=0;ii<48;ii++)///嵌套两次for循环,让数码管显示时间更长,代替流水灯中的延时函数
	 {       
		for(jj=0;jj<21;jj++)
		{	
			
			for(z=0;z<125;z++)/第一位显示
	        {
	  	       PORTC=0x02;
		       PORTA=shumaguan[a];
	        }
	        for(z=0;z<10;z++)///中间4位显示
	        {
	           PORTC=0x3c;
	           PORTA=shumaguan[0];
	        }
	        for(z=0;z<25;z++)///最后一位显示的数字
	        {
	           PORTC=0x40;
		       PORTA=shumaguan[b];
	        }
	     }
	 }
}


uchar kind=1;///样式选择,初始状态为样式1
uchar k=0;///控制流水灯开始、停止的变量
uchar i=0;//数组内数据选择变量


uint pu=0;
uint q,p;///数码管第一位、最后一位显示的变量

void main(void)
{
 	 DDRB=0xff;B口输出
	 PORTB=0x00;//初始状态为全低电平,led全亮
	 
     DDRC=0xff;///C口数码管位选
	 
	 DDRD &=0x00;///PD输入
	 PORTD |=0xff;//PD上拉输入

/*开中断
*/
  	 MCUCR |=0x02;
	 GICR |=BIT(6);
//	 DDRD&=~BIT(2);
//	 PORTD |=0X70;
	 SREG |=BIT(7);//打开全局中断
	 

	 
	 k=0;///初始状态不执行流水灯,
	 kind=1;//初始为样式1
	 p=1;///初始状态,数码管显示p00001
	 q=4;
	 while(1)进入死循环
	 {
	  	
		shownumber(q,p);数码管第一位显示p,最后一位是q
		if(PIND==0xfe)///判断k1是否按下
		{
		   kind=1;
		   q=0;
		   p=1;
		}
		else if(PIND==0xfd)///判断k1是否按下
		{
		   kind=2;
		   q=0;
		   p=2;///改变数码管显示的数字
		}
		
		else///k1键没有按动,执行当前流水灯
		{
		
		
		  if(k==1)只有当k等于1,执行流水灯,
		  {
		 	if(i<7)
			{
			   i++;
			}
			else
			{
			   i=0;
			}
			PORTB |=0xff;
			switch(kind)执行当前样式流水灯
			{
			    case 1:PORTB &=yangshi1[i];
			           //delay(210);
					   break;
				case 2:PORTB &=yangshi2[i];
			           //delay(210);
					   break;
			
			}
		
		  }
		 
		 
		 elsek等于0保持当前样式,暂停流水灯
		 {}


	    }
	 
	 }
}

#pragma interrupt_handler int0_isr:2
void int0_isr(void)///中断0,改变变量k的值决定流水灯的执行或停止
{
 	 if(k==0)
	 {
	  	k=1;
		q=0;//运行时,数码管第一位显示0
	 }
	 else
     {
	    k=0;
		q=4;//暂停时,数码管第一位显示p,其他位不变
	 }
     
}

代码中,流水灯未用到延时函数,原因是如果使用延时函数会影响到数码管动态显示,使得肉眼观察数码管只能看见最后一位,所以用延长数码管显示时间来代替延时函数,能起到与延时函数相同的效果

 

运行截图

1086305270f145708088b6a59bcdf3e9.png

a1934e2905d142bc905974cc4001235e.png

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值