http://www.atvoc.com
语音芯片-中青世纪  
首页
公司介绍
软件下载
产品世界
应用案例
中青论坛
联系我们
公司介绍
公司介绍
公司文化
公司新闻
部门设置

公司照片

最新动态

招聘贤才

相关信息
我们为什么选择数码语声?
 
PM50语音组合发码板图纸及程序

#include <AT892051.H>
//这是中青世纪开发的“PM50语音组合发码板”的单片机程序,设计用AT89C2051与PM50串行模式接口的程序范例,使用晶振11.0592MHZ,单片机管理一个键盘,例如当用户按键"6*12*37*1*63#"时,将控制PM50连续播放第6、第12、第37、第1、第63段,如果只按#号,将播放上一次组合播放的内容。这样以实现语音组合.
//PM50串行模式下,无论一段语音的长度多少,第1段语音在地址80H,第2段在81H,如此,最多128段。PM50的串行时钟为10HZ~100KHZ,建议使用1KHZ。
//以下是“PM50语音组合发码板”的原理图纸:
//以下是AT89C2051的程序设计

//I/O脚的定义

#define key_port P1

#define tx_pin P3_1 //数据脚

#define clk_pin P3_7 //时钟脚

#define busy_pin P3_2 //BUSY脚

#define test_pin P3_3 //测试脚

#define test_clk P3_4

#define low 0

#define high 1

typedef unsigned char byte;

unsigned int key_time;

unsigned int delay_time;

unsigned int input_time;

byte key_buf[21];

byte key_tmp[21];

byte key,last_key;

byte key_input;

byte sound_number;

byte play_number;

bit read;

bit play;

//延时子程序 单位 MS

void delay(byte t)

{

EA = 0;

delay_time = 0;

EA = 1;

while(delay_time < t);

}

void send_play(byte sound_no)

{

byte sd = sound_no + 0x80; //第一段为80H

byte loop;

tx_pin = low;

delay(45); //启动延时 45MS

tx_pin = high;

delay(1);

//now send data

for(loop = 0;loop < 8; loop++) //发送数据 8个

{

clk_pin = low;

tx_pin = sd & 0x01;

sd = sd >> 1;

delay(1); //发送频率 1 KHZ

clk_pin = high;

delay(1);

}

tx_pin = high;

}

//测试程序

void test(byte t)

{

byte loop;

byte sd = t;

for(loop = 0;loop < 8; loop++)

{

test_clk = low;

test_pin = sd & 0x01;

sd = sd >> 1;

delay(1);

test_clk = high;

delay(1);

}

test_pin = high;

}

//键盘处理

byte get_key()

{

byte tmp;

key_port = 0x6f;

for(tmp = 0; tmp <10;tmp++);

tmp = key_port & 0x0f;

if(tmp != 0x0f)

return tmp+0x10;

key_port = 0x5f;

for(tmp = 0; tmp <10;tmp++);

tmp = key_port & 0x0f;

if(tmp != 0x0f)

return tmp+0x20;

key_port = 0x3f;

for(tmp = 0; tmp <10;tmp++);

tmp = key_port & 0x0f;

if(tmp != 0x0f)

return tmp+0x40;

//no key on

return 0;

}

byte proc_key(byte key)

{

switch(key)

{

case 0x1e: return 12; //#

case 0x1d: return 10; //9

case 0x1b: return 7; //6

case 0x17: return 4; //3

case 0x2e: return 1; //0

case 0x2d: return 9; //8

case 0x2b: return 6; //5

case 0x27: return 3; //2

case 0x4e: return 11; //*

case 0x4d: return 8; //7

case 0x4b: return 5; //4

case 0x47: return 2; //1

default: return 0;

}

}

//时钟

void clkint (void) interrupt 1 using 0

{

TR0=0;

TH0=0xfc; /* clk 12mhz */

TL0=0x18; /* set interrupt freq.=1ms */

TR0=1; /* start timer/counter0 */

key_time++;

delay_time++;

input_time++ ;

}

//键盘处理主程序

void do_key()

{

if(key_time > 32) // 32ms to scan key

{

key_time = 0;

key = get_key();

if(key)

key = proc_key(key);

}

else return;

if(input_time > 5000)

{

input_time = 0;

if(sound_number)

{

key_tmp[key_input] = sound_number ;

if(++key_input > 19)

key_input = 19;

}

read = sound_number = 0;

}

if(!key)

{

key = last_key = 0;

return;

}

input_time = 0; //inputing .....

if(key == last_key) return; //rep

last_key = key;

test(key);

switch(key)

{

case 11: // *

if(sound_number)

{

key_tmp[key_input] = sound_number ;

if(++key_input > 19)

key_input = 19;

}

read = sound_number = 0;

break;

case 12: // #

if(sound_number)

{

key_tmp[key_input] = sound_number ;

if(++key_input > 19)

key_input = 19;

}

if(key_input > 0 )

{

for(sound_number = 0; sound_number < 20;sound_number++)

key_buf[sound_number] = 0;

for(sound_number = 0; sound_number < key_input;sound_number++)

key_buf[sound_number] = key_tmp[sound_number];

}

play = 1;

key_input = 0;

sound_number = 0;

play_number = 0;

read = 0;

break;

default:

if(read)

{

sound_number = (sound_number-1) * 10 + key;

read = 0;

}

else

{

sound_number= key;

read = 1;

}

break;

}

}

//主程序

void main(void)

{

//初始化

P1 = 0xff;

P3 = 0xff;

for(key_time = 0; key_time<21;key_time++)

{

key_buf[key_time] = 0;

key_tmp[key_time] = 0;

}

key_time = 0;

input_time = 0;

key_input = 0;

last_key = 0;

sound_number = 0;

read = play = 0;

play_number = 0;

TMOD = TMOD|0x01; // init Timer0 mode

TF0 = 0;

TR0=0;

TH0=0xfe;

TL0=0xc3;

TR0=1; // start timer/counter 0

ET0 = 1;

EA = 1;

//主循环

while(1)

{

do_key();

if(play)

{

if(key_buf[play_number])

{

if(!busy_pin)

send_play(key_buf[play_number++]-2);

}

else

play = 0;

}

}

}



友情指导:
3
友情链接:                                                                                                         申请友情链接