一、实验目的

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

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

二、实验内容

1. 验证课堂例题

编译下载运行课堂例题——“LED数码管动态显示”(IO_ex4)和“矩阵键盘显示按键编号”(IO_ex5),查看运行结果。理解程序的编程思想和程序执行过程。

2. 设计程序

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

具体要求如下:

(1)初始状态下,数码管显示“000001”,LED按照模式1进行运行;

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

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

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

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

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

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

三、实验结果

1. 在下方贴出使用Proteus绘制的电路原理图。

图1-1 实验电路图

2. 描述所设计程序的总体设计思路

本次程序设计主要是实现矩阵键盘对LED流水灯与数码管的控制,其中为节约IO,数码管的动态扫描依托于锁存器实现。总体思路为:主循环开始,默认状态为数码管显示“000001”,LED按照模式1进行运行。每次LED移位的过程中,对矩阵键盘进行扫描,判断按键状态,以此来决定下一状态数码管的显示和LED的流水状态。

因为使用的单片机为单核心单线程,所以如果LED流水与数码管刷新显示交替进行,流水延时较小时可以保证数码管动态显示频率足够,但是流水间隔太短无法达到流水效果。流水延时较大时流水效果正常,但是数码管动态刷新频率不足,导致数码管频闪,因此本次编程中,将延时语句替换为两次数码管刷新,这样既保证了流水灯正常显示,也保证了动态刷新数码管所需要的频率。

  1. 根据所设计的程序顶层结构,对主函数、关键功能子函数的设计思路进行简单描述,并给出各函数的流程图

方法一(查询法):

程序主要分为:主函数;延时函数;按键检测函数;按键定位函数;LED流水模式函数;初始化函数;数码管扫描函数。

主函数思路简单,初始化矩阵键盘,数码管,LED后进入主循环,判断工作模式状态,状态一下数码管显示“000001”,LED部分每次仅一个LED熄灭,熄灭LED从L0至L7转移,如此循环运行(初始为状态一)。当检测到按键“2”按下,工作模式标志位取反,并跳出当前循环模式,按模式二(状态二下数码管显示“000002”,LED部分每次仅一个LED熄灭,熄灭LED从L7至L0转移,如此循环运行)进行。

数码管扫描函数:采用动态扫描,首先输出位选信号,选中一位数码管后锁存器控制端拉低,锁存位选信号,此时输出段选信号,确定该位数码管输出的数字或者字母,后锁存器控制端拉低,锁存段选信号。循环扫描实现数码管动态刷新,同时,实现了IO复用。

按键检测函数:矩阵键盘连接方式为同一组IO的高低四位分别作为行线和列线,分别给行线和列线不同的电平值,当有按键按下时,IO口的电平状态发生变化,扫描这个值即可得知有按键被按下。

按键定位函数:采用行列扫描,通过高四位全部输出低电平,低四位输出高电平。当接收到的数据,低四位不全为高电平时,说明有按键按下,然后通过接收的数据值,判断是哪一列有按键按下,然后再反过来,高四位输出高电平,低四位输出低电平,然后根据接收到的高四位的值判断是那一行有按键按下,这样就能够确定是哪一个按键被按下。按键定位后改变相应按键对应模式的模式标志位。并返回该按键对应的显示码。

LED流水模式函数:流水的模式上,每次切换下一个灯的间隙进行数码管刷新,同时判断按键状态是否发生变化,如果是,立即跳出当前循环模式。

图2-1 主函数流程图

2-2 流水模式流程图

#include <iom16v.h>
#include <macros.h>//宏定义
#define  uchar unsigned char
#define  uint  unsigned int//全局变量定义
//数码管使用
uchar const DuanXuan[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//共阴级数码管显示0-F
uchar const WeiXuan[6]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};//从左到右第0-5位数码管
uchar LEDBuf[6]={0,0,0,0,0,1};//存放数码管显示数据,0-9数字格式
uint LED_model=1;//定义LED流水模式标志//函数声明
void delay(uint ms);             //延时函数
void LEDshow(uchar LEDBuf[6]);   //数码管显示函数
uchar key_press();               //按键检测函数
uchar key_where();               //按键定位函数
void LED_1() ;                   //LED流水模式一
void LED_2() ;                   //LED流水模式二
void Init();                     //初始化函数
//**************************************************************************************
//主函数
//**************************************************************************************
void main(void)
{    Init(); while(1){if  (LED_model)LED_1();elseLED_2();}
}//**************************************************************************************
//函数名:延时函数
//输入参数:ms
//**************************************************************************************
void delay(uint ms)
{uint p,q;for(p=0;p<ms;p++){for(q=0;q<1141;q++);}
}         //**************************************************************************************
//数码管模块子函数
//**************************************************************************************//**************************************************************************************
//函数名:LEDshow
//功能:在数码管上显示出对应的数字。0-5位数码管显示数据放在LEDBuf[]中,存放0-9数字格式
//输入参数:LEDBuf[]每个元素对应6位数码管每位的显示数字(0-F)
//**************************************************************************************void LEDshow(uchar LEDBuf[6])
{   uchar i;for(i=0;i<6;i++)              //循环扫描一次{   //数码管位选程序PORTB=WeiXuan[i];          //选择第i位数码管PORTA|=BIT(PA4);             //PA4输出高电平,位选端拉高PORTA&=~BIT(PA4);           //PA4输出低电平,位选端拉低,位选锁存//数码管段选程序 PORTB=DuanXuan[LEDBuf[i]]; //输出段选PORTA|=BIT(PA3);            //PA3输出高电平,段选端拉高PORTA&=~BIT(PA3);           //PA3输出低电平,段选端拉低,段选锁存  delay(1);}
}//**************************************************************************************
//矩阵键盘模块子函数
//**************************************************************************************//**************************************************************************************
//函数名:key_press
//功能:检测是否有低电平出现,来判断是否有按键按下
//返回值:1-有键按下,0-无键按下
//**************************************************************************************
uchar key_press(void)
{uchar temp;PORTC=0xF0;               //高4位输出高电平,低4位输出低电平//DDRC=0x0F;              //高4位为输入,低4位为输出 temp=PINC;                //读取PC口if(temp==0xF0)            //输入端未出现低电平(没有按键按下) {return 0;              //输出0}else                      //有按键按下{         return 1;              //输出1}
}//**************************************************************************************
//函数名:key_where
//功能:读行线列线电平,根据按键键值进行定位
//返回值:按键代表的十六进制数字(0-F)
//**************************************************************************************uchar key_where(void)
{uchar Code,j;                 //存储PINC值,即引脚读入值,j为计数值uchar Hang=0X7F;              //行线输出值uchar Lie;                    //列线值,4位 delay(10);if(key_press())               //调用按键检测函数{do{//DDRC=0X0F;                //高4位(列线)输入,低4位(行线)输出  Hang=((Hang<<1)|(Hang>>7)); //循环左移,每一次只输出一个低电平PORTC=Hang;                 //低四位在C口输出,行线逐位输出0        Code=PINC; Lie=Code&0xF0;              //读取key高四位(列线)}while(Lie==0xF0);            //列线出现全1为不在该行,列线出现0说明该键在该行while(key_press());           //等待按键松开 if(Code==0xEE||Code==0xDE)    //有2种情况{if(Code==0xEE)             //1110 1110  第1行第1列(1,1){  Code=0x1;            //显示1  LED_model=1;         //流水灯模式为模式一}         else        { Code=0x2;             //显示2LED_model=0;          //流水灯模式为模式二}         } elseCode=LEDBuf[5];          //其它按键按下,数码管与LED状态不变for( j=0;j<2;j++)LEDshow(LEDBuf);   }return Code;
}//**************************************************************************************
//函数名:LED_1
//功能:每次仅一个LED熄灭,熄灭LED从L0至L7转移,如此循环运行
//**************************************************************************************void LED_1(void)
{uchar i,j,temp;              DDRD=0xFF;temp=0x01;for(i=0;i<8;i++){PORTD=temp;temp<<=1;for( j=0;j<2;j++)LEDshow(LEDBuf);             //每次LED切换时刷新数码管if(key_press())              //判断键盘中是否有按键按下{          LEDBuf[5]=key_where();     //按下后显示在第五位break; }  LEDshow(LEDBuf);               //数码管刷新}
}//**************************************************************************************
//函数名:LED_2
//功能:每次仅一个LED熄灭,熄灭LED从L7至L0转移,如此循环运行
//**************************************************************************************void LED_2(void)
{uchar i,j,temp;DDRD=0xFF;temp=0x80;for(i=0;i<8;i++){PORTD=temp;temp>>=1;for(j=0;j<2;j++)LEDshow(LEDBuf);              //每次LED切换时刷新数码管if(key_press())                   //判断键盘中是否有按键按下{           LEDBuf[5]=key_where();break;                      //按下后显示在第五位}  LEDshow(LEDBuf);                   //数码管刷新   }
}//**************************************************************************************
//函数名:Init
//功能:初始化数码管,三极管,LED,矩阵键盘
//**************************************************************************************void Init(void)
{//初始化数码管DDRA|=BIT(3);            //PA3设置为输出DDRA|=BIT(4);            //PA4设置为输出DDRB=0XFF;               //PB口设置为输出//初始化三极管DDRA|=BIT(0);            //PA0设置为输出PORTA&=~BIT(0);          //PA0输出低电平导通三极管//初始化LEDDDRD=0xFF;               //PD设置为输出模式//初始化键盘DDRC=0x0F;               //高4位为输入,低4位为输出PORTC&=0xF0;             //低4位输出低电平
}

基于Atmega16的人机交互实验相关推荐

  1. 基于Atmega16的定时器实验

    一.实验目的 1. 理解单片机定时器的工作原理. 2. 掌握定时器溢出中断实现定时的编程方法. 二.实验内容 1. 验证课堂例题 编译下载运行课堂例题--"T/C0溢出中断"(T0 ...

  2. 基于Atmega16的GPIO实验(以流水灯为例)

    一.实验目的 1. 掌握AVR单片机开发平台的搭建方法. 2. 掌握GPIO的编程方法. 二.实验内容 1. 验证课堂例题 编译下载运行课堂例题--"LED流水灯"和"按 ...

  3. 计算机图形人机交互实验报告,用户界面设计人机交互实验报告.doc

    用户界面设计人机交互实验报告 <人机交互>实验报告 题目 实验一 图形用户界面的设计 专业 软件工程 班级 2011 学号 2011221104220026 姓名 孙元喜 导教师 关玉欣 ...

  4. 计算机在基于阅读的人机交互证明(HIP)中的单字符识别中超过人类

    人工交互证明(HIP)已经在互联网上变得司空见惯,以保护免费在线服务受自动脚本/机器人滥用的侵犯. 它们是旨在帮助人们易于解决的挑战,同时对于计算机来说仍然是难以解决的问题. 基于读数的HIP包括分割 ...

  5. linux 用mutex定义一个linkedlist,【基于LINUX的操作系统实验教程最终版材料】

    (基于LINUX的操作系统实验教程)(最终版) <基于LINUX的操作系统实验教程.doc>由会员分享,可免费在线阅读全文,更多与<(基于LINUX的操作系统实验教程)(最终版)&g ...

  6. python实现蒙特卡洛算法_用Python实现基于蒙特卡洛算法小实验

    用Python实现基于蒙特卡洛算法小实验 蒙特卡洛算法思想 蒙特卡洛(Monte Carlo)法是一类随机算法的统称,提出者是大名鼎鼎的数学家冯· 诺伊曼 ,他在20世纪40年代中期用驰名世界的赌城- ...

  7. python机器视觉教材_基于Python的机器视觉实验教学平台设计

    基于 Python 的机器视觉实验教学平台设计 韩志豪 ; 刘晓英 [期刊名称] <计算机测量与控制> [年 ( 卷 ), 期] 2020(028)003 [摘要] 针对机器视觉领域的学习 ...

  8. 基于matlab的谱估计,基于MATLAB的功率谱估计实验.doc

    基于MATLAB的功率谱估计实验 一.实验目的 1.进一步熟悉matlab软件的使用: 2.学会运用matlab自带函数实现编程: 3.掌握功率谱估计的方法. 二.实验原理 功率谱:随机信号的功率谱反 ...

  9. matlab实验论文,毕业论文--基于MATLAB的光学实验仿真

    毕业论文--基于MATLAB的光学实验仿真 本科毕业论文 题 目 基于基于 MATLABMATLAB 的光学实验仿真的光学实验仿真 学 院 物理科学与技术学院 专 业 物 理 学(师 范) 2014年 ...

最新文章

  1. Github上的PHP资源汇总大全
  2. 自然语言处理算法工程师历史最全资料汇总-基础知识点、面试经验
  3. python的x 2是什么意思_python中startx是什么意思
  4. 互联网之父公开拍卖万维网源代码,3400万买下后发现居然有bug
  5. 学习笔记之Iframe
  6. 程序员面试系列——单链表的反转
  7. Android应用开发之(通过ClipboardManager, ClipData进行复制粘贴)
  8. 内存管理范围和@property
  9. WPF中的一些常用类型转换
  10. Ant Design Pro入门之部署安装
  11. Spring3 MVC Login Interceptor(Spring 拦截器)
  12. 微软块级备份引擎服务器,文件级与块级备份区别
  13. vision软件_Roboguide软件:高速拾取仿真工作站相机与工具添加与配置
  14. 保存查看翻译:Thrift: Scalable Cross-Language Services Implementation中文翻译(Thrift:Œ可扩展的跨语言服务实现)...
  15. SVD — 奇异值分解
  16. 让win7任务栏资源管理器默认打开的“计算机”而不是“库”文件夹
  17. 关于input type=hidden/标签的记录
  18. ubuntu如何修改terminal终端的主机名
  19. 人工智能机器学习————MINST数据集的简单处理
  20. deepin,windows10双系统安装教程

热门文章

  1. 在fabric中搭建浏览器是报错,没有创建相关网络
  2. matlab绘制hpof振荡器的极限环和输出结果
  3. 从原理到应用 | 详解毫米波雷达Radar
  4. 210620AF 抖音矩阵营销视频课程
  5. html课题背景介绍,办公自动化系统论文-课题研究的背景和意义及国内外发展状况.doc...
  6. 收藏 | 2020测绘国家及行业标准都在这了
  7. 终极社会工程黑客攻击
  8. MD5校验和资源代码热更(U3D)
  9. Android BitmapShader实现圆角、圆形ImageView
  10. Windows下载安装docker详细步骤