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

📄 iic_comm.c

📁 硬件平台:C8051F314 包括键盘扫描程序
💻 C
📖 第 1 页 / 共 2 页
字号:
         break;
      // Default: all other cases undefined
      default:
         SMB0CN &= ~0x40;                    // Reset communication
         SMB0CN |= 0x40;
         break;
   }
   if (FAIL)                                 // If the transfer failed,
   {
      SMB0CN &= ~0x40;                       // Reset communication
      SMB0CN |= 0x40;
      SMBUS_BUSY = 0;                          // Free SMBus
   }
   SI=0;                                     // Clear SMBus interrupt flag
}

/************************************************************
-----SMBUS数据处理程序-----
功能: 根据接收到的info_id,作相应的处理
//void DataProcess(void)
*************************************************************/

void DataProcess(DATA_BUFF *RcvData)
{
  UCHAR temp = 0;
  static UCHAR *pTxdCnt;
  static UCHAR  txLen = 0;
  DATA_BUFF *pSndData;

//  while(DataProcess);
//  DataProcess = 1;  
  pTxdCnt = &SndDataLen;       // 指针指向发送数据长度全局变量 
  pSndData = &unSndDataBuf;    // 指针指向发送缓冲区首址

  if(RcvDataFlag)         // 缓冲区中有新收到的数据
  {
    temp = RcvData->databuf[0];   // info_id判断
    switch (temp){
    	case 0x30:
    		txLen = ReturnScanCode(RcvData);
    		break;
      case 0x31:
      	txLen = ReturnBatStatus(RcvData);
      	break;
      default:
      	break;
    }
    RcvDataFlag = 0;
  }	
  *pTxdCnt = txLen;
  if(txLen != 0)
    IIC_SndData(pSndData, pTxdCnt);           // 启动iic主发送
}

/************************************************************
-----回复主机查询按键程序-----
功能: 将需要发送的扫描码送入发送缓冲区
返回: 发送缓冲区中数据的长度,
       如果校验出错则返回长度为0,正确则为实际长度
//UCHAR ReturnScanCode(DATA_BUFF SndData)
*************************************************************/

UCHAR ReturnScanCode(DATA_BUFF *RcvData)
{
  UCHAR temp;
  UCHAR retlen;
  DATA_BUFF *pSndBuf;
  
  pSndBuf = &unSndDataBuf;

  temp = CompChksum(RcvData);
  if(temp == 1)   // 校验和正确,将发送数据填入发送缓冲区
  {
    pSndBuf->unDataUnion.stFRK.info_id = FRK_INFO_ID;
//    if(KeyBuffer[0] == 0xd0)  // KeyBuffer中保存的是通码
//    {
//      pSndBuf->unDataUnion.stFRK.info_len = 1;
//      pSndBuf->unDataUnion.stFRK.info_scancode[0] = KeyBuffer[1];
//      retlen = 4;  //
//    }  
//    else
//    {
    pSndBuf->unDataUnion.stFRK.info_len = 2;
    pSndBuf->unDataUnion.stFRK.info_scancode[0] = KeyBuffer[0];
    pSndBuf->unDataUnion.stFRK.info_scancode[1] = KeyBuffer[1];
    retlen = 5;
//    }
    CalChksum(pSndBuf);  //计算校验和并将其填入正确的位置
//    pSndBuf->unDataUnion.stFRK.checksum = temp;
  }
  else           // 校验和错误
    retlen = 0;
  return retlen;
}

/************************************************************
-----回复主机查询电池信息程序-----
功能: 将需要发送的电池信息送入发送缓冲区,本次暂时只支持电量
返回: 发送缓冲区中数据的长度,
       如果校验出错则返回长度为0,正确则为实际长度
//UCHAR ReturnBatStatus(DATA_BUFF SndData)
*************************************************************/

UCHAR ReturnBatStatus(DATA_BUFF *RcvData)
{
  UCHAR temp;
  UCHAR retlen;
  DATA_BUFF *pSndBuf;
  
  pSndBuf = &unSndDataBuf;

  temp = CompChksum(RcvData);
  if(temp == 1)   // 校验和正确,将发送数据填入发送缓冲区
  {
    pSndBuf->unDataUnion.stFRB.info_id = FRB_INFO_ID;
    pSndBuf->unDataUnion.stFRB.info_len = 2;
    pSndBuf->unDataUnion.stFRB.info_batvol[0] = BatVol[0];
    pSndBuf->unDataUnion.stFRB.info_batvol[1] = BatVol[1];
    CalChksum(pSndBuf);
    pSndBuf->unDataUnion.stFRB.checksum = temp;
    retlen = 5;
  }
  else           // 校验和错误
    retlen = 0;
  return retlen;
}

/************************************************************
-----比较校验和程序-----
功能: 计算接收缓冲区数据校验和并与接收到的校验和比较
返回: 如果校验出错则返回0,正确则返回1
//UCHAR CompChksum(DATA_BUFF RcvData)
*************************************************************/

UCHAR CompChksum(DATA_BUFF *RcvData)
{
  UCHAR i, temp = 0;
  UCHAR len = 0;
  UINT sum = 0;
  
  len = RcvData->databuf[1] + 2;   // 接收缓冲区数据长度 = 信息长度 + info_id + info_len
  for(i = 0; i < len; i++)
   sum += RcvData->databuf[i];
  temp = (UCHAR) sum;
  if(temp != RcvData->databuf[i])  // 校验和不等
    return 0;
  else
    return 1;
}

/************************************************************
-----计算校验和程序-----
功能: 计算发送缓冲区数据校验和
返回: 校验和
//void CalChksum(DATA_BUFF SndData)
*************************************************************/

void CalChksum(DATA_BUFF *SndData)
{
  UCHAR i;
  UCHAR len = 0;
  UINT temp = 0;

  len = SndData->databuf[1] + 2;   // 接收缓冲区数据长度 = 信息长度 + info_id + info_len
  for(i = 0; i < len; i++)
   temp += SndData->databuf[i];
  SndData->databuf[i] =  (UCHAR) temp;  // 将计算所得校验和填入发送缓冲区
}

///************************************************************
//-----iic主发送程序-----
//功能: 将发送缓冲区的数据通过IIC总线发送出去
//返回: 发送缓冲区中数据的长度,
////void IIC_SndData(DATA_BUFF *SndData, UCHAR *SndLen)
//*************************************************************/

void IIC_SndData(DATA_BUFF *SndData, UCHAR *SndLen)
{
  UCHAR i;
  
  while(SMBUS_BUSY);       // 等待总线空闲
  SMBUS_BUSY = 1;          // 开始发送数据前,设置总线忙
  
  iic_reset();  
  iic_init(SMB_MASTER);
  
  for(i = 0; i < *SndLen; i++)
    IIC_ByteWrite(SndData, i);
  
  while(SMBUS_BUSY);        // 等待总线空闲
//  SMBUS_BUSY = 1;
  iic_reset();
  iic_init(SMB_SLAVE);      // 发送完成后,将本机设置为从模式
  
}

/************************************************************
-----iic总线复位程序-----
//void iic_reset(void)
*************************************************************/

void iic_reset(void)
{
  SMB0CN &= ~0x40;                          // Disable SMBus
  SMB0CN |= 0x40;                           // Re-enable SMBus
}

/************************************************************
-----iic主方式发送单个字节程序-----
功能: 将发送缓冲区中SndLocation位置的数据通过IIC总线发送出去
返回: 
//void IIC_ByteWrite(DATA_BUFF *SndData, UCHAR SndLocation)
*************************************************************/

void IIC_ByteWrite( DATA_BUFF *SndData, unsigned char SndLocation)
{
   while (SMBUS_BUSY);                         // Wait for SMBus to be free.
   SMBUS_BUSY = 1;                             // Claim SMBus (set to busy)
   // 设置中断中用到的参数
   TARGET = MST_ADD;                         // 设置目标地址
   SMB_RW = WRITE;                           // 标志总线为写操作
   SMB_ACKPOLL = 1;                          // 中断程序将不断查询地址有无确认
   // 准备要发送的数据(1字节)
   SMB_SINGLEBYTE_OUT = SndData->databuf[SndLocation];
                                             // 将要发送数据存储于SMB_SINGLEBYTE_OUT,中断程序
                                             // 将会读取该位置的值并发送
   pSMB_DATA_OUT = &SMB_SINGLEBYTE_OUT;      
   SMB_DATA_LEN = 1;                         
   // Initiate SMBus Transfer
   STA = 1;
}

⌨️ 快捷键说明

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