AVR单片机设计电子琴程序
更新时间:2023-06-02 14:25:01 阅读量: 实用文档 文档下载
电子琴的c语言程序
AVR单片机设计电子琴程序
//-----------------------------------------------------------------
// 名称: 多首电子音乐的选播
//-----------------------------------------------------------------
// 说明: 本例运行时,每次按下K1将切换播放下一首电子音乐,对应的
// LED指示灯将被点亮.
//
//-----------------------------------------------------------------
#define F_CPU 8000000UL //8M晶振
#include <iom16v.h>
#include <macros.h>
#define uchar unsigned char
#define uint unsigned int
//指示灯控制(任一LED点亮时都会关闭其他指示灯)
#define LED1_ON() PORTA=0xFE
#define LED2_ON() PORTA=0xF7
#define LED3_ON() PORTA=0xBF
#define LED4_ON() PORTA=0x7F
//===========================================================
//当前按键序号,该矩阵中序号范围为0-15,16表示无按键
uchar KeyNo=16;
//C调音符频率表(部分)
uint TONE_FRQ[]=
{0,262*8,294*8,330*8,349*8,392*8,440*8,494*8,523*8,587*8,659*8,698*8,784*8,880*8,988*8,1046*8};
//共阳数码管段码表(0~F)
uchar SEG_CODE[]=
{
0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8, //0 1 2 3 4 5 6 7
0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E //8 9 A B C D E F
};
//音符延时表,它们分别对应于0~15号音符的输出频率
uint Tone_Delay_Table[] =
{
64021,64103,64260,64400,64524,64580,64684,64777,
64820,64898,64968,65030,65058,65110,65157,65178
};
//第一段(Tone为音符,Time为节拍)
uchar Music1_Tone[] =
{ 3,5,5,3,2,1,2,3,5,3,2,3,5,5,3,2,1,2,3,2,1,1,0xFF };
电子琴的c语言程序
uchar Music1_Time[] =
{ 2,1,1,2,1,1,1,2,1,1,1,2,1,1,2,1,1,1,2,1,1,1,0xFF };
//第二段
uchar Music2_Tone[] =
{ 1,3,3,3,3,5,4,2,5,3,7,6,5,5,7,4,4,3,6,7,2,1,0xFF };
uchar Music2_Time[] =
{ 2,1,1,2,1,1,1,2,1,1,3,2,1,1,2,4,1,1,2,1,1,1,0xFF };
//第三段
uchar Music3_Tone[] =
{ 0,1,2,3,4,5,5,6,7,8,9,10,11,12,13,14,15,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0xFF};
uchar Music3_Time[] =
{ 1,1,1,1,1,1,1,1,1,1,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1,1,1,1,0xFF};
//第四段1/2拍为底
uchar Music4_Tone[] =
{ 1,2,3,1,1,2,3,1,3,4,5,3,4,5,5,6,5,4,3,1,5,6,5,4,3,1,1,5,1,1,5,1,0xFF };
uchar Music4_Time[] =
{ 2,1,1,1,2,1,1,1,2,1,1,2,1,1,3,0.5,0.25,0.5,0.25,1,1,0.5,0.25,0.5,1,1,1,1,3,1,1,3,0xFF }; //======================================
uchar *Music_Tone_Ptr[]={Music1_Tone,Music2_Tone,Music3_Tone,Music4_Tone}, *Music_Time_Ptr[]={Music1_Time,Music2_Time,Music3_Time,Music4_Time}; //音乐片段索引,音符索引
uint Tone_Idx = 0;
//从当前数组中取音符的位置
uint i = 0,j=1,Music_Idx = 0;
//暂停控制
uint FALSE = 0, TRUE = 1, Pause = 1;
//=================================================
void delay_1ms(void)
{
uint i;
for(i=1;i<(uint)(F_CPU*143-2);i++)
;
}
void delay(unsigned int n)
{
unsigned int i;
for(i=0;i<n;i++)
delay_1ms();
}
//=================================================
电子琴的c语言程序
//-----------------------------------------------------------------
// 判断键盘矩阵是否有键按下
//-----------------------------------------------------------------
uchar KeyMatrix_Down()
{
//高4位输出,低4位输入,高4位先置0,放入4行
DDRB=0XF0;
PORTB=0X0F;
delay(1);
return PINB!=0x0f? 1:0;
}
//-----------------------------------------------------------------
// 键盘矩阵扫描子程序
//-----------------------------------------------------------------
void Keys_Scan()
{
//在判断是否有按键按下的函数KeyMatrix_Down中,
//高4位输出,低4位输入,高4位先置0,放入4行
//按键后00001111将变成0000XXXX,X中有1个为0,3个为1
//下面判断按键发生于0~3列中的哪一列
switch(PINB)
{
case 0B00001110: KeyNo=0; break;
case 0B00001101: KeyNo=1; break;
case 0B00001011: KeyNo=2; break;
case 0B00000111: KeyNo=3; break;
default:KeyNo=0xFF;
}
//高4位输入,低4位输出,低4位先置0,放入4列
DDRB=0x0F;
PORTB=0xF0;
delay(1);
//按键后11110000将变成XXXX0000,X中有1个为0,3个为1
//下面对0~3行分别附加起始值0、4、8、12
switch(PINB)
{
case 0B11100000: KeyNo+=0; break;
case 0B11010000: KeyNo+=4; break;
case 0B10110000: KeyNo+=8; break;
电子琴的c语言程序
case 0B01110000: KeyNo+=12; break;
default: KeyNo= 0xFF;
}
}
//-----------------------------------------------------------------
// 主程序
//-----------------------------------------------------------------
int main()
{//矩阵键盘
DDRB=0xFF;
PORTB=0xFF;
//LED灯
DDRA=0xFF;
PORTA=0xFF; //LED初始时全部关闭
//数码管
DDRC=0xFF;
PORTC=0xBF; //数码管初始显示“-”
DDRD|=BIT(PD7);
PORTD&=~BIT(PD7);
//外部中断
DDRD=~(BIT(PD2)|BIT(PD3)); //中断引脚设为输入
PORTD=BIT(PD2)|BIT(PD3); //中断输入引脚设为内部上拉
MCUCR=0x82; //INT0,INT1均为下降沿触发
GICR=BIT(INT0)|BIT(INT1); //INT0,INT1中断许可
TCCR1A=0x00; //TC1与OC1A不连接,禁止PWM功能
TCCR1B=0x09;//T1预分频:1,CTC模式(比较匹配时TC1自动清零?
SREG=0x80; //开中断
while(1)
{
if(KeyMatrix_Down()==0)
电子琴的c语言程序
{
//暂停控制
if(Pause)
{
continue;
}
TCCR1B=0x01; //T1预分频:1
Tone_Idx=Music_Tone_Ptr[Music_Idx][i];
if(Tone_Idx==0xFF)
{
//delay(2000); 每段音乐播放结束后停顿一段时间
delay(200);
i=0; //回到当前音乐片段的第0个音符
continue; //继续播放
}
//TIMSK|=BIT(TOIE1);
TIMSK=BIT(TOIE1); //启动定时器溢出中断,开始输出当前音符
//音符输出时长(节拍)由各段音乐中的MusicX_Time数组中对应音符的延时值决定 delay(Music_Time_Ptr[Music_Idx][Tone_Idx]*200/26);
//TIMSK&=~BIT(TOIE1);
TIMSK=0x00; //禁止定时器溢出中断,停止当前音符输出
i++; //取音符位置变量i递增
} else//(KeyMatrix_Down()) { if(Pause==0)
{continue;
}
TCCR1B=0x09;//T1预分频:1,CTC模式(比较匹配时TC1自动清零)
if(KeyMatrix_Down()) //有键按下则扫描按键
{Keys_Scan();
}
else continue;
if(KeyNo==0 || KeyNo>16) //按键无效或按下0键则继续
continue;
PORTC=SEG_CODE[KeyNo]; //数码管显示键值
OCR1A=F_CPU/2/TONE_FRQ[KeyNo];
TCNT1=0;TIMSK|= BIT(OCIE1A);
while(KeyMatrix_Down()); //等待释放
//PORTD=0x7F; TIMSK &=~BIT(OCIE1A);
电子琴的c语言程序
}
}
}
//----------------------------------------------------------------- // T1定时器溢出中断控制音符输出
//----------------------------------------------------------------- #pragma interrupt_handler timer1_ovf_isr:9
void timer1_ovf_isr(void)
{
//如果遇到音乐片段结束标志则返回
if(Tone_Idx==0xFF)return;
//根据Tone_Delay_Table[Tone_Idx]设置定时初值 //该初值即决定了输出的频率
TCNT1=Tone_Delay_Table[Tone_Idx];
PORTD^=BIT(PD7);
}
//----------------------------------------------------------------- // 按键触发INT0中断,控制音乐段切换
//----------------------------------------------------------------- #pragma interrupt_handler int0_isr:2
void int0_isr(void)
{
TIMSK=0x00; //禁止定时器溢出中断,音符输出停止 //切换到另一段音乐
if(Music_Idx==3)Music_Idx=0;
else Music_Idx++;
//切换到新的一段音乐后总是从其第0个音符开始输出 i=0;
//打开对应的指示灯
switch(Music_Idx)
{
case 0:LED1_ON();PORTC=SEG_CODE[1]; break; case 1:LED2_ON(); PORTC=SEG_CODE[2];break; case 2:LED3_ON(); PORTC=SEG_CODE[3];break; case 3:LED4_ON(); PORTC=SEG_CODE[4];break; }
delay(10); //在开始另一段音乐输出前暂停1s
}
//----------------------------------------------------------------- // 播放启动/停止控制
电子琴的c语言程序
//----------------------------------------------------------------- #pragma interrupt_handler int1_isr:3
void int1_isr(void)
{
Pause= !Pause;
if(Pause)
{
PORTC=0xFF; //如果停止则关闭数码管
PORTA=0xFF;//如果停止则关闭LED灯
TIMSK=0x00; //停止音符输出
}
else
{
//否则打开对应指示灯
switch(Music_Idx)
{
case 0:LED1_ON();PORTC=SEG_CODE[1]; break; case 1:LED2_ON(); PORTC=SEG_CODE[2];break; case 2:LED3_ON(); PORTC=SEG_CODE[3];break; case 3:LED4_ON(); PORTC=SEG_CODE[4];break; }
TIMSK=BIT(TOIE1);
}
}
// T1定时器比较匹配中断程序,控制音符频率输出 //----------------------------------------------------------------- #pragma interrupt_handler timer1_compa_isr:7 void timer1_compa_isr(void)
{
PORTD^=BIT(PD7);
}
正在阅读:
AVR单片机设计电子琴程序06-02
房地产的“五证、两书、一表”04-24
高中物理牛顿第二定律连接体专题03-08
论文-中国近代民族工业的发展(概述)06-04
国土资源法律法规政策业务知识试题06-06
财务管理与分析_习题集(含答案)05-05
中国现代矿业发展之路 - 图文07-03
上海铁路局桥涵限高架防护架管理细则,工路桥函2009.8703-14
变化率问题教案04-15
- 教学能力大赛决赛获奖-教学实施报告-(完整图文版)
- 互联网+数据中心行业分析报告
- 2017上海杨浦区高三一模数学试题及答案
- 招商部差旅接待管理制度(4-25)
- 学生游玩安全注意事项
- 学生信息管理系统(文档模板供参考)
- 叉车门架有限元分析及系统设计
- 2014帮助残疾人志愿者服务情况记录
- 叶绿体中色素的提取和分离实验
- 中国食物成分表2020年最新权威完整改进版
- 推动国土资源领域生态文明建设
- 给水管道冲洗和消毒记录
- 计算机软件专业自我评价
- 高中数学必修1-5知识点归纳
- 2018-2022年中国第五代移动通信技术(5G)产业深度分析及发展前景研究报告发展趋势(目录)
- 生产车间巡查制度
- 2018版中国光热发电行业深度研究报告目录
- (通用)2019年中考数学总复习 第一章 第四节 数的开方与二次根式课件
- 2017_2018学年高中语文第二单元第4课说数课件粤教版
- 上市新药Lumateperone(卢美哌隆)合成检索总结报告
- 电子琴
- 单片机
- 程序
- 设计
- AVR
- 干式变压器的使用注意事项及保养方法
- 酿酒酵母的发酵过程优化
- 科技发展史结课论文
- 【数学】安徽省蚌埠市高三下学期第二次教学质量检查考试试题(文)(扫描版)
- 绩效管理的六大环节
- 如何给孩子科学断奶
- 印度尼西亚各类商会协会大全
- 1.2政治权利与义务(周景富)
- 大学生职业生涯规划书
- 泾源县什字中学学校整体情况汇报材料 - 副本 - 副本 - 副本
- TEM4 SAMPLE SCRIPT (部分〉
- 2011--2012学年期中考试
- 《语言学概论》复习题
- Ansys有限元分析实例
- 基于地域视角研究黄梅戏的唱腔特色
- 管理案例编写与教学(一)
- 初中化学总复习 溶液复习课导学案
- 河南省平顶山市英语三年级下册Unit 5 期末复习(单项选择)
- 质量环境食品安全管理手册
- 我国地区经济发展差距及其发展态势分析