在2006年时候记得我在做 ISD1420的播放控制,当时在 选段播放上遇到了问题,当时网络上也没有详细描述具体的控制方法,也在咱们坛子里问过。
折腾了很久,后来还是实现出来了。但资料后来没有实际应用到产品上,今天翻看资料的时候发现了,拿出来给同样碰到问题的朋友做为参考。
以前写的C程序比较菜,注释比较多。(现在写的程序注释也很多 :)
电路图简单画了下,大家都看得懂:
(原文件名:1420.jpg)
程序不长,先附上 KEIL完整工程,再把程序直接贴上:
点击此处下载 ourdev_421265.rar(文件大小:22K) (原文件名:1420_code.rar)
程序原文:
/**********************************************************
功能: 使用STC2052单片机控制 ISD1420语音芯片的播放
1、顺序连续分段放音
2、选段播放(播放任意段)
3、所有的播放控制都是通过接收串口的命令来执行
编写: benladn911 AVR猎手
日期: 2006-6-28创建
2008-2-21添加注释和完善
**********************************************************/
#include<STC12C2052.H>
#include<intrins.h>
#include<stdio.h>
#include<string.h>
//硬件端口的定义
#define POW P3_7 //此引脚为单片机控制一个三极管给 ISD1420供电
#define PL P3_5 //接 ISD1420 的 PLAYL
#define PE P3_4 //接 ISD1420 的 PLAYE
#define REC P3_3 //接 ISD1420 的 REC
#define REC_LED P3_2 //ISD1420 的 REC LED
//操作模式的定义
#define mode1 0xC8 //循环放音操作,按一下 PE 键可循环放音,按 PL 键停止;或按 PL 键放音,松开即停止
#define mode2 0xD0 //按顺序连续分段录放音,每段语音长度不限
#define mode3 0xC0 //地址指针复位,开始录放第一段
#define mode4 0xD1 //按 PE 键可快速选段放音
//0xC1 //也为地址指针复位
unsigned char RX_index=0; //
bit FLAG_rev = 0; //
unsigned char PC_COMMAND;
unsigned char RX_BUFFER[10];//串行接收缓存
void io_init(void);
void init_serialcomm(void);
void serial_out(unsigned char d);
void delay5ms(void);
void delay(unsigned int x);
void nop(unsigned char i);
void paly(unsigned char i);//选择播放当前段操作
void main(void)
{
io_init();
init_serialcomm();
delay(1000);
serial_out(0xaa); //发送到PC机,看看PC端是否收到正确数据
serial_out(0x55);
serial_out(0x33);
POW = 0;//开启电源
//P1 = mode4;
//P1 = 0X00;
while(1)
{
}
}
//----- 端口初始化
void io_init(void)
{
P1M0 = 0x00; //设置STC的 IO 为标准51 IO模式
P1M1 = 0x00;
P3M0 = 0x00;
P3M1 = 0x00;
P1 = 0XFF;
P3 = 0XFF;
}
//串行口初始化
void init_serialcomm(void)
{
SCON = 0x50; //SCON: serail mode 1, 8-bit UART, enable ucvr
TMOD = 0x20; //TMOD: timer 1, mode 2, 8-bit reload
TH1 = 0xf3;//12MHz, 2400 bps
TL1 = 0xf3;
//IE |= 0x90; //Enable Serial Interrupt
TR1 = 1; // timer 1 run
ES=1;
EA=1;
}
//串行数据发送,查询模式
void serial_out(unsigned char d)
{
ES=0;
SBUF=d;while(TI==0){;}TI=0;
ES=1;
}
//串行中断接收
void receive() interrupt 4
{
if(RI)
{
RI = 0;
ES = 0;
PC_COMMAND = SBUF;
//RX_BUFFER[RX_index] = PC_COMMAND; //保存数据到数组里面
//RX_index++;
switch(PC_COMMAND)
{
case 0xa0:
serial_out(0xa0);
P1 = mode2; //按顺序连续分段录放音,每段语音长度不限 0xD0 连续寻址,A4
PE = 0;
nop(10);
PE = 1;
P1 = 0XFF;
break;
case 0xb0:
serial_out(0xb0);
P1 = mode3; //地址指针复位 0xC0
nop(10);
P1 = 0XFF;
break;
case 0xc0: //选段播放控制
serial_out(0xc0);
P1 = 0xD1; //第二步:快速选段放音
P1_0 = 0;
nop(10);
P1_0 = 1;
nop(10);
PE = 0;
nop(10);
PE = 1;
break;
case 0xd0:
serial_out(0xd0); //播放任意段的组合
paly(3);
paly(1);
paly(5);
paly(5);
paly(6);
paly(4);
paly(3);
paly(6);
paly(1);
break;
case 0x30:
serial_out(0x30);
//此操作循环放音操作,按一下 PE 键可循环放音,按 PL 键停止;或按 PL 键放音,松开即停止
//此操作没什么用
P1 = mode1;
PE = 0;
nop(10);
PE = 1;
//
break;
default: break;
}
ES = 1;
}
}
/*************************************************************
选段播放,i 的值就是要播放的当前段
i的取值:1 ~ ...
**************************************************************/
void paly(unsigned char i)
{
i--;
P1 = mode3; //第一步:地址指针复位 0xC0 A7--A0: 1100 0000 (A2、A5在应用中可直接接地)
nop(10);
//P1 = 0XFF;
delay(30);//必要的延时
if(i>0)
{
P1 = 0xD1; //第二步:快速选段放音 0xD1 A7--A0: 1101 0001 (A2、A5在应用中可直接接地)
do
{
P1_0 = 0; //给 A0 低电平脉冲
nop(10);
P1_0 = 1;
nop(10);
PE = 0;
nop(10);
PE = 1;
delay(50);//这个延时是非常必要的!
i--;
}
while(i!=0);
delay(30);//必要的延时
}
P1 = mode2; //第三步:播放当前段 0xD0 A7--A0: 1101 0000 (A2、A5在应用中可直接接地)
PE = 0;
nop(10);
PE = 1;
//P1 = 0XFF;
while(REC_LED==1){;}//等待播放
while(REC_LED==0){;}//等待播放结束
}
//----------------------------软件延时函数----------------------------
//50ms延时
void delay5ms(void)
{
unsigned char TempCyc = 250;
while(TempCyc--);
}
void delay(unsigned int x)
{
do
{
delay5ms();delay5ms();delay5ms();x--;
}
while(x!=0);
}
void nop(unsigned char i)
{
do
{
_nop_();
i--;
}
while(i!=0);
} |
|
|
|