打印
[AVR单片机]

MEGA32IIC 程序奇怪问题.

[复制链接]
2726|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
dudongdao|  楼主 | 2007-6-10 22:40 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
   这段程序是模仿马潮老师书上写的,但是应用的过程中发现当读的时候会多读一个字节,请高手指点一下,看问题在那儿?

/**********************************************************************************************************
*                I2C(TWI)
**********************************************************************************************************/
// MT: Master Transmit   MR: Master Receive 
// TWI Operation Macros  (Work in MT/MR Mode)define1
#define I2C_Start()              (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN))
#define I2C_Stop()               (TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN))
#define I2C_Wait()              {while(!(TWCR&(1<<TWINT)));}
#define I2C_TestAck()           (TWSR&0xf8)
#define I2C_SetAck()            (TWCR|=(1<<TWEA))
#define I2C_SetNoAck()        (TWCR&=~(1<<TWEA))
#define Twi_RR()                (TWCR=(1<<TWINT)|(1<<TWEN))             //need to Re-Receive
#define Twi_SR()                (TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWEA))   //Success Received
#define I2C_WriteChar(x)      {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);} 

// TWI Operation Macros  (Work in MT/MR Mode) define2
#define i2cSendStart()        (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN))
#define i2cSendStop()           (TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN))
#define i2cWaitForComplete()  {while(!(TWCR&(1<<TWINT)));}

#define i2cReceiveByte(x)       if (x) Twi_SR(); else Twi_RR()
#define i2cSendByte(x)             {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);}
#define i2cGetStatus()          inb(TWDR)
#define i2cGetReceivedByte()    inb(TWSR)

void IICErrStop(void)
{
    I2C_Stop();
    DlyUs(100);
}    

U8 WriteByteIIC( U8 SlaveAddr, U8 RegAddr, U8 *Data, U8 Number)
{
    I2C_Start();
    I2C_Wait();
    if(I2C_TestAck() != START)
    {    
        IICErrStop();
        return 1;
     } 
     
    I2C_WriteChar(SlaveAddr);                          // 写I2C从器件地址
    I2C_Wait();
    if(I2C_TestAck() != MT_SLA_ACK)
    {    
        IICErrStop();
        return 2;      
    }
    
    I2C_WriteChar(RegAddr); 
    I2C_Wait();
    if(I2C_TestAck() != MT_DATA_ACK)
    {    
        IICErrStop();
        return 3;    
    }
    
    while(Number--)
    {
        I2C_WriteChar(*Data);
        I2C_Wait();
        Data++;
        if(I2C_TestAck() != MT_DATA_ACK)
        {    
            IICErrStop(); 
            return 5;    
        }
    }    
    
    I2C_Stop();
    DlyUs(100); 
    return 0;                    
}

U8 ReadByteIIC( U8 SlaveAddr, U8 RegAddr, U8* Ptr, U8 Number)
{
    I2C_Start();
    I2C_Wait();
    if(I2C_TestAck() != START)
    {    
        IICErrStop(); 
        return 1;
    }    

    I2C_WriteChar(SlaveAddr + WRITE);                          // 写I2C从器件地址
    I2C_Wait();
    if(I2C_TestAck() != MT_SLA_ACK)
    {    
        IICErrStop();
        return 2;      
    }
    
    I2C_WriteChar(RegAddr);                // The high bit of the address
    I2C_Wait();
    if(I2C_TestAck() != MT_DATA_ACK)
    {    
        IICErrStop();
        return 3;    
    }
    
    I2C_Start();
    I2C_Wait();
    if(I2C_TestAck() != RE_START)
    {    
        IICErrStop();
        return 1;
    }    
     
    I2C_WriteChar(SlaveAddr + READ);                        // Read mode
    I2C_Wait();
    if(I2C_TestAck() != MR_SLA_ACK)
    {    
        IICErrStop();
        return 5;
    }  
    
    Twi_SR();
    while(Number--)
    {
        I2C_Wait();
        *Ptr = TWDR;
        Ptr++;
        if(Number == 0)
        {
            I2C_SetNoAck();    
        }
        else
        {
            I2C_SetAck();        
        }            
    }
    
    I2C_Wait();
    I2C_Stop();
    DlyUs(100);
    return 0;        

相关帖子

沙发
hotpower| | 2007-6-10 23:39 | 只看该作者

怎么没看见I2C模块是如何配置的???

这个最重要,否则用IO玩I2C,10个11玩完~~~

使用特权

评论回复
板凳
pantodd| | 2007-6-11 15:31 | 只看该作者

主机每收到一个数据,应清一次TWINT

使用特权

评论回复
地板
三禧电子| | 2007-6-11 17:08 | 只看该作者

很多地方都能看到hotpower!!!!

    很多地方都能看到hotpower!!!!

使用特权

评论回复
5
dudongdao|  楼主 | 2007-6-11 19:38 | 只看该作者

这里给出IIC初始化的程序,谢谢大家关注


#define     bit_is_set(sfr, bit)                   ( sfr & _BV(bit) )
#define     bit_is_clear(sfr, bit)                 ( ! (sfr & BIT(bit)) )
#define     loop_until_bit_is_set(sfr, bit)     do { } while (bit_is_clear(sfr, bit))
#define     loop_until_bit_is_clear(sfr, bit)     do { } while (bit_is_set(sfr, bit))
#define     cbit(sfr, bit)                         ( sfr &= (~bit) ) 
#define     cbi(sfr, bit)                         ( sfr &= ~ BIT(bit) ) 
#define     sbi(sfr, bit)                        ( sfr |= BIT(bit) )
#define     inb(sfr)                             sfr
#define     outb(sfr, val)                         ( sfr = (val) )
#define     outp(val, sfr)                         outb(sfr, val)
#define     inp(sfr)                             inb(sfr)
#define     inw(sfr)                            sfr
#define     outw(sfr, val)                         ( sfr =  val )
                                                    /* ---- MIN/MAX/ABS macros ----- */ 

#define     MIN(a,b)            ((a<b)?(a):(b))
#define         MAX(a,b)            ((a>b)?(a):(b))
#define     ABS(x)                ((x>0)?(x):(-x))


/**********************************************************************************************************
* 函数介绍:
* 输入参数:--
* 输出参数:--
* 返 回 值:--
**********************************************************************************************************/
void i2cSetBitrate(U16 bitrateKHz)
{
    U8 bitrate_div;
    // set i2c bitrate
    // calculate bitrate division    
    bitrate_div = ((F_CPU/1000l)/bitrateKHz);
    if(bitrate_div >= 16)
        bitrate_div = (bitrate_div-16)/2;
    outb(TWBR, bitrate_div);
}

//////////////////////////////////////////////////////////////////////////////
/**********************************************************************************************************
* 函数介绍:
* 输入参数:--
* 输出参数:--
* 返 回 值:--
**********************************************************************************************************/
void i2cInit(void)
{

    // set i2c bit rate to 100KHz
    i2cSetBitrate(100);
    // enable TWI (two-wire interface)
    sbi(TWCR, TWEN);
    // set state
//    I2cState = I2C_IDLE;
    // enable TWI interrupt and slave address ACK
    sbi(TWCR, TWIE);
    sbi(TWCR, TWEA);
    //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
    // enable interrupts
    SEI();
}

使用特权

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

本版积分规则

90

主题

413

帖子

1

粉丝