⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 twi._c

📁 avr 基于i2c接口的电源管理协议。包括主机发送主机接受从机发送接收。
💻 _C
字号:
//ICC-AVR application builder : 2007-1-9 16:35:49
// Target : M8
// Crystal: 8.0000Mhz

#include <iom8v.h>
#include <macros.h>

#include "twi.h"


//TWI的数据结构变量
struct str_TWI  strTWI;							
//定义全局变量
unsigned char ORGDATA[8]={0xAA,0xA5,0x55,0x5A,0x01,0x02,0x03,0x04};	//原始数据
//unsigned char CMPDATA[8];						//比较数据


//TWI initialize
// bit rate:72
//50KHZ
void twi_init(void)
{
 TWCR= 0X00; //disable twi
 TWBR= 0x48; //set bit rate
 TWSR= 0x00; //set prescale
 TWAR= 0x21; //set slave address
 //TWAR= 0x31; //set slave address
 TWCR= 0x45; //enable twi
}

//

unsigned char TWI_RW(unsigned char sla_rw,unsigned char *ptr,unsigned char len)
{
    unsigned char i;
    if (strTWI.STATUS==TW_BUSY)
    {
	 //TWI忙,不能进行操作
     return OP_BUSY;
    }
    strTWI.STATUS=TW_BUSY;
    strTWI.SLA=sla_rw;
    strTWI.DATALEN=len;
    strTWI.pBUF=ptr;
    strTWI.STATE=ST_START;
    strTWI.FAILCNT=0;
    TWCR=(1<<TWSTA)|TW_ACT;						//启动start信号
    return OP_RUN;
}

#pragma interrupt_handler twi_isr:18
void twi_isr(void)
{
 //twi event
 //根据strTWI.SLA的最低位决定 
 //bit0=1 TW_READ  读
 //bit0=0 TW_WRITE 写
    unsigned char action,state,status;
    action=strTWI.SLA&TW_READ;					//取操作模式
    state=strTWI.STATE;
    status=TWSR&0xF8;							//屏蔽预分频位
	putchar(0xdd);
   if ((status>=0x60)&&(status!=0x00))
   {
    switch(state)
    {
	case ST_START:	//START状态检查
	
	}
   }
   else if((status<0x60)&&(status!=0x00))
   {
    switch(state)
    {
    case ST_START:	//START状态检查
        if(status==TW_START)
        {//发送start信号成功
            TWDR=strTWI.SLA&0xFE;				//发送器件地址写SLAW
            TWCR=TW_ACT;         				//触发下一步动作,同时清start发送标志
        }
        else
        {//发送start信号出错
            state=ST_FAIL;
        }
        break;
    case ST_SLAW:	//SLAW状态检查
        if(status==TW_MT_SLA_ACK)
        {//发送器件地址成功
            TWDR=0xab;					       
            TWCR=TW_ACT;         				//触发下一步动作
        }
        else
        {//发送器件地址出错
            state=ST_FAIL;
        }
        break;
    case ST_WADDR:	//ADDR状态检查
        if(status==TW_MT_DATA_ACK)
        {//发送eeprom地址成功
            if (action==TW_READ)
            {//读操作模式
                TWCR=(1<<TWSTA)|TW_ACT;			//发送restart信号,下一步将跳到RESTART分支
            }
            else
            {//写操作模式
                TWDR=*strTWI.pBUF++;         	//写第一个字节
                strTWI.DATALEN--;
                state=ST_WDATA-1;				//下一步将跳到WDATA分支
                TWCR=TW_ACT;         			//触发下一步动作
            }
        }
        else
        {//发送eeprom地址出错
            state=ST_FAIL;
        }
        break;
    case ST_RESTART:	//RESTART状态检查,只有读操作模式才能跳到这里
        if(status==TW_REP_START)
        {//发送restart信号成功
            TWDR=strTWI.SLA;					//发器件地址读SLAR
            TWCR=TW_ACT;         				//触发下一步动作,同时清start发送标志
        }
        else
        {//重发start信号出错
            state=ST_FAIL;
        }
        break;
    case ST_SLAR:	//SLAR状态检查,只有读操作模式才能跳到这里
        if(status==TW_MR_SLA_ACK)
        {//发送器件地址成功
            if (strTWI.DATALEN--)
            {//多个数据
                TWCR=(1<<TWEA)|TW_ACT;			//设定ACK,触发下一步动作
            }
            else
            {//只有一个数据
                TWCR=TW_ACT;					//设定NAK,触发下一步动作
            }
        }
        else
        {//发送器件地址出错
            state=ST_FAIL;
        }
        break;
    case ST_RDATA:	//读取数据状态检查,只有读操作模式才能跳到这里
        state--;								//循环,直到读完指定长度数据
        if(status==TW_MR_DATA_ACK)
        {//读取数据成功,但不是最后一个数据
            *strTWI.pBUF++=TWDR;
            if (strTWI.DATALEN--)
            {//还有多个数据
                TWCR=(1<<TWEA)|TW_ACT;			//设定ACK,触发下一步动作
            }
            else
            {//准备读最后一个数据
                TWCR=TW_ACT;					//设定NAK,触发下一步动作
            }
        }
        else if(status==TW_MR_DATA_NACK)
        {//已经读完最后一个数据
            *strTWI.pBUF++=TWDR;
            TWCR=(1<<TWSTO)|TW_ACT;				//发送停止信号,不会再产生中断了
            strTWI.STATUS=TW_OK;
        }
        else
        {//读取数据出错
            state=ST_FAIL;
        }
        break;
    case ST_WDATA:	//写数据状态检查,只有写操作模式才能跳到这里
        state--;								//循环,直到写完指定长度数据
        if(status==TW_MT_DATA_ACK)
        {//写数据成功
            if (strTWI.DATALEN)
            {//还要写
                TWDR=*strTWI.pBUF++;
                strTWI.DATALEN--;
                TWCR=TW_ACT;         			//触发下一步动作
            }
            else
            {//写够了
                TWCR=(1<<TWSTO)|TW_ACT;			//发送停止信号,不会再产生中断了
                strTWI.STATUS=TW_OK;
                //启动写命令后需要10ms(最大)的编程时间才能真正的把数据记录下来
                //编程期间器件不响应任何命令
            }
        }
        else
        {//写数据失败
            state=ST_FAIL;
        }
        break;
    default:
        //错误状态
        state=ST_FAIL;
        break;
    }

    if (state==ST_FAIL)
    {//错误处理
        strTWI.FAILCNT++;
        if (strTWI.FAILCNT<FAIL_MAX)
        {//重试次数未超出最大值,
            TWCR=(1<<TWSTA)|TW_ACT;				//发生错误,启动start信号
        }
        else
        {//否则停止
            TWCR=(1<<TWSTO)|TW_ACT;				//发送停止信号,不会再产生中断了
            strTWI.STATUS=TW_FAIL;
        }
    }
    state++;
    strTWI.STATE=state;							//保存状态
   }
   else
   {
   //总线错误或从机模式引发的中断,不予处理
       return;
   }

}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -