C51 原创电子琴 (蜂鸣器/计时器/中断/矩阵按键)
需求分析
用C51的16个矩阵按键当作两个八度的琴键
按下时发出相应音调的声音,静态数码管显示相应音符的数字。
为了解锁更多曲目,两个多的琴键设计成#4,显示时加上小数点
下图分别为1和#4的显示,其中图一上标明了各按键的对应的音符:
思路
每当按键按下,判断是那个按键,
在按键尚未松开时循环以下内容:启动定时器,计时的时长为“该音调频率的一半“,每过这段时间,蜂鸣器所在引脚电平取反
各音符的频率
参考:https://blog.csdn.net/weixin_34724366/article/details/80642207
Highs 和 Lows 的计算方法:
1/(2f) s = 1000/(2f) ms = 500 / f ms
然后带入这个小程序即可
接线图
完整代码
#include <reg51.h>
typedef unsigned int u16;
typedef unsigned char u8;
#define GPIO_KEY P1
#define GPIO_DIG P0
sbit beep = P3^0;
/*******************************全局变量******* *******************/
u8 code Highs[24] = {
0xfc,0xfc,0xfd,0xfd,0xfd,0xfd,0xfe,0xfd,
0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xff ,0xff };
u8 code Lows[24] = {
0x44,0xfac,0x09,0x34,0x82,0xc7,0x05,0x5c,
0x22,0x56,0x84,0x9a,0xc1,0xe3,0x02,0x11 };
//共阴的表
u8 code ledSegment [24] = { 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,0xe6,
0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,0xe6,
0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,0xe6};
u8 KeyValue;
/***************************************************************/
void delay(u16 i)
{
while(i--);
}
void keyDown()
{
//char a = 0;
GPIO_KEY = 0x0f; //高四位低电平,低四位高电平
if(GPIO_KEY!= 0x0f) //如果有按键按下
{
delay(1000); //延时防抖
if(GPIO_KEY!= 0x0f)
{
//--------------------求被按下的按键在第几列----------------------------//
switch(GPIO_KEY)
{
case(0x07): KeyValue = 0; break; //0000 0111 : 第一列
case(0x0b): KeyValue = 1; break; //0000 1011 : 第二列
case(0x0d): KeyValue = 2; break; //0000 1101 : 第三列
case(0x0e): KeyValue = 3; break; //0000 1110 : 第四列
}
//--------------------求被按下的按键在第几行----------------------------//
GPIO_KEY = 0xf0; //高四位高电平,低四位低电平
switch(GPIO_KEY)
{
case(0x70): KeyValue += 0; break; //第一行
case(0xb0): KeyValue += 4; break;
case(0xd0): KeyValue += 8; break;
case(0xe0): KeyValue += 12; break; //第四行
}
//--------------------------开始计时----------------------------------//
GPIO_DIG = ~ledSegment[KeyValue]; //共阳数码管,共阴的表,所以要取反
//赋初值
TH0 = Highs[KeyValue];
TL0 = Lows[KeyValue];
//开始计时
TR0=1;
//退出条件:按键松开
while(GPIO_KEY!= 0xf0) // GPIO_KEY!= 0xf0 说明按键还没松,此时CPU始终在此循环中
{
}
}
}
}
void T0Init()
{
TMOD |= 0x01; //选择工作方式,给TMOD 赋值 ,这里选T0,方式一
ET0 = 1 ; //中断允许:总允许和T0允许
EA = 1;
}
void main(void)
{
T0Init();
while(1)
{
keyDown();
}
}
//计时器0的调用程序
void Timer0() interrupt 1 // T0溢出时引用
{
//退出条件:按键松开
if(!(GPIO_KEY== 0xf0 || GPIO_KEY== 0x0f)) //如果按键还没松开,进入下一个计时
{
TH0 = Highs[KeyValue];
TL0 = Lows[KeyValue];
beep = ~beep;
}
}
C51 原创电子琴 (蜂鸣器/计时器/中断/矩阵按键)的更多相关文章
- 【C51】单片机独立按键与矩阵按键
独立按键 首先既然是检测输入,对于当然要用到拉电阻,来检测引脚电平变化变化.51单片机中,除了P0口外,P2,P3,P4都是内置上拉电阻的准双向IO口,一般 的 51 P0引脚都外接了上拉电阻,当然也 ...
- C51 矩阵按键 个人笔记
矩阵按键 电路 每个按键一端和同行一端相连(JP4的高4位),另一端和同列一端相连(JP4的低4位) 判断按键是否按下: 法一:逐行扫描 for(int i = 8 ; i>3 ; i-- ) ...
- AD按键-矩阵按键-独立按键:
原理:利用数组分压+AD采集: 优点:一个IO口可以做成多个按键,节省IO口(矩阵键盘在>4时优点才能体现出来):可备用作为AD基准输入. 缺点:不能做成组合按键(或者电阻要精确选择):且离IO ...
- AD按键-矩阵按键:
原理:利用数组分压+AD采集: 优点:一个IO口可以做成多个按键,节省IO口(矩阵键盘在>4时优点才能体现出来):可备用作为AD基准输入. 缺点:不能做成组合按键(或者电阻要精确选择):且离IO ...
- TI-RTOS 之 GPIO中断(按键)
TI-RTOS 之 GPIO中断(按键) 前面已经用过LED, 定时器,这次来了解GPIO的中断是怎么用的,从CC1310+TI-RTOS的例程可以直接找到相应的例子程序,它的关键是在于要使能中断,也 ...
- 【.NET 与树莓派】矩阵按键
欢迎收看火星卫视,本期节目咱们严重探讨一下矩阵按键. 所谓矩阵按键,就是一个小键盘(其实一块PCB板),上面有几个 Key(开关),你不按下去的时候,电路是断开的,你按下去电路就会接通.至于说有多少个 ...
- 矩阵按键的试验---verilog
矩阵键盘的试验,采用三段式状态机处理方法. 难点在于检测状态机中:按键消抖以后逐列检测. 电路图: 代码 /********************************Copyright***** ...
- 字符设备驱动笔记——中断方式按键驱动之linux中断处理结构(五)
一.单片机下的中断处理 )分辨是哪一个中断 )调用处理函数 )清中断 二.linux下的中断处理 1)/arch/arm/kernel/irq.c asmlinkage void __exceptio ...
- 字符设备驱动笔记——中断方式按键驱动之linux异常处理结构(四)
.中断方式获取按键值 单片机: )按键按下 )cup发生中断,跳转到异常向量入口执行 )b 函数 a.保存被中断的现场 b.执行中断处理函数 c.恢复 linux: )trap_init()函数构造异 ...
随机推荐
- [Usaco2012 Open]Balanced Cow Subsets
Description Farmer John's owns N cows (2 <= N <= 20), where cow i produces M(i) units of milk ...
- Matlab实现Butterworth滤波器 分类: 图像处理 2014-06-02 00:05 527人阅读 评论(0) 收藏
下面是用Matlab实现的Butterworth高通.低通滤波器. clc;clear all;close all; I=imread('cameraman.tif'); subplot(3,2,1) ...
- ASP.NET MVC+Bootstrap个人博客之修复UEditor编辑时Bug(四)
我的个人博客站在使用百度富文本编辑器UEditor修改文章时,遇到了一些问题,(不知是bug,还是我没有配置好).但总算找到了解决方法,在此记录下来. 遇到的问题: 正常来讲,进入文章修改页,只需将U ...
- 利用Laravel 搭建oauth2 API接口 附 Unauthenticated 解决办法
利用Laravel 搭建oauth2 API接口 要求 laravel 5.4以上 安装 $ composer require laravel/passport 在配置文件 config/app.ph ...
- hihocoder offer收割编程练习赛12 C 矩形分割
思路: 模拟,深搜. 实现: #include <iostream> #include <cstdio> #include <string> using names ...
- swiper4实现的拥有header和footer的全屏滚动demo/swiper fullpage footer
用swiper4实现的拥有header和footer的全屏滚动demo, <!DOCTYPE html> <html lang="en"> <head ...
- 源代码管理git的使用
Git ----本地仓库---- 1.新建一个“本地仓库” git init 2.配置仓库 ①告诉git你是谁 git config user.name syl ②告诉git怎么联系你 git con ...
- Node.js——require加载规则
判断require中的标识参数: 非路径的标识参数:也被称为是核心模块,已经被编译到二进制文件中 带有路径标识参数:自定义模块,一般都是相对定位 第三方模块:表现形式与核心模块一样,但是实际不一样,它 ...
- Vue.js语法糖整理
el:element 需要获取的元素,一定是HTML中的根容器元素 data:用于数据的存储 methods:用于存储各种方法 数据绑定字面量只加载一次{{* msg}} data里面可以进行简单的运 ...
- codeforces_C. Sequence Transformation
http://codeforces.com/contest/1059/problem/C 题意: 最初给一个1.2.3.…….n的序列,每次操作先将所有元素的最大公约数加入答案序列,然后在序列中任意删 ...