sail_007 发表于 2009-3-15 09:02:04

从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始终不出来,我怀疑是时序哪有问题

luckroll 发表于 2009-3-15 10:18:48

读的时候软件错了

sail_007 发表于 2009-3-15 10:48:38

我没让它读,就是写数据,DA出来

sail_007 发表于 2009-3-15 20:15:48

#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);
    }
}还是自己调试出来了,把程序贴出来吧,给有用的人吧

xl1736 发表于 2013-12-23 23:18:46

请问你在进行AD/DA转换的时候有没有碰到单独使用一个功能可以,混合起来使用就会出问题的情况?
页: [1]
查看完整版本: 从51移植PCF8591到AVR上的问题