打印
[AVR单片机]

我用mega16单片机的TWI,经常程序走到wait() 就走不动了 求大

[复制链接]
1558|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
liwei900712|  楼主 | 2013-12-4 14:51 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
liwei900712|  楼主 | 2013-12-4 14:53 | 只看该作者
程序经常走到 wait();  就走不动了  求大神帮忙给看看 程序如下
#include "iom16v.h"
#include "macros.h"
#include "stdio.h"


//主模式启动状态
#define IIC_START                   0x08   //启动总线
#define IIC_RESTART                              0x10   //再启动总线

//主发送模式各种状态
#define MT_SLA_ACK                                   0x18   //SLA_W写地址已发送,收到应答位
#define MT_SLA_NACK                                  0x20   //SLA_W写地址已发送,收到非应答位
#define MT_DATA_ACK                                  0x28   //写入数据已发送,收到应答位
#define MT_DATA_NACK                                 0x30   //写入数据已发送,收到非应答位
#define MT_ARB_LOST                                  0x38   //SLA_W或数据仲裁失败

//主接收模式各种状态
#define MR_ARB_LOST                                  0x38   //SLA_W或数据仲裁失败
#define MR_SLA_ACK                                   0x40   //SLA_R已发送,收到应答位
#define MR_SLA_NACK                                  0x48   //SLA_R已发送,收到非应答位
#define MR_DATA_ACK                                  0x50   //接收到数据,应答位已返回
#define MR_DATA_NACK                                 0x58   //接收到数据,非应答位已返回

//IIC操作
#define IIC_Start()      (TWCR=BIT(TWINT)|BIT(TWSTA)|BIT(TWEN))
#define IIC_Stop()       (TWCR=BIT(TWINT)|BIT(TWSTO)|BIT(TWEN))
#define IIC_STATUS       (TWSR & 0xf8)
#define IIC_Send()                 (TWCR=BIT(TWINT)|BIT(TWEN))
#define IIC_SendAck()    (TWCR|=BIT(TWEA))
#define IIC_SendNoAck()  (TWCR&=~BIT(TWEA))
#define IIC_ReadNoAck()  (TWCR=BIT(TWINT)|BIT(TWEN))
#define IIC_ReadAck()    (TWCR=BIT(TWINT)|BIT(TWEN)|BIT(TWEA))
#define IIC_Wait()                 while(!( TWCR & BIT(TWINT)))

//IIC配置


unsigned char temp;
//LED7.H
//数码管显示

//数组声明并定义在存储数据区code
//0~9

//#pragma data:code  




void delay_ms(unsigned int y)
{
         unsigned int m,n;
         for(n=y;n>0;n--)
             for(m=0;m<1596;m++);
}



//IIC写函数
//硬件地址,写页地址,数据
void IIC_Write()
{
        unsigned char Error_Flag=0;        //声明并且初始化错误标志
       
        while(!Error_Flag)        //写入过程是否有错误?有:重新一次
        {
                        //起始信号
                        IIC_Start();                         //起始, TWINT=1,TWEN=1,TWSTA=1
                        IIC_Wait();                                //等待 TWINT==1;
                        if(IIC_STATUS!=IIC_START) Error_Flag=1;        //查询TWSR,是否起始错误
                       
                        //写硬件地址 SLA+W       
                        TWDR=0x62;                         //将要访问硬件地址写入数据寄存器
                        IIC_Send();                         //IIC发送, TWINT=1,TWEN=1;
                        IIC_Wait();                                //等待 TWINT==1;
                        if(IIC_STATUS!=MT_SLA_ACK) Error_Flag=1; //查询TWSR,是否写地址无应答
                       
                        //写页地址
                        TWDR=0x52;                        //将要写入页地址写入数据寄存器
                        IIC_Send();                                //IIC发送, TWINT=1,TWEN=1;
                        IIC_Wait();                                //等待 TWINT==1;
                        if(IIC_STATUS!=MT_DATA_ACK) Error_Flag=1; //查询TWSR,是否写数据无应答
                       
        }

        IIC_Stop();        //终止信号 TWINT=1,TWSTO=1,TWEN=1
}


//IIC读函数
//硬件地址,写页地址?
//返回读取数据
unsigned char IIC_Read()
{
        unsigned char Temp[7]={0,0,0,0,0,0,0};        //声明并且初始化错误标志
        unsigned int i;
        unsigned char Error_Flag=0;
        unsigned long PPM;
        while(!Error_Flag)
         
                {       
                        //起始信号
                        IIC_Start();                 //起始, TWINT=1,TWEN=1,TWSTA=1
                        IIC_Wait();                        //等待 TWINT==1;
                        if(IIC_STATUS!=IIC_START) Error_Flag=1; //查询TWSR,是否起始错误
       
                        //写硬件地址 SLA+W
               
                        TWDR=0x63;                 //将要访问硬件地址写入数据寄存器
                        IIC_Send();                 //IIC发送, TWINT=1,TWEN=1;
                        IIC_Wait();                        //等待 TWINT==1;
                        if(IIC_STATUS!=MR_SLA_ACK) Error_Flag=1; //查询TWSR,是否写地址无应答

                        for(i=0;i<7;i++)
                        {
                        IIC_ReadAck();       
                        IIC_Wait();
                        if(IIC_STATUS!=MR_DATA_ACK) Error_Flag=1;
                        Temp[i]=TWDR;       
                        delay_ms(2);               
                        }
                        if(Temp[0] == 0x08)
                {
                     PPM = Temp[1] << 8;
                     PPM |= Temp[2];

        
             }
                }
       
        //Temp=TWDR;                //从数据寄存器读取数据
        IIC_Stop();                //终止信号
       
        return PPM;                //返回数据
}


//IIC初始化函数
void IIC_Init()
{
        TWBR=12;                //晶振为11.0592Mhz,99kHz的波特率
        TWSR=0;                //无预分频
        TWCR=0x44;        //TWINT位清零,TWWC位清零
}

//主函数
void main()
{
        unsigned char data;
    unsigned int i;
        IIC_Init();                //IIC舒适化                               
        while(1)
        {       IIC_Write();
                         data=IIC_Read();
                       
        }
}

使用特权

评论回复
板凳
huangxz| | 2013-12-4 23:23 | 只看该作者
以前我遇到过,但是不是avr,是cortex-m3,
这种其实跟两种都有一定的关系,不过可能性大点的硬件电路,尽管iic已经是个标准了,但是有时候不同的器件兼容性还不是很好,
通过改变时序是可以解决这个问题的。

使用特权

评论回复
地板
airwill| | 2013-12-5 07:17 | 只看该作者
程序经常走到 wait();  就走不动了
应该 I2C 的协议和从机响应问题, 从机总是被动响应主机的命令. 如果来不及响应, 按照 I2C 协议会通过 SCL 信号通知主机, 如果主机方未能识别这个信号, 那就会出现这个情况. 当然如果未能识别 START 呢?

使用特权

评论回复
5
qin552011373| | 2013-12-6 08:51 | 只看该作者
估计是从机的问题

使用特权

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

本版积分规则

9

主题

22

帖子

0

粉丝