单片机
返回首页

单片机八音盒程序

2020-12-16 来源:51hei

单片机源程序如下:

#include

#include

#define uhar unsigned char

#define uint  unsigned int

sbit key1=P3^2;//定义按key1可切换花样                                                                  

sbit key2=P3^3;//定义按key2可切换歌曲

sbit fm=P3^5;//蜂鸣器连续的IO口,接蜂鸣器的管脚

sbit rs=P2^0;

sbit rw=P2^1;

sbit ep=P2^2;

uchar i;

uchar Tong_index=0;//音乐片段索引音符索引

uchar song_index=0;

uchar *discode;//暂存LCD需要显示的歌名

uchar *song_Tone,*song_Time;

uchar code dis1[]={'song1'};//第一首歌名,dis1~dis4位LCD第一行要显示的歌名;

uchar code dis2[]={'song2'};

uchar code dis3[]={'song3'};

uchar code dis4[]={'song4'};

uchar code dis[]={'K1:Down K2:Up'};        //第二行显示的内容

uint code Tong_tab[]={62018,62401,62491,62895,63184,63441,63506,63773,

63965,64137,64215,64360,64488,64603,64654,64751,64836,64876,64948,65012,65067,65535};                                                                 

//---------------------------简谱---------------------------------------

//编程规则:字节高位是简谱,低位是持续时间,代表多少个十六分音符。

//1-7代表中央C调,8-E代表高八度,0代表停顿

//最后的0是结束标志

//uchar code song1_Tone[]={         //        歌曲1的演奏音符

//11,9,11,14,12,14,12,11,11,7,8,9,8,7,8,

//11,9,11,14,13,12,14,11,11,7,8,9,6,7,

//12,14,14,13,12,13,14,12,13,14,12,12,11,10,7,8,

//11,9,11,14,13,12,14,11,11,8,9,10,6,7,0xff};//结束标志

//uchar code song1_Time[]={ // 歌曲1的节拍频率

//4,2,2,8,4,2,2,8,4,2,2,4,2,2,12,

//4,2,2,4,2,4,4,8,4,2,2,4,2,12,

//4,4,8,4,2,2,8,2,2,2,2,2,2,2,2,16,

//4,2,2,4,2,4,4,8,4,2,2,4,2,12,0xff};

//uchar code song2_Tone[]={         //        歌曲2的演奏音符

//7,8,9,7,7,8,9,7,9,10,11,9,10,11,

//11,12,11,10,9,7,11,12,11,10,9,7,7,4,7,7,4,7,0xff};//结束标志

//uchar code song2_Time[]={ // 歌曲2的节拍频率

//4,4,4,4,4,4,4,4,4,4,8,4,4,8,

//2,2,2,2,4,4,2,2,2,2,4,4,4,4,8,4,4,8,0xff};       

//uchar code song3_Tone[]={         //        歌曲3的演奏音符

//7,7,7,8,9,9,9,9,10,11,12,12,11,10,9,11,11,8,9,7,

//7,7,7,8,11,9,9,9,10,11,12,12,11,10,9,11,11,8,9,7,0xff};//结束标志

//uchar code song3_Time[]={ // 歌曲3的节拍频率

//2,2,2,2,4,2,2,2,2,4,2,2,2,2,4,2,2,2,2,4,

//2,2,2,2,4,2,2,2,2,4,2,2,2,2,4,2,2,2,2,5,0xff};

//uchar code song4_Tone[]={         //        歌曲4的演奏音符

//5,9,9,9,9,8,7,8,7,6,5,12,12,12,12,12,11,

//2,11,11,10,9,9,12,12,11,9,8,7,8,7,6,5,9,

//2,7,7,6,5,9,8,7,6,4,12,0xff};//结束标志

//uchar code song4_Time[]={ // 歌曲4的节拍频率

//2,2,2,2,2,2,2,2,2,2,8,2,2,2,2,4,2,

//2,2,2,2,8,2,2,2,2,4,2,2,2,2,2,4,2,

//2,2,2,2,4,2,2,2,2,2,8,0xff};


void delayms(uint ms)

{

         uchar a;

         while(ms--)

                 {

                 for(a=230;a>0;a--);

                 }


}

uchar Busy_Check(void)//测试LED忙碌状态

{

        uchar LCD_Status;

        rs=0;

        rw=1;

        ep=1

        _nop_();

         _nop_();

         _nop_();

         _nop_();

         LCD_Status=P0&0x80;

         ep=0;

         return LCD_Status;

}

void led_wemd(uchar cmd)//写入指令数据到LCD

{

        while(Busy_Check());

                rs=0;

                rw=0;

                ep=0;

                _nop_()

                _nop_()

                P0=cmd;

                _nop_()

                _nop_()

                _nop_()

                _nop_()

                ep=1;

                _nop_()

                _nop_()

                _nop_()

                _nop_()

                ep=0;

}

void lcd_pos(uchar pos)

{

        lcd_wcmd(pos|0x80);

}

void lcd_wdat(uchar dat)

  {

        while(Busy_Check());

                rs=0;

                rw=0;

                ep=0;

                _nop_()

                _nop_()

                P0=cmd;

                _nop_()

                _nop_()

                _nop_()

                _nop_()

                ep=1;

                _nop_()

                _nop_()

                _nop_()

                _nop_()

                ep=0;

}

void lcd_init(void) //lcd初始化设定

{

lcd_wcmd(0x38); //设置显示格式为16*2行显示,5*8点阵,8位


delay(1);

lcd_wcmd(0x0C);        //0x0c-显示开关设置

delay(1);

lcd_wcmd(0x06);        //0x06读写后指针+1

delay(1);

lcd_wcmd(0x01);//清除lcd显示内容

}

//----------------------------简谱音调对应的定时器初值---------------------------

//适合11.0592M的晶振,对定时器置入的初值

uchar code cuzhi[]={

         0xff,0xff,//占位用的,没有实际的意义

         0xFC,0x8E,//中央C调1-7

         0xFC,0xED,       

         0xFD,0x43,       

         0xFD,0x6A,       

         0xFD,0xB3,       

         0xFD,0xF3,       

         0xFE,0x2D,

         0xFE,0x47,        //高八度1-7          

         0xFE,0x76,

         0xFE,0xA1,

         0xFE,0xC7,       

         0xFE,0xD9,

         0xFE,0xF9,

         0xFF,0x16

         };

uchar yinyue[]={0xff,0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0x0,0x0};

//将音调转化为对应的LED样式

void delay1(uint z);        //延时1MS

void delay(uint z);        //延时165MS,即十六分音符

void song();

void beep();//蜂鸣器叫一声


void int0() interrupt 0

{

delayms(100);

if(INT0==0)

        {

                TR0=0;

                if(song_index>5)

                {

                song_index=5;

                }

                 else{song_index++;}

                 if(song_index==1)

                 {temp=songl[i];discode=dis2;}

                 if(song_index==2)

                 {temp=song2[i];discode=dis3;}

                 if(song_index==3)

                 {temp=song3[i];discode=dis4;}

                 if(song_index==4)

                 {temp=song4[i];discode=dis1;song_index=0;}

                 TR0=1;

                 i=0;

        }

}

void int1() interrupt 2  //外部中断1

{

  delayms(100);

if(INT1==0)

        {

                TR1=0;

                if(song_index<1)

                {

                song_index=0;

                }

                 else{song_index--;}

                 if(song_index==1)

                 {temp=song[i];discode=dis2;}

                 if(song_index==2)

                 {temp=song2[i];discode=dis3;}

                 if(song_index==3)

                 {temp=song3[i];discode=dis4;}

                 if(song_index==4)

                 {temp=song4[i];discode=dis1;song_index=0;}

                 TR0=1;

                 i=0;

        }

}


//---------------.按照51单片机的中断向量顺序编的号,也是缺省状态下的优先级------------

//外部中断0 interrupt 0

//定时器0     interrupt 1

//外部中断1 interrupt 2

//定时器1     interrupt 3

//串口中断   interrupt 4

//定时器2     interrupt 5

void timer0() interrupt 1         //用于产生各种音调 定时器0

{

        TH0=Tone_tab[Tone_index]/256;//重置T0定时初值

        TL0=Tone_tab[Tone_index]%256;

        fm=~fm;

}

void LCD_disp(void)

{

        uchar i;

        lcd_pos(0);

        i=0;

        while(discode!='')

        {

                lcd_wdat(discode[i]);

                i++;

        }

        lcd_pos(0x40);

        i=0;

        while(dis[i]!='')

        {

        lcd_wdat(dis[i]);

        i++;

        }

}

void int_init(void)

{

TMOD=0x01;

ET0=1;//允许Timer0中断

EX0=1;//允许INT0中断

IT0=1; //INT0为边沿触发

EX1=1;

IT1=1;

EA=1;

TR0=0; //Timer0停止

}

void main(void)

{

int_init();

song_Tone=song1_Tone;

song_Time=song1_Time;

discode=dis1;

lcd_init();

        while(1)

        {

                LCD_disp();

                Tone_index=song_Tone[i];

                if(Tone_index==0xFF)

                {

                        i=0;

                        TR0=0;

                }

                TR0=1;

                delayms(song_Time[Tone_index]*60);

                TR0=0

                i++

        }                                

}


进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • 红外线探测报警器

  • 短波AM发射器电路设计图

  • RS-485基础知识:处理空闲总线条件的两种常见方法

  • 如何调制IC555振荡器

  • 基于ICL296的大电流开关稳压器电源电路

  • 基于TDA2003的简单低功耗汽车立体声放大器电路

    相关电子头条文章