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

📄 twi.c

📁 mp3代码 要用的干净下啊 希望用东西共享啊
💻 C
📖 第 1 页 / 共 2 页
字号:
   WDR(); //喂狗;
   // 关Twi_中断 
          TWCR&=~(1<<TWIE); 
		  
   //发送开始条件 
   
   Twi_Start(); 
   WDR(); //喂狗;
   Twi_WaitForComplete(); 
   // 发送器件读地址 
   Twi_SendByte( deviceAddr | 0x01 );
   WDR(); //喂狗; 
   Twi_WaitForComplete(); 
   // 检查器件是否可用 
   if( TWSR == TW_MR_SLA_ACK) 
   { 
      // 接收数据并回应 
      while(length > 1) 
      { 
         Twi_Ack(); 
         Twi_WaitForComplete(); 
         *data++ = TWDR; 
         length--; 
		 WDR(); //喂狗;
      } 
      //  接收数据无回应 (末位信号) 
      Twi_NoAcK(); 
      Twi_WaitForComplete(); 
      *data++ = TWDR; 
   } 
   else 
   { 
      // 如未回应器件地址,停止发送,返回错误 
      retval = TWI_ERROR_NODEV; 
   } 
   // 发送停止条件,保持TWEA以便从接收 
   Twi_Stop(); 
   // 开Twi_中断 
          TWCR|=TWIE; 
   return retval; 
} 
/*********************************************************************************************************
** 函数名称:Twi_SlaveReceiveService
** 功能描述:此函数在本机被选中为从写入时运行 
** 输 入:  receiveDataLength:接收数据长度
**          * receiveData:数据缓冲区指针
** 输  出:             
** 全局变量: 
** 调用模块: 
** 说明:
** 注意:    
** 日 期:   2006年8月29日
********************************************************************************************************/
void Twi_SlaveReceiveService() 
{ 
   uint8 i; 
   WDR(); //喂狗;
  //此函数在本机被选中为从写入时运行 
   // 接收到的数据存入本地缓冲区
if((Twi_LocalBuffer.status==TWI_DATA_RECEIVE)&&(Twi_ReceiveBuffer.status==TWI_DATA_RECEIVE))   
    {
	for(i=0;!EmptyQueue(&Twi_ReceiveBuffer); i++) 
         { 
      	 EnQueue(&Twi_LocalBuffer, DeQueue(&Twi_ReceiveBuffer)); 
   		 } 
	Twi_ReceiveBuffer.status=TWI_DATA_FREE;
	Twi_LocalBuffer.status=TWI_DATA_READY;
	}
} 
/*********************************************************************************************************
** 函数名称:Twi_SlaveTransmitService
** 功能描述:此函数在本机被选中为从读出时运行 
** 输 入:  transmitDataLengthMax
** 输  出:             
** 全局变量: 
** 调用模块: 
** 说明:
** 注意:    
** 日 期:   2006年8月29日
********************************************************************************************************/
uint8 Twi_SlaveTransmitService(void) 
{ 
   uint8 i=0; 
   WDR(); //喂狗;
   //此函数在本机被选中为从读出时运行 
   //要发送的数据存入发送缓冲区
    
   
   if ((Twi_LocalBuffer.status==TWI_DATA_SEND)&&Twi_SendBuffer.status==TWI_DATA_FREE)
      {
	  InitQueue(&Twi_SendBuffer);     //清除上次发送的信息
	  for(i=0; (Twi_LocalBuffer.count>0)&&(Twi_SendBuffer.errorcode!=QUEUE_OVERFLOW); i++) 
         { 
      	 EnQueue(&Twi_SendBuffer,DeQueue(&Twi_LocalBuffer)); 
         }
	  Twi_SendBuffer.status= TWI_DATA_SEND;
	  Twi_LocalBuffer.status=TWI_DATA_FREE; 
	  } 
   return i; 
} 
/*********************************************************************************************************
** 函数名称:
** 功能描述:Twi_ (TWI) 中断服务程序 
** 输 入:  
** 输  出:             
** 全局变量: 
** 调用模块: 
** 说明:
** 注意:    
** 日 期:   2006年8月29日
********************************************************************************************************/
#pragma interrupt_handler twi_isr: iv_TWI
void twi_isr(void) 
{ 
   //读状态位 
   uint8 status; 
          status = TWSR & TWSR_STATUS_MASK; 
   switch(status) 
   { 
   // 主方式 
   case TW_START:                   // 0x08: START 已发送 
   case TW_REP_START:               // 0x10: 重复START 已发送 
     // 发送器件地址 
      Twi_SendByte(Twi_DeviceAddrRW);
      break; 
   // 主发送,主接收状态码 
   case TW_MT_SLA_ACK:               // 0x18: SLA+W 已发送;接收到ACK 
   case TW_MT_DATA_ACK:            // 0x28: 数据已发送;接收到ACK 
      if((Twi_SendBuffer.count>0)&&(Twi_SendBuffer.status==TWI_DATA_SEND)) 
         { 
         // 发送数据 
         Twi_SendByte( DeQueue(&Twi_SendBuffer)); 
         } 
      else 
         { 
         // 发送停止条件,保持TWEA以便从接收 
         Twi_Stop(); 
         // 设置状态 
         Twi_State = TWI_IDLE; 
         } 
      break;
   case TW_MR_DATA_NACK:            // 0x58: 接收到数据;NOT ACK 已返回 
      // 保存最终数据 
      EnQueue(&Twi_ReceiveBuffer,TWDR); 
      //继续发送条件 
   case TW_MR_SLA_NACK:            // 0x48: SLA+R 已发送,接收到NOT ACK 
   case TW_MT_SLA_NACK:            // 0x20: SLA+W 已发送,接收到NOT ACK 
   case TW_MT_DATA_NACK:            // 0x30: 数据已发送,接收到NOT ACK 
      // 发送停止条件,保持TWEA以便从接收 
      Twi_Stop(); 
      // 设置状态 
      Twi_State = TWI_IDLE; 
      break; 
   case TW_MT_ARB_LOST:            // 0x38: SLA+W 或数据的仲裁失败 
      // 释放总线 
      TWCR=TWCR&TWCR_CMD_MASK|(1<<TWINT); 
      // 设置状态 
      Twi_State = TWI_IDLE; 
      break; 
   case TW_MR_DATA_ACK:            // 0x50: 接收到数据,ACK 已返回 
         // 保存接收到的数据位 
         EnQueue(&Twi_ReceiveBuffer,TWDR);
      // 检查是否接收完 
   case TW_MR_SLA_ACK:               // 0x40: SLA+R 已发送,接收到ACK 
      if(!FullQueue(&Twi_ReceiveBuffer)&&(Twi_ReceiveBuffer.count<(Twi_ReceiveBuffer.memo-1))&&(Twi_ReceiveBuffer.status==TWI_DATA_RECEIVE)) 
         // 数据位将接收 , 回复 ACK (传送更多字节) 
         Twi_Ack(); 
      else 
         // 数据位将接收 , 回复 NACK (传送最后字节) 
         Twi_NoAcK(); 
      break; 
   // 从接收状态码 
   case TW_SR_SLA_ACK:               // 0x60: 自己的SLA+W 已经被接收,ACK 已返回 
   case TW_SR_ARB_LOST_SLA_ACK:// 0x68: SLA+R/W 作为主机的仲裁失败;自己的SLA+W 已经被接收,ACK 已返回 
   case TW_SR_GCALL_ACK:            // 0x70: 接收到广播地址,ACK 已返回 
   case TW_SR_ARB_LOST_GCALL_ACK: // 0x78: SLA+R/W 作为主机的仲裁失败;接收到广播地址,ACK 已返回 
      // 被选中为从写入 (数据将从主机接收) 
      // 设置状态 
      Twi_State = TWI_SLAVE_RX; 
      // 缓冲准备 
	  if ((Twi_ReceiveBuffer.status==TWI_DATA_FREE)&&(Twi_LocalBuffer.status==TWI_DATA_RECEIVE))
	     {
          InitQueue(&Twi_ReceiveBuffer);
		  Twi_ReceiveBuffer.status=TWI_DATA_RECEIVE;
		  // 接收数据,回应 ACK 
		  Twi_Ack();                                      //  notice 自己增加,为适应缓冲区独占
		  }
	   else
          // 拒绝接收数据,回应 NACK 
          Twi_NoAcK(); 				 					  //  notice 自己增加,为适应缓冲区独占
      break; 
   case TW_SR_DATA_ACK:            // 0x80: 以前以自己的 SLA+W 被寻址;数据已经被接收,ACK 已返回 
   case TW_SR_GCALL_DATA_ACK:   // 0x90: 以前以广播方式被寻址;数据已经被接收,ACK 已返回 
      
	  EnQueue(&Twi_ReceiveBuffer,TWDR); 
      //检查接收缓冲区状态 
      if(!FullQueue(&Twi_ReceiveBuffer)) 
      { 
         // 接收数据,回应 ACK 
         Twi_Ack(); 
      } 
      else 
      { 
         // 接收数据,回应 NACK 
         Twi_NoAcK(); 
      } 
      break; 
   case TW_SR_DATA_NACK:            // 0x88: 以前以自己的 SLA+W 被寻址;数据已经被接收,NOT ACK 已返回 
   case TW_SR_GCALL_DATA_NACK:   // 0x98: 以前以广播方式被寻址;数据已经被接收,NOT ACK 已返回 
      // 接收数据,回应 NACK 
      Twi_NoAcK(); 
      break; 
   case TW_SR_STOP:               // 0xA0: 在以从机工作时接收到STOP或重复START 
      Twi_Ack();
      // Twi_ 接收完成 
	  Twi_SlaveReceiveService();
      // 设置状态 
      Twi_State = TWI_IDLE; 
      break; 
   // 从发送 
   case TW_ST_SLA_ACK:               // 0xA8: 自己的SLA+R 已经被接收,ACK 已返回 
   case TW_ST_ARB_LOST_SLA_ACK:// 0xB0: SLA+R/W 作为主机的仲裁失败;自己的SLA+R 已经被接收,ACK 已返回 
      // 被选中为从读出 (数据将从传回主机) 
      // 设置状态 
      Twi_State = TWI_SLAVE_TX; 
      // 数据请求
	  
	   Twi_SlaveTransmitService();
   case TW_ST_DATA_ACK:            // 0xB8: TWDR 里数据已经发送,接收到ACK 
     // 发送数据位 
      if(Twi_SendBuffer.count>1) 
         // 回应 ACK  
		  {		TWDR=DeQueue(&Twi_SendBuffer); 
                Twi_Ack();
		  } 
      else 
         // 回应 NACK 
		  {      TWDR=DeQueue(&Twi_SendBuffer);
                 Twi_NoAcK();
		  } 
      break;    
   case TW_ST_DATA_NACK:            // 0xC0: TWDR 里数据已经发送接收到NOT ACK 
   case TW_ST_LAST_DATA:            // 0xC8: TWDR 的一字节数据已经发送(TWAE = “0”);接收到ACK 
      
      // 全部完成 
      // 从方式开放 
      Twi_Ack(); 
      // 设置状态 
      Twi_SendBuffer.status=TWI_DATA_FREE;
	  Twi_State = TWI_IDLE; 
      break; 
   case TW_NO_INFO:                 // 0xF8: 没有相关的状态信息;TWINT = “0” 
      // 无操作 
	  break; 
   case TW_BUS_ERROR:               // 0x00: 由于非法的START 或STOP 引起的总线错误 
    
      // 内部硬件复位,释放总线 
      TWCR=TWCR&TWCR_CMD_MASK|(1<<TWINT)|(1<<TWSTO)|(1<<TWEA); 
      // 设置状态 
      Twi_State = TWI_IDLE; 
      break; 
   } 
   TwiErrorCode=status;
} 

/*********************************************************************************************************
** 函数名称:Twi_Init
** 功能描述:TWI总线初始化
** 输 入:  
** 输  出:             
** 全局变量: 
** 调用模块: Twi_SetBitrate()
** 说明:
** 注意:    
** 日 期:   2006年8月29日
********************************************************************************************************/

void Twi_Init(void) 
{ 
   WDR(); //喂狗;
   //设置总线上拉   此处注意:如果有外部上拉,可以不使用内部弱上拉
   #if (CPU_TYPE == M64) || (CPU_TYPE == M128)
   DDRD&=~(1<<0);
   DDRD&=~(1<<1);
   PORTD|=(1<<0);   // Twi_ SCL on ATmega128,64 
   PORTD|=(1<<1);   // Twi_ SDA on ATmega128,64 
   #endif
   #if (CPU_TYPE == M32) || (CPU_TYPE == M16) 
   DDRC&=~(1<<0);
   DDRC&=~(1<<1);
   PORTC|=(1<<0);   // Twi_ SCL on ATmega163,323,16,32,等 
   PORTC|=(1<<1);   // Twi_ SDA on ATmega163,323,16,32,等 
   #endif 
   #if (CPU_TYPE == M8)
   DDRC&=~(1<<5);
   DDRC&=~(1<<4);
   PORTC|=(1<<5);   // Twi_ SCL on ATmega163,323,16,32,等 
   PORTC|=(1<<4);   // Twi_ SDA on ATmega163,323,16,32,等 
   
   #endif
   // 设置 Twi_ 波特率为 100KHz 
   Twi_SetBitrate(80); 

   // 清空从发送和从接收      
   Twi_SlaveReceive = 0; 
   Twi_SlaveTransmit = 0;
   
   InitQueue(&Twi_SendBuffer);
   InitQueue(&Twi_ReceiveBuffer);
   InitQueue(&Twi_LocalBuffer);
   // 状态设置 
   Twi_State = TWI_IDLE; 
   
   
    //设置从接收函数句柄(此函数在被选中为从接收时执行) 
 //Twi_SetSlaveReceiveHandler( Twi_SlaveReceiveService ); 
 //设置从发送函数句柄(此函数在被选中为从发送时执行) 
// Twi_SetSlaveTransmitHandler( Twi_SlaveTransmitService ); 
 Twi_SetLocalDeviceAddr(0x50, 0);   
   // 开Twi_中断和回应 Twi_总线使能  
   TWCR=(1<<TWIE)|(1<<TWEN)|(1<<TWEA); 
   SEI();                     // 开中断
} 



⌨️ 快捷键说明

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