标题:
avr单片机定时与中断做的电子琴(仿真+程序)
[打印本页]
作者:
jinsheng7533967
时间:
2018-12-13 18:23
标题:
avr单片机定时与中断做的电子琴(仿真+程序)
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
定时与中断做的电子琴.jpg
(411.75 KB, 下载次数: 70)
下载附件
2018-12-13 18:21 上传
avr单片机源码:
#include <iom16v.h>
#include <macros.h>
#define uchar unsigned char
#define uint unsigned int
#define LED1_ON() PORTA=0xFE
#define LED2_ON() PORTA=0xF7
#define LED3_ON() PORTA=0xBF
#define LED4_ON() PORTA=0x7F
uchar key_0=16;
uint Fr[]= {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};
uchar SEG_CODE[]=
{ 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E
};
uint Tone_Delay_Table[] =
{ 64021,64103,64260,64400,64524,64580,64684,64777,
64820,64898,64968,65030,65058,65110,65157,65178};
uchar spe1_Tone[] = { 3,5,5,3,2,1,2,3,5,3,
2,3,5,5,3,2,1,2,3,2,1,1,0xFF };
uchar spe1_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 spe2_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 spe2_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 spe3_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 spe3_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};
uchar spe4_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 spe4_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 *spe_Tone_Ptr[]={
spe1_Tone,spe2_Tone,spe3_Tone,spe4_Tone},
*spe_Time_Ptr[]=
{spe1_Time,spe2_Time,spe3_Time,spe4_Time};
uint Tone_Idx = 0;
uint i = 0,j=1,spe_Idx = 0;
uint FALSE = 0, TRUE = 1, Pause = 1;
void delay_1ms(void)
{
uint i;
for(i=1;i<(uint)(153*143-2);i++)
;
}
void delay(unsigned int n)
{
unsigned int i;
for(i=0;i<n;i++)
delay_1ms();
}
uchar KeyMatrix_Down()
{
DDRB=0XF0;
PORTB=0X0F;
delay(1);
return PINB!=0x0f? 1:0;
}
void Keys_Scan()
{
switch(PINB)
{
case 0B00001110: key_0=0; break;
case 0B00001101: key_0=1; break;
case 0B00001011: key_0=2; break;
case 0B00000111: key_0=3; break;
default:key_0=0xFF;
}
DDRB=0x0F;
PORTB=0xF0;
delay(1);
switch(PINB)
{
case 0B11100000: key_0+=0; break;
case 0B11010000: key_0+=4; break;
case 0B10110000: key_0+=8; break;
case 0B01110000: key_0+=12; break;
default: key_0= 0xFF;
}
}
int main()
{
DDRB=0xFF;
PORTB=0xFF;
DDRA=0xFF;
PORTA=0xFF;
DDRC=0xFF;
PORTC=0xBF;
DDRD|=BIT(PD7);
PORTD&=~BIT(PD7);
DDRD=~(BIT(PD2)|BIT(PD3));
PORTD=BIT(PD2)|BIT(PD3);
MCUCR=0x82;
GICR=BIT(INT0)|BIT(INT1);
TCCR1A=0x00;
TCCR1B=0x09;
SREG=0x80;
while(1)
{
if(KeyMatrix_Down()==0)
{
if(Pause)
{
continue;
}
TCCR1B=0x01;
Tone_Idx=spe_Tone_Ptr[spe_Idx][i];
if(Tone_Idx==0xFF)
{
delay(200);
i=0;
continue;
}
TIMSK=BIT(TOIE1);
delay(spe_Time_Ptr[spe_Idx][Tone_Idx]*200/26);
TIMSK=0x00;
i++;
}
else
{
if(Pause==0)
{
continue;
}
if(key_0==0 || key_0>16);
continue;
PORTC=SEG_CODE[key_0];
OCR1A=153/2/Fr[key_0];
TCNT1=0;TIMSK|= BIT(OCIE1A);
while(KeyMatrix_Down());
TIMSK &=~BIT(OCIE1A);
}
}
}
#pragma interrupt_handler timer1_ovf_isr:9
void timer1_ovf_isr(void)
{
if(Tone_Idx==0xFF)return;
TCNT1=Tone_Delay_Table[Tone_Idx];
PORTD^= BIT(PD7);
}
#pragma interrupt_handler int0_isr:2
void int0_isr(void)
{
TIMSK=0x00;
if(spe_Idx==3)spe_Idx=0;
else spe_Idx++;
i=0;
switch(spe_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);
}
#pragma interrupt_handler int1_isr:3
void int1_isr(void)
{
Pause= !Pause;
if(Pause)
{
PORTC=0xFF;
PORTA=0xFF;
TIMSK=0x00;
}
}
}
#pragma interrupt_handler timer1_compa_isr:7
void timer1_compa_isr(void)
{
PORTD^=BIT(PD7);
}
复制代码
全部源码附件中
定时与中断做的电子琴.zip
(14.79 KB, 下载次数: 52)
2018-12-13 18:22 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
chaoer123
时间:
2020-4-27 22:45
程序不难可以
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1