新手学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编辑过 太好了 好样的!!!!酷酷酷酷酷酷酷酷酷酷酷
-----此内容被archeng504于2007-05-25,12:44:54编辑过 学习! 轰鸣器?!
能否把效果录音,试听一下? 忍不住,再顶一下~! 呵呵,我也只读了这两个OS的源码。都很不错。 用一根悬挂线,20厘米左右,接PORTD7,用收音机FM或电视伴音竟然收的到,
单片机也有电磁辐射。 为什么 中断不用 AVRX_SIGINT(SIG_OUTPUT_COMPARE1A)
{
IntProlog(); // Switch to kernel stack/context
PORTD^=0X80;
OCR1A=Sing;
Epilog(); // Return to tasks
}
这个呢,去掉了 IntProlog 和 Epilog 有什么区别? 忍不住要顶一下 这个先标记下,有空了解下实现机制,学习中...
页:
[1]