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

📄 iic_comm.c

📁 硬件平台:C8051F314 包括键盘扫描程序
💻 C
📖 第 1 页 / 共 2 页
字号:
//------------------------------------------------------------------------------------
//
// FILE NAME      : iic_comm.c
// TARGET DEVICE  : C8051F314
// CREATED ON     : 07/14/06
// CREATED BY     : Jzp
//
// Revision 1.0  

// 功能描述:作为iic总线从机接受MAIN MCU的查询
//    P0.0 -> SDA (SMBus)
//    P0.1 -> SCL (SMBus)
//------------------------------------------------------------------------------------
#include <C8051F310.H>
#include "..\\inc\\define.h" 
#include "..\\inc\\key_scan.h"
#include "..\\inc\\ow_comm.h"

// global constant
// 作为从器件的地址
#define SLA_ADD        0xF0                 // Device addresses (7 bits, lsb is a don't care)
// 作为主器件时目标地址
#define MST_ADD        0xE0                                             

// sfr定义
//sfr16    TMR3RL   = 0x92;                    // Timer2 reload registers
//sfr16    TMR3     = 0x94;                    // Timer3 counter registers

//
#define  WRITE          0x00                 // SMBus WRITE command
#define  READ           0x01                 // SMBus READ command


// SMB0CN寄存器的高4位(MASTER/TXMODE/STA/STO),处理器通过该四位判断SMBUS总线当前状态。
// --MASTER
// 作为从机时状态标志
#define  SMB_SRADD      0x20                 // (SR) 接收到从地址 (也可能是总线竞争失败)
#define  SMB_SRSTO      0x10                 // (SR) 接受到停止位, or lost arbitration
#define  SMB_SRDB       0x00                 // (SR) 接受到数据, or lost arbitration
#define  SMB_STDB       0x40                 // (ST) 已发送完数据
#define  SMB_STSTO      0x50                 // (ST) 发送停止位
// 作为主机时状态标志
#define  SMB_MTSTA      0xE0                 // (MT) 开始传送
#define  SMB_MTDB       0xC0                 // (MT) 数据传送完
#define  SMB_MRDB       0x80                 // (MR) 接收到数据
// 初始化状态
#define  SMB_MASTER     1
#define  SMB_SLAVE      0


// 数据缓冲区长度
#define  DATABUF_LEN 8

// GLOBAL VARIABLES
typedef struct{
  UCHAR info_id;
  UCHAR info_len;
  UCHAR checksum;
} FRAME_QUERY;

typedef struct{
  UCHAR info_id;
  UCHAR info_len;
  UCHAR info_scancode[2];
  UCHAR checksum;
} FRAME_RETURN_KEY;

typedef struct{
  UCHAR info_id;
  UCHAR info_len;
  UCHAR info_batvol[2];
  UCHAR checksum;
} FRAME_RETURN_BAT;

typedef union{
  FRAME_QUERY stFQ;
  FRAME_RETURN_KEY stFRK;
  FRAME_RETURN_BAT stFRB;
} DATAUNION;

typedef union{
  UCHAR databuf[DATABUF_LEN];
  DATAUNION unDataUnion;
} DATA_BUFF;

DATA_BUFF unRcvDataBuf;            // 接收缓冲区
DATA_BUFF unSndDataBuf;            // 发送缓冲区
UCHAR SndDataLen;                  // 当前发送缓冲区中的数据长度
UCHAR RcvDataFlag;                 // iic接收数据标志 =1 有数据
UCHAR TARGET;                      // 发送目标地址
//UCHAR SMB_RW;                      // 总线读写状态 R/nW
UCHAR SMB_SINGLEBYTE_OUT;          // Global holder for single byte writes
UCHAR* pSMB_DATA_OUT;              // Global pointer for SMBus data.
                                   // All transmit data is read from here
UCHAR* pSMB_DATA_IN;               //
UCHAR SMB_DATA_LEN;                // Global holder for number of bytes
// 全局位变量
bit SMBUS_BUSY = 0;                  
bit SMB_RW;                        // 总线读写状态 R/nW                      
bit SMB_SENDWORDADDR;              
bit SMB_RANDOMREAD;                
bit SMB_ACKPOLL;                   

#define FRK_INFO_ID 0x10
#define FRB_INFO_ID 0x20

// 函数原型定义
UCHAR ReturnScanCode(DATA_BUFF *RcvData);
UCHAR ReturnBatStatus(DATA_BUFF *RcvData);
void CalChksum(DATA_BUFF *SndData);
UCHAR CompChksum(DATA_BUFF *RcvData);
void DataProcess(DATA_BUFF *RcvData);
void IIC_ByteWrite( DATA_BUFF *SndData, unsigned char SndLocation);
void IIC_SndData(DATA_BUFF *SndData, UCHAR *SndLen);
void iic_init(UCHAR flag);
void iic_reset(void);
void Timer1_Init(void);
void Timer3_Init(void);
void SMBUS_ISR(void);
void Timer3_ISR(void);



/************************************************************
-----TIMER3中断服务程序-----
*************************************************************/

void Timer3_ISR (void) interrupt 14
{
  SMB0CN &= ~0x40;                          // Disable SMBus
  SMB0CN |= 0x40;                           // Re-enable SMBus
                                            // 禁止-〉使能总线,相当于总线复位
  TMR3CN &= ~0x80;                          // Clear Timer3 interrupt-pending flag
}

/************************************************************
-----SMBUS中断服务程序-----
*************************************************************/

void SMBUS_ISR (void) interrupt 7
{
   static UCHAR iRcvCounter;                 // 接收数据计数
   static UCHAR iSndCounter;                 // 发送数据计数
   static UCHAR FAIL = 0;

   switch (SMB0CN & 0xF0)                    
   {
      // 从接收方式: 已收到地址
      case  SMB_SRADD:
         if((SMB0DAT&0xFE) == SLA_ADD)       // 地址匹配
         {                                    
            STA = 0;                         
            ACK = 1;                         // 确认
            if(SMB0DAT&0x01==READ)           // 本协议不支持主模式读
            {
//               SMB0DAT = SMB_DATA;           // Prepare outgoing byte
              FAIL = 1;
            }
            else                             // 准备接收数据
            {
              iRcvCounter = 0;               // 接收数据计数清零
              pSMB_DATA_IN = &unRcvDataBuf.databuf[0];  // 有新的数据到,将接收指针指向接收缓冲区首址
            }
         }
         else                                // 地址不匹配
         {                                   
            ACK = 0;                         // 不确认
         }
         break;
      // 从接收方式: 接收数据
      case  SMB_SRDB:
         iRcvCounter++;                     // 保存接收数据到缓冲区
         if(iRcvCounter >= 8)               // 防止接收越界
//           pSMB_DATA_IN = &unRcvDataBuf.databuf[0];
         *(pSMB_DATA_IN++) = SMB0DAT;
         ACK = 1;                                 // ACK received data
         break;
      // 从接收方式: 接收完成
      case  SMB_SRSTO:
         STO = 0;                            // STO must be cleared by software when
                                             // a STOP is detected as a slave
         RcvDataFlag = 1;                    // Indicate new data received
         break;
      // 从发送方式: 数据已发送
      case  SMB_STDB:
         break;                              // 本协议不支持
      // 从发送方式:检测到停止条件
      case  SMB_STSTO:
         break;                              // 不需任何操作
      // 主发送方式: 检测到起始条件已发出
      case SMB_MTSTA:
         SMB0DAT = TARGET;                   // 装入目标地址 7bit
         SMB0DAT |= SMB_RW;                  // 装入读写位 1bit
         STA = 0;                            // 
         iSndCounter = 0;                    // 发送数据计数清零
         break;
      // 主发送方式: 数据或地址字节已发出
      case SMB_MTDB:
         if (ACK)                            // Slave Address or Data Byte 
         {                                   // Acknowledged?
            if (SMB_RW==WRITE)               // Is this transfer a WRITE?
            {

               if (iSndCounter < SMB_DATA_LEN)         // Is there data to send?
               {
                  SMB0DAT = *pSMB_DATA_OUT;  // send data byte
                  pSMB_DATA_OUT++;           // increment data out pointer
                  iSndCounter++;                       // increment number of bytes sent
               }
               else
               {
                 STO = 1;                    // set STO to terminte transfer
                 SMBUS_BUSY = 0;               // clear software busy flag
               }
            }
         }
         else                                // If slave NACK,
         {
            if(SMB_ACKPOLL)
            {
               STA = 1;                      // Restart transfer
            }
            else
            {
               FAIL = 1;                     // Indicate failed transfer
            }                                // and handle at end of ISR
         }
         break;

      // 主接收方式: 已收到数据字节          // 本协议不支持
      case SMB_MRDB:
         FAIL = 1;                           

⌨️ 快捷键说明

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