ATmega16 发表于 2007-5-25 09:41:02

新手学AVR:基于SMALL RTOS和AVRX的歌曲实验----菊花台

基于Small rtos和avrx的歌曲实验:菊花台

1.一个CTC中断,一个歌曲演奏Song任务。

2.small rtos CTC 中断使用非系统管理中断,不受OS_ENTER_CRITICAL()影响。

3.AVRX下 CTC中断不进行内核切换。

4.乐谱'a'-'g'表示低音,1-7表示中音,'A'-'G'表示高音。

5.使用马老师AVR实验版,内部8MRC振荡,PORTD7接轰鸣器。





点击此处下载armok01155359.rar







---------------------------Small rtos--------------------------------------



#define IN_SONG_C

#include "../config/config.h"



uint16_t Sing;





SIGNAL(SIG_OUTPUT_COMPARE1A)

{

PORTD^=0X80;

OCR1A=Sing;

}





uint8_t playchar(uint8_t ch)

{



        switch(ch)

        {

        case 0: return 0;



        case 'a': return 1;

        case 'b': return 2;

        case 'c': return 3;

        case 'd': return 4;

        case 'e': return 5;

        case 'f': return 6;

        case 'g': return 7;

        case 1: return 8;

        case 2: return 9;

        case 3: return 10;

        case 4: return 11;

        case 5: return 12;

        case 6: return 13;

        case 7: return 14;

        case 'A': return 15;

        case 'B': return 16;

        case 'C': return 17;

        case 'D': return 18;

        case 'E': return 19;

        case 'F': return 20;

        case 'G': return 21;

       

        default : return 0;

        }

}



void Song(void)

{

        uint8_t i,temp,length,ch;

        uint16 sing;



        DDRD=0X80;





        TCCR1B = 0x00;//停止定时器

//        TIMSK |= 0x10;//中断允许

        TCNT1H = 0x00;

        TCNT1L = 0x00;//初始值

        OCR1AH = 0x00;

        OCR1AL = 0x00;//匹配A值

        OCR1BH = 0x00;

        OCR1BL = 0x00;//匹配B值

        ICR1H= 0xFF;

        ICR1L= 0xFF;//输入捕捉匹配值

        TCCR1A = 0x00;

        TCCR1B = 0x0A;//启动定时器







        while(1)

        {

       

                for(i=0;i<128;i++)

                {



                        temp=pgm_read_byte(Song_P+i);

                        ch=playchar(temp);

                        sing=pgm_read_word(Tone_P+ch);

                        length=pgm_read_byte(Length_P+i);

                       

                        if(sing)

                        {

                                cli();

                                Sing=sing;

                                sei();



                                temp=length;

                               

                                TIMSK |= 0x10;                //中断允许

                       

                                while(temp--)

                                {

                                        OSWait(K_TMO,OS_TICKS_PER_SEC/8);

                                }

                                  TIMSK &= ~0x10;                //中断关闭

                        }





                        else

                        {

                                temp=length;

                                while(temp--)

                                {

                                        OSWait(K_TMO,OS_TICKS_PER_SEC/8);

                                }

                        }

                }



        OSWait(K_TMO,OS_TICKS_PER_SEC);

        }

}



















---------------------------------AVRX----------------------------------------



#define IN_SONG_C

#include "../config/config.h"



uint16_t Sing;





SIGNAL(SIG_OUTPUT_COMPARE1A)

{

PORTD^=0X80;

OCR1A=Sing;

}



/*

AVRX_SIGINT(SIG_OUTPUT_COMPARE1A)

{

    IntProlog();                // Switch to kernel stack/context





PORTD^=0X80;

OCR1A=Sing;



    Epilog();                   // Return to tasks

}

*/





TimerControlBlockSONG_TIMER;







uint8_t playchar(uint8_t ch)

{



        switch(ch)

        {

        case 0: return 0;



        case 'a': return 1;

        case 'b': return 2;

        case 'c': return 3;

        case 'd': return 4;

        case 'e': return 5;

        case 'f': return 6;

        case 'g': return 7;

        case 1: return 8;

        case 2: return 9;

        case 3: return 10;

        case 4: return 11;

        case 5: return 12;

        case 6: return 13;

        case 7: return 14;

        case 'A': return 15;

        case 'B': return 16;

        case 'C': return 17;

        case 'D': return 18;

        case 'E': return 19;

        case 'F': return 20;

        case 'G': return 21;

       

        default : return 0;

        }

}







AVRX_GCC_TASKDEF(Song,30,1)

//void Song(void)

{

        uint8_t i,temp,length,ch;

        uint16 sing;



        DDRD=0X80;





        TCCR1B = 0x00;//停止定时器

//        TIMSK |= 0x10;//中断允许

        TCNT1H = 0x00;

        TCNT1L = 0x00;//初始值

        OCR1AH = 0x00;

        OCR1AL = 0x00;//匹配A值

        OCR1BH = 0x00;

        OCR1BL = 0x00;//匹配B值

        ICR1H= 0xFF;

        ICR1L= 0xFF;//输入捕捉匹配值

        TCCR1A = 0x00;

        TCCR1B = 0x0A;//启动定时器







        while(1)

        {

       

                for(i=0;i<131;i++)

                {



                        temp=pgm_read_byte(Song_P+i);

                        ch=playchar(temp);

                        sing=pgm_read_word(Tone_P+ch);

                        length=pgm_read_byte(Length_P+i);

                       

                        if(sing)

                        {

                                cli();

                                Sing=sing;

                                sei();



                                temp=length;

                               

                                TIMSK |= 0x10;                //中断允许

                       

                                while(temp--)

                                {

                                        AvrXDelay(&SONG_TIMER,125);



                                }

                                  TIMSK &= ~0x10;                //中断关闭

                        }





                        else

                        {

                                temp=length;

                                while(temp--)

                                {

                                        AvrXDelay(&SONG_TIMER,125);

                                }

                        }

                }



                                        AvrXDelay(&SONG_TIMER,1000);

        }

}




















-----此内容被ATmega16于2007-05-25,10:00:37编辑过

jackiezeng 发表于 2007-5-25 10:16:44

太好了

archeng504 发表于 2007-5-25 12:44:22

好样的!!!!酷酷酷酷酷酷酷酷酷酷酷
-----此内容被archeng504于2007-05-25,12:44:54编辑过

yangsen 发表于 2007-5-25 17:05:42

学习!

powerful 发表于 2007-5-25 17:42:01

轰鸣器?!



能否把效果录音,试听一下?

jackiezeng 发表于 2007-5-25 19:53:57

忍不住,再顶一下~!

zhonghua_li 发表于 2007-5-25 20:10:05

呵呵,我也只读了这两个OS的源码。都很不错。

ATmega16 发表于 2007-5-27 10:46:35

用一根悬挂线,20厘米左右,接PORTD7,用收音机FM或电视伴音竟然收的到,

单片机也有电磁辐射。

ddrfft 发表于 2010-3-14 12:00:36

为什么 中断不用 AVRX_SIGINT(SIG_OUTPUT_COMPARE1A)
{
    IntProlog();                // Switch to kernel stack/context


PORTD^=0X80;
OCR1A=Sing;

    Epilog();                   // Return to tasks
}
这个呢,去掉了 IntProlog 和 Epilog 有什么区别?

dahai66001 发表于 2011-4-23 21:03:16

忍不住要顶一下

qqwe13 发表于 2014-2-19 21:40:14

这个先标记下,有空了解下实现机制,学习中...
页: [1]
查看完整版本: 新手学AVR:基于SMALL RTOS和AVRX的歌曲实验----菊花台