📄 iic.c
字号:
#include "REG931.H"
#include "memory.h"
#include "system.h"
#include "key.h"
#include "vfd.h"
#include "display.h"
#include "uart.h"
#include "iic.h"
// these functions use for P89LPC931 MCU
/****************************************************************
* 设置总线函数(设置为从机)
* 功能用于设置I2C 控制寄存器包括总线时钟选择及从地址.不接受广播地址
* 入口参数addr 从地址
****************************************************************/
void Init_iic(void){
#ifdef INCLUDE_I2C_CODE
I2ADR = IIC_SLAVE_ADDR & 0xfe; /* 设置从地址不接收广播地址*/
I2CON = RELEASE_BUS_ACK; /* 启动硬件I2C */
EI2C=1; // enable iic interrupt
#endif
}
/***************************************************************
* 发送数据
* 功能:向总线发送数据
* 入口参数:c 所要发送的数据
* 出口参数:当接收到非应答位时返回0,否则返回1
***************************************************************/
#if 0
bit SendByte(uchar c){
#ifdef INCLUDE_I2C_CODE
if( I2STAT==0xC0 ) /* 上次发送数据后,接收到非应答位 */
{
I2CON = RELEASE_BUS_ACK;
return(0);
}
I2DAT = c; /* 发送数据 */
I2CON = RELEASE_BUS_ACK; /* 释放总线 */
while( SI==0 ); /* 等待字节数据发送完成 */
return(1);
#endif
}
#endif
/***************************************************************
* 接收字节函数
* 功能:读取总线传来的字节数据并发送应答位,正常接收返回1。
* 入口参数:c 此时读入的数据变量的地址
* 出口参数:接收到总线结束信号或重新启动总线信号时返回0
***************************************************************/
#if 0
bit RcvByte(uchar *c){
#ifdef INCLUDE_I2C_CODE
uchar uc;
I2CON = RELEASE_BUS_ACK; /* 清除标志位, clear SI */
while( SI == 0 ) ; /* 放开总线,等待接收 */
uc=I2STAT;
if( uc == 0xA0 ) /* 接收到停止位或重新启动位 */
{
I2CON = RELEASE_BUS_ACK;/* 先放开总线,再返回0 */
return(0);
}
*c = I2DAT; /* 取数据 */
return(1);
#endif
}
#endif
/****************************************************************
* I2C 中断服务函数
* 功能:用于监控总线上的信号,并对主机作出响应。
* 注: 要打开中断允许,最好把I2C中断优先级设置高一点。
* 接收到对本器件操作的寻址信号时,进入中断
* I2C中断入口地址为0033H,即interrupt 6
****************************************************************/
void I2c_Isr(void) interrupt 6 {
#ifdef INCLUDE_I2C_CODE
uchar indata;
uchar uc;
uc = I2STAT;
switch(uc) {
case RDSLA: /* 主机读操作 */
#if 0
while(1){
if(TxIndex<TxLen)
if( SendByte(TxDBuff[TxIndex])==0 ) break;
else
break;
TxIndex++;
}
I2CON = 0x44; /* 开放总线 */
MCU_KEYINT_PIN=1;
break;
#else
TxIndex=0;
I2DAT = TxDBuff[TxIndex++];
I2CON= RELEASE_BUS_ACK;
bIicBusy=1; //iic bus busy for rcv data
break;
case RDSLA_DATA:
if(TxIndex<TxLen){
I2DAT=TxDBuff[TxIndex];
TxIndex++;
}
I2CON = RELEASE_BUS_ACK; /* 清除标志位, clear SI */
MCU_KEYINT_PIN=1;
break;
case RDSLA_DATA_NOACK:
case RDSLA_STOP:
I2CON = RELEASE_BUS_ACK;/* 先放开总线,再返回0 */
bIicBusy=0; // iic bus idle
MCU_KEYINT_PIN=1;
// TxLen=TxIndex=0;
break;
#endif
///////////////////////////////////////////////////////
case WRSLA: /* 主机写操作 */
#if 0
if(!bRxDProcessEnd){
I2CON=RELEASE_BUS_NOACK;
bRxDProcessEnd=0;
break;
}
while(1) {
if( RcvByte(&indata)==0 ) break; /* 若接收到总线结束则退出 */
RxDBuff[RxIndex] = indata;
RxIndex++;
}
I2CON = 0x44; /* 开放总线 */
RxLen=RxDBuff[1]+3;
bRxDProcessEnd=0;
break;
#else
if(bRxDProcessEnd /* && !bIicBusy*/ ){
I2CON= RELEASE_BUS_ACK;
bIicBusy=1; //iic bus busy for rcv data
RxIndex=0;
}
else{
I2CON= RELEASE_BUS_ACK;
// bIicBusy=1;
}
break;
case WRSLA_DATA: /* 主机写 data */
if(bIicBusy){
indata= I2DAT; /* 取数据 */
if(RxIndex<RXD_BUF_SIZE)
RxDBuff[RxIndex]= indata;
else{
I2CON = RELEASE_BUS_NOACK; /* 清除标志位, clear SI */
break;
}
RxIndex++;
}
I2CON = RELEASE_BUS_ACK; /* 清除标志位, clear SI */
break;
// case WRSLA_DATA_NOACK:
case WRSLA_STOP: /* 接收到停止位或重新启动位 */
I2CON = RELEASE_BUS_ACK;/* 先放开总线,再返回0 */
RxLen= RxDBuff[1]+3;
bRxDProcessEnd=0;
bIicBusy=0; // iic bus idle
I2C_Uart_InforProcess( );
break;
#endif
default:
I2CON = RELEASE_BUS_ACK; /* 清除标志位, clear SI */
break;
}
#endif
}
void StartI2CData(uchar len){
#ifdef INCLUDE_I2C_CODE
TxLen=len;
TxIndex=0;
MCU_KEYINT_PIN=0;
#else
len=len;
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -