📄 iic.c
字号:
/*********************************************************************/
/* 模 块 名:单片机(C51) 文件名:IIC.c */
/* 提交日期:2006年1月15日 作 者:金雨和(jinyuhe@163.com) */
/* 版 本:V1.0 --Copyright(c) 2006-2008 */
/* 描 述:单片机(C51)串口2处理程序 */
/* 修改记录: */
/* 日 期 版本 修改人 修改内容 */
/* 1. */
/*********************************************************************/
#include <Reg935.h>
#include "uart.h"
#include "string.h"
#define IIC_INT KB1 //P0.1 IIC中断脚
#define IIC_ADDR 0x04 //IIC地址
#define IIC_CON_SET 0x44 //IIC命令设置
#define IIC_END_SYMBOL 0xFF //IIC发送结束符
unsigned char xdata g_ucI2CSendBuf[MAX_I2CDATALEN]; //IIC数据缓存
unsigned char xdata g_ucI2CSendBuf_Len; //IIC数据缓存内容长度
unsigned char xdata g_ucI2CSendBuf_offset; //IIC缓存数据读取当前位移
unsigned char xdata g_ucI2CRecvBuf[MAX_I2CDATALEN]; //IIC数据缓存
unsigned char xdata g_ucI2CRecvBuf_Len; //IIC数据缓存内容长度
unsigned char xdata g_ucI2CRecvBuf_offset; //IIC缓存数据读取当前位移
extern uchar xdata g_sndBuf[MAX_I2CDATALEN]; //数据发送缓冲
extern uchar g_sndBufLen; //数据发送缓冲长度
extern uchar g_sndBufOffset; //数据发送偏移
unsigned char xdata g_ucBspOnLine = 1; //默认值1,BSP当前存在
unsigned char xdata g_usBspTimeOut = 0; //Bsp是否超时时间纪录
bit g_workFlag = 0; //工作灯工作标志
bit g_verFlag = 0; //获取版本标志
unsigned char g_WorkCount = 0; //工作灯工作控制计数器
unsigned char g_resetFlag = 0; //C51复位密码
/*******************************************************************
** 函 数 名: IIC_Isr()
** 输 入: 无
** 输 出: 无
** 描 述: IIC中断函数。
** 全局变量: 无
** 调用模块:
** SetIICSendRegData -- IIC发送数据
** SetIICRecvRegData -- IIC接收数据
** 被调模块: 无
** 作 者:
** 创建日期: 2006年1月15日
** 修 改:
** 日 期 版本 修改人 修改内容
** 1.
********************************************************************/
void IIC_Isr() interrupt 6
{
switch(I2STAT)
{
case 0xA8: /* 从发送模式,收到自身地址,已返回ACK */
IICSendRegData();
break;
case 0x60:
IICRecvRegData();
break;
default:
break;
}
}
/*******************************************************************
** 函 数 名: IICInit()
** 输 入: 无
** 输 出: 无
** 描 述: 初始化IIC寄存器。
** 全局变量: 无
** 调用模块: 无
** 被调模块: 无
** 作 者:
** 创建日期: 2006年1月15日
** 修 改:
** 日 期 版本 修改人 修改内容
** 1.
********************************************************************/
void IICInit()
{
//使能IIC
EI2C = 1;
/***********************************************
P1.5-RST:仅为输入即P1M1.5=1,P1M2.5=0,
P1.2,P1.3为SDA,SCL输出为开漏即P1M1.2=1, P1M1.3=1, P1M2.2=1, P1M2.3=1
**************************************************/
P1M1 = 0x2C;
P1M2 = 0x0C;
I2ADR = IIC_ADDR;
/***********************************************************
I2EN = 1; //IIC使能
STA = 0; //从模式
STO = 0;
SI = 0; //复位中断
AA = 1;
CRSEL = 0; //使用内部SCL发生器
***********************************************************/
I2CON = IIC_CON_SET;
}
/*******************************************************************
** 函 数 名: IICSendRegData()
** 输 入: 无
** 输 出: 无
** 描 述: 将g_ucI2CBuf的数据通过IIC发送到BSP15。
** 全局变量:
** g_ucI2CSendBuf -- IIC发送缓冲
** g_ucI2CSendBuf_Len -- IIC发送缓冲长度
** g_ucI2CSendBuf_offset -- IIC发送缓冲偏移
** 调用模块: 无
** 被调模块:
** IIC_Isr -- IIC中断服务
** 作 者:
** 创建日期: 2006年1月15日
** 修 改:
** 日 期 版本 修改人 修改内容
** 1.
********************************************************************/
void IICSendRegData()
{
/* 循环发送,在数据没有发送完毕前,不退出发送程序 */
while(g_ucI2CSendBuf_offset < g_ucI2CSendBuf_Len)
{
if (I2STAT == 0xC0)
{
I2CON = IIC_CON_SET;
if(g_ucI2CSendBuf_offset >= g_ucI2CSendBuf_Len)
{
g_ucI2CSendBuf_offset = 0;
}
return;
}
else /*if (I2STAT == 0xB8)*/
{
I2DAT = g_ucI2CSendBuf[g_ucI2CSendBuf_offset];
g_ucI2CSendBuf_offset++;
I2CON = IIC_CON_SET;
}
/* 等待发送字节完毕 */
while( SI==0 );
}
do
{
/* 发送结束符 */
I2DAT = IIC_END_SYMBOL;
I2CON = IIC_CON_SET;
while( SI==0 );
}while(I2STAT != 0xC0);
g_ucI2CSendBuf_Len = 0;
g_ucI2CSendBuf_offset = 0;
I2CON = IIC_CON_SET;
}
/*******************************************************************
** 函 数 名: IICRecvRegData()
** 输 入: 无
** 输 出: 无
** 描 述: 接收BSP15通过IIC发送过来的数据,保存至g_ucI2CBuf中。
** 全局变量:
** g_ucI2CRecvBuf -- IIC接收缓冲
** g_ucI2CRecvBuf_Len -- IIC接收缓冲长度
** g_ucI2CRecvBuf_offset -- IIC接收缓冲偏移
** 调用模块:
** OnIICRecv -- 处理接收的IIC数据
** 被调模块:
** IIC_Isr -- IIC中断服务
** 作 者:
** 创建日期: 2006年1月15日
** 修 改:
** 日 期 版本 修改人 修改内容
** 1.
********************************************************************/
void IICRecvRegData()
{
unsigned char ucRecvLen = 0;
unsigned char ucRecvInfo[2];
/* 循环发送,在数据没有发送完毕前,不退出发送程序 */
while(g_ucI2CRecvBuf_offset < MAX_I2CDATALEN)
{
/* 等待接收字节完毕 */
while( SI==0 );
/* 接收到停止条件 */
if (I2STAT == 0xA0)
{
I2CON = IIC_CON_SET;
if(g_ucI2CRecvBuf_offset > 0)
{
if (g_ucI2CRecvBuf_Len == 0)
g_ucI2CRecvBuf_Len = g_ucI2CRecvBuf_offset;
OnIICRecv();
}
return;
}
else /*if (I2STAT == 0xB8)*/
{
if (I2DAT != IIC_END_SYMBOL)
{
if (ucRecvLen < 2)
{
ucRecvInfo[ucRecvLen] = I2DAT;
ucRecvLen ++;
}
else
{
g_ucI2CRecvBuf[g_ucI2CRecvBuf_offset] = I2DAT;
g_ucI2CRecvBuf_offset++;
}
}
else
{
g_ucI2CRecvBuf_Len = g_ucI2CRecvBuf_offset;
I2CON = IIC_CON_SET;
}
I2CON = IIC_CON_SET;
}
}//end while
/* 下面部分为异常处理,正常情况下应该不会运行到这里 */
if (g_ucI2CRecvBuf_Len == 0)
g_ucI2CRecvBuf_Len = g_ucI2CRecvBuf_offset;
if(g_ucI2CRecvBuf_offset > 0)
{
OnIICRecv();
}
g_ucI2CRecvBuf_offset = 0;
I2CON = IIC_CON_SET;
}
/*******************************************************************
** 函 数 名: OnIICRecv()
** 输 入: 无
** 输 出: 无
** 描 述: 对接收IIC数据后,IIC缓存g_ucI2CBuf中数据进行处理。
** 全局变量:
** g_workFlag -- 工作灯闪\灭控制
** g_resetFlag -- C51复位标志
** g_ucI2CRecvBuf -- IIC接收缓冲
** g_ucI2CRecvBuf_Len -- IIC接收缓冲长度
** 调用模块: 无
** 被调模块: 无
** 作 者:
** 创建日期: 2006年1月15日
** 修 改:
** 日 期 版本 修改人 修改内容
** 1.
********************************************************************/
void OnIICRecv()
{
unsigned char ucIdx = 0;
if (!g_ucI2CRecvBuf_Len)
return;
switch(g_ucI2CRecvBuf[0])
{
case ONLINE:
g_ucBspOnLine = 1;
g_usBspTimeOut = 0;
break;
case WORKLEDON: //工作灯亮
g_workFlag = 1;
break;
case WORKLEDOFF: //工作灯灭
g_workFlag = 0;
break;
case RESET: //C51复位
g_resetFlag = 1;
OCB = 0; //复位拉低
break;
case VER: //得到BSP15取版本号消息
g_verFlag = 1;
break;
case UART1: //串口1数据
case UART2: //串口1数据
if((g_ucI2CRecvBuf[g_ucI2CRecvBuf_Len-1] == 0x0A) || (g_ucI2CRecvBuf[g_ucI2CRecvBuf_Len-1] == 0x0D))
{
g_ucI2CRecvBuf[g_ucI2CRecvBuf_Len-1] = 0x0A;
g_ucI2CRecvBuf[g_ucI2CRecvBuf_Len] = 0x0D;
}
if((g_ucI2CRecvBuf[g_ucI2CRecvBuf_Len] == 0x0A) || (g_ucI2CRecvBuf[g_ucI2CRecvBuf_Len] == 0x0D))
{
g_ucI2CRecvBuf[g_ucI2CRecvBuf_Len] = 0x0A;
g_ucI2CRecvBuf[g_ucI2CRecvBuf_Len+1] = 0x0D;
g_ucI2CRecvBuf_Len++;
}
if(g_ucI2CRecvBuf[0] == UART1)
UART1SendData(&g_ucI2CRecvBuf[1],g_ucI2CRecvBuf_Len-1);
else
{
memcpy(g_sndBuf, &g_ucI2CRecvBuf[1], g_ucI2CRecvBuf_Len-1);
g_sndBufLen = g_ucI2CRecvBuf_Len-1;
g_sndBufOffset = 0;
}
break;
default:
break;
}
g_ucI2CRecvBuf_offset = 0;
g_ucI2CRecvBuf_Len = 0;
}
/*******************************************************************
** 函 数 名: IICSendIntToCPU()
** 输 入: 无
** 输 出: 无
** 描 述: 通知CPU,C51准备发送数据。
** 全局变量: 无
** 调用模块: 无
** 被调模块: 无
** 作 者:
** 创建日期: 2006年1月15日
** 修 改:
** 日 期 版本 修改人 修改内容
** 1.
********************************************************************/
void IICSendIntToCPU()
{
unsigned char usPos;
/* 通知CPU准备发送数据 */
IIC_INT = 1;
for(usPos=0; usPos<7; usPos++)
;
IIC_INT = 0;
for(usPos=0; usPos<5; usPos++)
;
IIC_INT = 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -