IIC基础知识
- IIC使用同步通信;
- IIC通信启动信号:时钟线高电平时,数据线提前下拉;
- 时钟线低电平时,设置数据线电平;
- 时钟线高电平时,读取数据线电平;
- ACK信号(应答信号):时钟线低电平时由接收方将数据线拉低;
- IIC通信结束信号,在时钟线处于高电平时将数据线拉高;
- i2c.h中的hi2c1和huart2,huart3一样,都是用于对某外设进行操作的句柄
- IIC通信一般使用七位地址码,IIC通信中每次发送都是1Byte,也就是8位,所以规定从机地址要左移一位。
- IIC协议规定,如果主机发起通信的目的是为了设置(写)从机,那么第八位为0;如果是为了读取从机,那么第八位为1。
//IIC读取函数
HAL_I2C_Master_Receive(&hi2c1, AHT20_ADRESS, &readBuffer, 1, HAL_MAX_DELAY);
//(外设操作句柄的指针, 要读取的从机地址, 用于接受数据的变量的指针, 读多少字节数据, 超时时间)
//IIC发送函数
HAL_I2C_Master_Transmit(&hi2c1, AHT20_ADRESS, sendBuffer, 3, HAL_MAX_DELAY);
//(外设操作句柄的指针, 从机地址, 用于发送数据的变量的指针, 发送数据长度, 超时时间)
//此处sendBuffer不加取地址符,因为数组名在 C 语言中自动退化为指向首元素的指针
//HAL 库需要的是数据缓冲区首地址的 uint8_t* 类型指针,而非数组指针,无需额外取地址
#include< > 和 #include” “的区别
sprintf函数
为了发送温湿度这种存在变量里的动态数据,通常使用sprintf函数构造字符串,sprintf 是 C 标准库中的一个函数,用于将格式化数据写入字符串(而不是直接输出到控制台或文件)。它的核心作用是将不同类型的数据(如整数、浮点数、字符串等)按照指定格式组合成一个字符串,常用于生成动态字符串或数据转换。
//函数原型
int sprintf(char *str, const char *format, …);
//参数:
//str:目标字符串的指针,结果会被写入这里。
//format:格式字符串,包含普通字符和格式说明符(如 %d, %f)。
//…:可变参数列表,按顺序对应格式字符串中的格式说明符。
//返回值:成功写入的字符数(不包括结尾的 \0),出错时返回负数。
#include <stdio.h>
int main() {
char buffer[100];
int age = 25;
char name[] = "Alice";
sprintf(buffer, "Name: %s, Age: %d", name, age);
// buffer 内容: "Name: Alice, Age: 25"
printf("%s\n", buffer);
return 0;
}
清零uintx_t的某位
(readBuffer[3] & 0x0F)
//此处按位与0x0F可以清零readBuffer[3]的高 4 位(假设readBuffer为uint8_t类型),仅保留低 4 位。
//例如
(0xF3 << 16) = 0x00F30000 // 实际有效数据应为低4位 0x03,错误的高 4 位 0xF 会污染最终结果。
(0xF3 & 0x0F) = 0x03 // 提取低4位
(0x03 << 16) = 0x00030000 // 正确的高位数据
#ifndef #define #endif作用
#ifndef(if not defined)
//作用:检查某个宏是否未被定义。若未定义,则编译其后的代码;若已定义,则跳过该代码块。
//语法:#ifndef MACRO_NAME
#define
//作用:定义一个宏。在头文件中通常用于标记该头文件已被包含。
//语法:#define MACRO_NAME
#endif
//作用:结束 #ifndef 或 #ifdef 的条件编译块。
//语法:#endif
二进制十六进制相关
在二进制数中,位的编号通常是从右往左开始数的,最右边的位称为第0位(最低有效位,LSB),依次向左递增
十六进制(Hex)和二进制(Bin)的转换非常直接,因为 16 是 2 的 4 次方,每个十六进制数字对应 4 位二进制数
0x3A → 二进制:
3 → 0011
A → 1010
合并:0011 1010 → 00111010(可简化为 111010,但建议保留 4 位对齐)。
0x1F → 二进制:
1 → 0001
F → 1111
合并:0001 1111 → 00011111。
二进制 → 十六进制
步骤:
从右向左将二进制数每 4 位分组,不足 4则在左侧补零。
每组转换为对应的十六进制字符。
10101100 → 十六进制:
分组:1010 1100
1010 → A,1100 → C
合并:0xAC。
11011 → 十六进制:
补零分组:0001 1011
0001 → 1,1011 → B
合并:0x1B(若从右分组错误会得到错误结果,必须左侧补零)。
好好好