📄 diy0201-11.c
字号:
//11. I/O端口的又一应用-声音输入处理。
//请修改以上程序,如何用声控(PB2 I/O口插上J1短路块)来启动。
// www.sl.com.cn
// nikko@sl.com.cn 02-9-9
// Target : 8515 Crystal: 8.0000Mhz
#include <io8515v.h>
#include <macros.h>
static unsigned char yuequ[]={0x66,0x27,0x68,0x26,0x28,0x28,0x27,0x26,0x47,0x43,
0x67,0x28,0x69,0x27,0x29,0x29,0x28,0x27,0x46,0x46,
0x4a,0x4d,0x4c,0x2d,0x2c,0x2b,0x2b,0x2a,0x29,0x4a,
0x46,0x20,0x4b,0x29,0x6a,0x28,0x27,0x23,0x28,0x27,
0x46,0x46,0x4a,0x4d,0x4c,0x2d,0x2c,0x2b,0x2b,0x2a,
0x29,0x4a,0x46,0x20,0x4b,0x29,0x6a,0x28,0x27,0x23,
0x28,0x27,0x46,0x46,0x00};
//乐曲编码
static unsigned int yinpin[16]={0,392,440,494,523,
587,659,698,784,880,988,1046,1174,1318,1397,1568};
//音频表
unsigned char yinyue,jiepai,delay_tone,pb_buf;
unsigned int yinfu,num=0;
//定义无符号字符型变量和无符号整型变量
void port_init(void)
{ //端口初始化
DDRA = 0x00;PORTA = 0xFF;
DDRB = 0x00;PORTB = 0xFF;
DDRC = 0x0F;PORTC = 0xFF;
DDRD = 0x00;PORTD = 0xFF;
}
//TIMER0 initialisation - prescale:1024
// desired value: 5mSec
// actual value: 4.992mSec (0.2%)
void timer0_init(void)
{//定时器0初始化
TCCR0 = 0x00; //stop timer
TCNT0 = 0xD9; //set count value
TCCR0 = 0x05; //start timer
}
#pragma interrupt_handler timer0_ovf_isr:8
void timer0_ovf_isr(void)
{//定时器0溢出中断处理函数
TCNT0 = 0xD9; //reload counter value
delay_tone++;
}
//TIMER1 initialisation - prescale:8
void timer1_init(void)
{//定时器1初始化
TCCR1B = 0x00; //stop
TCNT1H = 0x00; //setup
TCNT1L = 0x00;
OCR1AH = 0xff;
OCR1AL = 0xff;
TCCR1A = 0x00;
TCCR1B = 0x0A; //start Timer
}
#pragma interrupt_handler timer1_compa_isr:5
void timer1_compa_isr(void)
{//定时器1比较匹配中断函数
//compare occured TCNT1=OCR1A
PORTC^=0x01;//翻转PC0的输出状态
}
void init_devices(void)
{//芯片初始化
CLI(); //关中断
port_init();//调用端口初始化函数
timer0_init();//调用定时器0初始化函数
timer1_init();//调用定时器1初始化函数
MCUCR = 0x00;
GIMSK = 0x00;
TIMSK = 0x42;
// SEI(); //开中断
}
void main(void)
{ //主函数
unsigned char yin_temp;//定义局部字符型变量
init_devices();//调用芯片初始化函数
while(1)//等待PB2按键按下
{ //无键按下等待
pb_buf=PINB & 0x04; //pb2=0
if(pb_buf==0){break;}
}//有键按下运行下面的程序
DDRB = 0xFF;PORTB=0xFF;//PB口输出
yinyue=yuequ[num];//取第一个乐曲编码
SEI();//开中断
while(yinyue != 0)
{
yinyue=yuequ[num];//取乐曲编码
jiepai=(yinyue >>4) * 20;//求得节拍码
yinfu=yinyue& 0x0f;
yinfu=yinpin[yinfu];//取得音频
yinfu = 400000/yinfu; OCR1A=yinfu;//换算得到比较匹配值
while(delay_tone<jiepai);//节拍延时
delay_tone=0;num++;//取下个乐曲编码
}
CLI();//关中断
PORTC=0xFF;//停止输出
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -