调试HC18M003的IIC主机通讯模式程序,已经花了一天半的时间,依旧没有调通。在SDA输出端始终看不到有效的数据波形,反而是一直维持在高电平状态。调整心态,准备从头再搞一遍,为了能记录完整的操作过程,找到问题点,准备花点时间做笔记。没做一些处理,就记下来。
首先第一步,准备按照以下方式做测试程序。使能IIC外设,但不发送任何东西。检测SCL和SDA总线是否有变化,以及是否会发生IIC中断。虽然不发送数据,但仍然连接从机。从机使用PCF8574T,它的P7 - P0管脚上接上有上拉驱动的LED作为指示。如果IIC通讯成功,数据体现到P7 - P0管脚上,管脚上是低电平的,会点亮LED。同时,使用PC5作为IIC中断的指示管脚,在IIC中断处理中翻转这个管脚。
程序如下:
#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; //允许总中断
PORTA0 = 1;
IICIF = 0;
// 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++) {
// // 延迟
// }
// }
}
}实际测试,SCK和SDA总线上没有数据变化,IIC没发生中断。与预想的一样,没有任何问题。
我要赚赏金
