单片机论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 332|回复: 0
打印 上一主题 下一主题
收起左侧

avr单片机定时与中断做的电子琴(仿真+程序)

[复制链接]
跳转到指定楼层
楼主
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)




avr单片机源码:

  1. #include <iom16v.h>
  2. #include <macros.h>

  3. #define uchar unsigned char
  4. #define uint unsigned int

  5. #define LED1_ON() PORTA=0xFE
  6. #define LED2_ON() PORTA=0xF7
  7. #define LED3_ON() PORTA=0xBF
  8. #define LED4_ON() PORTA=0x7F

  9. uchar key_0=16;

  10. uint Fr[]= {0,262*8,294*8,330*8,349*8,392*8,440*8,
  11. 494*8,523*8,587*8,659*8,698*8,784*8,880*8,988*8 ,1046*8};


  12. uchar SEG_CODE[]=
  13. { 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
  14. 0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E
  15. };

  16. uint Tone_Delay_Table[] =
  17. { 64021,64103,64260,64400,64524,64580,64684,64777,
  18. 64820,64898,64968,65030,65058,65110,65157,65178};

  19. uchar spe1_Tone[] = { 3,5,5,3,2,1,2,3,5,3,
  20. 2,3,5,5,3,2,1,2,3,2,1,1,0xFF };

  21. uchar spe1_Time[] =
  22. { 2,1,1,2,1,1,1,2,1,1,1,2,1,1,2,1,1,1,2,1,1,1,0xFF };

  23. uchar spe2_Tone[] =
  24. { 1,3,3,3,3,5,4,2,5,3,7,6,5,5,7,4,4,3,6,7,2,1,0xFF };
  25. uchar spe2_Time[] =
  26. { 2,1,1,2,1,1,1,2,1,1,3,2,1,1,2,4,1,1,2,1,1,1,0xFF };

  27. uchar spe3_Tone[] = { 0,1,2,3,4,5,5,6,7,8,9,10,11,12,13,14,15,
  28. 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0xFF};

  29. uchar spe3_Time[] =
  30. { 1,1,1,1,1,1,1,1,1,1,1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  31. 1, 1, 1,1,1,1,1,1,1,1,1,1,0xFF};

  32. uchar spe4_Tone[] =
  33. { 1,2,3,1,1,2,3,1,3,4,5,3,4,5,5,6,5,4,3,1,5,6,
  34. 5,4,3,1,1,5,1,1,5,1,0xFF };

  35. uchar spe4_Time[] =
  36. { 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,
  37. 0.5,0.25,0.5,1,1,1,1,3,1,1,3,0xFF };

  38. uchar *spe_Tone_Ptr[]={
  39.         spe1_Tone,spe2_Tone,spe3_Tone,spe4_Tone},
  40.                 *spe_Time_Ptr[]=
  41.         {spe1_Time,spe2_Time,spe3_Time,spe4_Time};
  42.         
  43.         uint Tone_Idx = 0;
  44.         
  45.         uint i = 0,j=1,spe_Idx = 0;
  46.         
  47.         uint FALSE = 0, TRUE = 1, Pause = 1;
  48.         
  49.         void delay_1ms(void)
  50.         {
  51.                 uint i;
  52.                 for(i=1;i<(uint)(153*143-2);i++)
  53.                         ;
  54.         }
  55.         
  56.         void delay(unsigned int n)
  57.         {
  58.                 unsigned int i;
  59.                
  60.                 for(i=0;i<n;i++)
  61.                         
  62.                         delay_1ms();
  63.         }
  64.         
  65.         uchar KeyMatrix_Down()
  66.         {
  67.                 DDRB=0XF0;
  68.                 PORTB=0X0F;
  69.                 delay(1);
  70.                 return PINB!=0x0f? 1:0;
  71.         }
  72.         
  73.         void Keys_Scan()
  74.         {
  75.                 switch(PINB)
  76.                 {
  77.                 case 0B00001110: key_0=0; break;
  78.                 case 0B00001101: key_0=1; break;
  79.                 case 0B00001011: key_0=2; break;
  80.                 case 0B00000111: key_0=3; break;
  81.                 default:key_0=0xFF;
  82.                 }
  83.                
  84.                 DDRB=0x0F;
  85.                 PORTB=0xF0;
  86.                 delay(1);
  87.                
  88.                 switch(PINB)
  89.                 {
  90.                 case 0B11100000: key_0+=0; break;
  91.                 case 0B11010000: key_0+=4; break;
  92.                 case 0B10110000: key_0+=8; break;
  93.                 case 0B01110000: key_0+=12; break;
  94.                 default: key_0= 0xFF;
  95.                 }
  96.         }
  97.         
  98.         int main()
  99.         {
  100.                 DDRB=0xFF;
  101.                 PORTB=0xFF;
  102.                
  103.                
  104.                 DDRA=0xFF;
  105.                 PORTA=0xFF;

  106.                 DDRC=0xFF;
  107.                 PORTC=0xBF;
  108.                
  109.                 DDRD|=BIT(PD7);
  110.                 PORTD&=~BIT(PD7);
  111.                
  112.                 DDRD=~(BIT(PD2)|BIT(PD3));
  113.                 PORTD=BIT(PD2)|BIT(PD3);
  114.                
  115.                 MCUCR=0x82;
  116.                 GICR=BIT(INT0)|BIT(INT1);
  117.                
  118.                 TCCR1A=0x00;
  119.                 TCCR1B=0x09;
  120.                 SREG=0x80;
  121.                
  122.                 while(1)
  123.                         
  124.                 {
  125.                         if(KeyMatrix_Down()==0)
  126.                                 
  127.                         {
  128.                                 if(Pause)
  129.                                 {
  130.                                         continue;
  131.                                 }
  132.                                 TCCR1B=0x01;
  133.                                 
  134.                                 Tone_Idx=spe_Tone_Ptr[spe_Idx][i];
  135.                                 if(Tone_Idx==0xFF)
  136.                                 {
  137.                                        
  138.                                         delay(200);
  139.                                         i=0;
  140.                                         continue;         
  141.                                 }
  142.                                 
  143.                                 TIMSK=BIT(TOIE1);
  144.                                 
  145.                                 delay(spe_Time_Ptr[spe_Idx][Tone_Idx]*200/26);
  146.                                 
  147.                                 TIMSK=0x00;
  148.                                 
  149.                                 i++;
  150.                         }
  151.                         else  
  152.                         {
  153.                                 if(Pause==0)
  154.                                 {
  155.                                         continue;
  156.                                 }


  157.                                 if(key_0==0 || key_0>16);                              
  158.                                         continue;
  159.                                 
  160.                                 PORTC=SEG_CODE[key_0];
  161.                                 
  162.                                 OCR1A=153/2/Fr[key_0];
  163.                                 
  164.                                 TCNT1=0;TIMSK|= BIT(OCIE1A);
  165.                                 
  166.                                 while(KeyMatrix_Down());
  167.                                 
  168.                                 TIMSK &=~BIT(OCIE1A);
  169.                         }
  170.                 }
  171.         }
  172.         
  173. #pragma interrupt_handler timer1_ovf_isr:9
  174.         
  175.         void timer1_ovf_isr(void)
  176.         {
  177.                
  178.                 if(Tone_Idx==0xFF)return;
  179.                
  180.                 TCNT1=Tone_Delay_Table[Tone_Idx];
  181.                
  182.                 PORTD^= BIT(PD7);
  183.         }
  184.         
  185. #pragma interrupt_handler int0_isr:2
  186.         
  187.         void int0_isr(void)
  188.         {
  189.                 TIMSK=0x00;
  190.                
  191.                 if(spe_Idx==3)spe_Idx=0;
  192.                
  193.                 else spe_Idx++;
  194.                
  195.                 i=0;
  196.                
  197.                 switch(spe_Idx)
  198.                 {
  199.                 case 0:LED1_ON();PORTC=SEG_CODE[1]; break;
  200.                         
  201.                 case 1:LED2_ON(); PORTC=SEG_CODE[2];break;
  202.                         
  203.                 case 2:LED3_ON(); PORTC=SEG_CODE[3];break;
  204.                         
  205.                 case 3:LED4_ON(); PORTC=SEG_CODE[4];break;
  206.                         
  207.                 }
  208.                 delay(10);
  209.         }
  210.         
  211. #pragma interrupt_handler int1_isr:3
  212.         
  213.         void int1_isr(void)
  214.         {
  215.                 Pause= !Pause;
  216.                 if(Pause)
  217.                 {
  218.                         PORTC=0xFF;
  219.                         PORTA=0xFF;
  220.                         TIMSK=0x00;
  221.                 }
  222.                 }
  223.         }
  224.         
  225. #pragma interrupt_handler timer1_compa_isr:7
  226.         
  227.         void timer1_compa_isr(void)
  228.         {
  229.                 PORTD^=BIT(PD7);
  230.         }
复制代码

        
        全部源码附件中
       定时与中断做的电子琴.zip (14.79 KB, 下载次数: 10)
        

评分

参与人数 1黑币 +8 收起 理由
yoxi + 8 很给力!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 转播转播 分享分享 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|单片机论坛 |51黑电子论坛单片机. 联系QQ:125739409;技术交流QQ群582644647

Powered by 单片机教程网

快速回复 返回顶部 返回列表