⑴ 怎么写单片机控制外围芯片程序
兄弟,参加电子设计大赛吧??b题?
这个最重要的是看芯片资料,芯片资料内对通信方式,协议,时序,都有的,可以利用单片机自带的通信接口,即端口第二功能。也可以自己制定时序。
这是24c02的程序。用的ATmega16;
最后祝你有个好成绩
#include <iom16v.h>
#include <macros.h>
#include "delay.h"
#include "lcd.h"
#define uchar unsigned char
#define uint unsigned int
/**************************************************************************
* 函数名称: ERROR();
* 功 能: 蜂鸣器报错
* 参 数:无
* 描 述:PA0口置低可以鸣响蜂鸣器
**************************************************************************/
void ERROR()
{
uint i;
DDRA |= (1 << PA0);
PORTA &= ~(1 << PA0);
for( i = 0 ; i < 10000 ; i ++);
PORTA |= (1 << PA0);
}
//********************************************************************8
//*函数 向24c02发送一个字节
//*名称 wtwib();
//*参数 地址,数据
//*********************************************************************/
void wtwib(uchar ad,uchar da)
{ TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);//发送start
while (!(TWCR & (1<<TWINT)));
if ((TWSR & 0xF8) != 0x08)
ERROR();
TWDR =0xA0; //adress of e2prom
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
if ((TWSR & 0xF8) != 0x18)
ERROR();
TWDR =ad; //adress of the data
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
if ((TWSR & 0xF8) != 0x28)
ERROR();
TWDR =da; //send the data to the bus
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
if ((TWSR & 0xF8) != 0x28)
ERROR();
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);//send the stop signal
}
//=================================================================
//=======read a byte from 24c02
//========rtwib()
//==========need address
//================================================================
uchar rtwib(uchar ad)
{ uchar da;
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);//send the signal of start
while (!(TWCR & (1<<TWINT)));
if ((TWSR & 0xF8) != 0x08)
ERROR();
TWDR =0xA1; //adress of e2prom
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
if ((TWSR & 0xF8) != 0x18)
ERROR();
TWDR =ad; //adress of the data
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
if ((TWSR & 0xF8) != 0x28)
ERROR();
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);//send the signal of start
while (!(TWCR & (1<<TWINT)));
if ((TWSR & 0xF8) != 0x08)
ERROR();
TWDR =0xA1; //adress of e2prom
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
if ((TWSR & 0xF8) != 0x18)
ERROR();
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
if ((TWSR & 0xF8) != 0x58)
ERROR();
da=TWDR;
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);//send the stop signal
return da;
}
//========================================================
//====== send a page to the 24c02
//====== wtwis();
//=======need address and data and number;
//=========================================================
void wtwip(uchar ad,uchar n,uchar *da)
{ uchar i;
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);//发送start
while (!(TWCR & (1<<TWINT)));
if ((TWSR & 0xF8) != 0x08)
ERROR();
TWDR =0xA0; //adress of e2prom
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
if ((TWSR & 0xF8) != 0x18)
ERROR();
TWDR =ad; //adress of the data
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
if ((TWSR & 0xF8) != 0x28)
ERROR();
for(i=0;i<n;i++)
{ TWDR =da[i]; //send the data to the bus
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
if ((TWSR & 0xF8) != 0x28)
ERROR();
}
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);//send the stop signal
}
//====================================================
//========read a string from the 24C02
//========rtwis();
//========need address,number
//=====================================================
void rtwis(uchar ad,uchar *p,uchar n)
{ uchar i;
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);//send the signal of start
while (!(TWCR & (1<<TWINT)));
if ((TWSR & 0xF8) != 0x08)
ERROR();
TWDR =0xA1; //adress of e2prom
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
if ((TWSR & 0xF8) != 0x18)
ERROR();
TWDR =ad; //adress of the data
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
if ((TWSR & 0xF8) != 0x28)
ERROR();
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);//send the signal of start
while (!(TWCR & (1<<TWINT)));
if ((TWSR & 0xF8) != 0x08)
ERROR();
TWDR =0xA1; //adress of e2prom
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));
if ((TWSR & 0xF8) != 0x18)
ERROR();
for(i=0;i<n;i++)
{ TWCR = (1<<TWINT) | (1<<TWEN)|(1<<TWEA);
while (!(TWCR & (1<<TWINT)));
if ((TWSR & 0xF8) != 0x50)
ERROR();
p[i]=TWDR;
}
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);//send the stop signal
}
void main()
{ uchar a[16]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15},i=0;
init_lcd();
TWBR = 0x1F;
TWSR = 0x02;
for(i=0;i<16;i++)
wtwib( 0x00+i,i);
for(i=0;i<16;i++)
rtwib( 0x00+i);
for(i=0;i<16;i++)
a[i]=0;
for(i=0;i<16;i++)
send_d(a[i]+48);
}
⑵ 单片机如何控制语音芯片,
APR9600(语音录放)
台湾公司最新推出的APR9600语音录放芯片,是继美国ISD公司以后采用模拟存储技术的又一款音质好、噪音低、不怕断电、
复录放的新型语音电路,单片电路可录放32-60秒,串行控制时可分256段以上,并行控制时最大可分8段。与ISD同类芯片
它具有:价格便宜,有多种手动控制方式,分段管理方便、多段控制时电路简单、采样速度及录放音时间可调、每个单键均有
停止循环多种功能等特点,同时保留了ISD2500芯片的一些特点,都是DIP28双列直插塑料封装,在管脚排列上也基本相同。
图一是APR9600的全功能使用电路图,图二是APR9600的管脚排列图。表(一)为管脚功能说明。一、并行控制模式
在ISD芯片中要实现某键对某段的多段并行控制是十分复杂的,一般需要大量的二极管译码阵或单片机来辅助实现,另外在分
段录音时也存在很多困难。而在APR9300芯片中却十分简单,每段都有对应的键控制,按哪一键就录、放哪一段,而且可以方便地
对任意一段重新录音不影响其它段、对任意一段循环放音等。只是每段录音的最大时间是等分的,而且最多只能分八段。下面
以需要分四段为例说明:
并行四段控制需要将芯片的MSEL1端置1(高电平)、MSEL2端置0(低电平)、/M8端任意。模式置好后开始录音,置RE
端为0,压住/M1即听到“嘀”一声BUSY指示灯亮起即开始录音第一段,松键时又听到“嘀”一声BUSY指示灯熄灭即录音停止。
/M2、/M3、/M4分别录其他三段。录音时可以不按顺序,先录任意一段均可,不满意可重新录音。每段的最大时间为15秒(以全
片60秒录音计),录满时指示灯熄灭并响“嘀嘀”两声,当然实际每段录音可以长短不一。置RE端为1即是放音状态,按一下/M1
即放音第一段,放音期间再按一下/M1即停止放音,如果压住/M1键不放即循环放音第一段直到松键。/M2、/M3、/M4均分别控制第二、三、四段。/CE键为停止键,放音期间按一下它也能停止放音。
其它并行二段、八段的控制使用方式相同。
二、串行控制模式
串行控制方式用到的键要少得多,它仅需要一、二个键来控制所有的语音段录放,而且段数可以足够多,每段也没有时间限制。
只是在选段上没有并行控制模式方便。
置MSEL1、MSEL2均为0,在录音时/M8置1。置/RE端为0为录音状态,按住/M1即开始录第一段,松键即停止。再按住/M1
即录第二段,如此一直分段录音,直到芯片溢出。
在放音时(/RE=1)有两种状态,/M8置1为串行顺序控制方式,按一下/M1即放音第一段,再按一下即放第二段,如此顺序
逐段放音,到最后一段结束时即停止放音,必须按一下CE键复位,然后再按/M1键就可以又从第一段放音。这种方式下的段不可选
择只能按录音的顺序播放,适合走马灯、流程控制等电路使用;/M8置0为串行选段控制方式,按一下/M1只能放音第一段,再按
还是放音第一段。这时的/M2有效成为快进选段键,每按一下/M2即向后移动一段,例如现在按了三下/M2,再按/M1就放音第四段。
因此可以实现选段放音。按/CE键复位为第一段。
APR9600芯片还有其它几种控制方式,用户可根据需要自行实验设计。
APR9600的电性能参数:电源电压4.5-6.5V,静态电流1uA,工作电流25mA。其外接振荡电阻与采样率、语音频带、录放
时间的关系见表(三),该电阻可以根据用户需要的时间和音质效果无级调节。
单片机接M1-M8就行了