一、实验目的

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. Linux文本搜索工具grep
  2. 45 个常用Linux 命令,让你轻松玩转Linux!
  3. 如何修改动态库符号表
  4. 计算机由简单的二进制阴阳,二进制之美,大道至简,二生万物!
  5. 自媒体采集平台免费,免费的自媒体采集平台
  6. app的性能测试小工具Emmagee使用教程
  7. 数据中心的供配电系统
  8. ECAP等通道转角挤压详解
  9. 计算机硬盘图标怎么更改,电脑磁盘图标的修改
  10. 百度快照出问题投诉有没有用?
  11. OSEK直接网络管理软件开发
  12. 思科单臂路由与三层交换机配置
  13. WhbtomT(半路出家) 的每日英语 收集 (四)
  14. Visual Question Answering with Textual Representations for Images 论文笔记
  15. 第二届云计算大会暨大数据高峰论坛举办
  16. Toronto Research Chemicals BTK抑制剂丨ACP-5197
  17. 微信小程序入门篇(一)
  18. 微信开发工具任务栏图标不显示
  19. 如何恢复笔记本的工作报表呢
  20. Teamview连接后不能操作

热门文章

  1. 网上银行、数字人名币方案、二代征信、涉案查控方案介绍
  2. 进阶大数据架构师学习路线
  3. dw1.modify()函数说明
  4. JAVA调用微信投放卡券——HTML5线上发券(JS-SDK接口)
  5. 批处理pause暂停命令
  6. 银发大健康争夺战:互联网+健康领域老年用户激增,阿里/京东加速布局老年健康市场
  7. MATLAB 气体扩散,放射性气体扩散方程有限差分法的MATLAB实现
  8. Python办公自动化之释放双手自动写文章
  9. A Physics-based Noise Formation Model for Extreme Low-light Raw Denoising论文学习理解
  10. 腾讯QQ和淘宝旺旺在线客服代码