📄 iic._c
字号:
/************************************iic.c**************************
*iic.c负责同上层软件之间的通讯
*iic在NPI中处于两种工作方式 从机接收模式以及从机发送模式
*从机接收模式 在通讯过程中 应答主机请求 并将数据保存到相应数组以便主程序判断
*从机发送模式 通过pwr拉高请求主机接收数据 然后根据主机应答发送数据
********************************************************************/
#include <iom8v.h>
#include <macros.h>
#include "iic.h"
#include "define.h"
extern uchar buf[15]; //pc同i2c交互数据存放处
extern uchar cmd;//i2c数据缓存
extern uchar cmd_num;//i2c数据计数
extern uchar flag; //
extern uchar *data;
extern uchar j;
extern uchar req_flag,start_flag,vision_flag,cmd_flag;
//*****************************************************************************/
#pragma interrupt_handler TWI_ISR:18
void TWI_ISR(void)
{
//TWI被控接收器模式中断处理
switch (TestAck())
{
//从机接收
case SR_SLA_ACK: //SR_SLA_ACK=0x60; SLA+W已经被接收ACK 已返回
{
Twi_ACK();
break;
}
case MT_SR_SLA_ACK://MT_SR_SLA_ACK=0x68;SLA+R/W 作为主机的仲裁失败;自己的SLA+W 已经被接收,ACK 已返回
{
Twi_ACK();
break;
}
case SR_ALL_ACK://SR_ALL_ACK=0x70;接收到广播地址,ACK 已返回
{
Twi_ACK();
break;
}
case MT_SR_ALL_ACK://MT_SR_ALL_ACK=0x78;SLA+R/W 作为主机的仲裁失败;接收到广播地址,ACK 已返回
{
Twi_ACK();
break;
}
case SR_DATA_ACK://SR_DATA_ACK=0X80;以前以自己的 SLA+W 被寻址;数据已经被接收,ACK 已返回
{
cmd=TWDR;
buf[cmd_num]=cmd;
cmd_num++;
if(cmd==0x00 && cmd_num==2) //接收到主机请求数据结束位 置标记
{
req_flag=1;
start_flag=0;
vision_flag=0;
cmd_flag=0;
PWRON;
cmd_num=0;
}
if(cmd==0x0f) //接收到握手结束位 置标记
{
start_flag=1;
}
if(cmd==0x05 && cmd_num==2)
{
vision_flag=1;
}
Twi_ACK();
if(cmd==0xff) //接受到主机发送数据结束位 置标记
{
cmd_flag=1;
}
break;
}
case SR_DATA_NOACK://SR_DATA_NOACK=0x88;以前以自己的 SLA+W 被寻址;数据已经被接收,NOT ACK 已返回
{
cmd=TWDR;
buf[cmd_num]=cmd;
cmd_num++;
if(cmd==0x00 && cmd_num==2) //接收到主机请求数据结束位 置标记
{
req_flag=1;
start_flag=0;
vision_flag=0;
cmd_flag=0;
PWRON;
cmd_num=0;
}
if(cmd==0x0f) //接收到握手结束位 置标记
{
start_flag=1;
}
if(cmd==0x05 && cmd_num==2)
{
vision_flag=1;
}
Twi_ACK();
if(cmd==0xff) //接受到主机发送数据结束位 置标记
{
cmd_flag=1;
}
break;
}
case SR_ALL_DATA_ACK://SR_ALL_DATA_ACK=0x90;以前以广播方式被寻址;数据已经被接收,ACK 已返回
{
cmd=TWDR;
buf[cmd_num]=cmd;
cmd_num++;
if(cmd==0x00 && cmd_num==2) //接收到主机请求数据结束位 置标记
{
req_flag=1;
start_flag=0;
vision_flag=0;
cmd_flag=0;
PWRON;
cmd_num=0;
}
if(cmd==0x0f) //接收到握手结束位 置标记
{
start_flag=1;
}
if(cmd==0x05 && cmd_num==2)
{
vision_flag=1;
}
Twi_ACK();
if(cmd==0xff) //接受到主机发送数据结束位 置标记
{
cmd_flag=1;
}
break;
}
case SR_ALL_DATA_NOACK://SR_ALL_DATA_NOACK=0x98;以前以广播方式被寻址;数据已经被接收,NOT ACK 已返回
{
cmd=TWDR;
buf[cmd_num]=cmd;
cmd_num++;
if(cmd==0x00 && cmd_num==2) //接收到主机请求数据结束位 置标记
{
req_flag=1;
start_flag=0;
vision_flag=0;
cmd_flag=0;
PWRON;
cmd_num=0;
}
if(cmd==0x0f) //接收到握手结束位 置标记
{
start_flag=1;
}
if(cmd==0x05 && cmd_num==2)
{
vision_flag=1;
}
Twi_ACK();
if(cmd==0xff) //接受到主机发送数据结束位 置标记
{
cmd_flag=1;
}
break;
}
//*****************************从机发送************************/
case ST_SLA_ACK://SR_STOP_RESTART=0xa8, 自己的SLA+R 已经被接收,ACK 已返回
{
Twi_WB(*(data+j)); //从机发送数据
j++; //准备下一个数据
break;
}
case MT_ST_SLA_ACK://SR_STOP_RESTART=0xb0, SLA+R/W 作为主机的仲裁失败;自己的SLA+R 已经被接收,ACK 已返回
{
Twi_WB(*(data+j)); //从机发送数据
j++; //准备下一个数据
break;
}
case ST_DATA_ACK://SR_STOP_RESTART=0xb8, TWDR 里数据已经发送,接收到ACK
{
Twi_WB(*(data+j)); //从机发送数据
j++; //准备下一个数据
break;
}
case ST_DATA_NOACK://SR_STOP_RESTART=0xc0, TWDR 里数据已经发送,接收到NOT ACK
{
j=0; //发送完数据请零结束
Twi_ACK();
break;
}
case ST_LAST_DATA_ACK://SR_STOP_RESTART=0xc8, TWDR 的一字节数据已经发送,(TWAE = “0”);接收到ACK
{
j=0;//发送完数据请零结束
Twi_ACK();
break;
}
case SR_STOP_RESTART://SR_STOP_RESTART=0xa0, 在以从机工作时接收到STOP或重复START
{
j=0;
Twi_ACK();
break;
}
default:
{
Stop();//从机模式恢复TWI响应能力
break;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -