打印
[经验分享]

MPC82E52(原STC12C2052)模拟24C02

[复制链接]
2082|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
huamunv|  楼主 | 2009-9-28 00:19 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
为满足程序加载时,按用户的要求配置某IIC接口芯片配置寄存器,用STC单片机模拟24C02。
主模式的模拟很普遍,但该芯片复位后处于主模式,使得STC要配置它只能处于从模式状态,而IIC从模式的模拟却很少有现成的代码参考。下面是STC模拟被读一个字节的原代码,测试成功:
#ifndef uchar
#define uchar unsigned char
#endif
#ifndef uint
#define uint unsigned int
#endif
//#include<intrins.h>
//#include <serial.h>
#define ack 0
#define noack 1
#define false 0
#define ture 1
//#define EE_ADD 0x00
#define EE_BYTEADD 0x00////
#define EE_WRITE 0xa0
#define EE_READ 0xa1
sbit scl="P1"^7;////STC2052.PIN19-SPICLK-SPIC
sbit sda="P1"^5;////STC2052.PIN17-MOSI-SPID
//bit ack_flag=0;////局部定义产生重入
//void iic_sdelay(uchar);
bit iic_start_decide();
bit iic_stop_decide();
void iic_ack_send(bit);
bit iic_ack_decide();
//void iic_ack();
//void iic_noack();
bit iic_send(uchar);//reentrant;
bit EEPROM_Imitate(uchar *p);
//uchar iic_receive();//reentrant;/////////////////////////////////////////////////////////////////
//bit iic_writestr(uchar*,uchar,uchar);
//bit iic_writeabyte(uchar,uchar);
//bit iic_readstr(uchar*,uchar,uchar);
//bit iic_readabyte(void);
bit iic_start_decide()////iic开始判断
{
while(0==scl);////开始条件不满足
while((1==scl)&&(1==sda));////开始条件正在建立,则等待
if((1==scl)&&(0==sda))////开始
{
while(1==scl);////等待到时钟线开始跳变
return ture;
}
else
return false;
}
bit iic_stop_decide()
{
while(0==scl);////结束条件不满足
while((1==scl)&&(0==sda));////结束条件正在建立,则等待
if((1==scl)&&(1==sda))////结束
return ture;
else
return false;
}

void iic_ack_send(bit a)////回应ACK或NOACK
{
if(ack==a)
sda=0;
else
sda=1;
while(0==scl);////等待SCL低电平
while(1==scl);////时钟线高电平时保持
}
bit iic_ack_decide()
{
bit ack_flag;////局部变量
//////////////////////////////////////sda=1;  ////8位发送完毕,释放数据线SDA,准备接收应答位
while(0==scl);////等待SCL变高电平
ack_flag=0;
if(0==sda)////sda==0说明有回应
ack_flag=1;////设置回应成功标志
else
ack_flag=0;
//scl=0;    ////嵌住总线,准备发送或接收数据
//iic_sdelay(4);
while(1==scl);
return(ack_flag);
}
bit iic_send(uchar sdata) //reentrant
{uchar i;
for(i=0;i<8;i++)
{
sda=(bit)(sdata&0x80);
sdata=sdata<<1;
while(0==scl);
while(1==scl);////检测scl,高电平时数据保持,scl跳到低电平才改变数据
}
return(iic_ack_decide());////判断主机有无回应
}
uchar iic_receive() //reentrant
{uchar i;
uchar rdata="0";
sda=1;
for(i=0;i<8;i++)
{
rdata<<=1;
while(0==scl);////当时钟线为低时,数据无效,等待
if(1==sda)
rdata++;
while(1==scl);////防止在一个高电平时读8次
}
//iic_sdelay(4);
//scl=0;   ////嵌住总线,准备发送或接收数据////这里使用的是从模式
//iic_sdelay(8);
return (rdata);
}




//bit EEPROM_Imitate(uchar *p,uchar num)
bit EEPROM_Imitate(uchar *p)
{
//uchar i;
uchar s;
while(!iic_start_decide());//等待IIC开始
s=iic_receive();////器件地址
//serial_send(s);
if(EE_WRITE==s)
{
iic_ack_send(ack); ////回应
//serial_send(s);
}
else
{
iic_ack_send(noack);
goto enderr;
}
s=iic_receive();////存储字节地址
//serial_send(s);
if(EE_BYTEADD==s)
iic_ack_send(ack); ////回应
else
{
iic_ack_send(noack);
goto enderr;
}
while(!iic_start_decide());//如果iic开始
s=iic_receive();////器件地址
//serial_send(s);
if(EE_READ==s) ////主机要读EE的数据
iic_ack_send(ack); ////回应
else
{
iic_ack_send(noack);
goto enderr;
}

while(iic_send(*p)){p++;};////判断有NOACK后停止发送,接着判断停止位
if(iic_stop_decide())
return ture;
enderr:
scl=sda=1;
return false;
}
沙发
yefeng3309| | 2009-9-28 00:24 | 只看该作者
向楼上致敬,这么晚还在为广大用户方便使用MEGAWIN芯片做出自己的贡献。:victory:

使用特权

评论回复
板凳
suoma| | 2009-9-28 00:32 | 只看该作者
看来夜猫子不少啊

使用特权

评论回复
地板
hhtseng| | 2009-9-28 11:19 | 只看该作者
:L  ...........

使用特权

评论回复
5
huamunv|  楼主 | 2009-9-28 16:41 | 只看该作者
最近心情好,晚上也出来逛逛

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

88

主题

730

帖子

1

粉丝