找回密码
 立即注册
查看: 133|回复: 27

关于AiCube创建IIC项目的疑问?(在荣誉版主erci***耐心指导下已经解决)

[复制链接]
  • 打卡等级:偶尔看看III
  • 打卡总天数:55
  • 最近打卡:2025-10-31 09:22:07
已绑定手机

6

主题

580

回帖

1025

积分

金牌会员

积分
1025
发表于 5 天前 | 显示全部楼层 |阅读模式
前天开始USB的学习,按照老师指点,先学习AiCube


那么就先试一试IIC,我创建了多文件的项目,可以顺利通过编译

但是系统生成的函数I2C.c,把我搞糊涂了


//<<AICUBE_USER_HEADER_REMARK_BEGIN>>
////////////////////////////////////////
// 在此添加用户文件头说明信息  
// 文件名称: i2c.c
// 文件描述:
// 文件版本: V1.0
// 修改记录:
//   1. (2025-10-27) 创建文件
////////////////////////////////////////
//<<AICUBE_USER_HEADER_REMARK_END>>


#include "config.h"


//<<AICUBE_USER_INCLUDE_BEGIN>>
// 在此添加用户头文件包含  
//<<AICUBE_USER_INCLUDE_END>>


//<<AICUBE_USER_GLOBAL_DEFINE_BEGIN>>
// 在此添加用户全局变量定义、用户宏定义以及函数声明  
//<<AICUBE_USER_GLOBAL_DEFINE_END>>



////////////////////////////////////////
// I2C初始化函数
// 入口参数: 无
// 函数返回: 无
////////////////////////////////////////
void I2C_Init(void)
{
    I2C_SwitchP2425();                  //选择I2C数据口: SCL(P2.5), SDA(P2.4)

    I2C_MasterMode();                   //设置I2C为主机模式
    I2C_SetClockDivider(12);            //设置I2C为主机模式时钟

    I2C_Enable();                       //使能I2C功能

    //<<AICUBE_USER_I2C_INITIAL_BEGIN>>
    // 在此添加用户初始化代码  
    //<<AICUBE_USER_I2C_INITIAL_END>>
}

////////////////////////////////////////
// 主机模式等待命令完成
// 入口参数: 无
// 函数返回: 无
////////////////////////////////////////
void I2C_MasterWait(void)
{
    while (!I2C_CheckMasterFlag());     //等待完成标志
    I2C_ClearMasterFlag();              //清除完成标志
    I2C_Idle();                         //恢复IDLE状态
}

////////////////////////////////////////
// 主机模式发送起始信号
// 入口参数: 无
// 函数返回: 无
////////////////////////////////////////
void I2C_MasterStart(void)
{
    I2C_Start();                        //触发主机模式起始命令
    I2C_MasterWait();                   //等待命令完成
}

////////////////////////////////////////
// 主机模式发送停止信号
// 入口参数: 无
// 函数返回: 无
////////////////////////////////////////
void I2C_MasterStop(void)
{
    I2C_Stop();                         //触发主机模式停止命令
    I2C_MasterWait();                   //等待命令完成
}

////////////////////////////////////////
// 主机模式发送1字节数据
// 入口参数: dat (待发送的字节数据)
// 函数返回: 0   (接收的应答信号为ACK)
//           1   (接收的应答信号为NAK)
////////////////////////////////////////
BOOL I2C_MasterSendByte(uint8_t dat)
{
    I2C_WriteData(dat);                 //将数据写入I2C数据寄存器
    I2C_SendData();                     //触发主机模式写数据命令
    I2C_MasterWait();                   //等待命令完成
    I2C_RecvACK();                      //触发主机模式接收应答命令
    I2C_MasterWait();                   //等待命令完成

    return I2C_MasterReadACK();         //读取并返回应答信号
}

////////////////////////////////////////
// 主机模式接收1字节数据
// 入口参数: ack (待发送的应答信号)
// 函数返回:     (接收的字节数据)
////////////////////////////////////////
uint8_t I2C_MasterReadByte(BOOL ack)
{
    uint8_t dat;

    I2C_RecvData();                     //触发主机模式读数据命令
    I2C_MasterWait();                   //等待命令完成
    dat = I2C_ReadData();               //读取接收的数据
    if (!ack)
        I2C_MasterSetACK();             //将ACK数据写入寄存器
    else
        I2C_MasterSetNAK();             //将NAK数据写入寄存器
    I2C_SendACK();                      //触发主机模式发送应答命令
    I2C_MasterWait();                   //等待命令完成

    return dat;                         //返回接收的数据
}



//<<AICUBE_USER_FUNCTION_IMPLEMENT_BEGIN>>
// 在此添加用户函数实现代码  
//<<AICUBE_USER_FUNCTION_IMPLEMENT_END>>




就是主机模式接收1字节数据,要求入口参数是ack (待发送的应答信号)

主机读数据的时候,不是读完数据才发送ASK应答么?



回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:55
  • 最近打卡:2025-10-31 09:22:07
已绑定手机

6

主题

580

回帖

1025

积分

金牌会员

积分
1025
发表于 5 天前 | 显示全部楼层
难道以前


        IIC_SENDBYTE(slave);        //主机发送命令字。该字由 7 位的外围器件地址和 1 位读写控制位R/W组成(此时RW=0为写)
                                                   //slave 由 7 位的外围器件地址和 1 位读写控制位R/W组成(此时RW=0为写)
        IIC_WAITACK();  //等待从机应答ACK,结果由ask保存,为0就正确,为1就错误

这2个函数的功能,由

                        I2C_MasterSendByte(slave)          //主机模式发送1字节数据,函数返回: 0   (接收的应答信号为ACK)
                                                                         //函数返回:  1   (接收的应答信号为NAK)



这1个函数完成?

回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:55
  • 最近打卡:2025-10-31 09:22:07
已绑定手机

6

主题

580

回帖

1025

积分

金牌会员

积分
1025
发表于 5 天前 | 显示全部楼层
应该是我水平低,搞不懂他怎么处理:
  1. // 发送开始命令 发送器件地址(写) 发送数据地址 发送开始命令 发送器件地址(读)读数据
  2. //头尾2个器件地址(第1个最后一位写0,第2个最后一位写1),数据片内地址只发1次
  3. void IIC_Read_NByte( u8 slave,u8 addr,u8 *p,u8 number )        //iic读取连续的几个字节
  4. {
  5.         I2C_MasterStart();                        //发送一个启动信号"S”,开始一次通信的开始
  6.        
  7.         //IIC_SENDBYTE(slave);        //主机发送命令字。该字由 7 位的外围器件地址和 1 位读写控制位R/W组成(此时RW=1为读)
  8.                                 //slave 由 7 位的外围器件地址和 1 位读写控制位R/W组成(此时RW=1为读)
  9.         //IIC_WAITACK();                        //等待从机应答ACK,结果由ask保存,为0就正确,为1就错误
  10.         I2C_MasterSendByte(slave); //主机模式发送1字节数据,函数返回: 0   (接收的应答信号为ACK)
  11.                                                                          //函数返回:  1   (接收的应答信号为NAK)
  12.        
  13.        
  14.         //IIC_SENDBYTE(addr);        //要写入芯片24C02的读取数据片内地址addr
  15.         //IIC_WAITACK();                //等待从机应答ACK,结果由ask保存,为0就正确,为1就错误
  16.         I2C_MasterStart();                                 //发送一个启动信号"S”,开始一次通信的开始
  17.         I2C_MasterSendByte((u8)(slave+0x01)); //主器件发送器件地址(读/写选择位为"1"),主机模式发送1字节数据
  18.                                                                              //函数返回: 0   (接收的应答信号为ACK)函数返回:  1   (接收的应答信号为NAK)
  19.         //IIC_START();      
  20.         //IIC_SENDBYTE((u8)(slave+0x01)); //主器件发送器件地址(读/写选择位为"1")       
  21.         //IIC_WAITACK();                        //芯片24C02应答ACK,并随时钟送出数据
  22.        
  23.        
  24.         do
  25.         {
  26.                 *p = I2C_MasterReadByte(BOOL ack);        //第1圈P[0] 第2圈 P[1] 第3圈P[2]第4圈P[3]第5圈P[4]第6圈P[5].......
  27.                 p++;
  28.                 if( number!=1 )        //不是最后一位
  29.                 IIC_SENDACK();                //等待从机应答ACK,结果由ask保存,为0就正确,为1就错误,这句不写也OK
  30.         }
  31.         while(--number);
  32.         IIC_SENDNACK();
  33.         IIC_STOP();  //主机发送停止信号“P”       
  34. }
复制代码
像这里:


do
{
*p = I2C_MasterReadByte(BOOL ack); //第1圈P[0] 第2圈 P[1] 第3圈P[2]第4圈P[3]第5圈P[4]第6圈P[5].......
p++;
if( number!=1 ) //不是最后一位
IIC_SENDACK(); //等待从机应答ACK,结果由ask保存,为0就正确,为1就错误,这句不写也OK
}


I2C_MasterReadByte(BOOL ack); 是读当前地址的1个字节数据,那么这个入口参数BOOL ack,我从哪里获取?


总不能直接带入0吧?
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:55
  • 最近打卡:2025-10-31 09:22:07
已绑定手机

6

主题

580

回帖

1025

积分

金牌会员

积分
1025
发表于 5 天前 | 显示全部楼层


我能在def.h中找到:

typedef bit                     BOOL;

也知道是用它来代替ASK或者NASK

BOOL =0   就是ASK

BOOL =1   就是NASK
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:55
  • 最近打卡:2025-10-31 09:22:07
已绑定手机

6

主题

580

回帖

1025

积分

金牌会员

积分
1025
发表于 5 天前 | 显示全部楼层
*p = I2C_MasterReadByte(BOOL);        //第1圈P[0] 第2圈 P[1] 第3圈P[2]第4圈P[3]第5圈P[4]第6圈P[5]......

参数给BOOL,编译就报错

干脆不给参数:
截图202510271018368359.jpg

点评

BOOL是bit类型的别名,函数传参怎么能传类型名进去,要传实例。 接收后发NAK还是ACK查用到的从机IC手册。 【新提醒】《8051U深度入门到32位51大型实战视频》,【免费 + 包邮 送】实验箱@Ai8051U,100万套 - 字库生  详情 回复 发表于 5 天前
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:55
  • 最近打卡:2025-10-31 09:22:07
已绑定手机

6

主题

580

回帖

1025

积分

金牌会员

积分
1025
发表于 5 天前 | 显示全部楼层
不知道去哪里找资料,搞懂这2个函数如何用在IIC上?
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:344
  • 最近打卡:2025-10-31 08:54:30
已绑定手机

90

主题

3347

回帖

7495

积分

荣誉版主

无情的代码机器

积分
7495
发表于 5 天前 | 显示全部楼层
wuzhe*** 发表于 2025-10-27 10:18
*p = I2C_MasterReadByte(BOOL);        //第1圈P[0] 第2圈 P[1] 第3圈P[2]第4圈P[3]第5圈P[4]第6圈P[5]......

参 ...


BOOL是bit类型的别名,函数传参怎么能传类型名进去,要传实例。
接收后发NAK还是ACK查用到的从机IC手册。


【新提醒】《8051U深度入门到32位51大型实战视频》,【免费 + 包邮 送】实验箱@Ai8051U,100万套 - 字库生成,图片取模,串口绘图,串口助手,虚拟硬件,外部串行Flash编程 国芯人工智能技术交流网站 - AI32位8051交流社区
三天不学习,赶不上刘少奇~
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:55
  • 最近打卡:2025-10-31 09:22:07
已绑定手机

6

主题

580

回帖

1025

积分

金牌会员

积分
1025
发表于 5 天前 | 显示全部楼层
erci*** 发表于 2025-10-27 11:10
BOOL是bit类型的别名,函数传参怎么能传类型名进去,要传实例。
接收后发NAK还是ACK查用到的从机IC手册 ...

感谢指点,我也是蒙了,真每理解,这个应答,不是我先读,或者先写才有的么?

怎么我读的时候叫我当入口参数?不睡觉都赶不上刘少奇啊!

点评

看函数逻辑,参数作用是在读后回复时决定回复NAK还是ACK行为  详情 回复 发表于 5 天前
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:344
  • 最近打卡:2025-10-31 08:54:30
已绑定手机

90

主题

3347

回帖

7495

积分

荣誉版主

无情的代码机器

积分
7495
发表于 5 天前 | 显示全部楼层
wuzhe*** 发表于 2025-10-27 13:41
感谢指点,我也是蒙了,真每理解,这个应答,不是我先读,或者先写才有的么?

怎么我读的时候叫我当入口 ...

看函数逻辑,参数作用是在读后回复时决定回复NAK还是ACK行为
三天不学习,赶不上刘少奇~
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:55
  • 最近打卡:2025-10-31 09:22:07
已绑定手机

6

主题

580

回帖

1025

积分

金牌会员

积分
1025
发表于 5 天前 | 显示全部楼层
erci*** 发表于 2025-10-27 14:40
看函数逻辑,参数作用是在读后回复时决定回复NAK还是ACK行为

对,我打算先定义sbit  ACKHF
ACKHF=0;
这样才能调用这个函数往下走,谢谢指点!
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-11-1 07:47 , Processed in 0.131327 second(s), 96 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表