圣龙扬特-AVR电子

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 789|回复: 0
打印 上一主题 下一主题

ICCAVR:用M16演奏音乐的实验

[复制链接]

26

主题

1

好友

3446

积分

超级版主

Rank: 8Rank: 8

UID
7
帖子
140
精华
0
注册时间
2013-2-26
在线时间
20 小时

突出贡献

跳转到指定楼层
楼主
发表于 2013-2-28 20:09:35 |只看该作者 |倒序浏览
/*****************************************
*      用M16单片机I/O口生成模拟音乐             *
* 功    能:用I/O口生成模拟音乐                         *
* 时钟频率:内部8M(频率太低音乐不准)         *
* 设    计:tonghe                                                 *
* 修改日期:2007年04月13日                                 *
* 参考资料:ICC AVR应用实例                                 *
* 编译环境:ICC-AVR6.31                                         *
* 实验环境:M16学习板                                 *
* 发    声:无源蜂鸣器                                         *
* 结    果:试验通过                                         *
*****************************************/
#include <iom16v.h>
#include <macros.h>

#define uchar unsigned char
#define uint unsigned int

/****************************************
*     定义音乐数据二维数组{x,y}                        *
*  x:对应音符音阶(频率),0表示休止符        *
*  y:对应音符节拍                                                *
****************************************/
//以下音乐数据为《卡秋莎》,位于程序区
flash uint music_data[][2]=
    {
        {440,600},{494,200},{523,600},{440,200},{523,400},{494,200},
        {440,200},{494,400},{330,400},{494,600},{523,200},{587,600},
        {494,200},{587,400},{523,200},{494,200},{440,800},{659,400},
        {880,400},{784,400},{880,200},{784,200},{698,400},{659,200},
        {587,200},{659,400},{440,400},{  0,200},{698,400},{578,200},
        {659,600},{523,200},{494,200},{330,200},{523,200},{494,200},
        {440,800},{659,400},{880,400},{784,400},{880,200},{784,200},
        {698,400},{659,200},{587,200},{659,400},{440,400},{  0,200},
        {698,400},{587,200},{659,600},{523,200},{494,200},{330,200},
        {523,200},{494,200},{440,800},{  0,  0}
        };
       
#pragma data:data                                         //设置回到数据存储器区
uint delay=0;

/************************************
*         端口初始化函数                        *
************************************/
void port_init(void)
    {
        MCUCR=0x00;
        DDRC=0x01;
        }
/***********************************
*        定时器0初始化函数                   *
***********************************/
void timer0_init(void)
    {
        TCCR0 = 0x00;                                           //暂停定时器0
        TCNT0 = 0x19;                                         //装初值
        TCCR0 = 0x04;                                         //启动定时器0
        }
/**********************************
*定时器0中断入口函数:产生音乐节拍*
**********************************/
#pragma interrupt_handler timer0:8        //_ovf_isr:10
void timer0(void)                                          //_ovf_isr(void)
    {
        delay++;
        TCNT0 = 0x19;                                          //重装初值
        }

/***********************************
*        定时器1初始化函数                   *
***********************************/
void timer1_init(void)                                   //定时器1初始化:1秒定时,预分频256
    {
        TCCR1B = 0x00;                                            //停止定时器
//        TCNT1H = 0xF0;                                           //初值高字节
//        TCNT1L = 0xBE;                                           //定时初值低字节
        TCCR1A = 0x00;
        TCCR1B = 0x04;                                             //启动定时器
        }
/**********************************
*定时器1中断入口函数:产生方波发声*
**********************************/
#pragma interrupt_handler timer1:5        //_ovf_isr:9
void timer1(void)                                          //_ovf_isr(void) //定时器1中断入口
    {
//        TCNT1H = 0xF0;                                          //重装初值
//        TCNT1L = 0xBE;                                          //
        PORTC^=0x01;                                        //产生方波,发声
        }
/*********************************
SOUND函数
功能:输出频率为x的方波,延时y MS
范围:x:100-20000Hz,0:不发声
          y:0-65536 MS
*********************************/
void sound(uint x,uint y)
    {
        SEI();                                                              //
        delay=0;
        if(x!=0)
            {
                x=4000000/x;
                OCR1A=x;
                TCNT1=0x00;
                TIMSK|=0x40;
                while(delay<y)
                    ;
                TIMSK&=0xBF;
                }
        else
                {
                TIMSK&=0xBF;
                while(delay<y)
                        ;
                }
        CLI();
        }
/***********************
*************************/
void main(void)
        {
        uchar i=0;
        port_init();
        timer0_init();
        timer1_init();
        while(1)
            {
                while(music_data[i][0]!=0)
                        {
                        sound(music_data[i][0],music_data[i][1]);
                        i++;
                        }
                i=0;
                }
        }
       
       
回复

使用道具 举报

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

Archiver|手机版|圣龙扬特-AVR电子 ( 鲁ICP备05022832号 )

GMT+8, 2024-12-23 00:16 , Processed in 0.197857 second(s), 20 queries .

Powered by Discuz! X2.5

© 2001-2012 Comsenz Inc.

回顶部