从51移植PCF8591到AVR上的问题
#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始终不出来,我怀疑是时序哪有问题 读的时候软件错了 我没让它读,就是写数据,DA出来 #include<mega16.h>
#include<delay.h>
#define SCL PORTA.0
#define SDA PORTA.1
#define PCFAdress 0x90
#define DACControl 0x40
void IicStart()
{
SCL=1;
SDA=1;
delay_us(5);
SDA=0;
delay_us(5);
SCL=0;
}
void IicStop()
{
SCL=1;
SDA=0;
delay_us(5);
SDA=1;
delay_us(5);
SCL=0;
}
unsigned char WriteByte(unsigned char Byte)
{
unsigned char i=0;
SCL=0;
for(;i<8;i++)
{
if(Byte&0x80) SDA=1;else SDA=0;
delay_us(1);
SCL=1;
delay_us(5);
Byte=Byte<<1;
SCL=0;
}
DDRA&=0xFD; // 把SDA设置为输入状态
SDA=1;
delay_us(5);
SCL=1;
delay_us(5);
// if(0x02&PI)
// j=SDA;
SCL=0;
delay_us(2);
return PINA.1;
}
void PCF8591DACOut(unsigned char Adress,unsigned char Control,unsigned char DAT)
{
unsigned char ACK;
unsigned char i;
for(i=0;i<10;i++) //循环次数
{
IicStart();
ACK=WriteByte(Adress);
if(1==ACK)
{
IicStop();
continue;
}
ACK=WriteByte(Control);
if(1==ACK)
{
IicStop();
continue;
}
ACK=WriteByte(DAT);
if(1==ACK)
{
IicStop();
continue;
}
IicStop(); //传送成功,最后发送停止信号
if (0==ACK) break; //传送成功则退出循环
}
delay_ms(10);
}
void main()
{
DDRA=0XFF;
for(;;){
PCF8591DACOut(PCFAdress,DACControl,0X225);
}
}还是自己调试出来了,把程序贴出来吧,给有用的人吧 请问你在进行AD/DA转换的时候有没有碰到单独使用一个功能可以,混合起来使用就会出问题的情况?
页:
[1]