找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机电子琴程序代码

[复制链接]
跳转到指定楼层
楼主
ID:76127 发表于 2015-4-16 03:04 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
51 电子琴程序代码 姬家寨电子科技实验室 程序编程:姬学瑞   版权所有,侵权必究!
  1. #include <REGX51.H>
  2. #define   FOSC    12000000
  3. //=================================================================================================
  4. //--- 音阶频率表 ---
  5. unsigned int code JINJIEFREQ[] =
  6. {
  7.   262,294,330,349,392,440,494,
  8.   523,587,659,699,784,880,988,
  9.   1046,1175,1319,1391,1568,1760,1976,
  10. };
  11. //sfr     P4    = 0xC0;
  12. //sfr     P5    = 0xC8;
  13. //sbit    P5_5  = P5^5;
  14. #define SPK     P3_7//P5_5
  15. bit RunFlag = 0;
  16. unsigned char STH0,STL0;
  17. //sfr     AUXR  = 0x8E;
  18. #define T0FENPING  12
  19. //=================================================================================================
  20. //--- 定时器T0溢出中断服务程序 ---
  21. void T0_ISR(void) interrupt 1
  22. {
  23.   if(1 == RunFlag)                                  //--- 在音阶播放标志为1情况下 ---
  24.     {
  25.       TH0 = STH0;                                   //--- 重新装初值 ---
  26.       TL0 = STL0;
  27.       SPK = ~SPK;                                   //--- P5.5引脚上的电平翻转 ---
  28.     }
  29. }
  30. //=================================================================================================
  31. //--- main()主程序 ---
  32. void main(void)
  33. {
  34.   unsigned int i;
  35.   unsigned char j;

  36. //  AUXR |= 0x80;                                     //--- 使能T0的计数器时钟分频值为1 ---
  37.   TMOD = 0x01;                                      //--- 配置T0为定时模式,工作于方式2 ---
  38.   ET0 = 1;                                          //--- 使能T0中断 ---
  39.   TR0 = 1;
  40.   EA = 1;                                           //--- CPU开中断 ---
  41.   while(1)
  42.     {
  43.       for(j=0;j<7;j++)
  44.         {
  45.           if(0 == (P1 & (1 << j)))                  //--- 判断低音部分是否有键按下 ---
  46.             {
  47.               for(i=0;i<2000;i++);                  //--- 去按键抖动 ---
  48.               if(0 == (P1 & (1 << j)))              //--- 再判断低音部分是否真得有键按下 ---
  49.                 { //--- 根据表计算低音音阶频率的定时器T0的初值 ---
  50.                   STH0 = (65536 - FOSC / T0FENPING / 2 / JINJIEFREQ[j]) / 256;
  51.                   STL0 = (65536 - FOSC / T0FENPING / 2 / JINJIEFREQ[j]) % 256;
  52.                   TH0 = STH0;                       //--- 装入TH0,TL0的计数寄存器 ---
  53.                   TL0 = STL0;
  54.                   RunFlag = 1;                      //--- 置音阶播放标志为1 ---
  55.                 }
  56.               while(0 == (P1 & (1 << j)));          //--- 等待按键释放 ---
  57.               RunFlag = 0;                          //--- 清音阶播放标志 ---
  58.               SPK = 1;
  59.             }
  60.           if(0 == (P3 & (1 << j)))                  //--- 判断中音部分是否有键按下 ---
  61.             {
  62.               for(i=0;i<2000;i++);                  //--- 去按键抖动 ---
  63.               if(0 == (P3 & (1 << j)))              //--- 再判断中音部分是否真得有键按下 ---
  64.                 { //--- 根据表计算中音音阶频率的定时器T0的初值 ---
  65.                   STH0 = (65536 - FOSC / T0FENPING / 2 / JINJIEFREQ[j + 7]) / 256;
  66.                   STL0 = (65536 - FOSC / T0FENPING / 2 / JINJIEFREQ[j + 7]) % 256;
  67.                   TH0 = STH0;                       //--- 装入TH0,TL0的计数寄存器 ---
  68.                   TL0 = STL0;
  69.                   RunFlag = 1;                      //--- 置音阶播放标志为1 ---
  70.                 }
  71.               while(0 == (P3 & (1 << j)));          //--- 等待按键释放 ---
  72.               RunFlag = 0;                          //--- 清音阶播放标志 ---
  73.               SPK = 1;
  74.             }
  75.           if(0 == (P2 & (1 << j)))                  //--- 判断高音部分是否有键按下 ---
  76.             {
  77.               for(i=0;i<2000;i++);                  //--- 去按键抖动 ---
  78.               if(0 == (P2 & (1 << j)))              //--- 再判断高音部分是否真得有键按下 ---
  79.                 { //--- 根据表计算高音音阶频率的定时器T0的初值 ---
  80.                   STH0 = (65536 - FOSC / T0FENPING / 2 / JINJIEFREQ[j + 14]) / 256;
  81.                   STL0 = (65536 - FOSC / T0FENPING / 2 / JINJIEFREQ[j + 14]) % 256;
  82.                   TH0 = STH0;                       //--- 装入TH0,TL0的计数寄存器 ---
  83.                   TL0 = STL0;
  84.                   RunFlag = 1;                      //--- 置音阶播放标志为1 ---
  85.                 }
  86.               while(0 == (P2 & (1 << j)));          //--- 等待按键释放 ---
  87.               RunFlag = 0;                          //--- 清音阶播放标志 ---
  88.               SPK = 1;
  89.             }
  90.         }
  91.     }
  92. }
复制代码



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

使用道具 举报

沙发
ID:76386 发表于 2015-5-7 15:44 | 只看该作者
好东西,谢谢
回复

使用道具 举报

板凳
ID:75461 发表于 2015-5-8 17:28 | 只看该作者
谢谢分享
回复

使用道具 举报

地板
ID:79329 发表于 2015-5-8 19:16 | 只看该作者
楼主真厉,不错!
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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