当前位置: 首页 > news >正文

进阶五 按键切换不同led流水效果

 功能概述

  1. 初始化
    • 初始化外部中断0(INT0)为边沿触发方式。
    • 开启全局中断。
  2. LED显示模式
    • crol():将P1口的LED向左旋转一位。
    • cror():将P1口的LED向右旋转一位。
    • blink():使所有LED闪烁(全亮和全灭交替)。
    • off():关闭所有LED。
  3. 模式切换
    • 每次按下连接到INT0的按钮时,会切换到下一个LED显示模式。
    • 模式循环为:左旋转 -> 右旋转 -> 闪烁 -> 关闭 -> 左旋转 ...

详细分析

  • 中断初始化
    • IT0 = 1;:设置INT0为边沿触发方式。
    • EX0 = 1;:启用INT0中断。
    • EA = 1;:启用全局中断。
  • LED控制函数
    • crol():使用_crol_函数将P1口的值左移一位。
    • cror():使用_cror_函数将P1口的值右移一位。
    • blink():使所有LED闪烁,亮500毫秒,灭500毫秒。
    • off():关闭所有LED。
  • 主循环
    • main()函数中初始化中断后,进入无限循环,调用fst()函数。
    • fst()函数根据count的值选择相应的LED显示模式。
  • 中断服务程序
    • ex0_isr()是INT0的中断服务程序。
    • 包含简单的去抖动处理,通过延时和再次检查引脚状态来防止机械开关的抖动。
    • 每次中断触发时,count递增,并在达到4时重置为0,确保模式循环。

潜在问题和改进建议

  1. 去抖动处理
    • 当前的去抖动处理是简单的延时,可能不够完善。可以考虑使用硬件去抖动或更复杂的软件去抖动算法。
  2. LED状态
    • ex0_isr()中,P1=0x7f;会强制设置P1口的状态,这可能会干扰其他模式。建议移除或根据需要调整。
  3. 模式循环
    • 当前的模式循环是0到3,确保count的范围始终在0到3之间。
#include<reg51.h>
#include<intrins.h>typedef unsigned char uchar;
typedef unsigned int uint;volatile uint count = 0;  // Added volatile since it's modified in ISRvoid ex0_init(void);
void crol(void);
void cror(void);
void blink(void);
void off(void);
void fst(void);
void delayms(uint);void delayms(uint x)
{uint i;while(x--){for(i=89;i>0;i--);}
}void crol(void)
{P1 = _crol_(P1, 1);delayms(500);
}void cror(void)
{P1 = _cror_(P1, 1);  // Fixed function namedelayms(500);
}void blink(void)
{P1=0x00;delayms(500);P1=0xff;delayms(500);
}void off(void)
{P1=0xff;
}void fst(void)
{switch(count){case 0: crol(); break;case 1: cror(); break;case 2: blink(); break;case 3:	off();break;default: count = 0;}
}void main()
{ex0_init();  // Initialize external interrupt onceP1=0x80;while(1){fst();}
}void ex0_init(void)
{IT0 = 1;   // Edge-triggered interruptEX0 = 1;   // Enable EX0 interruptEA = 1;    // Enable global interrupts
}void ex0_isr(void) interrupt 0
{delayms(10);  // 延时去抖动if(INT0 == 0)  // 再次检查引脚状态{count++;if(count >= 4){count = 0;}  }		P1=0x7f;while(!INT0);}

http://www.lqws.cn/news/459541.html

相关文章:

  • 李宏毅 《生成式人工智能导论》| 第6讲-第8讲:大语言模型修炼史
  • 关于ubuntu环境下vscode进行debug的随笔
  • 【工具教程】识别PDF中文字内容,根据文字内容对PDF批量重命名,提取识别PDF内容给图片重新命名的操作步骤和注意事项
  • 第十三章 模板
  • 机器学习流量识别(pytorch+NSL-KDD+多分类建模)
  • 自动化性能回退机制——蓝绿部署与灰度发布
  • 前端 CSS 框架:分类、选择与应用
  • 「AI高校」| 《清华大学:AI赋能教育高考志愿填报工具使用指南》
  • 新品上市 | 尺寸小且具有丰富接口的读卡器:RFID高频系列CK-FR06
  • MySQL之事务深度解析
  • django FileSystemStorage is located outside of the base path component
  • Android Studio报错:Could not move temporary workspace () to immutable location
  • NY339NY341美光固态闪存NW841NW843
  • MySQL入门初解
  • 数据分析和可视化:Py爬虫-XPath解析章节要点总结
  • 【Dify学习笔记】:RagFlow接入Dify基础教程
  • Real-World Deep Local Motion Deblurring论文阅读
  • Linux——linux的基本命令
  • ceph 自动调整 pg_num
  • 链接过程使用链接器将该目标文件与其他目标文件、库文件、启动文件等链接起来生成可执行文件。附加的目标文件包括静态连接库和动态连接库。其中的启动文件是什么意思?
  • SpringMVC知识点总结
  • python自助棋牌室管理系统
  • golang编译时传递参数或注入变量值到程序中
  • JVM对象内存分配机制全解析
  • Springboot仿抖音app开发之Nacos 分布式服务与配置中心(进阶)
  • C/C++ 高频八股文面试题1000题(一)
  • 408第二季 - 组成原理 - 流水线
  • 开疆智能ModbusTCP转EtherCAT网关连接IVO编码器配置案例
  • Python 的内置函数 globals
  • [MSPM0开发]之九 MSPM0G3507的ADC