这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » 国产MCU » 芯圣HC18M003的IIC主机发送模式的调试笔记之二

共3条 1/1 1 跳转至

芯圣HC18M003的IIC主机发送模式的调试笔记之二

专家
2023-10-26 16:46:33     打赏

  在前一次调试的基础上,发送开始信号,之后什么也不错,目的是检查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++) {
//    // 延迟
//    }
//}
}
}


问题出现了。先看下示波器采集到的波形:

图片1.png

可以看到,SCL和SDA是一直在连续不断地发生着。这与预想的是不一样的。同时,采集中断发生的信号:

图片2.png

注:因为我的示波器只有两个通道,黄色的临时转到了PA0口,用于探测中断处理中产生的信号;粉色的不变,继续采集SDA。检测的周期以及电压单位都没有改变。可以看到,中断信号是不断产生的。猜测是因为SCL每发送完几个就会产生中断的吧。和SCL的波形对比如下(粉色的采集的是SCL,黄色的是中断信号):

图片3.png

  现在这种情况,我已经是理解不了了。按理说,我只是启动了一次“START”开始信号,示波器即使能铺捉到,也只应该是一次的,中断也只应该产生一次。事实上,我觉得到了这一步,处理应该是进行不下去了。所以调试到这里,我觉得我可以停下来了。只能希望联系到厂家的技术人员,获得技术支持了。





关键词: 菜鸟学单片机     HC18M003     IIC主机发送模式    

专家
2023-10-30 17:41:36     打赏
2楼

今天又想了想,也许在第一次发送完“START”信号后产生的第一个中断是,就应该立即发送数据或者指令。这是考虑到IIC通讯的时序处理。嗯,抽空可以再试试。以前的逻辑可能会有问题,没考虑IIC通讯上数据连续性的问题。


院士
2024-07-05 18:48:06     打赏
3楼

谢谢分享。


共3条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]