|
发表于 2012-6-17 15:29:08
|
显示全部楼层
不是,可以用查询的。
你参考一下呢:
//TWI总线操作
//TWI总线上的主机发送Start或ReStart信号
#define TWI_Work_Start() (TWCR=(1<<TWINT)+(1<<TWSTA)+(1<<TWEN))
//TWI总线上的主机发送Stop信号
#define TWI_Work_Stop() (TWCR=(1<<TWINT)+(1<<TWSTO)+(1<<TWEN))
//TWI总线继续传输
#define TWI_Work_Continue() (TWCR=(1<<TWINT)+(1<<TWEN))
//TWI总线继续传输,主机返回ACK信号
#define TWI_Work_SentAck() (TWCR=(1<<TWINT)+(1<<TWEA)+(1<<TWEN))
//TWI总线继续传输,主机返回NotACK信号
#define TWI_Work_SentNotAck() (TWCR=(1<<TWINT)+(1<<TWEN))
//TWI总线上的主机发送字节数据
#define TWI_Work_WriteByte(byte_dat) {TWDR=(byte_dat);TWI_Work_Continue();}
//等待TWI总线完成当前工作
#define TWI_Work_Wait() {while(!(TWCR&(1<<TWINT)));}
/*******************************************************************************
*作 者:电子信息工程技术教研室
*功 能:TWI总线初始化
*入口参数:无
*返 回 值:无
*说 明:1、fscl=fmcu/(16+2×TWBR×4的TWPS次方)
* fscl=4M/(16+2×12×1)=4M/40=100k
*******************************************************************************/
void TWI_Hard_Init(void)
{
//设置TWI比特寄存器TWBR
TWBR=12;
//设置TWI状态寄存器TWSR
TWSR&=0xfc;
}
/*******************************************************************************
*作 者:电子信息工程技术教研室
*功 能:通过TWI总线向从机的内部地址写入数据
*入口参数:从机器件、从机的内部地址、数组、数量
*返 回 值:错误
*说 明:无
*******************************************************************************/
uchar TWI_MT_Write(uchar sla_adr,uint in_adr,uchar *shuzu_dat,uchar cnt_num)
{
uchar sta_error=0,sla_temp,in_temp,cnt_temp;
//根据从机器件选择从机地址
switch(sla_adr)
{
//24C08存储阵列
case(TWI_Sla_24C08L):
{
sla_temp=TWI_Sla_24C08L+(in_adr>>7);
in_temp=(uchar)(in_adr-((in_adr>>8)<<8));
}
break;
default:
{
}
break;
}
//TWI总线上的主机发送Start信号
TWI_Work_Start();
//等待TWI总线完成当前工作
TWI_Work_Wait();
//判断状态码:START已发送
if(TWSR&0xf8!=TWI_Status_Start) sta_error+=1;
//TWI总线上的主机发送字节数据,此处是Sla+W
TWI_Work_WriteByte(sla_temp);
//等待TWI总线完成当前工作
TWI_Work_Wait();
//判断状态码:MT模式下发送数据,接收到ACK
if(TWSR&0xf8!=TWI_Status_MTSlaACK) sta_error+=1;
//TWI总线上的主机发送字节数据,此处是内部地址
TWI_Work_WriteByte(in_temp);
//等待TWI总线完成当前工作
TWI_Work_Wait();
//判断状态码:MT模式下发送数据,接收到ACK
if(TWSR&0xf8!=TWI_Status_MTDataACK) sta_error+=1;
//写入数据
for(cnt_temp=0;cnt_temp<cnt_num;cnt_temp++)
{
//TWI总线上的主机发送字节数据
TWI_Work_WriteByte(*(shuzu_dat+cnt_temp));
//等待TWI总线完成当前工作
TWI_Work_Wait();
//判断状态码:MT模式下发送数据,接收到ACK
if(TWSR&0xf8!=TWI_Status_MTDataACK) sta_error+=1;
}
//TWI总线上的主机发送Stop信号
TWI_Work_Stop();
//返回错误状态
return sta_error;
}
/*******************************************************************************
*作 者:电子信息工程技术教研室
*功 能:通过TWI总线从从机的内部地址读出数据
*入口参数:从机器件、从机的内部地址、数组、数量
*返 回 值:错误
*说 明:无
*******************************************************************************/
uchar TWI_MR_Read(uchar sla_adr,uint in_adr,uchar *shuzu_dat,uchar cnt_num)
{
uchar sta_error=0,sla_temp,in_temp,cnt_temp;
//根据从机器件选择从机地址
switch(sla_adr)
{
//24C08存储阵列
case(TWI_Sla_24C08L):
{
sla_temp=TWI_Sla_24C08L+(in_adr>>7);
in_temp=(uchar)(in_adr-((in_adr>>8)<<8));
}
break;
default:
{
}
break;
}
//TWI总线上的主机发送Start信号
TWI_Work_Start();
//等待TWI总线完成当前工作
TWI_Work_Wait();
//判断状态码:START已发送
if(TWSR&0xf8!=TWI_Status_Start) sta_error+=1;
//TWI总线上的主机发送字节数据,此处是Sla+W
TWI_Work_WriteByte(sla_temp);
//等待TWI总线完成当前工作
TWI_Work_Wait();
//判断状态码:MT模式下发送数据,接收到ACK
if(TWSR&0xf8!=TWI_Status_MTSlaACK) sta_error+=1;
//TWI总线上的主机发送字节数据,此处是内部地址
TWI_Work_WriteByte(in_temp);
//等待TWI总线完成当前工作
TWI_Work_Wait();
//判断状态码:MT模式下发送数据,接收到ACK
if(TWSR&0xf8!=TWI_Status_MTDataACK) sta_error+=1;
//TWI总线上的主机发送ReStart信号
TWI_Work_Start();
//等待TWI总线完成当前工作
TWI_Work_Wait();
//判断状态码:ReSTART已发送
if(TWSR&0xf8!=TWI_Status_ReStart) sta_error+=1;
//TWI总线上的主机发送字节数据,此处是Sla+R
TWI_Work_WriteByte(sla_temp+1);
//等待TWI总线完成当前工作
TWI_Work_Wait();
//判断状态码:MR模式下发送Sla+R,接收到ACK
if(TWSR&0xf8!=TWI_Status_MRSlaACK) sta_error+=1;
//接收数据
if(cnt_num>1)
{
for(cnt_temp=0;cnt_temp<(cnt_num-1);cnt_temp++)
{
//TWI总线继续传输,主机返回ACK信号
TWI_Work_SentAck();
//等待TWI总线完成当前工作
TWI_Work_Wait();
//判断状态码:MR模式下接收到数据,ACK已返回
if(TWSR&0xf8!=TWI_Status_MRDataACK) sta_error+=1;
*(shuzu_dat+cnt_temp)=TWDR;
}
}
//TWI总线继续传输,主机返回NotACK信号
TWI_Work_SentNotAck();
//等待TWI总线完成当前工作
TWI_Work_Wait();
//判断状态码:MR模式下接收到数据,NotACK已返回
if(TWSR&0xf8!=TWI_Status_MRDataNotACK) sta_error+=1;
*(shuzu_dat+cnt_num-1)=TWDR;
//TWI总线上的主机发送Stop信号
TWI_Work_Stop();
//返回错误状态
return sta_error;
} |
|