基于51单片机的点阵+音乐=祝你生日快乐

发布者:美好未来最新更新时间:2012-09-12 来源: 21IC 关键字:51单片机  点阵  89C51 手机看文章 扫描二维码
随时随地手机看文章

//-----------------------------------------------------
//<<12*12点阵+音乐产生>>
// MCU:89C51  晶振:12M
//编写日期:2010。12。25
//编写人:李春起
#include
#define uchar unsigned char
#define uint unsigned int
uint a=0,a1=0,a2=0;
uint miusfla,miust,mius=64536;
uint disfla1,sta=0;
char flag=0,mdflag=0;
sbit k1=P3^2;
sbit k2=P3^3;
sbit YY=P3^1;

uchar code tabfas[]={
//==============笑脸===================================
//P0口
0xFF,0xFF,0xFF,0xFF,0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
0xFF,0xFF,0xFF,0xFF,0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
//P1口
0x8E,0x4D,0xAB,0x57,0x5F,0x9F,0x9F,0x5F,0x5F,0xAF,0x4F,0x8F,
0x8E,0x4D,0xAB,0x97,0x9F,0x9F,0x9F,0x9F,0x9F,0xAF,0x4F,0x8F,
//P2口
0x87,0x88,0x50,0x20,0xA4,0x68,0x68,0xA4,0x20,0x50,0x88,0x87,
0x87,0x88,0x50,0x20,0xA4,0x68,0x68,0xA4,0x20,0x50,0x88,0x87,  
//P0口
0xFF,0xFF,0xFF,0xFF,0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
0xFF,0xFF,0xFF,0xFF,0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
0xFF,0xFF,0xFF,0xFF,0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
0xFF,0xFF,0xFF,0xFF,0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
0xFF,0xFF,0xFF,0xFF,0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
0xFF,0xFF,0xFF,0xFF,0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
0xFF,0xFF,0xFF,0xFF,0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
0xFF,0xFF,0xFF,0xFF,0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
0xFF,0xFF,0xFF,0xFF,0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
0xFF,0xFF,0xFF,0xFF,0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
0xFF,0xFF,0xFF,0xFF,0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
0xFF,0xFF,0xFF,0xFF,0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
0xFF,0xFF,0xFF,0xFF,0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
0xFF,0xFF,0xFF,0xFF,0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
0xFF,0xFF,0xFF,0xFF,0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
0xFF,0xFF,0xFF,0xFF,0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
//P1口
0x8E,0x8D,0xEB,0x87,0x8F,0xCF,0x4F,0x4F,0x4F,0xCF,0x0F,0x0F, //祝
0x0E,0x0D,0x8B,0xE7,0x8F,0x8F,0x0F,0x0F,0xEF,0x0F,0x0F,0x0F,  //钟
0x0E,0x0D,0x0B,0x87,0x4F,0x0F,0x0F,0xCF,0x0F,0x0F,0x0F,0x0F, //仕
0x0e,0xed,0xab,0xa7,0xef,0xaf,0xbf,0xaf,0xef,0xaf,0xaf,0x0f,//廉
0x0E,0x0D,0x8B,0xE7,0x8F,0x8F,0xEF,0x8F,0x8F,0x8F,0x0F,0x0F, //生
0x0E,0x0D,0x0B,0xE7,0x2F,0x2F,0x2F,0x2F,0xEF,0x0F,0x0F,0x0F, //日
//0x0E,0x4D,0xDB,0x67,0xCF,0x4F,0x0F,0x8F,0x4F,0x4F,0x2F,0x0F,    //新
//0x0E,0x0D,0x8B,0x47,0x7F,0x4F,0xCF,0x4F,0x4F,0x4F,0x4F,0x0F,    //年
0x0E,0x0D,0xEB,0x07,0x8F,0x8F,0xEF,0x8F,0x8F,0x8F,0x0F,0x0F, //快
0x0E,0x8D,0x4B,0x47,0x4F,0xAF,0x1F,0x0F,0x0F,0x0F,0x0F,0x0F, //乐
0xCE,0x2D,0x2B,0x27,0x4F,0x8F,0x8F,0x4F,0x2F,0x2F,0x2F,0xCF, //心形
0x0F,0x0F,0x2B,0x27,0xAF,0x6F,0xFF,0x6F,0xAF,0x2F,0x2F,0x0F, //李
0x0E,0x0D,0x2B,0xA7,0xAF,0xFF,0xAF,0xAF,0x2F,0x0F,0x0F,0x0F, //春
0x0E,0x0D,0x4B,0x47,0xEF,0x4F,0x4F,0x8F,0x8F,0x8F,0x0F,0x0F,  //起
//0x0E,0xFD,0x5B,0x57,0x5F,0xFF,0x0F,0x4F,0x4F,0xCF,0x4F,0x0F, //题
0xCE,0x2D,0x2B,0x27,0x4F,0x8F,0x8F,0x4F,0x2F,0x2F,0x2F,0xCF, //心形
//P2口
0x08,0x04,0xFE,0x05,0x08,0x43,0x3E,0x02,0x3E,0x23,0x30,0x00, //祝
0x00,0x09,0x0A,0x7F,0x2A,0x08,0x0F,0x09,0x7F,0x09,0x0F,0x00,  //钟
0x00,0x02,0x01,0x7F,0x02,0x22,0x22,0x3F,0x22,0x22,0x02,0x00,   //仕
0xc0,0x3f,0x88,0x6a,0x2a,0xff,0x2a,0xff,0x2a,0x6a,0xde,0x88,//廉
0x00,0x21,0x20,0x20,0x24,0x24,0x3F,0x24,0x24,0x20,0x20,0x00, //生
0x00,0x00,0x00,0x3F,0x22,0x22,0x22,0x22,0x3F,0x00,0x00,0x00,  //日
//0x00,0x2A,0x5A,0xFF,0x1A,0x2A,0x40,0x3F,0x02,0x7E,0x02,0x00,   //新
//0x08,0x09,0x0F,0x09,0x09,0x09,0xFF,0x09,0x09,0x09,0x08,0x00,    //看
0x01,0x06,0x7F,0x22,0x14,0x0C,0x07,0x0C,0x14,0x27,0x24,0x00, //快
0x00,0x23,0x12,0x0E,0x22,0x7F,0x06,0x0A,0x13,0x22,0x00,0x00, //乐
0x03,0x04,0x08,0x10,0x20,0x60,0x20,0x10,0x08,0x04,0x02,0x01,  //心形
0x00,0x00,0x11,0x11,0x12,0x52,0xFB,0x1A,0x16,0x11,0x11,0x00, //李
0x00,0x12,0x0A,0xFE,0xAB,0xAA,0xAA,0xFE,0x0A,0x12,0x00,0x00, //春
0x40,0x21,0x1D,0x09,0x1F,0x25,0x41,0x5D,0x54,0x53,0x58,0x00,   //起
//0x84,0x45,0x35,0x3D,0x55,0x95,0x84,0xAF,0x9D,0x91,0xAF,0x80, //题
0x03,0x04,0x08,0x10,0x20,0x60,0x20,0x10,0x08,0x04,0x02,0x01,  //心形
};
//----------------音符----------------------
uint code miusdata[]={
//祝你生日快乐
64260,64260,64399,64260,64579,64524,64260,64260,
64399,64260,64684,64580,64260,64260,64898,64777,
64580,64524,64399,64819,64819,64777,64580,64777,
64684,0,
64260,64260,64399,64260,64579,64524,64260,64260,
64399,64260,64684,64580,64260,64260,64898,64777,
64580,64524,64399,64819,64819,64777,64580,64684,
64580,0,  
64580,64580,64684,64580,64819,64777,64580,64580,
64684,64580,64898,64819,64580,64580,65058,64968,
64819,64777,64684,65000,65000,64960,64819,64967,
64898,0,
64580,64580,64684,64580,64819,64777,64580,64580,
64684,64580,64898,64819,64580,64580,65058,64968,
64819,64777,64684,65000,65000,64960,64819,64898,
64819,0
};
//---------------节拍-----------------------
uchar code miustime[]={
40,40,80,80,80,160,40,40,80,80,80,160,40,40,
80,80,80,80,80,40,40,80,80,80,160,80,
40,40,80,80,80,160,40,40,80,80,80,160,40,40,
80,80,80,80,80,40,40,80,80,80,160,80,
40,40,80,80,80,160,40,40,80,80,80,160,40,40,
70,75,80,80,80,40,40,80,80,80,160,80,
40,40,80,80,80,160,40,40,80,80,80,160,40,40,
70,75,80,80,80,40,40,80,80,80,160,80,
};
void delay500();

//==========按键==========================================
void kk()
{
   if(!k1){delay500();if(++flag>1)flag=0;else {a=72;a2=0;}sta=1;}
   if(!k2){delay500();if(++mdflag>1)mdflag=0;sta=1;}
}
//=========延时===========================================
void delay(uint m)
{
   uint i,j;
   for(i=0;i   {
     for(j=0;j<300;j++)
  {kk();if(sta){sta=0;goto abc;}}
   }
   abc:;
}
//------按键消拉动用----------------
void delay500()
{
  uint i1;
  P0=0XFF;
  P1=0X0F;
  P2=0X00;
  for(i1=0;i1<32000;i1++);
}
//=========定时器T0用于频率产生和显示======================
void time0() interrupt 1
{
  P0=0XFF;
  P1=0X0F;
  P2=0X00;
  TH0=mius>>8;
  TL0=mius&0xff;
  YY=~YY;
  switch(flag)
  {
    case 0:{ //笑脸
           P0=tabfas[a];
              P1=tabfas[a+24];
              P2=tabfas[a+48];
              if(++disfla1<700){if(++a>11)a=0;}
              if(disfla1>=700){if(++a>23)a=11;}
              if(disfla1>800){a=0;disfla1=0;}
         }break;
case 1:{ //汉字
           P0=tabfas[a];
           P1=tabfas[a+192];
     P2=tabfas[a+348];
     if(++disfla1<500){if(++a>(a2+83))a=(a2+72);}
       else{if(++a>(a2+83))a=(a2+72);}
     if(disfla1>1000){a2+=12;disfla1=0;}
     if(a2>144){a2=0;}
         }break;
default:break;
  }
}
//========定时器T1只用于显示================================
void time1() interrupt 3
{
  P0=0XFF;
  P1=0X0F;
  P2=0X00;
  TH1=0xf8;
  TL1=0x30;
  switch(flag)
  {
    case 0:{ //笑脸
           P0=tabfas[a];
              P1=tabfas[a+24];
              P2=tabfas[a+48];
              if(++disfla1<700){if(++a>11)a=0;}
              if(disfla1>=700){if(++a>23)a=11;}
              if(disfla1>800){a=0;disfla1=0;}
         }break;
case 1:{ //汉字
           P0=tabfas[a];
           P1=tabfas[a+192];
     P2=tabfas[a+348];
     if(++disfla1<500){if(++a>(a2+83))a=(a2+72);}
       else{if(++a>(a2+83))a=(a2+72);}
     if(disfla1>1000){a2+=12;disfla1=0;}
     if(a2>144){a2=0;}
         }break;
default:break;
  }
}
/////////////////////////////////////////////////////////////
//=========================================================//
//----------------主程序-----------------------------------//
//=========================================================//
/////////////////////////////////////////////////////////////
void main()
{
  P0=0XFF;
  P1=0X0F;
  P2=0X00;
  P3=0XFD;
  TMOD=0X11;
  TH0=mius>>8;
  TL0=mius&0xff;
  TH1=0xf8;
  TL1=0x30;
  TR0=1;
  ET0=1;
  TR1=0;
  ET1=1;
  EA=1;
  while(1)
  {
    switch(mdflag)
    {
      case 0:{//音乐暂停
      TR0=0;TR1=1;kk();sta=0;
           }break;
     case 1:{ //音乐继续
       TR0=0;
       delay(1);
                TR0=1;  
                mius=miusdata[a1];
                if(mius==0){TR0=0;TR1=1;}
      else {TR1=0;TR0=1;}
                delay(miustime[a1]);
                if(++a1>=104)a1=0;
           }break;
   default:break;
    }
  }
}   

关键字:51单片机  点阵  89C51 引用地址:基于51单片机的点阵+音乐=祝你生日快乐

上一篇:基于AT89S52单片机的舵机控制系统设计
下一篇:基于单片机的阳台智能隐形防盗网

推荐阅读最新更新时间:2024-03-16 13:08

51单片机-温度传感器代码解析Ⅱ
1.小于0度的转换 我们知道当测量的实际温度为0度以下时,temp没转换时的情况为下图所示 我们已经知道高5位为1表示的是负数,那么-0.5度的时候为什么是1111 1111 1111 1000。 负数的计算涉及到补码的知识。首先0xFFF8,除去高5位那就是 111 1111 1000 反码为 000 0000 0111 而补码就是反码加1,也就是补码为000 0000 1000 这样0.5就是由补码(十进制的8)乘以0.0625得来。 我们要知道,负数的时候需要关注的是temp的低11位,补码其实就是2的11次方(2048)减去temp的低11位的数值。 -55度的时候,补码为2048-0x0490=880。
[单片机]
<font color='red'>51单片机</font>-温度传感器代码解析Ⅱ
51单片机学习笔记:ST7920控制器的12864液晶使用总结
总结: 1、 控制芯片不同,液晶接口定义,或者寄存器定义也可能不同 2、 显示方式有并行和串行,串行方式据说不能读数据寄存器(DR),那指令暂存器IR是否可读? 3、 含字库芯片显示字符时不必对字符取模了,但字库有可能缺斤少两,就是说有一部分字(哪怕是常用字),在字库中没有,如果你第一次测试代码就遇到该字在字库中没有的情况,建议去买体育彩票,支持体育运动! 4、 对芯片的结构地址一定要理解清楚,个人阅读网上一些资料发现大多是不准确的,甚至自相矛盾 很多数据手册中内容更是模棱两可,不明所以,数据手册之间也有矛盾的! 我根据自己的实验结果,再结合一些资料,得出以下结论: ST7920可以控制256×64 点阵的二维绘图缓冲空间, 对
[单片机]
<font color='red'>51单片机</font>学习笔记:ST7920控制器的12864液晶使用总结
89C51编程器,89C51 programmer
89c51芯片的编程器,图片有些小,凑合看吧,附带程序 程序: #include at89x52.h #include stdio.h #include intrins.h #include ctype.h sbit rdy=P3^2; sbit vpp=P3^3; sbit p26=P3^4; sbit p27=P3^5; sbit p36=P3^6; sbit p37=P3^7; sbit prog=P2^7; void init_serial() { SCON=0x50; /*mode 1*/ TMOD=0x20; TH1=0xfd; PCON=0x80; /*38400bps*/ TR1=1; /*load tmr1*/
[单片机]
<font color='red'>89C51</font>编程器,<font color='red'>89C51</font> programmer
51单片机常用波特率初值表12M晶振
为什么51单片机的晶振一般使用11.0592? 用11.0592晶振的原因是51单片机的定时器导致的。用51单片机的定时器做波特率发生器时,如果用11.0592Mhz的晶振,根据公式算下来需要定时器设置的值都是整数;如果用12Mhz晶振,则波特率都是有偏差的,比如9600,用定时器取0XFD,实际波特率10000,一般波特率偏差在4%左右都是可以的,所以也还能用 STC90C516 晶振12M 波特率9600 ,倍数时误差率6.99%,不倍数时误差率8.51%,数据肯定会出错。 这也就是串口通信时大家喜欢用11.0592MHz晶振的原因,在波特率倍速时,最高可达到57600,误差率0.00%。 用12MHz,最
[单片机]
<font color='red'>51单片机</font>常用波特率初值表12M晶振
8051单片机实战分析(以STC89C52RC为例) | 04 - 蜂鸣器驱动
蜂鸣器发声原理是电流通过电磁线圈,使电磁线圈产生磁场来驱动振动膜发声的,因此需要一定的电流才能驱动它,单片机IO引脚输出的电流较小,单片机输出的TTL电平基本上驱动不了蜂鸣器,因此需要增加一个电流放大的电路。三极管的作用为驱动,通过三极管放大驱动电流,从而可以让蜂鸣器发出声音。 有源蜂鸣器和无源蜂鸣器的区别: 这里的“源”不是指电源。而是指震荡源。 也就是说,有源蜂鸣器内部带震荡源,所以只要一通电就会叫。 而无源内部不带震荡源,所以如果用直流信号无法令其鸣叫。必须用2K~5K的方波去驱动它。 有源蜂鸣器往往比无源的贵,就是因为里面多个震荡电路。 有源蜂鸣器示意图: 无源蜂鸣器示意图: 无源蜂鸣器的优点是:
[单片机]
80<font color='red'>51单片机</font>实战分析(以STC89C52RC为例) | 04 - 蜂鸣器驱动
#51单片机#A/D差分输入信号
在上一节已经提到过,控制字的第 4 位和第 5 位是用于控制 PCF8591 的模拟输入引脚是单端输入还是差分输入。差分输入是模拟电路常用的一个技巧,这里我们把相关知识做一些简单介绍。 从严格意义上来讲,其实所有的信号都是差分信号,因为所有的电压只能是相对于另外一个电压而言。但是大多数系统,我们都是把系统的 GND 作为基准点。而对于 A/D 来说的差分输入,通常情况下是除了 GND 以外,另外两路幅度相同,极性相反的输入信号,其实理解起来很简单,就如同跷跷板一样。如图17-8 所示。 图 17-8 差分输入原理 差分输入的话,就不是单个输入,而是由 2 个输入端构成的一组输入。PCF8591 一共是4 个模拟输入端,可以配置
[单片机]
#<font color='red'>51单片机</font>#A/D差分输入信号
MCS-51单片机有哪些寻址方式,是怎样操作的?
什么是寻址方式?MCS-51单片机有哪些寻址方式,是怎样操作的?各种寻址方式的寻址空间和范围是什么? 答: MCS-51单片机有7种寻址方式:立即数寻址、寄存器寻址、直接寻址、寄存器间接寻址、变址寻址、位寻址和指令寻址。可以分为两类:操作数寻址和指令寻址。 立即数寻址的寻址空间和范围是:在程序存储空间,随指令读入MOV A,#46H 直接寻址的寻址空间和范围是:片内RAM中,低128字节和SFR MOV A,46H 寄存器寻址的寻址空间和范围是:使用R0~R7、A、B、C、DPTR MOV A,R2 寄存器间接寻址的寻址空间和范围是:片内RAM:使用@Ri,SP;范围为256B,不含SFR,片外RAM:使用@Ri,@DP
[单片机]
解析8051单片机的三种数据传输方式
单片机CPU与外部设备交换信息通常有如下几种方式:无条件传送方式,查询传送方式和中断传送方式。我们以单片机与微型打印机接口为例讲述这三种方式。假定用户要打印三个数据,这三个数据保存在单片机的内部数据存储器10H,11H,和12H中,8051用并口P2与微型打印机的并行数据口DB进行数据交换。 (1)无条件传送方式 这种数据传送方式中没有联络信号,即CPU总是认为打印机在如何时候都是处于“准备好”的状态。这种传送方式中只需要在程序中加入数据送往P2的指令,数据传送便可以实现。但这种数据传送方式有一个致命弱点,数据易丢失,这是因为CPU的速度相当快,而打印机的速度相对来说较慢,其结果是在打印机打印一个数据的时间内,CPU已送来了多
[单片机]
解析80<font color='red'>51单片机</font>的三种数据传输方式
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
  • ARM裸机篇--按键中断
    先看看GPOI的输入实验:按键电路图:GPF1管教的功能:EINT1要使用GPF1作为EINT1的功能时,只要将GPFCON的3:2位配置成10就可以了!GPF1先配 ...
  • 网上下的--ARM入门笔记
    简单的介绍打今天起菜鸟的ARM笔记算是开张了,也算给我的这些笔记找个存的地方。为什么要发布出来?也许是大家感兴趣的,其实这些笔记之所 ...
  • 学习ARM开发(23)
    三个任务准备与运行结果下来看看创建任务和任运的栈空间怎么样的,以及运行输出。Made in china by UCSDN(caijunsheng)Lichee 1 0 0 ...
  • 学习ARM开发(22)
    关闭中断与打开中断中断是一种高效的对话机制,但有时并不想程序运行的过程中中断运行,比如正在打印东西,但程序突然中断了,又让另外一个 ...
  • 学习ARM开发(21)
    先要声明任务指针,因为后面需要使用。 任务指针 volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • 学习ARM开发(20)
  • 学习ARM开发(19)
  • 学习ARM开发(14)
  • 学习ARM开发(15)
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved