在前一次调试的基础上,发送开始信号,之后什么也不错,目的是检查SCL和SDA上的变化,以及是否会产生连续不断的中断。程序在原来的基础上,开放以下代码:
IICCON |= 0x20; // 产生开始信号
预想的结果是在SCL和SDA上产生一次“开始信号”,产生一次中断,PA0连接的LED应该会亮,不是闪烁。
程序如下:
#include"holychip_define.h" #define DEVICEADD 0x4E //IIC器件地址 测试IIC LCD1602 //#define DEVICEADD 0xAE //IIC器件地址 unsigned char guc_IICSendData = 0; //IIC主机发送数据 unsigned char guc_IICReceiveData = 0; //IIC主机接收数据 unsigned char guc_IICErrFlag = 0;//IIC错误标志位 unsigned char gbt_IICSendReceiveFlag = 0;//0:发送模式 1:接收模式 unsigned char gbt_IICReveivingFlag = 0;//标志位为1时,认为正在接收数据 unsigned char gbt_IICBusyingFlag = 0; //忙信号,忙时禁止发送和接收 unsigned char fuc_IICStep = 0; void IICSendReceiveStart(unsigned char fuc_IICSendReveiveFlag,unsigned char fuc_IICSendData); //IIC主机模式下发送或接收数据 /*************************************************************************************** * @说明 中断服务函数 *@参数无 * @返回值 无 * @注依据IIC状态码在中断中实现收发 ***************************************************************************************/ void interrupt IIC_Isr(void) { //==============主机发送模式==========================================================// if(IICIF) { // IIC中断,加上指示 PORTA0 = ~PORTA0; //if(!gbt_IICSendReceiveFlag) { // //主机发送模式 //switch (fuc_IICStep) { //case 0x00://第一步:发送器件地址 //if(IICSTA == 0x08) { //IICCON &=~ 0x20; // STA=0,禁止继续发START信号 ////IICDAT = 0xAE; //IICDAT = DEVICEADD; //fuc_IICStep = 0x01; //break; //} else { // //未正常接收ACK信号 // fuc_IICStep = 0xFF; //} // //case 0x01://第二步:发送数据 //if(IICSTA == 0x18) { //IICDAT = guc_IICSendData; //fuc_IICStep = 0x02; //break; //} else { // //未正常接收ACK信号 // fuc_IICStep = 0xFF; //} // //case 0x02://第二步:从机接收数据,发送完成 //if(IICSTA == 0x28) { //IICCON |= 0x10; //fuc_IICStep = 0x00; //gbt_IICBusyingFlag = 0; //break; //} else { // //未正常接收ACK信号 // fuc_IICStep = 0xFF; //} // //case 0xFF://未正常接收ACK信号 //fuc_IICStep = 0; //guc_IICErrFlag = 1; //gbt_IICBusyingFlag = 0; //break; //default:break; //} //} IICIF = 0;//清除中断标志位 } } /*************************************************************************************** * @说明 IIC主机模式下发送或接收数据 * @参数 fuc_IICSendReveiveFlag:IIC发送标志位 0:发送模式 1:接收模式 fuc_IICSendData:IIC发送数据 * @返回值 无 * @注若fuc_IICSendReveiveFlag=1时形参fuc_IICSendData无效可任意传入 ***************************************************************************************/ void IICSendReceiveStart(unsigned char fuc_IICSendReveiveFlag,unsigned char fuc_IICSendData) { if(!fuc_IICSendReveiveFlag) { guc_IICSendData = fuc_IICSendData; //发送数据 gbt_IICBusyingFlag = 1;//IIC正在发送数据标志位 gbt_IICSendReceiveFlag = 0;//当前为主机发送 } else { gbt_IICBusyingFlag = 1; //IIC正在发送数据标志位 gbt_IICSendReceiveFlag = 1;//当前为主机接收 } IICIF = 0; IICCON |= 0x20; // 产生开始信号 } /*************************************************************************************** * @实现效果IIC主机发送与接收 ***************************************************************************************/ void main() { unsigned int i=0; unsigned int j=0; /************************************系统初始化****************************************/ OSCCON = 0x04; //Fosc=32M Fcpu=4M(Fosc4分频 2T) /************************************IO初始化*****************************************/ ANSELC= 0xFF; //PC口所有管脚都设为数字形式 //TRISD= 0x04; //SCL映射PC2 SDA映射PC0时IO配置 TRISC= 0x05; //PC0、PC2均设为输出模式, PC0-SDA,PC2-SCL IICMAP= 0x11; //SCL映射PC2 SDA映射PC0 映射后默认将IIC_SDA口设为开漏带上拉输出 ANSELA= 0x01; //PA0设为数字形式 TRISA= 0x01; //PA0为输出口-IIC中断指示 /************************************IIC初始化*****************************************/ IICCON = 0x40;//启动IIC模块 IICIE = 1; //允许IIC中断 PEIE = 1; //允许未屏蔽中断 GIE = 1; //允许总中断 // 关闭中断指示LED PORTA0 = 1; // 清除IIC中断标志 IICIF = 0; // 使IIC外设向IIC总线发送“START”信号 IICCON |= 0x20; // 产生开始信号 while(1) { //IICSendReceiveStart(0,0xA5);//0,AA:IIC开始发送AA //while(gbt_IICBusyingFlag); //发送中,忙信号 // //for (i=0; i<50000; i++) { //for (j=0; j<200; j++) { // // 延迟 // } //} } }
问题出现了。先看下示波器采集到的波形:
可以看到,SCL和SDA是一直在连续不断地发生着。这与预想的是不一样的。同时,采集中断发生的信号:
注:因为我的示波器只有两个通道,黄色的临时转到了PA0口,用于探测中断处理中产生的信号;粉色的不变,继续采集SDA。检测的周期以及电压单位都没有改变。可以看到,中断信号是不断产生的。猜测是因为SCL每发送完几个就会产生中断的吧。和SCL的波形对比如下(粉色的采集的是SCL,黄色的是中断信号):
现在这种情况,我已经是理解不了了。按理说,我只是启动了一次“START”开始信号,示波器即使能铺捉到,也只应该是一次的,中断也只应该产生一次。事实上,我觉得到了这一步,处理应该是进行不下去了。所以调试到这里,我觉得我可以停下来了。只能希望联系到厂家的技术人员,获得技术支持了。