找回密码
 立即注册

QQ登录

只需一步,快速开始

帖子
查看: 2408|回复: 12
打印 上一主题 下一主题
收起左侧

一边点阵屏显示生日快乐,一边生日歌 同时进行 求单片机程序思路?

[复制链接]
跳转到指定楼层
楼主
一边点阵屏显示生日快乐,一边生日歌,怎么写。(同时进行)
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

举报

沙发
ID:624769 发表于 2022-1-24 22:59 | 只看该作者
你是要思路还是代码?
思路是:
如果对生日歌要求不高,
两个定时器
一个控制点阵的动态扫描以及滚动。
一个负责定时器频率输出驱动扬声器,播放生日歌。

对生日歌有要求的,可以买一个音乐IC也就几毛钱的东西,接扬声器播放生日歌。
对生日歌要求高的,可以买一个MP3播放芯片,又单片机控制播放生日歌。

这个思路,一般会写代码的都能想到。
想不到的……,估计代码是写不出来的……
回复

举报

板凳
ID:57657 发表于 2022-1-25 10:19 | 只看该作者
需要两个定时器和频率输出控制寄存器,只有STC部分型号可以实现。
回复

举报

地板
ID:453974 发表于 2022-1-25 15:25 | 只看该作者
第一种方案,51单片机有操作系统,可以使用一下
第二种方案,可以考虑用两个单片机进行串口通信
第三种方案,买一个储存好音乐的音乐片,由单片机控制放歌,然后再显示
回复

举报

5#
ID:57657 发表于 2022-1-25 17:25 | 只看该作者
累不死的狗 发表于 2022-1-25 15:25
第一种方案,51单片机有操作系统,可以使用一下
第二种方案,可以考虑用两个单片机进行串口通信
第三种方 ...

没用过操作系统,要啥串口通信? 音乐片? 你自己编的曲都可以放进去。
回复

举报

6#
ID:891164 发表于 2022-1-25 19:59 | 只看该作者
npn 发表于 2022-1-25 10:19
需要两个定时器和频率输出控制寄存器,只有STC部分型号可以实现。

我用的是STC 80C52,调试了好久,没能实现,不知啥情况。这是我的代码。
  1. #include "reg51.h"                         //此文件中定义了单片机的一些特殊功能寄存器
  2. #include "intrins.h"
  3. typedef unsigned int u16;          //对数据类型进行声明定义
  4. typedef unsigned char u8;
  5. u8 w;
  6. u16 j,n,m;

  7. sbit SRCLK=P3^6;
  8. sbit RCLK=P3^5;
  9. sbit SER=P3^4;
  10. sbit speaker=P1^5;

  11. u8 code led[9][10]={      
  12. {0x28,0xBF,0x24,0x01,0xF7,0x98,0xF7,0x01},       //祝
  13. {0x44,0x48,0x5F,0x69,0x49,0x49,0x4F,0x40},       //石
  14. {0x25,0x6D,0xB5,0x25,0x00,0x41,0x7F,0x41},       //红
  15. {0x24,0x28,0xFF,0x28,0x00,0x5F,0xDF,0x5F},       //梅
  16. {0x15,0x25,0x65,0x25,0xFF,0x25,0x25,0x25},       //生
  17. {0x00,0x7F,0x49,0x49,0x49,0x49,0x7F,0x00},       //日
  18. {0x38,0xFF,0x38,0x01,0x2A,0xFC,0x2A,0x39},       //快
  19. {0x18,0x29,0x4A,0x88,0xBF,0x88,0x0A,0x09},       //乐

  20. };
  21. unsigned char timer0h,timer0l,time;
  22. //生日歌
  23. code unsigned char sszymmh[]={5,1,1, 5,1,1, 6,1,2, 5,1,2, 1,2,2, 7,1,4,
  24. 5,1,1, 5,1,1, 6,1,2, 5,1,2, 2,2,2, 1,2,4,
  25. 5,1,1, 5,1,1, 5,2,2, 3,2,2, 1,2,2, 7,1,2, 6,1,2,
  26. 4,2,1, 4,2,1, 3,2,2, 1,2,2, 2,2,2, 1,2,4};
  27. // 音阶频率表 高八位
  28. code unsigned char FREQH[]={
  29. 0xF2,0xF3,0xF5,0xF5,0xF6,0xF7,0xF8,
  30. 0xF9,0xF9,0xFA,0xFA,0xFB,0xFB,0xFC,0xFC, //1,2,3,4,5,6,7,8,i
  31. 0xFC,0xFD,0xFD,0xFD,0xFD,0xFE,
  32. 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFF,
  33. } ;
  34. // 音阶频率表 低八位
  35. code unsigned char FREQL[]={
  36. 0x42,0xC1,0x17,0xB6,0xD0,0xD1,0xB6,
  37. 0x21,0xE1,0x8C,0xD8,0x68,0xE9,0x5B,0x8F, //1,2,3,4,5,6,7,8,i
  38. 0xEE,0x44, 0x6B,0xB4,0xF4,0x2D,
  39. 0x47,0x77,0xA2,0xB6,0xDA,0xFA,0x16,
  40. };

  41. void delay(unsigned char t)
  42. {
  43. unsigned char t1;
  44. unsigned long t2;
  45. for(t1=0;t1<t;t1++)
  46. {
  47. for(t2=0;t2<8000;t2++)
  48. {
  49. ;
  50. }
  51. }
  52. TR1=0;
  53. }
  54. void t0int() interrupt 1
  55. {
  56. TR0=0;
  57. speaker=!speaker;
  58. TH0=timer0h;
  59. TL0=timer0l;
  60. TR0=1;
  61. }
  62. void song()
  63. {
  64. TH0=timer0h;
  65. TL0=timer0l;
  66. TR0=1;
  67. delay(time);
  68. }
  69. void play()
  70. {
  71.         
  72.                 unsigned char k,i;
  73.         TMOD=1; //置CT0定时工作方式1
  74.         EA=1;
  75.         ET0=1;//IE=0x82 //CPU开中断,CT0开中断
  76.         while(1)
  77.         {  
  78.                 int a=0;
  79.                    i=0;
  80.            while(i<75){ //音乐数组长度 ,唱完从头再来
  81.            k=sszymmh[i]+7*sszymmh[i+1]-1;
  82.            timer0h=FREQH[k];
  83.            timer0l=FREQL[k];
  84.            time=sszymmh[i+2];
  85.            i=i+3;
  86.                    song();}}}  

  87. /*******************************************************************************
  88. * 函 数 名         : delay
  89. * 函数功能                   : 延时函数,i=1时,大约延时10us
  90. *******************************************************************************/
  91. void delay1(u16 i)
  92. {
  93.         while(i--);        
  94. }

  95. /*******************************************************************************
  96. * 函数名         : Hc595SendByte(u8 dat)
  97. * 函数功能                   : 向74HC595发送一个字节的数据
  98. * 输入           : 无
  99. * 输出                  : 无
  100. *******************************************************************************/
  101. void Hc595SendByte(u8 dat)
  102. {
  103.         u8 a;
  104.         SRCLK=0;
  105.         RCLK=0;
  106.         for(a=0;a<8;a++)
  107.         {
  108.                 SER=dat>>7;
  109.                 dat<<=1;

  110.                 SRCLK=1;
  111.                 _nop_();
  112.                 _nop_();
  113.                 SRCLK=0;        
  114.         }

  115.         RCLK=1;
  116.         _nop_();
  117.         _nop_();
  118.         RCLK=0;
  119. }

  120. void deng()
  121. {

  122.                 while(1)
  123.                 {
  124.            for(n=0;n<8;n++)        //第一维下标取值范围为祝、石、红、梅、生、日、快、乐,7个字符
  125.             {for(m=0;m<200;m++)        //每个字符扫描显示200次,控制每个字符显示汉字
  126.                   {         w=0x01; //行初值
  127.                      for(j=0;j<9;j++) //第二维下标取值范围为0~7,控制8行
  128.                           {Hc595SendByte(w); //行控制
  129.                            P0=~led[n][j]; //列控制,将指定数组元素取反后赋值给P0口,显示码
  130.                            delay1(60);
  131.                            w<<=1; //行变量左移指向下一行
  132.                            P0=0xff;
  133.                                                    }
  134.                                    }
  135.                      }}}
  136.                         
  137. void init()
  138. {
  139.     TMOD=0x01;
  140.         TL0=0;
  141.         TH0=0;
  142.         ET0=1;
  143.         EA=1;
  144.         TR0=1;
  145. }                                                         
  146. /*******************************************************************************
  147. * 函 数 名       : main
  148. * 函数功能                 : 主函数
  149. * 输    入       : 无
  150. * 输    出             : 无
  151. *******************************************************************************/
  152. void main()
  153. {
  154. init();
  155.    while(1)
  156.    {   
  157.    
  158.    deng();
  159.    }   
  160. }
  161. void time0() interrupt 3  
  162. {
  163. play();                                                                                                                                      
  164. }   
复制代码
     
回复

举报

7#
ID:213173 发表于 2022-1-26 08:07 | 只看该作者
pingfunny 发表于 2022-1-25 19:59
我用的是STC 80C52,调试了好久,没能实现,不知啥情况。这是我的代码。

开两个定时器中断,一个控制点阵扫描和音乐节奏,另一个控制音乐频率。具体的输出内容由主函数调配。不要试图一次调试成功。可以先显示一个字符和播放一个音符。调通后再丰富内容就水到渠成了。
回复

举报

8#
ID:213173 发表于 2022-1-26 08:34 | 只看该作者
pingfunny 发表于 2022-1-25 19:59
我用的是STC 80C52,调试了好久,没能实现,不知啥情况。这是我的代码。

给你一个简易电子琴的仿真示例,按这个构架把数码管动态显示改为点阵屏,键盘改为固定顺序演奏。你的愿望就可以实现。 简易电子琴.rar (89.27 KB, 下载次数: 7)



回复

举报

9#
ID:161164 发表于 2022-1-26 10:00 | 只看该作者
pingfunny 发表于 2022-1-25 19:59
我用的是STC 80C52,调试了好久,没能实现,不知啥情况。这是我的代码。

你只是把两个程序复制粘贴在一起吧
主程序一个while(1)
定时中断内又一个while(1)
还加上一个内含8000个循环的delay
能跑得起来才怪

想办法把两个while(1)合起来
想办法用其他方法实现8000个循环的delay
就可以成功
回复

举报

10#
ID:584814 发表于 2022-1-28 08:23 | 只看该作者
一边点阵屏显示生日快乐,一边生日歌 同时进行 ? 求思路 ?
款点的做法是送苹果手机,那个是可以一边显一边歌甚至还可以动用3D,钱的事都不是事;
如果%%还想玩浪,就用手绘嘴唱,反正你也不会写程序,编程思路对你没什么用
回复

举报

11#
ID:161164 发表于 2022-1-28 14:14 | 只看该作者
手痒帮你弄了一个0.2倍速版


AT89C52.rar (1.04 KB, 下载次数: 18)




回复

举报

12#
ID:316468 发表于 2022-1-28 19:20 | 只看该作者
几毛钱一个音乐芯片就可以解决的事情,何必大费周章呢?量产都没必要去编这些程序吧?毕竟时间也是成本,虽然程序不是太难。
回复

举报

13#
ID:276685 发表于 2022-1-28 22:40 | 只看该作者
你可以建立一个与点阵屏同大小的缓冲区,运用定时器以60hz进行刷屏。主程序只需改变这个缓冲区即可完成滚动,显示文字的效果。音乐可以考虑MP3存入SD卡,去百度一个解码库,然后根据采样频率刷新dac,与刷屏共用定时器也可以。SD也可以建立缓冲区,类似环形但是新数据不能覆盖未播放的老数据。main只需读取SD卡即可。即保证了音乐不卡顿和刷屏的及时。
回复

举报

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

本版积分规则

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

Powered by 单片机教程网

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