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

📄 samtwi.c

📁 At91sam7s64+ucosII+pid温度控制
💻 C
字号:
#include "AT91SAM7S128.h"
#include "lib_at91sam7s128.h"
#include "SAMtwi.h"

#include "SAMpioc.h"

void TWIinit(void)
{
  // clock
  AT91C_BASE_PMC->PMC_PCER  = (1<<AT91C_ID_TWI); // TWI
  // pin
  AT91C_BASE_PIOA->PIO_PDR  = (1<<4)|(1<<3);
  AT91C_BASE_PIOA->PIO_ASR  = (1<<4)|(1<<3);    // PA4:TWCK , PA3:TWD
  AT91C_BASE_PIOA->PIO_MDER = (1<<4)|(1<<3);    // open drain
  AT91C_BASE_PIOA->PIO_PPUDR= (1<<4)|(1<<3);    // pull-up R
  
  AT91C_BASE_TWI->TWI_CR=AT91C_TWI_SWRST;        // SW reset
  AT91C_BASE_TWI->TWI_CR=AT91C_TWI_MSEN;         // TWI enable
  //AT91C_BASE_TWI->TWI_CWGR=(1<<16)|(1497<<8)|(1497);  // 错!1497超出了8位的范围。about 8kHz @ 48MHz
 //AT91C_BASE_TWI->TWI_CWGR=(3<<16)|(255<<8)|(255);	//about 12kHz
 	AT91C_BASE_TWI->TWI_CWGR=(4<<16)|(180<<8)|(180);	//about 8kHz
// AT91C_BASE_TWI->TWI_CWGR=(1<<16)|(150<<8)|(150);		//about 80khz
 // AT91C_BASE_TWI->TWI_CWGR=(1<<16)|(200<<8)|(200);//about 60KHz
 //  AT91C_BASE_TWI->TWI_CWGR=(1<<16)|(120<<8)|(120);//about 100KHz
  AT91C_BASE_TWI->TWI_IDR=0xFFFFFFFF;
}

void TWIsend(unsigned char mode,unsigned short addr,unsigned char *dat,unsigned char size)
{
 unsigned int s=0;
 char tmp;
 if(!size) return;  // size = 0 
 
 //AT91C_BASE_TWI->TWI_CR=0x04;  // TWI enable

 tmp = mode&0xf0 ;
if(tmp == 0xa0)
{
	 AT91C_BASE_TWI->TWI_CWGR=(1<<16)|(120<<8)|(120);//about 100KHz
}
else if(tmp == 0x70)	//7290
{
		AT91C_BASE_TWI->TWI_CWGR=(4<<16)|(180<<8)|(180);	//about 8kHz
}
else if(tmp == 0x90)		//ads1110
{
	AT91C_BASE_TWI->TWI_CWGR=(1<<16)|(150<<8)|(150);		//about 80khz
}
Delay(200);
 if((mode&0x01)==0x00)
   {
	 AT91C_BASE_TWI->TWI_MMR=(mode<<15)|(1<<8);
	 AT91C_BASE_TWI->TWI_IADR=addr&0x00FF;
	}						
 else
	{						
	 AT91C_BASE_TWI->TWI_MMR=((mode&0xFE)<<15)|(2<<8);
	 AT91C_BASE_TWI->TWI_IADR=addr;
    }
/*
  s=AT91C_BASE_TWI->TWI_SR; 
  AT91C_BASE_TWI->TWI_THR=*(dat++);
  AT91C_BASE_TWI->TWI_CR=AT91C_TWI_START;
  while(size-->1)
    {
	 while(!(s&AT91C_TWI_TXRDY)) s=AT91C_BASE_TWI->TWI_SR; 
	 AT91C_BASE_TWI->TWI_THR=*(dat++);
	}

   AT91C_BASE_TWI->TWI_CR=AT91C_TWI_STOP; // TWI STOP
   s=AT91C_BASE_TWI->TWI_SR;
   while(!(s&AT91C_TWI_TXCOMP))  s=AT91C_BASE_TWI->TWI_SR; 
*/   

 // in single byte... (datasheet page285)
 if(1==size) 
     {
	  AT91C_BASE_TWI->TWI_CR=AT91C_TWI_START | AT91C_TWI_STOP | AT91C_TWI_MSEN;
	  AT91C_BASE_TWI->TWI_THR=*dat;
	 }
 // multiple bytes	 
 else 
     {
      s=AT91C_BASE_TWI->TWI_SR;   
      AT91C_BASE_TWI->TWI_THR=*(dat++);
      AT91C_BASE_TWI->TWI_CR=1; // TWI START
 
      while((size--)>1)
        {
		 AT91C_BASE_TWI->TWI_CR=AT91C_TWI_START | AT91C_TWI_MSEN;
         s=AT91C_BASE_TWI->TWI_SR;
         while(!(s&AT91C_TWI_TXRDY)) s=AT91C_BASE_TWI->TWI_SR;
        AT91C_BASE_TWI->TWI_THR=*(dat++);  
        }      
 // last byte
      AT91C_BASE_TWI->TWI_CR=AT91C_TWI_STOP; // TWI STOP
         s=AT91C_BASE_TWI->TWI_SR;
         while(!(s&AT91C_TWI_TXRDY)) s=AT91C_BASE_TWI->TWI_SR;
        AT91C_BASE_TWI->TWI_THR=*dat;  
    }
	
 s=AT91C_BASE_TWI->TWI_SR;
 while(!(s&AT91C_TWI_TXCOMP))  s=AT91C_BASE_TWI->TWI_SR; 

  //AT91C_BASE_TWI->TWI_CR=0x08;  // TWI disable
}
void ADCsend_By_TWI(unsigned char mode,unsigned short addr,unsigned char *dat,unsigned char size)
{
 unsigned int s=0;
  char tmp;

  if(!size) return;  // size = 0 

	AT91C_BASE_TWI->TWI_CWGR=(1<<16)|(150<<8)|(150);		//about 80khz

Delay(200);


 
 //AT91C_BASE_TWI->TWI_CR=0x04;  // TWI enable


   {
	  AT91C_BASE_TWI->TWI_MMR=(mode<<15)|(0<<12)|(0<<8);
	 AT91C_BASE_TWI->TWI_IADR=addr&0x00FF;
	}						

 // in single byte... (datasheet page285)
 if(1==size) 
     {
	  AT91C_BASE_TWI->TWI_CR=AT91C_TWI_START | AT91C_TWI_STOP | AT91C_TWI_MSEN;
	  AT91C_BASE_TWI->TWI_THR=*dat;
	 }
 // multiple bytes	 
 else 
     {
      s=AT91C_BASE_TWI->TWI_SR;   
      AT91C_BASE_TWI->TWI_THR=*(dat++);
      AT91C_BASE_TWI->TWI_CR=1; // TWI START
 
      while((size--)>1)
        {
		 AT91C_BASE_TWI->TWI_CR=AT91C_TWI_START | AT91C_TWI_MSEN;
         s=AT91C_BASE_TWI->TWI_SR;
         while(!(s&AT91C_TWI_TXRDY)) s=AT91C_BASE_TWI->TWI_SR;
        AT91C_BASE_TWI->TWI_THR=*(dat++);  
        }      
 // last byte
      AT91C_BASE_TWI->TWI_CR=AT91C_TWI_STOP; // TWI STOP
         s=AT91C_BASE_TWI->TWI_SR;
         while(!(s&AT91C_TWI_TXRDY)) s=AT91C_BASE_TWI->TWI_SR;
        AT91C_BASE_TWI->TWI_THR=*dat;  
    }
	
 s=AT91C_BASE_TWI->TWI_SR;
 while(!(s&AT91C_TWI_TXCOMP))  s=AT91C_BASE_TWI->TWI_SR; 

  //AT91C_BASE_TWI->TWI_CR=0x08;  // TWI disable
}
void ADCread_By_TWI(unsigned char mode,unsigned short addr,unsigned char *dat,unsigned char size)
{
 unsigned int s=0;
unsigned int i=0;
 char tmp;
  if(!size) return;  // size = 0 

AT91C_BASE_TWI->TWI_CWGR=(1<<16)|(150<<8)|(150);		//about 80khz

Delay(200);
 

 
 //AT91C_BASE_TWI->TWI_CR=0x04;  // TWI enable


   {
	 AT91C_BASE_TWI->TWI_MMR=(mode<<15)|(1<<12)|(0<<8);
	 AT91C_BASE_TWI->TWI_IADR=addr&0x00FF;
	}						

 // in single byte... (datasheet page285)
if(1==size)
  	{
     AT91C_BASE_TWI->TWI_CR=AT91C_TWI_START | AT91C_TWI_STOP;   
      s=AT91C_BASE_TWI->TWI_SR;
      while(!(s&AT91C_TWI_TXCOMP))  s=AT91C_BASE_TWI->TWI_SR;
        *dat= AT91C_BASE_TWI->TWI_RHR;
    }
 // multiple bytes
 else
   {
     AT91C_BASE_TWI->TWI_CR=AT91C_TWI_START | AT91C_TWI_MSEN;
        s=AT91C_BASE_TWI->TWI_SR;
        while(!(s&AT91C_TWI_TXCOMP))  // wait for stop 
         {

		 if(++i>=0x10000)
		 {
		 	break;
		}
		 //AT91F_US_PutChar ((AT91PS_USART) AT91C_BASE_DBGU,0xa1);
          s=AT91C_BASE_TWI->TWI_SR;	 
		    if(s&AT91C_TWI_RXRDY) 
			    {
				 *dat=AT91C_BASE_TWI->TWI_RHR;
				// AT91F_US_PutChar ((AT91PS_USART) AT91C_BASE_DBGU,*dat);
				 dat++;
				 size--;
				 // last byte
				 if(1==size) AT91C_BASE_TWI->TWI_CR=AT91C_TWI_STOP;   
				}
			
		 } 
    }

  //AT91C_BASE_TWI->TWI_CR=0x08;  // TWI disable 

}
void TWIread(unsigned char mode,unsigned short addr,unsigned char *dat,unsigned char size)
{
 unsigned int s=0;
 unsigned int i = 0;
  char tmp;
   if(!size) return;
 tmp = mode&0xf0 ;
if(tmp == 0xa0)
{
	 AT91C_BASE_TWI->TWI_CWGR=(1<<16)|(120<<8)|(120);//about 100KHz
}
else if(tmp == 0x70)	//7290
{
	AT91C_BASE_TWI->TWI_CWGR=(4<<16)|(180<<8)|(180);	//about 8kHz
}
else if(tmp == 0x90)		//ads1110
{
	AT91C_BASE_TWI->TWI_CWGR=(1<<16)|(150<<8)|(150);		//about 80khz
}
Delay(200);


 //AT91C_BASE_TWI->TWI_CR=0x04;  // TWI enable

 if((mode&0x01)==0x00)
    {
	 AT91C_BASE_TWI->TWI_MMR=(mode<<15)|(1<<12)|(1<<8);
	 AT91C_BASE_TWI->TWI_IADR=addr&0x00FF;
	}						
 else
	{						
	 AT91C_BASE_TWI->TWI_MMR=((mode&0xFE)<<15)|(1<<12)|(2<<8);
	 AT91C_BASE_TWI->TWI_IADR=addr;
    }
 /*
 AT91C_BASE_TWI->TWI_CR=AT91C_TWI_START;
 s=AT91C_BASE_TWI->TWI_SR;
   while(size-->1)
     {
	  while(!(s&AT91C_TWI_RXRDY)) s=AT91C_BASE_TWI->TWI_SR;
	  *(dat++)=AT91C_BASE_TWI->TWI_RHR;
	  *(dat)=s;
	 }

 AT91C_BASE_TWI->TWI_CR=AT91C_TWI_STOP;
 s=AT91C_BASE_TWI->TWI_SR;
 while(!(s&AT91C_TWI_RXRDY)) s=AT91C_BASE_TWI->TWI_SR;
 *dat=AT91C_BASE_TWI->TWI_RHR;
 */

	
 // single byte	
 if(1==size)
  	{
     AT91C_BASE_TWI->TWI_CR=AT91C_TWI_START | AT91C_TWI_STOP;   
      s=AT91C_BASE_TWI->TWI_SR;
      while(!(s&AT91C_TWI_TXCOMP))  s=AT91C_BASE_TWI->TWI_SR;
        *dat= AT91C_BASE_TWI->TWI_RHR;
    }
 // multiple bytes
 else
   {
     AT91C_BASE_TWI->TWI_CR=AT91C_TWI_START | AT91C_TWI_MSEN;
	 
        s=AT91C_BASE_TWI->TWI_SR;
        while(!(s&AT91C_TWI_TXCOMP))  // wait for stop 
         {
		 if(++i>=0x10000)
		 {
		 	break;
		 }
          s=AT91C_BASE_TWI->TWI_SR;	 
		    if(s&AT91C_TWI_RXRDY) 
			    {
				 *(dat++)=AT91C_BASE_TWI->TWI_RHR;
				 size--;
				 // last byte
				 if(1==size) AT91C_BASE_TWI->TWI_CR=AT91C_TWI_STOP;   
				}
		 } 
    }

  //AT91C_BASE_TWI->TWI_CR=0x08;  // TWI disable 
}
/*************************************************************************
ads1110 i2c driver
*************************************************************************/


void I2C_IOinit()			//改iic外设由io控制
{
	AT91F_PIOA_CfgPMC();//配置io口时钟
	AT91F_PIO_CfgOutput(AT91C_BASE_PIOA,I2C_SETOUT);
	SCL_IS_L;
	SDA_IS_H;
	Delay(DLY4);
}
void I2C_Start()
{
	SDA_IS_H;
	Delay(DLY4);
	SCL_IS_H;
	Delay(DLY4);
	SDA_IS_L;
	Delay(DLY4);
	Delay(DLY4);
	SCL_IS_L;
}
void I2C_Stop()
{
	SDA_IS_OUT;
	SDA_IS_L;
	Delay(DLY4);
	SCL_IS_H;
	Delay(DLY4);
	SDA_IS_H;
	Delay(DLY4);
	TWIinit();				//恢复iic外设
}
char I2C_WrByte(char x)
{
int i;
char tmp;
	tmp = x;
	
	SCL_IS_L;
	SDA_IS_OUT;
	Delay(DLY4);
	for(i=0;i<8;i++)
	{
		if(tmp&0x80 == 0x80)
		{
			SDA_IS_H;
		}
		else
		{
			SDA_IS_L;
		}
		Delay(DLY2);
		SCL_IS_H;
		Delay(DLY4);
		SCL_IS_L;
		tmp = tmp<<1;
		Delay(DLY4);
	}
	SDA_IS_IN;
	SCL_IS_H;
	Delay(DLY4);
	if(AT91F_PIO_GetInput(AT91C_BASE_PIOA) & SDA)
		tmp = 1;			//返回1,错误的应答
	else
		tmp = 0;			//返回0,正确的应答
	SCL_IS_L;
	return(tmp);
}
char I2C_ReByte(char ask)
{
int i;
char tmp = 0;
	SDA_IS_IN;
	Delay(DLY4);
	for(i=0;i<8;i++)
	{
		tmp=tmp<<1;
		SCL_IS_H;
		Delay(DLY4);
		if(AT91F_PIO_GetInput(AT91C_BASE_PIOA) & SDA)
		{
			tmp += 1;
		}
		SCL_IS_L;
		Delay(DLY4);
	}
	SDA_IS_OUT;
	if(ask)
	{
		SDA_IS_H;//若为1,表示不希望再接收数据,发送停止信号。接收完毕
	}
	else
	{
		SDA_IS_L;//ASK为0表示希望继续接收数据。
	}
	Delay(DLY4);
	SCL_IS_H;
	Delay(DLY4);
	SCL_IS_L;
	return(tmp);
}
			
		
					

/*************************************************************************
eepot x9241 drive
*************************************************************************/




unsigned char  read_eepot_wiper ( char address   )
{
unsigned char i ,baddr,saddr;
	if(address >=4)
	{
		baddr = EEPOT_ADDR1;
		saddr = EEPOT_RWCR | ((address - 4)<<2);
	}
	else
	{
		baddr = EEPOT_ADDR0;
		saddr = EEPOT_RWCR | ((address)<<2);
	}
	
	TWIread(baddr,saddr,&i,1);
	return(i);
}

int    write_eepot_wiper( char a, char d )
{
unsigned char baddr,saddr;
	if(a >=4)
	{
		baddr = EEPOT_ADDR1;
		saddr = EEPOT_WWCR | ((a - 4)<<2);
	}
	else
	{
		baddr = EEPOT_ADDR0;
		saddr = EEPOT_WWCR | ((a)<<2);
	}
	TWIsend(baddr,saddr,&d,1);
	return(1);
}

void write_eepot_inc(char a)
{
unsigned char baddr,saddr;
unsigned char  d;
	if(a >=4)
	{
		baddr = EEPOT_ADDR1;
		saddr = EEPOT_SKIP | ((a - 4)<<2);
	}
	else
	{
		baddr = EEPOT_ADDR0;
		saddr = EEPOT_SKIP | ((a)<<2);
	}
	d= 0xff;
	TWIsend(baddr,saddr,&d,1);
}	
void write_eepot_dec(char a)
{
unsigned char baddr,saddr;
unsigned char  d;
	if(a >=4)
	{
		baddr = EEPOT_ADDR1;
		saddr = EEPOT_SKIP | ((a - 4)<<2);
	}
	else
	{
		baddr = EEPOT_ADDR0;
		saddr = EEPOT_SKIP | ((a)<<2);
	}
	d= 0x00;
	TWIsend(baddr,saddr,&d,1);
}		

⌨️ 快捷键说明

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