首先,要进行实现定时功能,选择没有输出管教的内部定时器 timer 4
timer 4 定时功能实现
一、首先由规格书可知,定时器4是需要先进行8位的 prescaler 和 4位的 clock divider 的分频设定,其相应的寄存器分别为TCFG0 和 TCFG1
二、根据之上分频器计算出的频率,因本模块取1ms产生一次中断,所以可求得总共所需的次数,赋值给TCNTB4
三、在启动定时器之前,要进行手动更新操作,设置寄存器 TCON,在启动时,要进行清除手动更新位,配置 TCON寄存器
注意点:当赋值给TCNTB4时,该值也将拷贝到 TCNT4中,TCNT4的值每次减1,当其值为0时,产生一次中断,另外在进行启动定时器之前,要进行中断的相应寄存器的设置
利用定时器功能实现音乐播放
一、选择定时器1进行操作,在开发板上找到蜂鸣器LS1,在电路板上找到其位置,然后在核心板上找到其端口GPB1,设置为时钟TCOUT1
二、在初始化操作时,根据参数传进的频率来进行设置 TCNTB1寄存器的值,TCMPB1的值可由自己手动设置,同样地,TCNTB1和TCMPB1的值会分别拷贝给TCNT1和TCMP1,当TCNT1的值减为0或TCNT1的值和TCMP1相等时,产生电平转换
三、定时器的启动步骤,和定时器4一样
四、利用函数的调用来实现时间调用的功能
五、根据传递进来音调的不同和持续时间的长短可以谱写出美妙的音乐
因定时器与音乐播放紧密相关,将代码合成一个模块,便于操作
TIMER.C
- #include "2440addr.h"
- #include "uart.h"
- #include "key.h"
- #include "led.h"
- #include "timer.h"
- #include "song.h"
- static int div2ms, div10ms;
- static volatile unsigned int timer1mscnt,timer10mscnt;
- /*
- Function name : Timer4_Handle
- Description : deal with the interrruption of Timer 4
- Input parameter : none
- Return : none
- Others : none
- */
- static void __irq Timer4_Handle()
- {
- rSRCPND |= (1<<14);
- rINTPND |= (1<<14);
- if(timer1mscnt)
- {
- timer1mscnt--;
- }
- div2ms++;
- switch(div2ms&1) // 2个事情隔1毫秒交替执行
- {
- case 0:
- {
- //checkkey(); // 2 毫秒执行一次
- break;
- }
- case 1:
- {
- set10mstimer(); // 2 毫秒执行一次
- break;
- }
- default:
- {
- break;
- }
- }
- }
- /*
- Function name : delay1ms
- Description : delay the time ,1ms
- Input parameter : one unsigned int vlaue --- waits
- Return : none
- Others : none
- */
- void delay1ms(unsigned int waits)
- {
- timer1mscnt = waits;
- while(1)
- {
- if(0==timer1mscnt)
- {
- //Uart_Printf("1s delay/n");
- break;
- }
- }
- }
- /*
- Function name : delay10ms
- Description : delay the time ,10ms
- Input parameter : one unsigned int vlaue --- wait1ms
- Return : none
- Others : none
- */
- void delay10ms(unsigned int wait1ms)
- {
- timer10mscnt = wait1ms;
- while(1)
- {
- if(0==timer10mscnt) break;
- }
- }
- /*
- Function name : set10mstimer
- Description : Every 2ms to execute the fuction,every case occur use time 10ms
- Input parameter : none
- Return : none
- Others : none
- */
- void set10mstimer(void)
- {
- (div10ms<4)?(++div10ms):(div10ms=0); // Each time 2ms, total 10ms
- switch(div10ms)
- {
- case 0:
- {
- break;
- }
- case 1:
- {
- if(timer10mscnt)
- timer10mscnt--;
- // Uart_Printf("timer1 10 ms ccured/n");
- break;
- }
- case 2:
- {
- break;
- }
- case 3:
- {
- if(playsongflag) //Every 10ms occured
- { uart0_puts("playing.../n");
- playsong();
- }
- break;
- }
- case 4:
- {
- break;
- }
- }
- }
- /*
- Function name : Timer4_init
- Description : Timer 4 init
- Input parameter : one unsigned int value -- ms
- Return : none
- Others : none
- */
- void Timer4_init(unsigned int ms)
- {
- timer1mscnt = 0;
- timer10mscnt = 0;
- div2ms = 0;
- div10ms = 0;
- rTCFG0 |= 0xff<<8;
- rTCFG1 = (rTCFG1& ~(0xf<<16)) |(1<<16);
- ms=(ms==0)? 1:ms;
- rTCNTB4 =(PCLK>>10)*0.001*ms;
- rTCON |= (1<<21); //manual update
- rINTMSK &= ~(1<<14);
- rSRCPND |= (1<<14);
- rINTPND |= (1<<14);
- rTCON = ((rTCON & ~(0x7<<20))|(1<<20)|(1<<22)); //disable manual update, auto load,start
- pISR_TIMER4 = (unsigned ) Timer4_Handle;
- }
- /*
- Function name : StartBuzzer
- Description : Start the Buzzer
- Input parameter : one unsigned int value --- freq
- Return : none
- Others : none
- */
- void StartBuzzer(unsigned int freq)
- {
- rGPBCON = (rGPBCON & ~(0x3<<2)) |(2<<2);
- rTCFG0 |= ((rTCFG0 &~0xf)|(7));
- rTCFG1 = ((rTCFG1 &(~0xf))|(2));
- freq = (freq==0)? 1:freq;
- rTCNTB1 = (PCLK>>6)/freq;
- rTCMPB1 = (rTCNTB1>>1);
- rTCON |= (1<<9);
- rTCON = ((rTCON & ~(0xf<<8))|(1<<8)|(1<<10)|(1<<11));
- }
- /*
- Function name : StopBuzzer
- Description : Stop the Buzzer
- Input parameter : none
- Return : none
- Others : none
- */
- void StopBuzzer(void)
- {
- rTCON = ((rTCON & ~(0xf<<8))|(0<<8));
- }
TIMER.H
- #ifndef _TIMER_H
- #define _TIMER_H
- extern void Timer4_init(unsigned int ms);
- extern void delay10ms(unsigned int waitms);
- extern void delay1ms(unsigned int waitms);
- extern void set10mstimer(void);
- extern void StartBuzzer(unsigned int hz);
- extern void StopBuzzer(void);
- #endif
SONG.C 代码
- /* Copyright (C), 2008-2010, wanczy Tech. Co., Ltd.
- File name : song.c
- Author : cy
- version : V1.0
- Date : 2010-6-28
- Description : song module function implement
- History :
- 1 Date 2010-6-28
- Author cy
- Modification
- */
- #include "timer.h"
- #include "song.h"
- //音符频率对应表
- unsigned short tonefreq[][8]={
- /* 1 2 3 4 5 6 7*/
- /* low */
- {0, 262, 294, 330, 349, 392, 440, 494 },
- {0, 277, 311, 330, 370, 415, 466, 494 }, //("#"表示半音,用于上升或下降半个音)
- /* middle */
- {0, 523, 578, 659, 698, 784, 880, 988 },
- {0, 554, 622, 659, 740, 831, 932, 988 }, //#
- /* high */
- {0, 1046, 1175, 1318, 1397, 1568, 1760, 1976},
- {0, 1109, 1245, 1318, 1480, 1661, 1865, 1976} //#
- };
- struct songdata { //圣斗士
- int tone;
- int freq;
- int time;
- }song[] = {
- {STARTTONE,3,TIMELONG/2},
- {STARTTONE,6,TIMELONG/2},
- {STARTTONE,6,TIMELONG/2},
- {STARTTONE,6,TIMELONG/2},
- {STARTTONE,7,TIMELONG/4},
- {STARTTONE,1,TIMELONG/2},
- {STARTTONE,7,TIMELONG/2},
- {STARTTONE,5,TIMELONG},
- {STARTTONE,0,TIMELONG/10},
- {STARTTONE,6,TIMELONG/4},
- {STARTTONE,5,TIMELONG/2},
- {STARTTONE,3,TIMELONG/4},
- {STARTTONE,4,TIMELONG/4},
- {STARTTONE,1,TIMELONG/2},
- {STARTTONE,1,TIMELONG/2},
- {STARTTONE,1,TIMELONG/2},
- {STARTTONE,2,TIMELONG/2},
- {STARTTONE,1,TIMELONG/2},
- {STARTTONE,3,TIMELONG},
- {STARTTONE,0,TIMELONG/10},
- {STARTTONE,3,TIMELONG/2},
- {STARTTONE,6,TIMELONG/2},
- {STARTTONE,6,TIMELONG/2},
- {STARTTONE,6,TIMELONG/2},
- {STARTTONE,7,TIMELONG/4},
- {STARTTONE,+1,TIMELONG/2},
- {STARTTONE,+2,TIMELONG/2},
- {STARTTONE,7,TIMELONG},
- {STARTTONE,0,TIMELONG/10},
- {STARTTONE,5,TIMELONG/4},
- {STARTTONE,6,TIMELONG/2},
- {STARTTONE,6,TIMELONG/2},
- {STARTTONE,6,TIMELONG/2},
- {STARTTONE,7,TIMELONG/4},
- {STARTTONE,+1,TIMELONG/2},
- {STARTTONE,7,TIMELONG},
- {STARTTONE,0,TIMELONG/10},
- {STARTTONE,6,TIMELONG/4},
- {STARTTONE,7,TIMELONG/2},
- {STARTTONE,+1,TIMELONG/2},
- {STARTTONE,+1,TIMELONG/2},
- {STARTTONE,7,TIMELONG/2},
- {STARTTONE,+5,TIMELONG/2},
- {STARTTONE,6,TIMELONG},
- {STARTTONE,6,TIMELONG/4},
- {STARTTONE,7,TIMELONG/2},
- {STARTTONE,+1,TIMELONG/2},
- {STARTTONE,+1,TIMELONG/2},
- {STARTTONE,7,TIMELONG/2},
- {STARTTONE,+2,TIMELONG/2},
- {STARTTONE,+1,TIMELONG},
- {STARTTONE,0,TIMELONG/10},
- {STARTTONE,6,TIMELONG/4},
- {STARTTONE,7,TIMELONG/2},
- {STARTTONE,+1,TIMELONG/2},
- {STARTTONE,+1,TIMELONG/2},
- {STARTTONE,7,TIMELONG/2},
- {STARTTONE,+5,TIMELONG/2},
- {STARTTONE,6,TIMELONG/2},
- {STARTTONE,+5,TIMELONG/4},
- {STARTTONE,+4,TIMELONG/2},
- {STARTTONE,+3,TIMELONG/2},
- {STARTTONE,+2,TIMELONG/4},
- {STARTTONE,+3,TIMELONG/2},
- {STARTTONE,+4,TIMELONG/4},
- {STARTTONE,+4,TIMELONG/2},
- {STARTTONE,6,TIMELONG/2},
- {STARTTONE,6,TIMELONG/4},
- {STARTTONE,6,TIMELONG/2},
- {STARTTONE,6,TIMELONG/4},
- {STARTTONE,7,TIMELONG/2},
- {STARTTONE,+5,TIMELONG},
- {STARTTONE,0,TIMELONG/10},
- {STARTTONE,+1,TIMELONG/4},
- {STARTTONE,+1,TIMELONG/2},
- {STARTTONE,+2,TIMELONG/4},
- {STARTTONE,+3,TIMELONG/2},
- {STARTTONE,+3,TIMELONG/2},
- {STARTTONE,+4,TIMELONG/4},
- {STARTTONE,+3,TIMELONG/2},
- {STARTTONE,+2,TIMELONG/4},
- {STARTTONE,+3,TIMELONG/2},
- {STARTTONE,+1,TIMELONG/4},
- {STARTTONE,+1,TIMELONG/2},
- {STARTTONE,+2,TIMELONG/4},
- {STARTTONE,+1,TIMELONG/2},
- {STARTTONE,+3,TIMELONG},
- {STARTTONE,0,TIMELONG/10},
- {STARTTONE,+3,TIMELONG/4},
- {STARTTONE,+2,TIMELONG},
- {STARTTONE,0,TIMELONG/10},
- {STARTTONE,+1,TIMELONG/4},
- {STARTTONE,6,TIMELONG/4},
- {STARTTONE,+1,TIMELONG/2},
- {STARTTONE,6,TIMELONG/4},
- {STARTTONE,7,TIMELONG/2},
- {STARTTONE,+1,TIMELONG/2},
- {STARTTONE,+2,TIMELONG/2},
- {STARTTONE,+1,TIMELONG},
- {STARTTONE,0,TIMELONG/10},
- {STARTTONE,+1,TIMELONG/4},
- {STARTTONE,+2,TIMELONG/2},
- {STARTTONE,+3,TIMELONG/2},
- {STARTTONE,+3,TIMELONG/2},
- {STARTTONE,+4,TIMELONG/4},
- {STARTTONE,+3,TIMELONG/2},
- {STARTTONE,+2,TIMELONG/4},
- {STARTTONE,+3,TIMELONG/2},
- {STARTTONE,+1,TIMELONG/4},
- {STARTTONE,+1,TIMELONG/2},
- {STARTTONE,+2,TIMELONG/4},
- {STARTTONE,+1,TIMELONG/2},
- {STARTTONE,+3,TIMELONG},
- {STARTTONE,0,TIMELONG/10},
- {STARTTONE,+3,TIMELONG/4},
- {STARTTONE,+4,TIMELONG/2},
- {STARTTONE,+5,TIMELONG/4},
- {STARTTONE,+4,TIMELONG/2},
- {STARTTONE,+3,TIMELONG/4},
- {STARTTONE,+4,TIMELONG/2},
- {STARTTONE,+3,TIMELONG/4},
- {STARTTONE,+2,TIMELONG/2},
- {STARTTONE,+1,TIMELONG/4},
- {STARTTONE,7,TIMELONG/2},
- {STARTTONE,+1,TIMELONG/2},
- {STARTTONE,+2,TIMELONG/4},
- {STARTTONE,+2,TIMELONG/2},
- {STARTTONE,+1,TIMELONG*2},
- };
- int songplaytime,songindex,songfreq,songtone; //定义播放的时间,索引,音调频率,音调
- int playsongflag; //定义标签决定是否进行播放
- /*
- Function name : playsong
- Description : the play song function
- Input parameter : none
- Return : none
- Others : none
- */
- void playsong(void)//由定时器每10ms调用一次
- {
- if(songplaytime)
- {
- songplaytime--; //
- }
- else
- {
- StopBuzzer();
- songplaytime = song[songindex].time;
- songfreq = song[songindex].freq;
- songtone = song[songindex].tone;
- if(songfreq)
- {
- StartBuzzer(tonefreq[songtone][songfreq]);
- }
- songplaytime--;
- ++songindex;
- // (songindex<(sizeof(bjfyn)/sizeof(struct songdata)))?++songindex:(songindex=0);
- if(songindex>=(sizeof(song)/sizeof(struct songdata))) //如果音乐播放到末尾,则停止播放
- Stopplaysong();
- }
- }
- /*
- Function name : Startplaysong
- Description : Start to play song
- Input parameter : none
- Return : none
- Others : none
- */
- void Startplaysong(void)
- {
- songplaytime = 0;
- songindex = 0;
- playsongflag = 1;
- }
- /*
- Function name : Stopplaysong
- Description : Stop to play song
- Input parameter : none
- Return : none
- Others : none
- */
- void Stopplaysong(void)
- {
- playsongflag = 0;
- songplaytime = 0;
- songindex = 0;
- StopBuzzer();
- }
- /*
- Function name : pauseplaysong
- Description : pause to play song
- Input parameter : none
- Return : none
- Others : none
- */
- void pauseplaysong(void)
- {
- playsongflag = 0;
- songplaytime = 0;
- StopBuzzer();
- }
SONG.H
- #ifndef _SONG_H
- #define _SONG_H
- #define TIMELONG 80
- #define STARTTONE 2
- extern int playsongflag;
- extern void playsong(void);
- extern void Startplaysong(void);
- extern void Stopplaysong(void);
- extern void pauseplaysong(void);
- #endif