【小白提问】【已解决】对Ai8051U库函数的I2C模块的疑问
描述
本人新手,最近学习Ai8051U时用到I2C通讯,故而阅读Ai8051U创新风格库函数的I2C模块,有一部分不知道为什么这么写,想知道这么些有什么好处,若有大佬方便指点一二,在下感激不尽
这是set_i2c.c中的set_i2c_mode函数

78行: arg = va_arg(args, char *)是获取可变参数列表中的下一个参数,并存入arg变量,该函数的所有参数都是字符串(char *)
79到84行: 用sscanf函数匹配arg是否符合下面这些宏的值,并做出对应操作
#define I2c_End "end"
#define I2c_Enable "\x01enable" //设置I2C使能,默认为使能状态
#define I2c_Disable "\x01disable" //设置I2C外设关闭
#define I2c_P24_3 "i2c0" // 引脚切换宏定义,前面的是SCL,后面的是SDA
#define I2c_P15_4 "i2c1"
#define I2c_P32_3 "i2c3"
我的问题是
问题1
不理解79到81行为什么要用sscanf函数,82到84行用sscanf函数是因为要匹配整数(%d)和浮点数(%f)。79到81行为什么要用sscanf函数呢?直接判断是否相等不就行了吗,比如改成这样:
if (arg == "end")break; //遇到哨兵,结束
i2c_enable = arg == "\x01enable" ? 1 : i2c_enable; //使能i2c功能
i2c_enable = arg == "\x01disable" ? 0 : i2c_enable; //关闭i2c功能
原写法是:
if (sscanf(arg, "en%c", &_char) == 1)break; // 遇到哨兵,结束
i2c_enable = sscanf(arg, "\x01enabl%c", &_char) == 1 ? 1 : i2c_enable;//使能i2c功能
i2c_enable = sscanf(arg, "\x01disabl%c", &_char) == 1 ? 0 : i2c_enable;//关闭i2c功能
问题2
还有一个问题是,为什么83和84行的匹配字符串是 "%fkh%c"
和 "%fmh%c"
而不是 "%fkhz"
和 "%fmhz"
,比如改成这样:
i2c_speed = sscanf(arg, "%fkhz", &_i2c_speed) == 1 ? (_i2c_speed*1e3) : i2c_speed;//获取i2c通讯速率
i2c_speed = sscanf(arg, "%fmhz", &_i2c_speed) == 1 ? (_i2c_speed*1e6) : i2c_speed;//获取i2c通讯速率
原写法是:
i2c_speed = sscanf(arg, "%fkh%c", &_i2c_speed, &_char) == 2 ? (_i2c_speed*1e3) : i2c_speed;//获取i2c通讯速率
i2c_speed = sscanf(arg, "%fmh%c", &_i2c_speed, &_char) == 2 ? (_i2c_speed*1e6) : i2c_speed;//获取i2c通讯速率
原写法有什么好处吗?还是说我自己的写法是完全错误的?求大佬解答,谢谢。
有个建议
khz(千赫兹)和 mhz(兆赫兹)是不符合规范的单位,建议改成 kHz 和 MHz。望采纳
最后感谢创新风格库函数的编写人员,这个函数库真挺好用的。
已解决
问题1
问题1是我搞错了,直接用==判断其实比较的是两个字符串指针的地址是否相同,并不是比较字符串内容,C语言没学好了属于是,实际上应该分别比较每个字符,比如arg == "end"应该为arg[0]=='e'&&arg[1]=='n'&&arg[2]=='d'。然而之所以不这样是因为:
在嵌入式系统中,参数传递往往需要具备一定的灵活性和容错性。使用sscanf可以统一处理不同类型的参数格式,例如同时支持字符串、整数或浮点数的匹配,避免因参数类型不一致导致的错误。虽然当前代码中仅处理字符串,但统一的解析方式有助于后续功能扩展
详见2楼人工智能的回答。
问题2
问题2已经被3楼的大佬解释清楚了。