📄 iic_comm.c
字号:
//------------------------------------------------------------------------------------
//
// 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 + -