(在线等)一个单片机程序中如何使用两个定时器(T0和T1)

我想用单片机做个简易电子琴,可以弹奏简单乐曲和播放存储的音乐。用4*4键盘模拟电子琴的按键,用一个独立按键控制播放。这两个功能我已经用两个.C程序实现了,代码见下,如果把这两个.C程序合并到一个里面就行了,但是两个程序中都用到了T0定时器,合并的时候会发生冲突。能不能把其中的一个T0定时器改成T1合并呢?请高手帮个忙。谢谢!
一楼和二楼分别是两个C程序的代码
能不能帮我把它们合并成一个C程序,同时有这两个功能?

/*******************************************************
蜂鸣器唱歌程序
当独立按键P3^2按下时蜂鸣器便开始唱歌。
*******************************************************/
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar Count;
sbit Speak =P1^2;
sbit key1=P3^2;
unsigned char code SONG[] ={
0x26,0x20,0x20,0x20,0x20,0x20,0x26,0x10,0x20,0x10,0x20,0x80,0x26,0x20,0x30,0x20,
0x30,0x20,0x39,0x10,0x30,0x10,0x30,0x80,0x26,0x20,0x20,0x20,0x20,0x20,0x1c,0x20,
0x20,0x80,0x2b,0x20,0x26,0x20,0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,0x80,0x26,0x20,
0x30,0x20,0x30,0x20,0x39,0x10,0x26,0x10,0x26,0x60,0x40,0x10,0x39,0x10,0x26,0x20,
0x30,0x20,0x30,0x20,0x39,0x10,0x26,0x10,0x26,0x80,0x26,0x20,0x2b,0x10,0x2b,0x10,
0x2b,0x20,0x30,0x10,0x39,0x10,0x26,0x10,0x2b,0x10,0x2b,0x20,0x2b,0x40,0x40,0x20,
0x20,0x10,0x20,0x10,0x2b,0x10,0x26,0x30,0x30,0x80,0x18,0x20,0x18,0x20,0x26,0x20,
0x20,0x20,0x20,0x40,0x26,0x20,0x2b,0x20,0x30,0x20,0x30,0x20,0x1c,0x20,0x20,0x20,
0x20,0x80,0x1c,0x20,0x1c,0x20,0x1c,0x20,0x30,0x20,0x30,0x60,0x39,0x10,0x30,0x10,
0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,0x10,0x26,0x10,0x26,0x10,0x2b,0x10,0x2b,0x80,
0x18,0x20,0x18,0x20,0x26,0x20,0x20,0x20,0x20,0x60,0x26,0x10,0x2b,0x20,0x30,0x20,
0x30,0x20,0x1c,0x20,0x20,0x20,0x20,0x80,0x26,0x20,0x30,0x10,0x30,0x10,0x30,0x20,
0x39,0x20,0x26,0x10,0x2b,0x10,0x2b,0x20,0x2b,0x40,0x40,0x10,0x40,0x10,0x20,0x10,
0x20,0x10,0x2b,0x10,0x26,0x30,0x30,0x80,0x00
};
void Time0_Init()
{
TMOD = 0x01;
IE = 0x82;
TH0 = 0xDC;
TL0 = 0x00;
}
/********************************************************************
* 功能 : 定时器中断,中断中实现 Count 加一
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Time0_Int() interrupt 1
{
TH0 = 0xDC;
TL0 = 0x00;
Count++;
}
/********************************************************************
* 名称 : Delay_xMs()
* 功能 : 延时子程序
* 输入 : x
* 输出 : 无
***********************************************************************/
void Delay_xMs(uint x)
{
uint i,j;
for(i=0; i<x; i++)
{
for(j=0; j<3; j++);
}
}
void delay(void)
{
int i;
for(i=0;i<1827;i++);
}
/********************************************************************
* 名称 : Play_Song()
* 功能 : 播放蜂鸣器控制程序
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Play_Song(void)
{
uchar Temp1,Temp2;
uint Addr;
Count = 0; //中断计数器清0
Addr =0;
while(1)
{
Temp1 = SONG[Addr++];
if (Temp1 == 0xFF) //休止符
{
TR0 = 0;
Delay_xMs(100);
}
else if (Temp1 == 0x00) //歌曲结束符
{
return;
}
else
{
Temp2 = SONG[Addr++];
TR0 = 1;
while(1)
{
Speak = ~Speak;
Delay_xMs(Temp1);
if(Temp2 == Count)
{
Count = 0;
break;
}
}
}
}
}
/********************************************************************
* 名称 : Main()
* 功能 : 主函数
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Main()
{
Time0_Init(); //定时器0中断初始化
while(1)
{
if(key1==0)
{
delay();
if(key1==0) Play_Song();
}
}
}
温馨提示:答案为网友推荐,仅供参考
第1个回答  2011-06-15
/****************************************************************
简易电子琴程序
用4*4矩阵按键模拟电子琴按键来弹奏简单的乐曲。
****************************************************************/

#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
/* 音符与计数值对应表 */
uint code tab[]={64021,64103,64260,64400,
64524,64580,64684,64777,
64820,64898,64968,65030,
65058,65110,65157,65178};
sbit Speak = P1^2; // 此引脚输出脉冲
uchar STH0;
uchar STL0;
/* 键消抖延时函数 */
void delay(void)
{
uchar i;
for (i=300;i>0;i--);
}
/* 键扫描函数 */
uchar getkey()
{
uchar scancode,tmpcode;
if ((P1&0xf0)==0xf0)
return(0);
scancode = 0xfe;
while((scancode&0x10)!=0) // 逐行扫描
{
P1 = scancode; // 输出行扫描码
if ((P1&0xf0)!=0xf0) // 本行有键按下
{
tmpcode = (P1&0xf0)|0x0f;
/* 返回特征字节码,为1的位即对应于行和列 */
return((~scancode)+(~tmpcode));
}
else scancode = (scancode<<1)|0x01; // 行扫描码左移一位
}
}
void time0_int() interrupt 1 using 0
{
TH0 = STH0;
TL0 = STL0;
Speak=~Speak; // 反相,产生输出脉冲
}
void main()
{
uchar key,k;
TMOD = 0x11; // T0,工作方式1
ET0 = 1; //开定时器0中断
EA = 1; //开总中断
while(1)
{
P1 = 0xf0; // 发全0行扫描码
if ((P1&0xf0)!=0xf0) // 若有键按下
{
delay(); // 延时去抖动
if ((P1&0xf0)!=0xf0) // 延时后再判断一次,去除抖动影响
{
key = getkey(); // 调用键盘扫描函数
// 根据获取的按键位置得到k值
switch(key)
{
case 0x11: // 1行1列
k = 0;
break;
case 0x21: // 1行2列
k = 1;
break;
case 0x41: // 1行3列
k = 2;
break;
case 0x81: // 1行4列
k = 3;
break;
case 0x12: // 2行1列
k = 4;
break;
case 0x22: // 2行2列
k = 5;
break;
case 0x42: // 2行3列
k = 6;
break;
case 0x82: // 2行4列
k = 7;
break;
case 0x14: // 3行1列
k = 8;
break;
case 0x24: // 3行2列
k = 9;
break;
case 0x44: // 3行3列
k = 10;
break;
case 0x84: // 3行4列
k = 11;
break;
case 0x18: // 3行4列
k = 12;
break;
case 0x28: // 3行4列
k = 13;
break;
case 0x48: // 3行4列
k = 14;
break;
case 0x88: // 3行4列
k = 15;
break;
default:
break;
}
Speak = ~Speak; // 反相

/* 根据所得的k值设定计数器1的计数初值 */
STH0 = tab[k]/256;
STL0 = tab[k]%256;
TR0 = 1; // 开始计数
P1 = 0xf0; // 发全0行扫描码
while ((P1&0xf0)!=0xf0) // 若没有松开按键
{
P1 = 0xf0;
}
TR0 = 0; // 若按键松开,则停止计数,不产生脉冲输出
}
}
}
}
第2个回答  2011-06-15
这两个功能互相独立,用一个定时器就可以实现,不需用两个定时器

你要做的就是合并两个主程序,把一些功能代码块打包一下,如果这两个.C都是自己写的,我想这对你应该不能难
第3个回答  2011-06-15
你可以把两个定时器中断优先级设置一下 看看行不行本回答被提问者采纳
第4个回答  2011-06-15
应该可以