51按键外部中断控制流水灯

2023-05-16

实验二 外部按键输入

一、实验目的
1、了解单片机检测口方法
2、了解单片机外部中断原理
3、了解按键输入原理
二、实验内容
1、完成按键扫描控制流水灯
2、完成按键外部中断控制流水灯
三、实验原理
在这里插入图片描述

四、实验电路与程序
1、软件实验一:按键扫描控制流水灯
1)实验要求:读取四个按键的输入,检测到按下后控制灯流动一段时间,然后继续读取按键输入。
2)实验目的:1. 掌握按键消抖方法;2. 掌握单片机端口检测方法
3)实验说明:通过本实验,可以了解单片机读取IO口电平的方法,同时也可以了解单片机编程,调试方法。
4)、程序框图
在这里插入图片描述

5)、代码
main.c

  1. #include <reg52.h>

  2. #include <key.h>

  3. void main(void)

  4. {

  5. unsigned char key_val;

  6. P1=0xFF;

  7. while(1)

  8. {

  9. key_val=key_scan();//扫描键盘

  10. light_led(key_val);//选择不同的点灯方式

  11. }

  12. }

    key.h

  13. #ifndef _KEY_H

  14. #define _KEY_H

  15. #include <reg52.h>

  16. void delay(unsigned int z);

  17. unsigned char key_scan(void);

  18. void light_led(unsigned char mode);

  19. void flow_forward(void);

  20. void flow_back(void);

  21. void light_all(void);

  22. void dark_all(void);

  23. #endif

    key.c

  24. #include <key.h>

  25. unsigned char key_scan(void)

  26. {

  27. while(P3==0x0f)//等待按键按下

  28. {

  29. ;

  30. }

  31. delay(10);//软件消抖

  32. switch (P3)

  33. {

  34. case 0xFE: return 0;//判断是哪个按键按下

  35. case 0xFD: return 1;

  36. case 0xFB: return 2;

  37. case 0xF7: return 3;

  38. }

  39. }

  40. void flow_forward(void)

  41. {

  42. int i=0;

  43. P1=0xFE;

  44. for(i=0;i<8;i++)

  45. {

  46. delay(500);

  47. P1=(P1<<1)|(P1>>7);//循环左移1位

  48. }

  49. }

  50. void flow_back(void)

  51. {

  52. int i=0;

  53. P1=0xFE;

  54. for(i=0;i<8;i++)

  55. {

  56. delay(500);

  57. P1=(P1>>1)|(P1<<7);//循环右移1位

  58. }

  59. }

  60. void light_all(void)//点亮所有灯

  61. {

  62. P1=0;

  63. }

  64. void dark_all(void)//熄灭所有灯

  65. {

  66. P1=1;

  67. }

  68. void light_led(unsigned char mode)

  69. {

  70. switch (mode)

  71. {

  72. case 0:dark_all();//灯全灭

  73. break;

  74. case 1:light_all();//灯全亮

  75. break;

  76. case 2:flow_forward();//流水灯正流

  77. break;

  78. case 3:flow_back();//流水灯反流

  79. }

  80. }

2、软件实验二:按键外部中断控制流水灯
1)实验要求:按键1按下时流水灯正流,按键0按下时流水灯反流。
2)实验目的:1. 掌握中断服务子程序的编写方法; 2. 掌握定时器中断的配置方法。
3)实验说明:通过本实验,可以了解单片机掌握中断服务子程序的编写方法和定时器中断的配置方法,同时也可以了解单片机编程,调试方法。
4)、程序框图
在这里插入图片描述

5)、代码
汇编代码

  1. ORG 0000H ;程序执行的起始地址
  2. LJMP Main ;跳转到main函数
  3. ORG 0003H ;外部中断0起始地址
  4. LJMP 0100H ;外部中断0服务子程序地址
  5. ORG 0013H ;外部中断1起始地址
  6. LJMP 0200H ;外部中断1服务子程序地址
  7. Main: ;主函数
  8. MOV IE, #10000101B ;置位EA,EX1,EX0
  9. MOV TCON, #00000000B ;外部中断0和1都是低电平触发
  10. LOOP: JMP LOOP ;while(1)死循环
  11. ORG 0100H ;外部中断0服务子程序
  12. EXT0:
  13. CALL DELAY1 ;短延时,按键消抖
  14. MOV R3, #32 ;灯流4次
  15. MOV A, #0FEH
  16. EXT0L: MOV P1, A ;P1口赋值
  17. RR A ;循环右移一位
  18. CALL DELAY
  19. DJNZ R3, EXT0L
  20. RETI ;中断返回
  21. ORG 0200H ;外部中断1服务子程序
  22. EXT1:
  23. CALL DELAY1 ;短延时,按键消抖
  24. MOV R3, #32 ;灯流4次
  25. MOV A, #0FEH
  26. EXT1L: MOV P1, A ;P1口赋值
  27. RL A ;循环左移一位
  28. CALL DELAY
  29. DJNZ R3, EXT1L
  30. RETI ;中断返回
  31. DELAY: MOV R1, #200 ;执行200*200个跳转
  32. DELAY1: MOV R2, #200
  33. DELAY2: DJNZ R2, DELAY2
  34. DJNZ R1, DELAY1
  35. RET
  36. END

C程序代码
main.c

  1. #include <reg52.h>
  2. #include <key.h>
  3. #include <interrupt.h>
  4. int task_flag;
  5. int timer_flag;
  6. void main()
  7. {
  8. Config_EXTI();//初始化外部中断
  9. Config_Timer();//初始化定时器
  10. P1=0xFE;//初始化GPIO
  11. while(1)//任务调度器
  12. {
  13. if(timer_flag)//每1000ms执行一次任务
  14. {
  15. timer_flag=0;
  16. switch (task_flag)//判断执行哪个任务
  17. {
  18. case 1 :flow_forward();//流水灯正流
    
  19. break;
    
  20. case 2 :flow_back();//流水灯反流
    
  21. break;
    
  22. }
  23. }
  24. }
  25. }

interrupt.h

  1. #ifndef _INTERRUPT_H
  2. #define _INTERRUPT_H
  3. #include <reg52.h>
  4. #include <key.h>
  5. void delay(unsigned int z);
  6. void Config_EXTI(void);
  7. void Config_Timer(void);
  8. extern int task_flag;
  9. extern int timer_flag;
  10. #endif

interrupt.c

  1. #include <interrupt.h>
  2. void delay(unsigned int z)//延时ms
  3. {
  4.   unsigned int x,y;
    
  5.   for(x = z; x > 0; x--)
    
  6.   for(y = 114; y > 0 ; y--);
    
  7. }
  8. void Config_Timer(void)
  9. {
  10. TMOD=0x01;//设置定时器0为工作方式1(M1 M0为01),是向上计数
    
  11. TH0=(65536-45872)/256;//装初值11.0582晶振定时50ms数为45872,高位
    
  12. TL0=(65536-45872)%256;//低位
    
  13. EA=1;//开总中断
    
  14. ET0=1;//开定时器0中断
    
  15. TR0=1;//启动定时器0
    
  16. }
  17. void Config_EXTI(void)
  18. {
  19. EA=1;//开中断总允许
  20. IT0=1;//下降沿触发外部中断0
  21. EX0=1;//开外部中断0
  22. IT1=1;//下降沿触发外部中断1
  23. EX1=1;//开外部中断1
  24. }
  25. void EXT0_Handle() interrupt 0
  26. {
  27.  delay(10);
    
  28.  task_flag=1;//开启正向流水灯任务
    
  29. }
  30. void EXT1_Handle() interrupt 2
  31. {
  32.  delay(10);
    
  33.  task_flag=2;//开启反向流水灯任务
    
  34. }
  35. void T0_Handle() interrupt 1
  36. {
  37. static int num=0;
    
  38.    TMOD=0x01;//重装初值
    
  39. TH0=(65536-45872)/256;//高位
    
  40. TL0=(65536-45872)%256;//低位
    
  41. if(num<20)//每1000ms把timer_flag置位
    
  42. {
    
  43.    num++;
    
  44. }
    
  45. else
    
  46. {
    
  47.   num=0;
    
  48.   timer_flag=~timer_flag;
    
  49. }
    
  50. }

key.h

  1. #ifndef _KEY_H
  2. #define _KEY_H
  3. #include <reg52.h>
  4. unsigned char key_scan(void);
  5. void flow_forward(void);
  6. void flow_back(void);
  7. #endif

key.c

  1. #include <key.h>
  2. void flow_forward(void)
  3. {
  4. P1=(P1<<1)|(P1>>7);//循环左移1位
  5. }
  6. void flow_back(void)
  7. {
  8. P1=(P1>>1)|(P1<<7);//循环右移1位
  9. }
    五、实验总结
  10. 在键盘扫描程序中,卡的比较久时间的是点灯。后面发现不同的开发板,灯的位置不一样。第二个卡的比较久的地方是判断P3口时,没有考虑到高四位的情况,考虑进去之后,switch p3就正常了。
    2.设计键盘外部中断的时候,考虑到如果把流水灯放在中断回调函数里面进行的话,会导致执行回调函数的时候,别的中断来了会很麻烦。于是改为在回调函数里面设置标志位,while(1)里面根据标志位来选择执行哪个点灯代码。但是流水灯需要延时,如果用跑空循环来作延时的话,有点像是阻塞型任务,别的中断来的时候,中断套中断,就很麻烦。于是就开了一个定时器,定时器中断里面设置一个flag,每1秒钟flag置位一下,然后去看看要不要切换任务,以及执行哪个任务。这样子就给单片机节省出大量的资源来了。
  11. 汇编代码比较遗憾的地方是没有加进定时器中断,delay用跑空循环实现。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

51按键外部中断控制流水灯 的相关文章

  • docker mysql5.7中文乱码解决

    docker mysql5 7中文乱码解决 docker安装mysql5 7见文章docker安装mysql5 7 进入容器 docker exec it mysql5 7 docker bin bash 安装vim 更新包 apt upd
  • linux网络基础

    文章目录 前言1 网络通信概述2 网络设备概述3 应用层概述4 IP地址分类 xff08 IPv4 xff09 5 linux网络编程实践5 1 socket编程接口介绍5 2 IP地址格式转换函数实践5 3 服务器和客户端程序5 4 发送
  • sudo apt-get update 出现签名无效或者没有数字签名

    错误提示 获取 5 http packages ros org ros ubuntu bionic InRelease span class token punctuation span span class token number 4
  • 现代控制原理专业词汇中英文对照

    自动控制原理专业词汇中英文对照 xff08 一 xff09 自动控制原理专业词汇中英文对照 xff08 二 xff09 自动控制原理专业词汇中英文对照 xff08 三 xff09 中文英文状态state状态变量state variables
  • 自动控制原理专业词汇中英文对照(一)

    自动控制原理专业词汇中英文对照 xff08 二 xff09 自动控制原理专业词汇中英文对照 xff08 三 xff09 现代控制原理专业词汇中英文对照 中文英文自动控制automatic control cybernation自动控制系统a
  • 远程服务器上安装Anaconda并创建python环境、安装pytorch(Linux)

    实验室共用服务器 xff0c 所以需要在自己的文件夹下创建自己的环境 使用远程连接工具 xff1a mobaxterm 第一步 xff1a 官网下载Anaconda 官网 xff1a https www anaconda com distr
  • 使用vscode 的remote 远程连接华为云

    文章目录 使用vscode 的remote 远程连接华为云前言remote development免密码登录使用vscode 远程编写一个c函数 使用vscode 的remote 远程连接华为云 前言 博主前阵子 xff0c 买了个华为云的
  • python扫盲之self、join()和shape、dim

    目录 1 self2 join 3 张量的shape和dim 1 self self相当于全局变量 xff0c 如果某个变量会应用到不止一个函数中 xff0c 那就在 init 函数中定义带有self的变量 xff1b 相反 xff0c 如
  • (matlab)mat文件中的cell数据存到xls中-writematrix()

    mydata3 mat文件的数据结构是这样的 xff1a 其中的trajLU xff08 列名 xff09 是struct类型 xff0c 其中的数据是1 1的cell xff0c 每个cell里又是n 3的double数据 xff0c 说
  • python读取DataFrame的某行或某列

    常用操作 xff0c 记录一下防止忘记 span class token keyword import span numpy span class token keyword as span np span class token keyw
  • python numpy数组含逗号的切片

    普通切片操作 xff1a span class token builtin list span 名 span class token punctuation span 首 xff1a 尾 xff1a 步长 span class token
  • python多张子图画在一张画布上,显示图例和标题,并保存。

    1 分别画4个折线图子图 xff0c 并保存为svg格式 xff08 矢量图 xff0c 放大不模糊 xff09 x span class token operator 61 span span class token punctuatio
  • jupyter使用help函数查询函数功能

    写在前边 切记 xff1a 函数不要带小括号 xff01 xff01 先 import 对应的python库 xff01 xff01 span class token function import span xx help span cl
  • python 列表赋值给另一个列表不改变原列表(深拷贝和浅拷贝)

    先放结论 xff1a 要想列表复制给另一个列表不改变原列表 xff0c 应使用方法三深拷贝 列表内的数值是不可变类型 xff0c 列表内的列表是可变类型 a span class token operator 61 span span cl
  • Ubuntu 20.04 安装 tensorflow-gpu

    1 安装Anaconda3 1 1 下载安装包 wget P tmp https repo anaconda com archive Anaconda3 2020 02 Linux x86 64 sh 1 2 安装 bash tmp Ana
  • 实验3  数据库综合查询

    实验3 数据库综合查询 一 实验目的 掌握SELECT语句的基本语法和查询条件表示方法 xff1b 掌握查询条件种类和表示方法 xff1b 掌握连接查询的表示及使用 xff1b 掌握嵌套查询的表示及使用 xff1b 了解集合查询的表示及使用
  • Ubuntu18安装mysql8.0

    一 删除mysql 5 7 卸载 sudo apt get remove mysql common sudo apt get autoremove purge mysql server 5 7 清理残留数据 dpkg l grep rc a
  • 将arduino uno的数据上传到云平台

    文章目录 将arduino uno的数据上传到云平台解决方案adruino uno方面代码esp8266 方面代码主函数阿里云sdkcpp部分函数头部分 将arduino uno的数据上传到云平台 解决方案 加一块esp8266的单片机 x
  • 华为IS-IS基础配置

    目录 一 原理概述 二 实验要求 三 实验拓扑 四 实验步骤 一 原理概述 1 IS IS xff1a Intermediate System to Intermediate System xff0c 中间系统到中间系统 2 链路状态协议

随机推荐

  • 基于markdown-it打造的markdown编辑器

    前言 markdown it是一个用来解析markdown的库 xff0c 它可以将markdown编译为html xff0c 然后解析时markdown it会根据规则生成tokens xff0c 如果需要自定义 xff0c 就通过rul
  • WiFi模块ESP-07s开发过程(学习笔记)

    目录 注意事项获取AT指令用到的指令通过返回的指令提取自己想要的信息 注意事项 转义字符 xff1a xff1a C中定义了一些字母前加 34 34 来表示常见的那些不能显示的ASCII字符 xff0c 如 0 t n等 xff0c 就称为
  • Vue3 table表格使用axios调用后端Api数据,统一返回格式

    1 安装axios npm install axios 2 封装axios span class token keyword import span span class token namespace axios span span cl
  • 关于C++的string字符串拼接问题(和“字符转字符串”问题有关)

    xff08 只有气到我肺都炸了的情况下我才可能废一些时间去写博客 xff08 主要是写一些气话 xff09 xff0c 但现在气消得差不多了我也骂不出什么话了 正文 1 字符串拼接分软拼接和硬拼接 xff08 软硬拼接 是我自己发明的词 实
  • [week2]化学——识别烷烃基

    文章目录 题意InputOutput输入样例输出样例 分析总结代码 题意 化学很神奇 xff0c 以下是烷烃基 假设如上图 xff0c 这个烷烃基有6个原子和5个化学键 xff0c 6个原子分别标号1 6 xff0c 然后用一对数字 a b
  • [week2]模拟OJ成绩排名系统(简易版)

    文章目录 题意InputOutput输入样例输出样例 分析总结代码 题意 题面宛如小作文233 程序设计思维作业和实验使用的实时评测系统 xff0c 具有及时获得成绩排名的特点 xff0c 那它的功能是怎么实现的呢 xff1f 我们千辛万苦
  • [week3]区间选点问题——贪心算法

    目录 题意InputOutput输入样例输出样例 分析总结代码 题意 数轴上有 n 个闭区间 a i b i 取尽量少的点 xff0c 使得每个区间内都至少有一个点 xff08 不同区间内含的点可以是同一个 xff09 Input 第一行1
  • [week3]区间覆盖问题——贪心算法

    目录 题意InputOutput输入样例输出样例提示 分析总结代码 题意 数轴上有 n 1 lt 61 n lt 61 25000 个闭区间 ai bi xff0c 选择尽量少的区间覆盖一条指定线段 1 t xff08 1 lt 61 t
  • [csp模拟1]咕咕东的奇遇——(一)

    目录 题意InputOutput输入样例输出样例提示 分析总结代码 题意 咕咕东是个贪玩的孩子 xff0c 有一天 xff0c 他从上古遗迹中得到了一个神奇的圆环 这个圆环由字母表组成首尾相接的环 xff0c 环上有一个指针 xff0c 最
  • Linux挂载镜像的一些命令

    Linux挂载镜像的一些命令 在Linux中 xff0c 可以用losetup命令来设置无分区空白镜像到loop设备上 xff0c 用kpartx 来kpartx映射分区的镜像到loop设备上 之后通过mount命令将loop设备与系统文件
  • [week5]平衡字符串——尺取法

    目录 题意InputOutput输入样例输出样例提示 分析总结代码 题意 一个长度为 n 的字符串 s xff0c 其中仅包含 Q W E R 四种字符 如果四种字符在字符串中出现次数均为 n 4 xff0c 则其为一个平衡字符串 现可以将
  • [csp模拟2]T4——咕咕东的奇妙序列

    文章目录 题意InputOutput输入样例输出样例提示 分析总结代码 题意 咕咕东 正在上可怕的复变函数 xff0c 但对于稳拿A Plus的 咕咕东 来说 xff0c 她早已不再听课 xff0c 此时她在睡梦中 突然想到了一个奇怪的无限
  • [week9]签到题(长凳)——贪心算法

    文章目录 题意InputOutput输入样例输出样例提示 分析总结代码 题意 SDUQD 旁边的滨海公园有 x 条长凳 第 i 个长凳上坐着 a i 个人 这时候又有 y 个人将来到公园 xff0c 他们将选择坐在某些公园中的长凳上 xff
  • [week14] Q老师与十字叉

    文章目录 题意InputOutput输入样例输出样例提示 分析总结代码 题意 Q老师 得到一张 n 行 m 列的网格图 xff0c 上面每一个格子要么是白色的要么是黑色的 Q老师认为失去了 十字叉 的网格图莫得灵魂 一个十字叉可以用一个数对
  • [week15] ZJM 与霍格沃兹 —— 字符串哈希

    文章目录 题意InputOutput输入样例输出样例提示 分析总结代码 题意 ZJM 为了准备霍格沃兹的期末考试 xff0c 决心背魔咒词典 xff0c 一举拿下咒语翻译题 题库格式 xff1a 魔咒 对应功能 背完题库后 xff0c ZJ
  • [week14] D - Q老师染砖(选做) —— 矩阵快速幂优化DP

    文章目录 题意InputOutput输入样例输出样例提示 分析总结代码 题意 衣食无忧的 Q老师 有一天突发奇想 xff0c 想要去感受一下劳动人民的艰苦生活 具体工作是这样的 xff0c 有 N 块砖排成一排染色 xff0c 每一块砖需要
  • [week14] E - Q老师度假(选做)—— 矩阵快速幂优化DP(拓展)

    文章目录 题意InputOutput输入样例输出样例提示 分析总结代码 题意 忙碌了一个学期的 Q老师 决定奖励自己 N 天假期 假期中不同的穿衣方式会有不同的快乐值 已知 Q老师 一共有 M 件衬衫 xff0c 且如果昨天穿的是衬衫 A
  • [week15] B - ZJM与生日礼物(选做)—— 字典树

    文章目录 题意InputOutput输入样例输出样例提示 分析总结代码 题意 ZJM 收到了 Q老师 送来的生日礼物 xff0c 但是被 Q老师 加密了 只有 ZJM 能够回答对 Q老师 的问题 xff0c Q老师 才会把密码告诉 ZJM
  • [week15] C - ZJM与纸条(选做)—— KMP算法

    文章目录 题意InputOutput输入样例输出样例提示 分析总结代码 题意 ZJM 的女朋友是一个书法家 xff0c 喜欢写一些好看的英文书法 有一天 ZJM 拿到了她写的纸条 xff0c 纸条上的字暗示了 ZJM 的女朋友 想给 ZJM
  • 51按键外部中断控制流水灯

    实验二 外部按键输入 一 实验目的 1 了解单片机检测口方法 2 了解单片机外部中断原理 3 了解按键输入原理 二 实验内容 1 完成按键扫描控制流水灯 2 完成按键外部中断控制流水灯 三 实验原理 四 实验电路与程序 1 软件实验一 xf