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

📄 lib_twi.c

📁 atmelsam7s64twi完美底层驱动
💻 C
字号:
#include "lib_twi.h"
#include "lib_AT91SAM7S64.h"
#define  ERROR      (AT91C_TWI_NACK)//状态寄存器的一位,如果置1表示从机未应答
//*============================================================================
//*		                 TWI初始化
//*============================================================================
//*----------------------------------------------------------------------------
//* 函数名: AT91F_SetTwiClock
//* 功能:   设置TWI时钟波形发生寄存器
//*----------------------------------------------------------------------------
void AT91F_SetTwiClock(void)
{
	int sclock;

    sclock = (10*MCK /AT91C_TWI_CLOCK);
	if (sclock % 10 >= 5)
		sclock = (sclock /10) - 5;
	else
		sclock = (sclock /10)- 6;
	sclock = (sclock + (4 - sclock %4)) >> 2;	// div 4

    AT91C_BASE_TWI->TWI_CWGR	= ( 1<<16 ) | (sclock << 8) | sclock  ;
}

 //*----------------------------------------------------------------------------
//*函数名: AT91F_TWI_Open
//* 功能:  初始化TWI接口
//*----------------------------------------------------------------------------
void AT91F_TWI_Open(void)
{
	// 配置I/O口作为TWI功能
	AT91F_TWI_CfgPIO ();

        // 将TWD和TWCK定义为开路
         AT91F_PIO_CfgOpendrain(AT91C_BASE_PIOA,Twd_Twck);

     	// 开TWI时钟源
	AT91F_TWI_CfgPMC ();

	// 配置TWI工作在主模式,禁止TWI中断,采用查询读写方式
	AT91F_TWI_Configure (AT91C_BASE_TWI);

	// 设置TWI时钟波形发生寄存器
	AT91F_SetTwiClock();
}

//*=============================================================================
//*		                    写EPROM
//*=============================================================================
//*----------------------------------------------------------------------------
//* 函数名:AT91F_TWI_WriteByte
//* 功能:  发送(以字节为单位)数据到设备(EPROM)
//*参数说明:
//         pTwi:指向TWI结构的首地址-----设为AT91C_BASE_TWI
//         mode:TWI的工作模式----用于设置WTI的主模式寄存器(内部器件地址长度,主机读写方向,器件地址),见DATASHEET
//         int_address:器件的内部地址(要写入的位置)
//         data2send:代写的数据缓冲区地址
//         nb:写入的字节数
//*----------------------------------------------------------------------------
int AT91F_TWI_WriteByte(const AT91PS_TWI pTwi ,int mode, int int_address, char *data2send, int nb)
{
	unsigned int status,counter=0,error=0;

	// 设置TWI内部地址寄存器---可设为0,1,2,3位内部地址
	if ((mode & AT91C_TWI_IADRSZ) != 0)  pTwi->TWI_IADR = int_address;

	// 设置TWI的主模式寄存器(此处为主机写)
	 pTwi->TWI_MMR = mode & ~AT91C_TWI_MREAD;

         // 如果只写1个字节
	if(nb <2)
        {
         //发送START状态,使能传输,传输完后发送STOP状态
	 pTwi->TWI_CR = AT91C_TWI_START | AT91C_TWI_MSEN | AT91C_TWI_STOP;
         //将数据写入发送保持寄存器
	 pTwi->TWI_THR = *data2send;
	}

        //如果一次写入多个字节
	else
	{
	  for(counter=0;counter<nb;counter++)
          {

           //发送START状态,使能传输
           pTwi->TWI_CR = AT91C_TWI_START | AT91C_TWI_MSEN;

           //最后一个数据发送完后,接着发送STOP状态
           if (counter == (nb - 1)) pTwi->TWI_CR = AT91C_TWI_STOP;

           //读取状态寄存器
           status = pTwi->TWI_SR;

           //如果发送完一个字节后没收到应答信号,则表明有一次传输错误
           if ((status & ERROR) == ERROR)   error++;

           while (!(status & AT91C_TWI_TXRDY))
           {
             status = pTwi->TWI_SR;
             if ((status & ERROR) == ERROR) error++;
            } //END while

             //传输下一个字节
             pTwi->TWI_THR = *(data2send+counter);
	   }//END for
	}//END  else

        //读取状态寄存器
	status = pTwi->TWI_SR;
        //如果发送完一个字节后没收到应答信号,则表明有一次传输错误
	if ((status & ERROR) == ERROR) error++;

	//等待数据发送完
        while (!(status & AT91C_TWI_TXCOMP))
        {
          //读取状态寄存器
    	 status = pTwi->TWI_SR;
         //如果发送完一个字节后没收到应答信号,则表明有一次传输错误
    	 if ((status & ERROR) == ERROR) error++;
        }//END while

     return error;
}

//*=============================================================================
//*		                      读(EPROM)
//*=============================================================================
//*----------------------------------------------------------------------------
//* 函数名:AT91F_TWI_ReadByte
//* 功能: 从设备(EPROM)中读取一个字节的数据
//*参数说明:
//         pTwi:指向TWI结构的首地址-----设为AT91C_BASE_TWI
//         mode:TWI的工作模式----用于设置WTI的主模式寄存器(内部器件地址长度,主机读写方向,器件地址),见DATASHEET
//         int_address:器件的内部地址(要写入的位置)
//         data2read:数据缓冲区地址
//         nb:要读出的字节数
//* Creation            : 张正锋 2005-12-30 zhangzf@baite-group.com
//*----------------------------------------------------------------------------
int AT91F_TWI_ReadByte(const AT91PS_TWI pTwi ,int mode, int int_address, char *data2read, int nb)
{
	unsigned int status,counter=0,error=0;

        // 设置TWI内部地址寄存器---可设为0,1,2,3位内部地址
	if ((mode & AT91C_TWI_IADRSZ) != 0) pTwi->TWI_IADR = int_address;

	// 设置TWI的主模式寄存器(此处为主机读)
	pTwi->TWI_MMR = mode | AT91C_TWI_MREAD;

	//如果只读取一个字节
	if (nb == 1)
        {
            //发送START状态,接收完后发送STOP状态
	   pTwi->TWI_CR = AT91C_TWI_START | AT91C_TWI_STOP;

           //读取状态寄存器
	   status = pTwi->TWI_SR;
          //如果没收到应答信号,则表明有一次传输错误
    	   if ((status & ERROR) == ERROR) error++;

           //等待操作完
	   while (!(status & AT91C_TWI_TXCOMP)){
    	      status = pTwi->TWI_SR;
              if ((status & ERROR) == ERROR) error++;
    	   }

           //将数据放入缓冲区
	   *(data2read) = pTwi->TWI_RHR;
	 } //END if

        //如果读取多个字节
 	else
       {
           //发送START状态,接收完后发送STOP状态
 	   pTwi->TWI_CR = AT91C_TWI_START | AT91C_TWI_MSEN;

           //读取状态寄存器
	   status = pTwi->TWI_SR;
           //如果没收到应答信号,则表明有一次传输错误
	   if ((status & ERROR) == ERROR) error++;

	  //等待操作完
           while (!(status & AT91C_TWI_TXCOMP))
           {
             	status = pTwi->TWI_SR;
   		if ((status & ERROR )== ERROR) error++;

                //查看是否收到一个字节数据
    		if(status & AT91C_TWI_RXRDY)
                {
                 //将数据放入缓从区
		 *(data2read+counter++) = pTwi->TWI_RHR;

                 //如果是最后一次读取则发送STOP 状态
		 if (counter == (nb - 1)) pTwi->TWI_CR = AT91C_TWI_STOP;
	         } //END if
	    } //END while
	} //END else

      return error;
}





⌨️ 快捷键说明

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