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

📄 twi.c

📁 atmel ARM7单片机at91sam7x256软件中断实验程序
💻 C
字号:

/**************************************************************************************************
*
* Copyright (C) ART Limited, 2006. All rights reserved.
* 
* File:          twi.c
* Programmed by: allan
* Data:          2006.12.18
* 
**************************************************************************************************/

#include "project.h"

#define ADRR_24C01A    (0x50 << 16)      //器件地址
#define ERROR          (AT91C_TWI_NACK)

/*******************************************************************************
 * 说明:AT91F_SetTwiClock函数,初始化
 * 参数:无
 * 返回值:无
*******************************************************************************/
void AT91F_SetTwiClock(void) 
{
	int sclock;
	
	/* 这里, CKDIV = 1 and CHDIV=CLDIV  ==> CLDIV = CHDIV = 1/4*((Fmclk/FTWI) -6)*/
	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;	  // 除 4
    
    AT91C_BASE_TWI->TWI_CWGR	= ( 1<<16 ) | (sclock << 8) | sclock  ;
}

/*******************************************************************************
 * 说明:AT91F_TWI_WriteByte函数,向从器件发送一个字节
 * 参数:const AT91PS_TWI pTwi ,int mode, int int_address, char *data2send, int nb
 * 返回值:int
*******************************************************************************/
int AT91F_TWI_WriteByte(const AT91PS_TWI pTwi ,int mode, int int_address, char *data2send, int nb) 
{
	unsigned int status,counter=0,error=0;

	if ((mode & AT91C_TWI_IADRSZ) != 0)
          pTwi->TWI_IADR = int_address;             // 设置 TWI 内部地址寄存器
    pTwi->TWI_MMR = mode & ~AT91C_TWI_MREAD;        // 设置 TWI 主机模式寄存器

	if(nb <2)
	  {
		  pTwi->TWI_CR = AT91C_TWI_START | AT91C_TWI_MSEN | AT91C_TWI_STOP;
		  pTwi->TWI_THR = *data2send;
	  }
	else 
	  {
	      for(counter=0;counter<nb;counter++)      // 设置 TWI 主机模式寄存器
	         {       
                 pTwi->TWI_CR = AT91C_TWI_START | AT91C_TWI_MSEN;
                 
                 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++;
                    }
                 
                 pTwi->TWI_THR = *(data2send+counter);
	         }
	  }
	  
	status = pTwi->TWI_SR;
	
	if ((status & ERROR) == ERROR) error++;
	
	while (!(status & AT91C_TWI_TXCOMP))
	  {
    		status = pTwi->TWI_SR;
    		if ((status & ERROR) == ERROR) error++;
      }
      
	return error;
}

/*******************************************************************************
 * 说明:AT91F_TWI_ReadByte函数,读取从器件一个字节
 * 参数:const AT91PS_TWI pTwi ,int mode, int int_address, char *data, int nb
 * 返回值:int
*******************************************************************************/
int AT91F_TWI_ReadByte(const AT91PS_TWI pTwi ,int mode, int int_address, char *data, int nb)
{
	unsigned int status,counter=0,error=0;
	
	if ((mode & AT91C_TWI_IADRSZ) != 0)
       pTwi->TWI_IADR = int_address;                // 设置 TWI 内部地址寄存器
	
	pTwi->TWI_MMR = mode | AT91C_TWI_MREAD;         // 设置 TWI 主机模式寄存器
	
	if (nb == 1)
 	  {                                   // 开始传送
	      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++;
    	      }

	      *(data) = pTwi->TWI_RHR;
	  }
 	
 	else
 	  {
 	      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)
    		     {
			          *(data+counter++) = pTwi->TWI_RHR;
			          if (counter == (nb - 1)) pTwi->TWI_CR = AT91C_TWI_STOP;
		         }
	       }
	  }
	  
	return 0;
}

/*******************************************************************************
 * 说明:AT91F_TWI_Open函数,初始化TWI器件
 * 参数:无
 * 返回值:无
*******************************************************************************/
void AT91F_TWI_Open(void)
{
	AT91F_TWI_CfgPIO ();                     // 配置 TWI PIOs
	AT91F_TWI_CfgPMC ();                     // 通过允许TWI时钟来配置PMC
	AT91F_TWI_Configure (AT91C_BASE_TWI);    // 配置TWI主机模式
	AT91F_SetTwiClock();                     // 设置TWI时钟波形发生器寄存器
}


/*******************************************************************************
 * 说明:AT91F_TestEEPROM函数,测试EEPROM
 * 参数:无
 * 返回值:int
 *         0:成功
 *        -1:失败
*******************************************************************************/
int AT91F_TestEEPROM(void)
{
	char write, read,status;
	AT91F_TWI_Open();                 // 初始化TWI器件
	write = 0x55;
	
	// 先写入再读取一个字节
	status =AT91F_TWI_WriteByte(AT91C_BASE_TWI, ADRR_24C01A | AT91C_TWI_IADRSZ_2_BYTE, 0x04, &write, 1);
	if (status)
	   {
		  AT91F_DBGU_Printf("Write Satus = %d\n\r",status);
       }
    
    DelayNS(10);      // 等待10ms
	
	status =AT91F_TWI_ReadByte(AT91C_BASE_TWI, ADRR_24C01A | AT91C_TWI_IADRSZ_2_BYTE, 0x04, &read, 1);
	if (status)
	   {
		  AT91F_DBGU_Printf("Read Satus = %d\n\r",status);
       }
	
	if (read == write) 
	   {
	  	  AT91F_DBGU_Printk("Test TWI OK\n\r");
	  	  
          return 0;
	   } 
	else 
	   {
	 	  AT91F_DBGU_Printk("Error during test\n\r");
          AT91F_DBGU_Printf("Error during test write 0x%X and read 0x%X\n\r",write,read);

          return -1;
	   }
}

⌨️ 快捷键说明

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