|
#include<mega16.h>
#include<delay.h>
#define uchar unsigned char
#define scl PORTA.0
#define sda PORTA.1
void delay1(uchar count)
{
uchar i,j;
for(i=count;i>0;i--)
for(j=110;j>0;j--);
}
void delay()
{
delay_us(6); //此处51写的是2个_nop_
}
void init()
{
sda=1;
delay();
scl=1;
delay();
}
void send_ack(uchar i) //发送应答信号
{
sda = i;
delay();
scl = 1;
delay();
scl = 0;
}
void start()
{
sda=1;
delay();
scl=1;
delay();
sda=0;
delay();
scl=0; //退出时为SCL为低电平,允许下一步SDA数据(写或读数据)发生变化
}
void stop()
{
sda=0;
delay();
scl=1; //退出时为高电平,释放SCL总线
delay();
sda=1; //退出时为高电平,释放SDA总线
// delay();
}
uchar write_dat(uchar dat) //写一个字节
{
uchar temp,i;
uchar j;
temp=dat;
sda=1; //可以不要
for(i=8;i>0;i--)
{
dat>>=1;
if(dat&0x01)
sda=1;
else
sda=0;
scl=1;
delay();
scl=0; //退出时为SCL为低电平,允许下一步SDA数据(循环内部)发生变化
delay();
}
sda=1; //等待应答信号
delay();
scl=1;
delay();
j=sda;
scl=0; //退出时为SCL为低电平,允许下一步SDA数据发生变化
delay();
return j;
}
uchar read_dat()
{
uchar temp=0;
uchar j;
for(j=0;j<8;j++)
{
scl=1; //放TEMP之后也可以
delay();
temp<<=1;
if(sda) temp|=0x01;
scl=0;
delay();
}
return temp;
}
void i2cbyte_write(uchar device ,uchar ctrl,uchar dat)
{
uchar i; //循环变量
uchar ack;
for(i=0;i<10;i++) //循环次数
{
start();
ack=write_dat(device);
if(ack==1)
{
stop();
continue;
}
ack=write_dat(ctrl);
if(ack==1)
{
stop();
continue;
}
ack=write_dat(dat);
if(ack==1)
{
stop();
continue;
}
stop(); //传送成功,最后发送停止信号
if (ack==0) break; //传送成功则退出循环
}
delay_ms(5);
}
uchar i2cbyte_read(uchar device)
{
uchar dat;
uchar i,ack;
for(i=0;i<10;i++)
{
ack=write_dat(device);
if(ack==1)
{
stop();
continue;
}
dat=read_dat();
stop();
}
return dat;
}
void main()
{
DDRA=0XFF;
init();
while(1)
{
//start();
//delay_us(10);
i2cbyte_write(0x90,0x40,200);
}
}
这个程序在51上完全可以,可是到了AVR始终不出来,我怀疑是时序哪有问题 |
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|