一、实验目的

1.掌握AVR单片机开发平台的搭建方法。
2.掌握GPIO的编程方法。

二、实验内容及结果

1.设计程序
自行设计电路,包括流水灯和4个按键,完成“按键控制流水灯样式”的程序编写与调试。
具体要求如下:
(1)初始状态下,所有LED灯点亮;
(2)K1为启/停键,按下后控制LED流水灯按照当前指定样式运行或停止;
(3)K2为流水灯样式选择键,分两种样式,默认为样式1。每次按下K2当前样式立即转变。
样式1:每次仅一个LED熄灭,熄灭LED从L0至L7转移,如此循环运行。
样式2:每次仅一个LED熄灭,熄灭LED从L7至L0转移,如此循环运行。

2.实验结果
(1)在下方贴出使用Proteus绘制的电路原理图。对应Proteus仿真文件链接.

图1 实验电路图

(2)描述所设计程序(“按键控制流水灯样式”)的总体设计思路(可包括根据任务划分的程序顶层结构、各任务的设计思路、各任务间的数据传递,如何解决关键问题):
①程序顶层结构:
程序顶层包含各类头文件,定义相应变量,初始化LED灯与按键引脚。
②各任务设计思路:
首先编写延时函数、按键初始化、LED初始化函数,设定按键对应端口为输入端口(方向寄存器置低电平),并设定上拉电阻使能(数据寄存器置高电平),再设定LED对应端口为输出端口(方向寄存器置高电平),并且输出低电平(因为电路图中LED低电平导通)。
然后编写按键1、2、3的扫描函数,首先进行按键消抖,然后进行按键是否按下的判断,对于按键1编写控制启停的程序,按键2编写控制样式变换的程序,按键3编写流水灯速率改变的程序(思考题要求),最后判断按键是否松开。
主函数中首先初始化LED与按键,然后进入while循环,在循环中不断进行按键1、2、3的扫描,当对应按键按下后就执行对应功能。
③解决问题:
a. 流水灯的实现:
本程序通过定义一个含八个16进制数一位数组,使用for循环为八个LED灯对应的端口的数据寄存器进行赋值的方式实现流水灯功能。
b. 实现按下K2时样式立即改变:
在执行for循环进行流水灯的过程中,也在不断进行着按键扫描函数。若是按键2按下,则会通过break语句跳出该模式流水灯的循环。
c. 实现流水灯按照当前指定样式运行或停止:
在执行for循环进行流水灯的过程中,若检测到按键1按下,则会进入一个while(1)的循环,在里面会为LED端口的数据寄存器进行不断的赋值(其值固定),但不再进行for循环,故其会实现流水灯的暂停。在这个过程中,也不短进行着按键检测,若检测到按键1再次按下,则通过break跳出该死循环,继续进行for循环,即接着之前的流水灯程序进行。
(3)根据所设计的程序顶层结构,对主函数、中断函数(如果没有使用中断可不写)、关键功能子函数的设计思路进行简单描述,并给出各函数的流程图

图2 按键检测函数流程图

在按键检测函数中,通过读取输入引脚寄存器中对应引脚的电平状态可判断按键是否被按下,若被按下,则改变按键对应的按键标志位(按键1对应power,其控制程序的运行或停止;按键2对应led_number,其控制流水灯的样式;按键3对应timer,其控制流水灯速度。)在主循环中,通过不断地按键检测,可实现对流水灯状态的改变。

图3 主函数流程图

在主函数中,首先进行相关引脚的初始化,程序刚刚运行时,power的值为0,通过按键扫描待到按键1按下开始执行流水灯程序。在执行流水灯的过程中,也在不断进行按键扫描,若检测到按键1或按键2按下时,即可跳出该样式流水灯的执行过程,执行另一样式的流水灯程序(非思考题)。若检测到按键3按下,可通过对延时时间的改变实现对流水灯循环速度进行改变,本程序中,按键3提供三种不同的速度。

4.程序代码

* 【编译环境】: ICCAVR
* 【程序目的】: 按键控制流水灯
* 【晶   振】:  8M
* 【芯   片】:  ATMEGA16                                                      */
/******************************************************************************//*** 头文件定义 ***/
/******************************************************************************/
#include <iom16v.h>
#define uchar unsigned char
#define uint unsigned int
#define Get_Bit(val, bitn) (val &(1<<(bitn)) )
int power=0;
int led_mode=1;
int timer=100;
uint led_number[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
int i;
/******************************************************************************//*** 延时函数 ***/
/******************************************************************************/
void delay_ms(unsigned int a)
{unsigned int j;while(--a!=0){for(j=0;j<120;j++);}
}
/******************************************************************************/ /*** LED初始化函数 ***/
/******************************************************************************/
void LED_Init(void)
{DDRD=0xFF;   //PD端口皆设置为输出端口PORTD=0xFF;  //PD端口输出高电平
}
/******************************************************************************//*** 按键初始化函数 ***/
/******************************************************************************/
void Key_Init(void)
{DDRC=0xF0;     //PC高四位设为输出端口,低四位设为输入端口PORTC=0xFF;    //PC0-PC3上拉电阻使能
}
/******************************************************************************//*** 按键1函数——控制流水灯暂停或继续 ***/
/******************************************************************************/
void Key_1(void)
{if(Get_Bit(PINC,0)==0)//检验PC0的电平状态是否为低电平{delay_ms(20);//延时消抖if(Get_Bit(PINC,0)==0){if(power==0){power=1;}else{power=0;}}}while(Get_Bit(PINC,0)==0);//判断按键是否松开
}
/******************************************************************************//*** 按键2函数——模式选择按键 ***/
/******************************************************************************/
void Key_2(void)
{if(Get_Bit(PINC,1)==0)//检验PC1的电平状态是否为低电平{delay_ms(20);//延时消抖if(Get_Bit(PINC,1)==0){if(led_mode==1){led_mode=2;}else{led_mode=1;}}}  while(Get_Bit(PINC,1)==0);//判断按键是否松开
}
/******************************************************************************//*** 按键3函数——改变流水灯速度 ***/
/******************************************************************************/
void Key_3(void)
{if(Get_Bit(PINC,2)==0)//检验PC2的电平状态是否为低电平{delay_ms(20);//延时消抖if(Get_Bit(PINC,2)==0){switch(timer){case 100: timer= 500;break;case 500: timer=1000;break;case 1000: timer=100;break;}}}while(Get_Bit(PINC,2)==0);//判断按键是否松开
}
/******************************************************************************//*** 主函数 ***/
/******************************************************************************/
void main(void)
{LED_Init();Key_Init();while(1){Key_1();Key_2();Key_3();PORTD=0x00;if(power==1&&led_mode==1)//流水灯样式为模式一{PORTD=0x00;delay_ms(500);for(i=0;i<=7;i++){Key_1();Key_2();Key_3();PORTD=led_number[i];delay_ms(timer);if(power==0)//暂停流水灯{while(1){PORTD=led_number[i];Key_1();if(power==1)//从停止位置继续流水灯{break;}}}//if(led_mode==2)//流水灯模式切换时跳出该模式,把该两句注释掉可完成完成一个周期后再模式变换的要求,现在即能完成要求//{break;}       //把该两句注释掉可完成完成一个周期后再模式变换的要求,现在即能完成要求}}if(power==1&&led_mode==2)//总电源打开,且流水灯样式为模式二{   PORTD=0x00;delay_ms(500);for(i=7;i>=0;i--){Key_1();Key_2();Key_3();PORTD=led_number[i];delay_ms(timer);if(power==0)//暂停流水灯{while(1){ Key_1();PORTD=led_number[i];if(power==1)//从停止位置开始流水灯{break;}}}//if(led_mode==1)//流水灯模式切换时跳出该模式,把该两句注释掉可完成完成一个周期后再模式变换的要求,现在即能完成要求//{break;}       //把该两句注释掉可完成完成一个周期后再模式变换的要求,现在即能完成要求}}}
}

三、实验思考题

1.如果要求每次按下 K2 时,运行模式不能马上发生变化,而是要执行完当前模式的一个周期再改变模式,如何进行程序设计?

可以通过注释掉主函数中K2按下时就立即跳出流水灯样式循环的for循环来达到运行模式不马上变化的功能,而是执行完当前的周期再改变

//if(led_mode==2)//流水灯模式切换时跳出该模式,把该两句注释掉可完成完成一个周期后再模式变换的要求,现在即能完成要求
//{break;}       //把该两句注释掉可完成完成一个周期后再模式变换的要求,现在即能完成要求//if(led_mode==1)//流水灯模式切换时跳出该模式,把该两句注释掉可完成完成一个周期后再模式变换的要求,现在即能完成要求
//{break;}       //把该两句注释掉可完成完成一个周期后再模式变换的要求,现在即能完成要求

2.如果要用 K3 控制 LED 流水灯速度,如何修改程序?

可以通过写一个switch—case语句来控制timer的变动,从而改变delay_ms(timer)的延时时间,进而最终改变流水灯的变化速度。

/*** 按键3函数——改变流水灯速度 ***/
/******************************************************************************/
void Key_3(void)
{if(Get_Bit(PINC,2)==0)//检验PC2的电平状态是否为低电平{delay_ms(20);//延时消抖if(Get_Bit(PINC,2)==0){switch(timer){case 100: timer= 500;break;case 500: timer=1000;break;case 1000: timer=100;break;}}}while(Get_Bit(PINC,2)==0);//判断按键是否松开
}
/******************************************************************************/

四、程序缺点分析

由于流水灯的速度控制是通过延时函数来实现的,故在按下按键的时候需要长按一段时间以防按键按下过快,主程序正执行到延迟函数,无法及时跳出。

AVR单片机实践--ATmega16按键控制流水灯相关推荐

  1. 单片机-四个按键控制流水灯

    单片机-四个按键控制流水灯 代码 代码 代码片. #include "reg51.h" sbit key1 = P2 ^ 0; sbit key2 = P2 ^ 1; sbit k ...

  2. 51单片机_7-1独立按键控制流水灯方向

    文章目录 要求 资源 效果 main函数 要求 1.使用单片机内部定时器做为延时函数 2.独立按键K1控制流水灯左移 3.独立按键K2控制流水灯右移 资源 工程文件压缩包 链接:https://pan ...

  3. Proteus:单片机按键控制流水灯方向

    题目概述: 单片机:按键控制流水灯方向. 编程: #include <reg51.h> #include<intrins.h> #define uchar unsigned c ...

  4. 四、 按键控制流水灯的运行与暂停

    按键控制流水灯的运行与暂停 项目要求: [1]程序开始时,4个LED灯全亮一会,然后,再全灭一会,开始进入跑马灯. [2]跑马灯过程为:D4灯亮,其余熄灭,延时,D3灯亮,其余熄灭,延时,D6灯亮, ...

  5. CC2530开发-----按键控制流水灯暂停

    CC2530开发-按键控制流水灯 今天所要实现的效果如下 一.导入CC2530的包以及定义按键和LED的位置 #include "iocc2530.h" #define D3 P1 ...

  6. 【51单片机Task】:led十六进制控制led灯详解、按键控制流水灯、跑马灯等任务

    学习目标: 学习普中51单片机的按键控制led灯. 电路图:                      学习内容:         LED灯的十六进制怎么算???         在这给大家算一下:首 ...

  7. 51单片机按键控制流水灯

    1.按键的使用 <1>独立按键的原理图 按键所对应的引脚为P3的0.1.2.3引脚口,并且这里总共有四个独立按键,它们公共的一段都接到了GND电源的负极.这样我们就知道按键上电的默认电平为 ...

  8. 基于51单片机《按键控制流水灯》

    1.用4个LED灯发光二极管实现至少四种灯光效果 2.可以通过输入按键在几种灯光之间切换 3.可以通过暂停按键停止彩色灯光效果,使小灯全亮,再次按下按键后继续之前的效果 4.增加自动在几种效果间切换功 ...

  9. 51单片机实现独立按键控制LED灯

    本节博客主要实现以下效果: 3-1独立按键控制LED亮灭 本段代码主要使用了if...else...语句实现按下按下灯亮,松开按键时灯灭 #include <REGX51.H>void m ...

最新文章

  1. FPGA逻辑设计回顾(8)单比特信号的CDC处理方式之Toggle同步器
  2. 松果出行CTO朱蓝天做客《智慧Talk》,解开共享电单车产研密码
  3. linux运算_CentOS「linux」学习笔记22:算术运算符、逻辑运算符、关系运算符
  4. 代码合并工具_分享几款比较常用的代码比较工具
  5. 懂技术对产品有哪些帮助?
  6. 微信占用空间太大,删除又担心工作相关聊天记录,有啥好办法没?
  7. java(16) - 泛型
  8. IDEA导入javaWeb项目注解爆红问题
  9. java中代码pu_一、线程Java代码实现1.继承Thread声明Thread的子类public class MyThread extends Thread { pu...
  10. python爬虫淘宝比价
  11. 个人公众号成长记 - 如何涨粉?
  12. Error:间接寻址级别不同——C++真的魔鬼
  13. Python自动化:根据模板批量生成含指定数据的word文档
  14. 移动通信各制式、调制的速率及频谱利用率(2G-4G)
  15. Python爬虫爬下IT之家图片
  16. Oracle之数据库升级——升级补丁修复概述
  17. Spring自定义数据源配置不当引起的Mybatis拦截器Interceptors 失效/不生效
  18. MVD(三-视图加入动画)
  19. macOS 常驻桌面便利贴应用
  20. nginx 进行 https 反向代理 nextcloud 后 APP 不能访问的解决办法

热门文章

  1. 七星瓢虫让我想起...
  2. 四足爬行机器人运动_四足爬行机器人步态分析与运动控制-机电工程.PDF
  3. iSpring Suite教程:iSpring Suite 9系统要求(上)
  4. (java毕业设计)基于java智能停车场管理系统源码
  5. 超凡蜘蛛侠2游戏进入商店时显示服务器,超凡蜘蛛侠2游戏闪退不能玩是什么原因?游戏黑屏进不去的原因和解决办法[图]...
  6. Java | 通过程序代码打开EXE应用或者文件
  7. 十四、基于FPGA的SDI协议介绍(二)
  8. Linux5配置本地yum源,linux5.2配置本地yum源
  9. OpenCV笔记整理【模板匹配】
  10. linux pdf 合并 脚本,Ubuntu中使用pdftk合并、分离PDF文档等操作